Mercurial > hg > graal-compiler
changeset 16943:f8e60d11c0ec
Merge
author | Stefan Anzinger <stefan.anzinger@oracle.com> |
---|---|
date | Mon, 25 Aug 2014 21:15:59 -0700 |
parents | ae0f235469db (diff) 87a40fe1ba0c (current diff) |
children | a04d9cbc149f 4feac7e51f42 |
files | graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/HostBackend.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/InputType.java graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInfo.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/DonorThreadPool.java graal/com.oracle.graal.hotspot.jdk8.test/src/com/oracle/graal/hotspot/jdk8/test/CRC32UpdateByteBufferSubstitutionTest.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/BytecodeVerificationTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/GraalClassLoaderTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SlowPathTest.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Generic.java graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/PolymorphicLimit.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AbstractParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/ExtensionContext.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableAnnotationMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableExecutableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/api/element/WritableVariableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeAnnotationMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeAnnotationValue.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeCompilationUnit.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeElementScanner.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeExecutableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeImport.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeNames.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTree.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeBuilder.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTreeKind.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTypeElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeTypeMirror.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/CodeVariableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/ast/GeneratedElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/FixWarningsVisitor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/GenerateOverrideVisitor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/OrganizedImports.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/AbstractCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/Compiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/CompilerFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JDTCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/compiler/JavaCCompiler.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeExecutionData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeFieldData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGuardData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationThrowsData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ClassElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CodeElementFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/CompilationUnitFactory.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ParameterSpec.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/Template.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemCodeGenerator.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemParser.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLASTProber.java |
diffstat | 29 files changed, 1114 insertions(+), 153 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Mon Aug 25 21:15:59 2014 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.asm.amd64.test; +import static org.junit.Assume.*; + import java.nio.*; import org.junit.*; @@ -35,6 +37,11 @@ public class SimpleAssemblerTest extends AssemblerTest { + @Before + public void assumeNotSparc() { + assumeFalse(System.getProperty("os.arch").toLowerCase().contains("sparc")); + } + @Test public void intTest() { CodeGenTest test = new CodeGenTest() {
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Aug 25 21:15:59 2014 -0700 @@ -77,6 +77,7 @@ final int inst = masm.getInt(pos); Op2s op2 = Op2s.byValue((inst&OP2_MASK) >> OP2_SHIFT); switch(op2) { + case Br: case Fb: return Fmt00b.read(masm, op2, pos); case Sethi: @@ -213,6 +214,10 @@ private static final int DISP22_MASK = 0b00000000001111111111111111111111; // @formatter:on + public Fmt00b(boolean annul, ConditionFlag cond, Op2s op2, Label label) { + this(annul ? 1 : 0, cond.getValue(), op2.getValue(), 0, label); + } + public Fmt00b(boolean annul, FCond cond, Op2s op2, Label label) { this(annul ? 1 : 0, cond.getValue(), op2.getValue(), 0, label); } @@ -810,14 +815,19 @@ } public void verify() { - assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT); - assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT); - assert ((rs1 << RS1_SHIFT) & RS1_MASK) == (rs1 << RS1_SHIFT); - assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT); - assert ((x << X_SHIFT) & X_MASK) == (x << X_SHIFT); - assert ((immAsi << IMM_ASI_SHIFT) & IMM_ASI_MASK) == (immAsi << IMM_ASI_SHIFT); - assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT); - assert isSimm13(simm13); + assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT) : this; + assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT) : this; + assert ((rs1 << RS1_SHIFT) & RS1_MASK) == (rs1 << RS1_SHIFT) : this; + assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT) : this; + assert ((x << X_SHIFT) & X_MASK) == (x << X_SHIFT) : this; + assert ((immAsi << IMM_ASI_SHIFT) & IMM_ASI_MASK) == (immAsi << IMM_ASI_SHIFT) : this; + assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT) : this; + assert isSimm13(simm13) : this; + } + + @Override + public String toString() { + return String.format("%s: [rd: 0x%x, op3: 0x%x, rs1: 0x%x, i: 0x%x, x: 0x%x, immAsi: 0x%x, rs2: 0x%x, simm13: 0x%x", getClass().getName(), rd, op3, rs1, i, x, immAsi, rs2, simm13); } } @@ -1432,7 +1442,8 @@ Movstouw(0x111, "movstouw"), Movstosw(0x113, "movstosw"), Movxtod(0x118, "movxtod"), - Movwtos(0x119, "movwtos"), + Movwtos(0b1_0001_1001, "movwtos"), + UMulxhi(0b0_0001_0110, "umulxhi"), // end VIS3 // start CAMMELLIA @@ -1682,6 +1693,18 @@ public String getOperator() { return operator; } + + public ConditionFlag negate() { + switch (this) { + case CarrySet: + return CarryClear; + case CarryClear: + return CarrySet; + default: + GraalInternalError.unimplemented(); + } + return null; + } } public enum RCondition { @@ -1978,6 +2001,13 @@ } } + public static class Umulxhi extends Fmt3p { + public Umulxhi(Register src1, Register src2, Register dst) { + /* VIS3 only */ + super(Ops.ArithOp, Op3s.Impdep1, Opfs.UMulxhi, src1, src2, dst); + } + } + public static class Movxtod extends Fmt3p { public Movxtod(Register src, Register dst) { /* VIS3 only */ @@ -2812,6 +2842,13 @@ } } + public static class Fsmuld extends Fmt3p { + + public Fsmuld(Register src1, Register src2, Register dst) { + super(Ops.ArithOp, Op3s.Fpop1, Opfs.Fsmuld, src1, src2, dst); + } + } + public static class Fmul8x16 extends Fmt3p { public Fmul8x16(Register src1, Register src2, Register dst) {
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Mon Aug 25 21:15:59 2014 -0700 @@ -327,7 +327,7 @@ public void emit(SPARCMacroAssembler masm) { if (value == 0) { new Clr(dst).emit(masm); - } else if (-4095 <= value && value <= 4096) { + } else if (isSimm13(value)) { new Or(g0, value, dst).emit(masm); } else if (value >= 0 && ((value & 0x3FFF) == 0)) { new Sethi(hi22(value), dst).emit(masm);
--- a/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java Mon Aug 25 21:15:59 2014 -0700 @@ -32,7 +32,7 @@ @Before public void setUp() { - assumeTrue(isArchitecture("AMD64")); + assumeTrue(isArchitecture("x86_64")); } @Test
--- a/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCAllocatorTest.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/SPARCAllocatorTest.java Mon Aug 25 21:15:59 2014 -0700 @@ -55,7 +55,7 @@ @Test public void test3() { - test("test3snippet", 4, 0, 0); + test("test3snippet", 3, 1, 0); } public static long test3snippet(long x) {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Aug 25 21:15:59 2014 -0700 @@ -35,6 +35,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; @@ -232,7 +233,7 @@ break; case Float: case Double: - append(new BranchOp(cond, trueDestination, falseDestination, kind)); + append(new BranchOp(finalCondition, trueDestination, falseDestination, kind)); break; default: throw GraalInternalError.shouldNotReachHere("" + left.getKind()); @@ -241,8 +242,7 @@ @Override public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability) { - // append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, label)); - throw GraalInternalError.unimplemented(); + append(new BranchOp(ConditionFlag.CarrySet, overflow, noOverflow, Kind.Long)); } @Override @@ -308,10 +308,10 @@ switch ((Kind) cmpKind) { case Short: case Char: - append(new CompareOp(ICMP, emitZeroExtend(left, 16, 32), emitZeroExtend(right, 16, 32))); + append(new CompareOp(ICMP, emitSignExtend(left, 16, 32), emitSignExtend(right, 16, 32))); break; case Byte: - append(new CompareOp(ICMP, emitZeroExtend(left, 8, 32), emitZeroExtend(right, 8, 32))); + append(new CompareOp(ICMP, emitSignExtend(left, 8, 32), emitSignExtend(right, 8, 32))); break; case Int: append(new CompareOp(ICMP, left, right)); @@ -355,9 +355,7 @@ @Override public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) { - // a temp is needed for loading long and object constants - boolean needsTemp = key.getKind() == Kind.Long || key.getKind() == Kind.Object; - append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, needsTemp ? newVariable(key.getLIRKind()) : Value.ILLEGAL)); + append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key, newVariable(key.getLIRKind()))); } @Override @@ -457,16 +455,16 @@ Variable result = newVariable(LIRKind.derive(input)); switch (input.getKind().getStackKind()) { case Long: - append(new Op1Stack(LNEG, result, input)); + append(new Unary2Op(LNEG, result, load(input))); break; case Int: - append(new Op1Stack(INEG, result, input)); + append(new Unary2Op(INEG, result, load(input))); break; case Float: - append(new Op1Stack(FNEG, result, input)); + append(new Unary2Op(FNEG, result, load(input))); break; case Double: - append(new Op1Stack(DNEG, result, input)); + append(new Unary2Op(DNEG, result, load(input))); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -479,10 +477,10 @@ Variable result = newVariable(LIRKind.derive(input)); switch (input.getKind().getStackKind()) { case Int: - append(new Op1Stack(INOT, result, input)); + append(new Unary2Op(INOT, result, load(input))); break; case Long: - append(new Op1Stack(LNOT, result, input)); + append(new Unary2Op(LNOT, result, load(input))); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -597,12 +595,33 @@ @Override public Value emitMulHigh(Value a, Value b) { - throw GraalInternalError.unimplemented(); + switch (a.getKind().getStackKind()) { + case Int: + return emitMulHigh(IMUL, a, b); + case Long: + return emitMulHigh(LMUL, a, b); + default: + throw GraalInternalError.shouldNotReachHere(); + } } @Override public Value emitUMulHigh(Value a, Value b) { - throw GraalInternalError.unimplemented(); + switch (a.getKind().getStackKind()) { + case Int: + return emitMulHigh(IUMUL, a, b); + case Long: + return emitMulHigh(LUMUL, a, b); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + private Value emitMulHigh(SPARCArithmetic opcode, Value a, Value b) { + Variable result = newVariable(LIRKind.derive(a, b)); + MulHighOp mulHigh = new MulHighOp(opcode, load(a), load(b), result, newVariable(LIRKind.derive(a, b))); + append(mulHigh); + return result; } @Override @@ -665,10 +684,10 @@ Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind().getStackKind()) { case Int: - append(new RemOp(IUREM, result, a, loadNonConst(b), state, this)); + append(new RemOp(IUREM, result, load(a), load(b), state, this)); break; case Long: - append(new RemOp(LUREM, result, a, loadNonConst(b), state, this)); + append(new RemOp(LUREM, result, load(a), loadNonConst(b), state, this)); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -680,9 +699,13 @@ @Override public Value emitUDiv(Value a, Value b, LIRFrameState state) { SPARCArithmetic op; + Value actualA = a; + Value actualB = b; switch (a.getKind().getStackKind()) { case Int: op = IUDIV; + actualA = emitZeroExtend(actualA, 32, 64); + actualB = emitZeroExtend(actualB, 32, 64); break; case Long: op = LUDIV; @@ -690,7 +713,7 @@ default: throw GraalInternalError.shouldNotReachHere(); } - return emitBinary(op, false, a, b, state); + return emitBinary(op, false, actualA, actualB, state); } @Override @@ -912,14 +935,14 @@ append(new BinaryRegConst(SPARCArithmetic.LAND, result, asAllocatable(inputVal), Constant.forLong(mask), null)); return result; } else { - assert inputVal.getKind() == Kind.Int || inputVal.getKind() == Kind.Short || inputVal.getKind() == Kind.Byte : inputVal.getKind(); + assert inputVal.getKind() == Kind.Int || inputVal.getKind() == Kind.Short || inputVal.getKind() == Kind.Byte || inputVal.getKind() == Kind.Char : inputVal.getKind(); Variable result = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int)); long mask = IntegerStamp.defaultMask(fromBits); - Constant constant = Constant.forLong(mask); - if (canInlineConstant(constant)) { + Constant constant = Constant.forInt((int) mask); + if (fromBits == 32) { + append(new ShiftOp(IUSHR, result, inputVal, Constant.forInt(0))); + } else if (canInlineConstant(constant)) { append(new BinaryRegConst(SPARCArithmetic.IAND, result, asAllocatable(inputVal), constant, null)); - } else if (fromBits == 32) { - append(new ShiftOp(IUSHR, result, inputVal, Constant.forInt(0))); } else { Variable maskVar = newVariable(LIRKind.derive(inputVal).changeType(Kind.Int)); emitMove(maskVar, constant);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Mon Aug 25 21:15:59 2014 -0700 @@ -26,11 +26,10 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.sparc.SPARC.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import java.util.*; -import sun.misc.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; @@ -61,8 +60,6 @@ */ public class SPARCHotSpotBackend extends HotSpotHostBackend { - private static final Unsafe unsafe = Unsafe.getUnsafe(); - public SPARCHotSpotBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) { super(runtime, providers); } @@ -139,12 +136,18 @@ @Override public void enter(CompilationResultBuilder crb) { final int frameSize = crb.frameMap.totalFrameSize(); - + final int stackpoinerChange = -frameSize; SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; if (!isStub && pagesToBang > 0) { emitStackOverflowCheck(crb, pagesToBang, false); } - new Save(sp, -frameSize, sp).emit(masm); + + if (SPARCAssembler.isSimm13(stackpoinerChange)) { + new Save(sp, stackpoinerChange, sp).emit(masm); + } else { + new Setx(stackpoinerChange, g3).emit(masm); + new Save(sp, g3, sp).emit(masm); + } if (ZapStackOnMethodEntry.getValue()) { final int slotSize = 8;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java Mon Aug 25 21:15:59 2014 -0700 @@ -29,12 +29,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.CC; -import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; -import com.oracle.graal.asm.sparc.SPARCAssembler.Jmpl; -import com.oracle.graal.asm.sparc.SPARCAssembler.Lduw; -import com.oracle.graal.asm.sparc.SPARCAssembler.Movcc; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; +import com.oracle.graal.asm.sparc.SPARCAssembler.*; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @@ -74,5 +70,6 @@ new Movcc(ConditionFlag.NotZero, CC.Icc, l7, sp).emit(masm); new Jmpl(asRegister(handlerInCallerPc), 0, g0).emit(masm); + new Nop().emit(masm); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Mon Aug 25 21:15:59 2014 -0700 @@ -206,12 +206,15 @@ } public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) { + Variable newValueTemp = newVariable(newValue.getLIRKind()); + emitMove(newValueTemp, newValue); + LIRKind kind = newValue.getLIRKind(); assert kind.equals(expectedValue.getLIRKind()); Kind memKind = (Kind) kind.getPlatformKind(); SPARCAddressValue addressValue = asAddressValue(address); - append(new CompareAndSwapOp(asAllocatable(addressValue), asAllocatable(expectedValue), asAllocatable(newValue))); - return emitConditionalMove(memKind, expectedValue, newValue, Condition.EQ, true, trueValue, falseValue); + append(new CompareAndSwapOp(asAllocatable(addressValue), asAllocatable(expectedValue), asAllocatable(newValueTemp))); + return emitConditionalMove(memKind, expectedValue, newValueTemp, Condition.EQ, true, trueValue, falseValue); } public StackSlot getDeoptimizationRescueSlot() {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java Mon Aug 25 21:15:59 2014 -0700 @@ -36,6 +36,9 @@ @Opcode("LEAVE_CURRENT_STACK_FRAME") final class SPARCHotSpotLeaveCurrentStackFrameOp extends SPARCLIRInstruction { + public SPARCHotSpotLeaveCurrentStackFrameOp() { + } + @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { // Save O registers over restore.
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java Mon Aug 25 21:15:59 2014 -0700 @@ -63,5 +63,7 @@ new Stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm); new Stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset)).emit(masm); new Stw(g0, new SPARCAddress(thread, threadJavaFrameAnchorFlagsOffset)).emit(masm); + + new Movdtox(f31, i0).emit(masm); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Mon Aug 25 21:15:59 2014 -0700 @@ -30,6 +30,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.*; @@ -85,8 +86,14 @@ private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5}; private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7}; - - private final Register[] callerSaveRegisters = {g1, g3, g4, g5, o0, o1, o2, o3, o4, o5, o7}; + // @formatter:off + private final Register[] callerSaveRegisters = + {g1, g3, g4, g5, o0, o1, o2, o3, o4, o5, o7, + f0, f1, f2, f3, f4, f5, f6, f7, + f8, f9, f10, f11, f12, f13, f14, f15, + f16, f17, f18, f19, f20, f21, f22, f23, + f24, f25, f26, f27, f28, f29, f30, f31}; + // @formatter:on /** * Registers saved by the callee. This lists all L and I registers which are saved in the @@ -238,10 +245,7 @@ if (locations[i] == null) { // Stack slot is always aligned to its size in bytes but minimum wordsize int typeSize = SPARC.spillSlotSize(target, kind); - int modulus = currentStackOffset % typeSize; - if (modulus != 0) { - currentStackOffset += typeSize - modulus; - } + currentStackOffset = NumUtil.roundUp(currentStackOffset, typeSize); locations[i] = StackSlot.get(target.getLIRKind(kind.getStackKind()), currentStackOffset, !type.out); currentStackOffset += typeSize; }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java Mon Aug 25 21:15:59 2014 -0700 @@ -28,6 +28,7 @@ import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov; import com.oracle.graal.hotspot.stubs.*; @@ -61,7 +62,7 @@ // Get return address (is in o7 after leave). Register returnAddress = asRegister(cc.getArgument(1)); - new Mov(o7, returnAddress).emit(masm); + new Add(o7, Return.PC_RETURN_OFFSET, returnAddress).emit(masm); Register scratch = g5; SPARCCall.indirectJmp(crb, masm, scratch, linkage); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Mon Aug 25 21:15:59 2014 -0700 @@ -223,25 +223,48 @@ int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask(); + Unsigned vectorSize = Word.unsigned(VECTOR_SIZE); Unsigned srcOffset = Word.unsigned(srcPos).shiftLeft(log2ElementSize).add(headerSize); Unsigned destOffset = Word.unsigned(destPos).shiftLeft(log2ElementSize).add(headerSize); Unsigned destStart = destOffset; - Unsigned sizeInBytes = Word.unsigned(length).shiftLeft(log2ElementSize); Unsigned destEnd = destOffset.add(Word.unsigned(length).shiftLeft(log2ElementSize)); - Unsigned nonVectorBytes = sizeInBytes.unsignedRemainder(Word.unsigned(VECTOR_SIZE)); + Unsigned destVectorEnd = null; + Unsigned nonVectorBytes = null; + Unsigned sizeInBytes = Word.unsigned(length).shiftLeft(log2ElementSize); + if (supportsUnalignedMemoryAccess) { + nonVectorBytes = sizeInBytes.unsignedRemainder(vectorSize); + destVectorEnd = destEnd; + } else { + boolean inPhase = srcOffset.and((int) VECTOR_SIZE - 1).equal(destOffset.and((int) VECTOR_SIZE - 1)); + boolean hasAtLeastOneVector = sizeInBytes.aboveOrEqual(vectorSize); + // We must have at least one full vector, otherwise we must copy each byte separately + if (hasAtLeastOneVector && inPhase) { // If in phase, we can vectorize + nonVectorBytes = vectorSize.subtract(destStart.unsignedRemainder(vectorSize)); + } else { // fallback is byte-wise + nonVectorBytes = sizeInBytes; + } + destVectorEnd = destEnd.subtract(destEnd.unsignedRemainder(vectorSize)); + } + Unsigned destNonVectorEnd = destStart.add(nonVectorBytes); - while (destOffset.belowThan(destNonVectorEnd)) { ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, ANY_LOCATION), ANY_LOCATION); destOffset = destOffset.add(1); srcOffset = srcOffset.add(1); } - while (destOffset.belowThan(destEnd)) { + // Unsigned destVectorEnd = destEnd.subtract(destEnd.unsignedRemainder(8)); + while (destOffset.belowThan(destVectorEnd)) { ObjectAccess.writeWord(dest, destOffset, ObjectAccess.readWord(src, srcOffset, ANY_LOCATION), ANY_LOCATION); destOffset = destOffset.add(wordSize()); srcOffset = srcOffset.add(wordSize()); } + // Do the last bytes each when it is required to have absolute alignment. + while (!supportsUnalignedMemoryAccess && destOffset.belowThan(destEnd)) { + ObjectAccess.writeByte(dest, destOffset, ObjectAccess.readByte(src, srcOffset, ANY_LOCATION), ANY_LOCATION); + destOffset = destOffset.add(1); + srcOffset = srcOffset.add(1); + } } public static class Templates extends AbstractTemplates {
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/IntegerBits.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/IntegerBits.java Mon Aug 25 21:15:59 2014 -0700 @@ -103,4 +103,60 @@ public void run10() { runTest("test4", 0xffffffff); } + + @Test + public void run11() { + runTest("test2", 0xFFFFFFFF); + } + + @Test + public void run12() { + runTest("test2", 0x7FFFFFFF); + } + + @Test + public void run17() { + runTest("test2", 0x80000000); + } + + @Test + public void run18() { + runTest("test2", 0x40000000); + } + + @Test + public void run13() { + runTest("test3", 0x7FFFFFFF); + } + + @Test + public void run14() { + runTest("test3", 0xFFFFFFFF); + } + + @Test + public void run15() { + runTest("test3", 0x80000000); + } + + @Test + public void run16() { + runTest("test3", 0x40000000); + } + + @Test + public void run19() { + runTest("test4", 0x80000000); + } + + @Test + public void run20() { + runTest("test4", 0x40000000); + } + + @Test + public void run21() { + runTest("test4", 0x00000001); + } + }
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/micro/BigMixedParams04.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/micro/BigMixedParams04.java Mon Aug 25 21:15:59 2014 -0700 @@ -53,6 +53,212 @@ return 42; } + /** + * Test SPARC mixed params with double/single float register overlapping + * + * @param f1 + * @param d2 + * @param f3 + * @return Must always return the argument d2 + */ + @SuppressWarnings("all") + public static double test2(int i1, float f1, double d2, float f3, + // @formatter:off + double ad1 , + double ad2 , + double ad3 , + double ad4 , + double ad5 , + double ad6 , + double ad7 , + double ad8 , + double ad9 , + double ad10, + double ad11, + double ad12, + double ad13, + double ad14, + double ad15, + double ad16, + float af1 , + float af2 , + float af3 , + float af4 , + float af5 , + float af6 , + float af7 , + float af8 , + float af9 , + float af10, + float af11, + float af12, + float af13, + float af14, + float af15, + float af16 + // @formatter:on + ) { + + // now do something with the locals to make sure the locals don't get optimized away. + for (int i = 0; i < i1; i++) { + af1 += f1; + af2 += f1; + af3 += f1; + af4 += f1; + af5 += f1; + af6 += f1; + af7 += f1; + af8 += f1; + af9 += f1; + af10 += f1; + af11 += f1; + af12 += f1; + af13 += f1; + af14 += f1; + af15 += f1; + af16 += f1; + ad1 += f1; + ad2 += f1; + ad3 += f1; + ad4 += f1; + ad5 += f1; + ad6 += f1; + ad7 += f1; + ad8 += f1; + ad9 += f1; + ad10 += f1; + ad11 += f1; + ad12 += f1; + ad13 += f1; + ad14 += f1; + ad15 += f1; + ad16 += f1; + } + // @formatter:off + boolean orderFloat = + af1 < af2 && + af2 < af3 && + af3 < af4 && + af4 < af5 && + af5 < af6 && + af6 < af7 && + af7 < af8 && + af8 < af9 && + af9 < af10 && + af10 < af11 && + af11 < af12 && + af12 < af13 && + af13 < af14 && + af14 < af15 && + af15 < af16; + boolean orderDouble = + ad1 < ad2 && + ad2 < ad3 && + ad3 < ad4 && + ad4 < ad5 && + ad5 < ad6 && + ad6 < ad7 && + ad7 < ad8 && + ad8 < ad9 && + ad9 < ad10 && + ad10 < ad11 && + ad11 < ad12 && + ad12 < ad13 && + ad13 < ad14 && + ad14 < ad15 && + ad15 < ad16; + // @formatter:on + if (orderDouble && orderFloat) { + return f1 + d2 + f3; // this should not be destroyed + } + Assert.fail(); + return 0.0; + } + + /** + * Test SPARC mixed params with double/single float register overlapping + * + * @param f1 + * @param d2 + * @param f3 + * @return Must always return the argument d2 + */ + @SuppressWarnings("all") + public static double test3(boolean f, int idx, + // @formatter:off + double ad1 , + double ad2 , + double ad3 , + double ad4 , + double ad5 , + double ad6 , + double ad7 , + double ad8 , + double ad9 , + double ad10, + double ad11, + double ad12, + double ad13, + double ad14, + double ad15, + double ad16, + float af1 , + float af2 , + float af3 , + float af4 , + float af5 , + float af6 , + float af7 , + float af8 , + float af9 , + float af10, + float af11, + float af12, + float af13, + float af14, + float af15, + float af16 + ) { + switch(f ? idx + 16 : idx) { + case 1 : return ad1 ; + case 2 : return ad2 ; + case 3 : return ad3 ; + case 4 : return ad4 ; + case 5 : return ad5 ; + case 6 : return ad6 ; + case 7 : return ad7 ; + case 8 : return ad8 ; + case 9 : return ad9 ; + case 10: return ad10; + case 11: return ad11; + case 12: return ad12; + case 13: return ad13; + case 14: return ad14; + case 15: return ad15; + case 16: return ad16; + case 1 + 16: return af1 ; + case 2 + 16: return af2 ; + case 3 + 16: return af3 ; + case 4 + 16: return af4 ; + case 5 + 16: return af5 ; + case 6 + 16: return af6 ; + case 7 + 16: return af7 ; + case 8 + 16: return af8 ; + case 9 + 16: return af9 ; + case 10 + 16: return af10; + case 11 + 16: return af11; + case 12 + 16: return af12; + case 13 + 16: return af13; + case 14 + 16: return af14; + case 15 + 16: return af15; + case 16 + 16: return af16; + } + Assert.fail(); // should not reach here + return 0; + + } + // @formatter:on + @Test public void run0() throws Throwable { runTest("test", 0, -1, -1, -1, -1, 1d, 2d, true, false, (byte) -128, (short) -0x7FFF, (char) 0xFFFF, -0x7FFFFFF); @@ -82,4 +288,86 @@ public void run5() throws Throwable { runTest("test", 5, -1, -1, -1, -1, 1d, 2d, true, false, (byte) -128, (short) -0x7FFF, (char) 0xFFFF, -0x7FFFFFF); } + + @Test + public void run6() throws Throwable { + // @formatter:off + runTest("test2", 20, 1.0f, -3.2912948246387967943231233d, 3.0f, + 1d, + 2d, + 3d, + 4d, + 5d, + 6d, + 7d, + 8d, + 9d, + 10d, + 11d, + 12d, + 13d, + 14d, + 15d, + 16d, + 1f, + 2f, + 3f, + 4f, + 5f, + 6f, + 7f, + 8f, + 9f, + 10f, + 11f, + 12f, + 13f, + 14f, + 15f, + 16f + ); + // @formatter:on + } + + @Test + public void run7() throws Throwable { + // @formatter:off + for(int i =0; i<32*2; i++) + runTest("test3", i%2==0, i/2, + 1d, + 2d, + 3d, + 4d, + 5d, + 6d, + 7d, + 8d, + 9d, + 10d, + 11d, + 12d, + 13d, + 14d, + 15d, + 16d, + 1f, + 2f, + 3f, + 4f, + 5f, + 6f, + 7f, + 8f, + 9f, + 10f, + 11f, + 12f, + 13f, + 14f, + 15f, + 16f + ); + // @formatter:on + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/SignExtendShort.java Mon Aug 25 21:15:59 2014 -0700 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.jtt.optimize; + +import org.junit.*; + +import com.oracle.graal.jtt.*; + +/* + */ +public class SignExtendShort extends JTTTest { + + public static int val; + + public static boolean test(short[] b) { + val = b[2]; + int x = 0; + return val >= x; + } + + @Test + public void run0() throws Throwable { + runTest("test", new short[]{0, 0, 0}); + } + + @Test + public void run1() throws Throwable { + runTest("test", new short[]{0, 0, 1}); + } + + @Test + public void run2() throws Throwable { + runTest("test", new short[]{0, 0, -1}); + } + + @Test + public void run3() throws Throwable { + runTest("test", new short[]{0, 0, Short.MAX_VALUE}); + } + + @Test + public void run4() throws Throwable { + runTest("test", new short[]{0, 0, Short.MIN_VALUE}); + } +}
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/Switch02.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/Switch02.java Mon Aug 25 21:15:59 2014 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.jtt.optimize; +import java.util.*; + import org.junit.*; import com.oracle.graal.jtt.*; @@ -30,6 +32,9 @@ * Tests optimization of switches. */ public class Switch02 extends JTTTest { + private static char staticCharVal = 0; + private static short staticShortVal = 0; + private static byte staticByteVal = 0; public static int test(int arg) { switch (arg) { @@ -40,6 +45,168 @@ } } + public static int test2char(char arg) { + int result = 392123; + Object x = null; + char val = staticCharVal != 0 ? staticCharVal : arg; + switch (val) { + case (char) 0xFFFF: + result = 23212 / val; + break; + case (char) 0xFFFF - 3: + result = 932991439 / val; + break; + case (char) 0xFFFF - 6: + result = 47329561 / val; + break; + case (char) 0xFFFF - 9: + result = 1950976984 / val; + break; + case (char) 0xFFFF - 10: + result = 97105581 / val; + switch (result) { + case 1: + result = 321; + break; + default: + result = 2391; + break; + } + break; + case (char) 0xFFFF - 12: + result = 99757362 / val; + break; + case (char) 0xFFFF - 15: + result = 912573 / val; + x = new LinkedList<>(); + break; + case (char) 0xFFFF - 18: + x = new HashSet<>(); + result = 876765 / val; + break; + case (char) 0xFFFF - 19: + result = 75442917 / val; + break; + case (char) 0xFFFF - 21: + result = 858112498 / val; + x = new Hashtable<>(); + break; + default: + result = 34324341 / val; + } + result = result + (x == null ? 0 : x.hashCode()); + return result; + } + + public static int test2short(short arg) { + int result = 392123; + Object x = null; + short val = staticShortVal != 0 ? staticShortVal : arg; + switch (val) { + case (short) -0x7FFF: + result = 23212 / val; + break; + case (short) -0x7FFF + 3: + result = 932991439 / val; + break; + case (short) -0x7FFF + 6: + result = 47329561 / val; + break; + case (short) -0x7FFF + 9: + result = 1950976984 / val; + break; + case (short) -0x7FFF + 10: + result = 97105581 / val; + switch (result) { + case 1: + result = 321; + break; + default: + result = 2391; + break; + } + break; + case (short) -0x7FFF + 12: + result = 99757362 / val; + break; + case (short) -0x7FFF + 15: + result = 912573 / val; + x = new LinkedList<>(); + break; + case (short) -0x7FFF + 18: + x = new HashSet<>(); + result = 876765 / val; + break; + case (short) -0x7FFF + 19: + result = 75442917 / val; + break; + case (short) -0x7FFF + 21: + result = 858112498 / val; + x = new Hashtable<>(); + break; + default: + result = 34324341 / val; + } + result = result + (x == null ? 0 : x.hashCode()); + return result; + } + + public static int test2byte(byte arg) { + int result = 392123; + Object x = null; + byte val = staticByteVal != 0 ? staticByteVal : arg; + switch (val) { + case (byte) -0x7F: + result = 23212 / val; + break; + case (byte) -0x7F + 3: + result = 932991439 / val; + break; + case (byte) -0x7F + 6: + result = 47329561 / val; + break; + case (byte) -0x7F + 9: + result = 1950976984 / val; + break; + case (byte) -0x7F + 10: + result = 97105581 / val; + switch (result) { + case 1: + result = 321; + break; + default: + result = 2391; + break; + } + break; + case (byte) -0x7F + 12: + result = 99757362 / val; + break; + case (byte) -0x7F + 15: + result = 912573 / val; + x = new LinkedList<>(); + break; + case (byte) -0x7F + 18: + x = new HashSet<>(); + result = 876765 / val; + break; + case (byte) -0x7F + 19: + result = 75442917 / val; + break; + case (byte) -0x7F + 20: + result = 856261268 / val; + break; + case (byte) -0x7F + 21: + result = 858112498 / val; + x = new Hashtable<>(); + break; + default: + result = 34324341 / val; + } + result = result + (x == null ? 0 : x.hashCode()); + return result; + } + @Test public void run0() throws Throwable { runTest("test", 0); @@ -50,4 +217,63 @@ runTest("test", 1); } + @Test + public void run2() throws Throwable { + runTest("test2char", (char) (0x0)); + runTest("test2char", (char) (0xFFFF)); + runTest("test2char", (char) (0xFFFF - 21)); // miss + runTest("test2char", (char) (0xFFFF - 22)); // hit + runTest("test2char", (char) (0xFFFF - 23)); // miss (out of bound) + + staticCharVal = (char) 0xFFFF; + runTest("test2char", (char) 0); + staticCharVal = (char) (0xFFFF - 21); + runTest("test2char", (char) 0xFFFF); + staticCharVal = (char) (0xFFFF - 22); + runTest("test2char", (char) 0xFFFF); + staticCharVal = (char) (0xFFFF - 23); + runTest("test2char", (char) 0xFFFF); + } + + @Test + public void run3() throws Throwable { + runTest("test2short", (short) 0x0); + runTest("test2short", (short) -0x7FFF); + runTest("test2short", (short) (-0x7FFF + 21)); // Miss + runTest("test2short", (short) (-0x7FFF + 22)); // hit + runTest("test2short", (short) (-0x7FFF + 23)); // miss (out of bound) + runTest("test2short", (short) 0x7FFF); // miss (out of bound) + + staticShortVal = (short) -0x7FFF; + runTest("test2short", (short) 0); + staticShortVal = (short) (-0x7FFF + 21); + runTest("test2short", (short) 0); + staticShortVal = (short) (-0x7FFF + 22); + runTest("test2short", (short) 0); + staticShortVal = (short) (-0x7FFF + 23); + runTest("test2short", (short) 0); + staticShortVal = (short) 0x7FFF; + runTest("test2short", (short) 0); + } + + @Test + public void run4() throws Throwable { + runTest("test2byte", (byte) 0); + runTest("test2byte", (byte) -0x7F); + runTest("test2byte", (byte) (-0x7F + 21)); // Miss + runTest("test2byte", (byte) (-0x7F + 22)); // hit + runTest("test2byte", (byte) (-0x7F + 23)); // miss (out of bound) + runTest("test2byte", (byte) 0x7F); // miss (out of bound) + + staticByteVal = (byte) -0x7F; + runTest("test2short", (short) 0); + staticByteVal = (byte) (-0x7F + 21); + runTest("test2short", (short) 0); + staticByteVal = (byte) (-0x7F + 22); + runTest("test2short", (short) 0); + staticByteVal = (byte) (-0x7F + 23); + runTest("test2short", (short) 0); + staticByteVal = (byte) 0x7F; + runTest("test2short", (short) 0); + } }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Mon Aug 25 21:15:59 2014 -0700 @@ -27,6 +27,7 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import com.oracle.graal.compiler.common.*; @@ -37,8 +38,8 @@ public enum SPARCArithmetic { // @formatter:off - IADD, ISUB, IMUL, IDIV, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR, - LADD, LSUB, LMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, + IADD, ISUB, IMUL, IUMUL, IDIV, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR, + LADD, LSUB, LMUL, LUMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR, DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR, INEG, LNEG, FNEG, DNEG, INOT, LNOT, @@ -161,6 +162,10 @@ @State protected LIRFrameState state; protected Constant y; + public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) { + this(opcode, result, x, y, null); + } + public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y, LIRFrameState state) { this.opcode = opcode; this.result = result; @@ -248,7 +253,7 @@ @Opcode private final SPARCArithmetic opcode; @Def({REG}) protected Value result; - @Use({REG, CONST}) protected Value x; + @Alive({REG, CONST}) protected Value x; @Alive({REG, CONST}) protected Value y; @Temp({REG}) protected Value scratch1; @Temp({REG}) protected Value scratch2; @@ -282,9 +287,16 @@ switch (opcode) { case ISUB: assert isSimm13(crb.asIntConst(src1)); - new Sub(SPARC.g0, asIntReg(src2), asIntReg(src2)).emit(masm); - new Add(asIntReg(src2), crb.asIntConst(src1), asIntReg(dst)).emit(masm); + new Sub(SPARC.g0, asIntReg(src2), asIntReg(dst)).emit(masm); + new Add(asIntReg(dst), crb.asIntConst(src1), asIntReg(dst)).emit(masm); break; + case LSUB: { + long c = crb.asLongConst(src1); + assert isSimm13(c); + new Sub(SPARC.g0, asLongReg(src2), asLongReg(dst)).emit(masm); + new Add(asLongReg(dst), (int) c, asLongReg(dst)).emit(masm); + break; + } case IAND: throw GraalInternalError.unimplemented(); case IDIV: @@ -292,13 +304,14 @@ exceptionOffset = masm.position(); new Sdivx(asIntReg(dst), asIntReg(src2), asIntReg(dst)).emit(masm); break; - case LDIV: + case LDIV: { int c = crb.asIntConst(src1); assert isSimm13(c); exceptionOffset = masm.position(); new Sdivx(asLongReg(src2), c, asLongReg(dst)).emit(masm); new Mulx(asLongReg(src1), asLongReg(dst), asLongReg(dst)).emit(masm); break; + } case FSUB: case FDIV: case DSUB: @@ -410,6 +423,7 @@ break; case DAND: SPARCAddress addr = (SPARCAddress) crb.recordDataReferenceInCode(asConstant(src2), 4); + addr = SPARCMove.guaranueeLoadable(addr, masm); new Lddf(addr, asDoubleReg(dst)).emit(masm); new Fandd(asDoubleReg(src1), asDoubleReg(dst), asDoubleReg(dst)).emit(masm); break; @@ -440,7 +454,6 @@ new Sdivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case IUDIV: - new Srl(asIntReg(src1), 0, asIntReg(src1)).emit(masm); exceptionOffset = masm.position(); new Udivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; @@ -506,7 +519,11 @@ new Fsubs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); break; case FMUL: - new Fmuls(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); + if (dst.getPlatformKind() == Kind.Double) { + new Fsmuld(asFloatReg(src1), asFloatReg(src2), asDoubleReg(dst)).emit(masm); + } else if (dst.getPlatformKind() == Kind.Float) { + new Fmuls(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); + } break; case FDIV: new Fdivs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); @@ -569,22 +586,25 @@ } else if (isConstant(src2)) { switch (opcode) { case IREM: + assert !src1.equals(scratch1); + assert !src1.equals(scratch2); + assert !src2.equals(scratch1); + // But src2 can be scratch2 assert isSimm13(crb.asIntConst(src2)); - new Sra(asIntReg(src1), 0, asIntReg(src1)).emit(masm); exceptionOffset = masm.position(); new Sdivx(asIntReg(src1), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm); new Mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch2)).emit(masm); new Sub(asIntReg(src1), asIntReg(scratch2), asIntReg(dst)).emit(masm); break; case IUREM: - new Sra(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm); - exceptionOffset = masm.position(); - new Udivx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm); - new Mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm); - new Sub(asIntReg(src1), asIntReg(scratch1), asIntReg(dst)).emit(masm); + GraalInternalError.unimplemented(); break; case LREM: assert isSimm13(crb.asIntConst(src2)); + assert !src1.equals(scratch1); + assert !src1.equals(scratch2); + assert !src2.equals(scratch1); + // But src2 can be scratch2 exceptionOffset = masm.position(); new Sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm); new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm); @@ -592,6 +612,10 @@ break; case LUREM: assert isSimm13(crb.asIntConst(src2)); + assert !src1.equals(scratch1); + assert !src1.equals(scratch2); + assert !src2.equals(scratch1); + // But src2 can be scratch2 exceptionOffset = masm.position(); new Udivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm); new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm); @@ -608,6 +632,9 @@ new Setx(crb.asLongConst(src1), asLongReg(scratch2), false).emit(masm); srcLeft = scratch2; } + assert !asLongReg(srcLeft).equals(asLongReg(scratch1)); + assert !asLongReg(src2).equals(asLongReg(scratch1)); + // But src2 can be scratch2 exceptionOffset = masm.position(); new Sdivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm); new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm); @@ -618,6 +645,8 @@ new Setx(crb.asLongConst(src1), asLongReg(scratch2), false).emit(masm); srcLeft = scratch2; } + assert !asLongReg(srcLeft).equals(asLongReg(scratch1)); + assert !asLongReg(src2).equals(asLongReg(scratch1)); exceptionOffset = masm.position(); new Udivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm); new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm); @@ -628,17 +657,22 @@ new Setx(crb.asIntConst(src1), asIntReg(scratch2), false).emit(masm); srcLeft = scratch2; } + assert !asIntReg(srcLeft).equals(asIntReg(scratch1)); + assert !asIntReg(src2).equals(asIntReg(scratch1)); exceptionOffset = masm.position(); new Sdivx(asIntReg(srcLeft), asIntReg(src2), asIntReg(scratch1)).emit(masm); new Mulx(asIntReg(scratch1), asIntReg(src2), asIntReg(scratch1)).emit(masm); new Sub(asIntReg(srcLeft), asIntReg(scratch1), asIntReg(dst)).emit(masm); break; case IUREM: - new Sra(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm); + assert !asIntReg(dst).equals(asIntReg(scratch1)); + assert !asIntReg(dst).equals(asIntReg(scratch2)); + new Srl(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm); + new Srl(asIntReg(src2), 0, asIntReg(dst)).emit(masm); exceptionOffset = masm.position(); - new Udivx(asIntReg(scratch1), asIntReg(src2), asIntReg(scratch1)).emit(masm); - new Mulx(asIntReg(scratch1), asIntReg(src2), asIntReg(scratch1)).emit(masm); - new Sub(asIntReg(src1), asIntReg(scratch1), asIntReg(dst)).emit(masm); + new Udivx(asIntReg(scratch1), asIntReg(dst), asIntReg(scratch2)).emit(masm); + new Mulx(asIntReg(scratch2), asIntReg(dst), asIntReg(dst)).emit(masm); + new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -653,6 +687,7 @@ public static void emit(CompilationResultBuilder crb, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info) { int exceptionOffset = -1; + Label notOrdered = new Label(); if (isRegister(src)) { switch (opcode) { case INEG: @@ -716,18 +751,20 @@ new Fstod(asFloatReg(src), asDoubleReg(dst)).emit(masm); break; case F2L: - new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(dst), asFloatReg(dst)).emit(masm); - new Fbe(false, 4 * 4).emit(masm); + new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm); + new Fbo(false, notOrdered).emit(masm); new Fstox(asFloatReg(src), asFloatReg(dst)).emit(masm); new Fitos(asFloatReg(dst), asFloatReg(dst)).emit(masm); new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm); + masm.bind(notOrdered); break; case F2I: - new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(dst), asFloatReg(dst)).emit(masm); - new Fbo(false, 4 * 4).emit(masm); + new Fcmp(CC.Fcc0, Opfs.Fcmps, asFloatReg(src), asFloatReg(src)).emit(masm); + new Fbo(false, notOrdered).emit(masm); new Fstoi(asFloatReg(src), asFloatReg(dst)).emit(masm); new Fitos(asFloatReg(dst), asFloatReg(dst)).emit(masm); new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm); + masm.bind(notOrdered); break; case MOV_D2L: new Movdtox(asDoubleReg(src), asLongReg(dst)).emit(masm); @@ -742,18 +779,20 @@ new Movwtos(asIntReg(src), asFloatReg(dst)).emit(masm); break; case D2L: - new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(dst), asDoubleReg(dst)).emit(masm); - new Fbo(false, 4 * 4).emit(masm); + new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm); + new Fbo(false, notOrdered).emit(masm); new Fdtox(asDoubleReg(src), asDoubleReg(dst)).emit(masm); new Fxtod(asDoubleReg(dst), asDoubleReg(dst)).emit(masm); new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm); + masm.bind(notOrdered); break; case D2I: - new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(dst), asDoubleReg(dst)).emit(masm); - new Fbo(false, 4 * 4).emit(masm); + new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm); + new Fbo(false, notOrdered).emit(masm); new Fdtoi(asDoubleReg(src), asDoubleReg(dst)).emit(masm); new Fitod(asDoubleReg(dst), asDoubleReg(dst)).emit(masm); new Fsubd(asDoubleReg(dst), asDoubleReg(dst), asDoubleReg(dst)).emit(masm); + masm.bind(notOrdered); break; case FNEG: new Fnegs(asFloatReg(src), asFloatReg(dst)).emit(masm); @@ -803,10 +842,14 @@ case IUSHR: case IUDIV: case IUREM: - rk = result.getKind(); + rk = result.getKind().getStackKind(); xsk = x.getKind().getStackKind(); ysk = y.getKind().getStackKind(); - assert rk == Kind.Int && xsk == Kind.Int && ysk == Kind.Int; + boolean valid = false; + for (Kind k : new Kind[]{Kind.Int, Kind.Short, Kind.Byte, Kind.Char}) { + valid |= rk == k && xsk == k && ysk == k; + } + assert valid : "rk: " + rk + " xsk: " + xsk + " ysk: " + ysk; break; case LADD: case LSUB: @@ -839,7 +882,7 @@ rk = result.getKind(); xk = x.getKind(); yk = y.getKind(); - assert rk == Kind.Float && xk == Kind.Float && yk == Kind.Float; + assert (rk == Kind.Float || rk == Kind.Double) && xk == Kind.Float && yk == Kind.Float; break; case DAND: case DADD: @@ -856,4 +899,56 @@ throw GraalInternalError.shouldNotReachHere("missing: " + opcode); } } + + public static class MulHighOp extends SPARCLIRInstruction { + + @Opcode private final SPARCArithmetic opcode; + @Def({REG}) public AllocatableValue result; + @Alive({REG}) public AllocatableValue x; + @Alive({REG}) public AllocatableValue y; + @Temp({REG}) public AllocatableValue scratch; + + public MulHighOp(SPARCArithmetic opcode, AllocatableValue x, AllocatableValue y, AllocatableValue result, AllocatableValue scratch) { + this.opcode = opcode; + this.x = x; + this.y = y; + this.scratch = scratch; + this.result = result; + } + + @Override + public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + assert isRegister(x) && isRegister(y) && isRegister(result) && isRegister(scratch); + switch (opcode) { + case IMUL: + new Mulx(asIntReg(x), asIntReg(y), asIntReg(result)).emit(masm); + new Srax(asIntReg(result), 32, asIntReg(result)).emit(masm); + break; + case IUMUL: + assert !asIntReg(scratch).equals(asIntReg(result)); + new Srl(asIntReg(x), 0, asIntReg(scratch)).emit(masm); + new Srl(asIntReg(y), 0, asIntReg(result)).emit(masm); + new Mulx(asIntReg(result), asIntReg(scratch), asIntReg(result)).emit(masm); + new Srlx(asIntReg(result), 32, asIntReg(result)).emit(masm); + break; + case LMUL: + assert !asLongReg(scratch).equals(asLongReg(result)); + new Umulxhi(asLongReg(x), asLongReg(y), asLongReg(result)).emit(masm); + + new Srlx(asLongReg(x), 63, asLongReg(scratch)).emit(masm); + new Mulx(asLongReg(scratch), asLongReg(y), asLongReg(scratch)).emit(masm); + new Sub(asLongReg(result), asLongReg(scratch), asLongReg(result)).emit(masm); + + new Srlx(asLongReg(y), 63, asLongReg(scratch)).emit(masm); + new Mulx(asLongReg(scratch), asLongReg(x), asLongReg(scratch)).emit(masm); + new Sub(asLongReg(result), asLongReg(scratch), asLongReg(result)).emit(masm); + break; + case LUMUL: + new Umulxhi(asLongReg(x), asLongReg(y), asLongReg(result)).emit(masm); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Mon Aug 25 21:15:59 2014 -0700 @@ -96,9 +96,10 @@ Kind ikind = input.getKind(); assert ikind == Kind.Int; Register tmp = asRegister(scratch); + assert !tmp.equals(dst); new Srl(src, 1, tmp).emit(masm); new Srl(src, 0, dst).emit(masm); - new Or(src, tmp, dst).emit(masm); + new Or(dst, tmp, dst).emit(masm); new Srl(dst, 2, tmp).emit(masm); new Or(dst, tmp, dst).emit(masm); new Srl(dst, 4, tmp).emit(masm); @@ -115,6 +116,7 @@ Kind lkind = input.getKind(); assert lkind == Kind.Long; Register tmp = asRegister(scratch); + assert !tmp.equals(dst); new Srlx(src, 1, tmp).emit(masm); new Or(src, tmp, dst).emit(masm); new Srlx(dst, 2, tmp).emit(masm);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Mon Aug 25 21:15:59 2014 -0700 @@ -25,12 +25,12 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; @@ -62,30 +62,44 @@ } public static class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp { - + // TODO: Conditioncode/flag handling needs to be improved; protected final Condition condition; + protected final ConditionFlag conditionFlag; protected final LabelRef trueDestination; protected final LabelRef falseDestination; protected final Kind kind; + public BranchOp(ConditionFlag condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) { + this.conditionFlag = condition; + this.trueDestination = trueDestination; + this.falseDestination = falseDestination; + this.kind = kind; + this.condition = null; + } + public BranchOp(Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind) { this.condition = condition; this.trueDestination = trueDestination; this.falseDestination = falseDestination; this.kind = kind; + this.conditionFlag = null; } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + assert condition == null && conditionFlag != null || condition != null && conditionFlag == null; Label actualTarget; Condition actualCondition; + ConditionFlag actualConditionFlag; boolean needJump; if (crb.isSuccessorEdge(trueDestination)) { - actualCondition = condition.negate(); + actualCondition = condition != null ? condition.negate() : null; + actualConditionFlag = conditionFlag != null ? conditionFlag.negate() : null; actualTarget = falseDestination.label(); needJump = false; } else { actualCondition = condition; + actualConditionFlag = conditionFlag; actualTarget = trueDestination.label(); needJump = !crb.isSuccessorEdge(falseDestination); } @@ -94,7 +108,13 @@ emitFloatCompare(masm, actualTarget, actualCondition); } else { CC cc = kind == Kind.Int ? CC.Icc : CC.Xcc; - emitCompare(masm, actualTarget, actualCondition, cc); + if (actualCondition != null) { + emitCompare(masm, actualTarget, actualCondition, cc); + } else if (actualConditionFlag != null) { + emitCompare(masm, actualTarget, actualConditionFlag); + } else { + GraalInternalError.shouldNotReachHere(); + } new Nop().emit(masm); // delay slot } if (needJump) { @@ -104,7 +124,7 @@ } private static void emitFloatCompare(SPARCMacroAssembler masm, Label target, Condition actualCondition) { - switch (actualCondition.mirror()) { + switch (actualCondition) { case EQ: new Fbe(false, target).emit(masm); break; @@ -134,6 +154,10 @@ new Nop().emit(masm); } + private static void emitCompare(SPARCMacroAssembler masm, Label target, ConditionFlag actualCondition) { + new Fmt00b(false, actualCondition, Op2s.Br, target).emit(masm); + } + private static void emitCompare(SPARCMacroAssembler masm, Label target, Condition actualCondition, CC cc) { switch (actualCondition) { case EQ: @@ -176,7 +200,7 @@ private final LabelRef[] keyTargets; private LabelRef defaultTarget; @Alive({REG}) protected Value key; - @Temp({REG, ILLEGAL}) protected Value scratch; + @Temp({REG}) protected Value scratch; private final SwitchStrategy strategy; public StrategySwitchOp(SwitchStrategy strategy, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) { @@ -188,7 +212,6 @@ this.scratch = scratch; assert keyConstants.length == keyTargets.length; assert keyConstants.length == strategy.keyProbabilities.length; - assert (scratch.getKind() == Kind.Illegal) == (key.getKind() == Kind.Int); } @Override @@ -204,8 +227,13 @@ crb.recordInlineDataInCode(keyConstants[index]); } long lc = keyConstants[index].asLong(); - assert NumUtil.isInt(lc); - new Cmp(keyRegister, (int) lc).emit(masm); + if (SPARCAssembler.isSimm13(lc)) { + assert NumUtil.isInt(lc); + new Cmp(keyRegister, (int) lc).emit(masm); + } else { + new Setx(lc, asIntReg(scratch)).emit(masm); + new Cmp(keyRegister, asIntReg(scratch)).emit(masm); + } emitCompare(masm, target, condition, CC.Icc); break; case Long: { @@ -253,12 +281,20 @@ // Compare index against jump table bounds int highKey = lowKey + targets.length - 1; - if (lowKey != 0) { - // subtract the low value from the switch value - new Sub(value, lowKey, value).emit(masm); - new Cmp(value, highKey - lowKey).emit(masm); + + // subtract the low value from the switch value + if (isSimm13(lowKey)) { + new Sub(value, lowKey, scratchReg).emit(masm); } else { - new Cmp(value, highKey).emit(masm); + new Setx(lowKey, g3).emit(masm); + new Sub(value, g3, scratchReg).emit(masm); + } + int upperLimit = highKey - lowKey; + if (isSimm13(upperLimit)) { + new Cmp(scratchReg, upperLimit).emit(masm); + } else { + new Setx(upperLimit, g3).emit(masm); + new Cmp(scratchReg, upperLimit).emit(masm); } // Jump to default target if index is not within the jump table @@ -268,19 +304,20 @@ } // Load jump table entry into scratch and jump to it - new Sll(value, 3, value).emit(masm); // Multiply by 8 - new Rdpc(scratchReg).emit(masm); + new Sll(scratchReg, 3, scratchReg).emit(masm); // Multiply by 8 + // Zero the left bits sll with shcnt>0 does not mask upper 32 bits + new Srl(scratchReg, 0, scratchReg).emit(masm); + new Rdpc(g3).emit(masm); // The jump table follows four instructions after rdpc new Add(scratchReg, 4 * 4, scratchReg).emit(masm); - new Jmpl(value, scratchReg, g0).emit(masm); - new Sra(value, 3, value).emit(masm); // delay slot, correct the value (division by 8) + new Jmpl(g3, scratchReg, g0).emit(masm); + new Nop().emit(masm); + // new Sra(value, 3, value).emit(masm); // delay slot, correct the value (division by 8) // Emit jump table entries for (LabelRef target : targets) { - Label label = target.label(); - label.addPatchAt(masm.position()); - new Bpa(0).emit(masm); + new Bpa(target.label()).emit(masm); new Nop().emit(masm); // delay slot } }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Mon Aug 25 21:15:59 2014 -0700 @@ -25,16 +25,18 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.api.code.CompilationResult.RawData; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.*; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.*; +import com.oracle.graal.lir.StandardOp.ImplicitNullCheck; +import com.oracle.graal.lir.StandardOp.MoveOp; +import com.oracle.graal.lir.StandardOp.NullCheck; import com.oracle.graal.lir.asm.*; public class SPARCMove { @@ -135,7 +137,7 @@ @Override public void emitMemAccess(SPARCMacroAssembler masm) { - final SPARCAddress addr = address.toAddress(); + final SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm); final Register dst = asRegister(result); switch (kind) { case Boolean: @@ -172,21 +174,17 @@ public static class LoadAddressOp extends SPARCLIRInstruction { @Def({REG}) protected AllocatableValue result; - @Use({COMPOSITE, UNINITIALIZED}) protected SPARCAddressValue address; + @Use({COMPOSITE, UNINITIALIZED}) protected SPARCAddressValue addressValue; public LoadAddressOp(AllocatableValue result, SPARCAddressValue address) { this.result = result; - this.address = address; + this.addressValue = address; } @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - SPARCAddress addr = address.toAddress(); - if (addr.hasIndex()) { - new Add(addr.getBase(), addr.getIndex(), asLongReg(result)).emit(masm); - } else { - new Add(addr.getBase(), addr.getDisplacement(), asLongReg(result)).emit(masm); - } + SPARCAddress address = addressValue.toAddress(); + loadEffectiveAddress(address, asLongReg(result), masm); } } @@ -283,7 +281,21 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { SPARCAddress address = (SPARCAddress) crb.asAddress(slot); - new Add(address.getBase(), address.getDisplacement(), asLongReg(result)).emit(masm); + loadEffectiveAddress(address, asLongReg(result), masm); + } + } + + private static void loadEffectiveAddress(SPARCAddress address, Register result, SPARCMacroAssembler masm) { + if (address.getIndex().equals(Register.None)) { + if (isSimm13(address.getDisplacement())) { + new Add(address.getBase(), address.getDisplacement(), result).emit(masm); + } else { + assert result.encoding() != address.getBase().encoding(); + new Setx(address.getDisplacement(), result).emit(masm); + new Add(address.getBase(), result, result).emit(masm); + } + } else { + new Add(address.getBase(), address.getIndex(), result).emit(masm); } } @@ -299,7 +311,7 @@ @Override public void emitMemAccess(SPARCMacroAssembler masm) { assert isRegister(input); - SPARCAddress addr = address.toAddress(); + SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm); switch (kind) { case Boolean: case Byte: @@ -344,21 +356,22 @@ @Override public void emitMemAccess(SPARCMacroAssembler masm) { + SPARCAddress addr = guaranueeLoadable(address.toAddress(), masm); switch (kind) { case Boolean: case Byte: - new Stb(g0, address.toAddress()).emit(masm); + new Stb(g0, addr).emit(masm); break; case Short: case Char: - new Sth(g0, address.toAddress()).emit(masm); + new Sth(g0, addr).emit(masm); break; case Int: - new Stw(g0, address.toAddress()).emit(masm); + new Stw(g0, addr).emit(masm); break; case Long: case Object: - new Stx(g0, address.toAddress()).emit(masm); + new Stx(g0, addr).emit(masm); break; case Float: case Double: @@ -451,8 +464,29 @@ } } + /** + * Guarantees that the given SPARCAddress given before is loadable by subsequent call. If the + * displacement exceeds the imm13 value, the value is put into a scratch register o7, which must + * be used as soon as possible. + * + * @param addr Address to modify + * @param masm assembler to output the prior stx command + * @return a loadable SPARCAddress + */ + public static SPARCAddress guaranueeLoadable(SPARCAddress addr, SPARCMacroAssembler masm) { + boolean displacementOutOfBound = addr.getIndex().equals(Register.None) && !SPARCAssembler.isSimm13(addr.getDisplacement()); + if (displacementOutOfBound) { + Register scratch = g3; + new Setx(addr.getDisplacement(), scratch, false).emit(masm); + return new SPARCAddress(addr.getBase(), scratch); + } else { + return addr; + } + } + private static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input) { SPARCAddress dst = (SPARCAddress) crb.asAddress(result); + dst = guaranueeLoadable(dst, masm); Register src = asRegister(input); switch (input.getKind()) { case Byte: @@ -483,6 +517,7 @@ private static void stack2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input) { SPARCAddress src = (SPARCAddress) crb.asAddress(input); + src = guaranueeLoadable(src, masm); Register dst = asRegister(result); switch (input.getKind()) { case Boolean: @@ -517,28 +552,10 @@ Register scratch = g5; switch (input.getKind().getStackKind()) { case Int: - if (crb.codeCache.needsDataPatch(input)) { - crb.recordInlineDataInCode(input); - new Setuw(input.asInt(), asRegister(result)).emit(masm); - } else { - if (input.isDefaultForKind()) { - new Clr(asRegister(result)).emit(masm); - } else { - new Setuw(input.asInt(), asRegister(result)).emit(masm); - } - } + new Setx(input.asLong(), asIntReg(result)).emit(masm); break; case Long: - if (crb.codeCache.needsDataPatch(input)) { - crb.recordInlineDataInCode(input); - new Setx(input.asLong(), asRegister(result), true).emit(masm); - } else { - if (input.isDefaultForKind()) { - new Clr(asRegister(result)).emit(masm); - } else { - new Setx(input.asLong(), asRegister(result)).emit(masm); - } - } + new Setx(input.asLong(), asLongReg(result)).emit(masm); break; case Float: // TODO: Handle it the same way, as in the double case with Movwtos
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java Mon Aug 25 21:15:59 2014 -0700 @@ -27,10 +27,12 @@ import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Movxtod; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.SaveRegistersOp; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.sparc.*; /** * Saves registers to stack slots. @@ -78,6 +80,7 @@ saveRegister(crb, masm, slots[i], savedRegisters[i]); } } + new Movxtod(SPARC.i0, SPARC.f31).emit(masm); } public StackSlot[] getSlots() {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Mon Aug 25 21:15:59 2014 -0700 @@ -204,7 +204,8 @@ // @formatter:off assert (!slot.getRawAddFrameSize() && slot.getRawOffset() < outgoingSize) || ( slot.getRawAddFrameSize() && slot.getRawOffset() < 0 && -slot.getRawOffset() <= spillSize) || - ( slot.getRawAddFrameSize() && slot.getRawOffset() >= 0); + ( slot.getRawAddFrameSize() && slot.getRawOffset() >= 0) : + String.format("RawAddFrameSize: %b RawOffset: 0x%x spillSize: 0x%x outgoingSize: 0x%x", slot.getRawAddFrameSize(), slot.getRawOffset(), spillSize, outgoingSize); // @formatter:on if (slot.isInCallerFrame()) { accessesCallerFrame = true;
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java Mon Aug 25 21:15:59 2014 -0700 @@ -108,7 +108,7 @@ public void test7() { char[] src = "1234567890".toCharArray(); char[] dst = new char[src.length]; - int n = Runtime.getRuntime().availableProcessors(); + int n = Math.min(32, Runtime.getRuntime().availableProcessors()); testN(n, "copyArr", src, dst, 100); }
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java Mon Aug 25 23:22:05 2014 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java Mon Aug 25 21:15:59 2014 -0700 @@ -72,7 +72,11 @@ public void testMulHighUnsigned() { test("mulHighUnsigned", 7, 15); test("mulHighUnsigned", Integer.MAX_VALUE, 15); + test("mulHighUnsigned", 15, Integer.MAX_VALUE); + test("mulHighUnsigned", Integer.MAX_VALUE, Integer.MAX_VALUE); + test("mulHighUnsigned", 15, Integer.MIN_VALUE); test("mulHighUnsigned", Integer.MIN_VALUE, 15); + test("mulHighUnsigned", Integer.MIN_VALUE, Integer.MIN_VALUE); } @Test @@ -98,7 +102,11 @@ public void testLongMulHigh() { test("longMulHigh", 7L, 15L); test("longMulHigh", Long.MAX_VALUE, 15L); + test("longMulHigh", 15L, Long.MAX_VALUE); + test("longMulHigh", Long.MAX_VALUE, Long.MAX_VALUE); test("longMulHigh", Long.MIN_VALUE, 15L); + test("longMulHigh", 15L, Long.MIN_VALUE); + test("longMulHigh", Long.MIN_VALUE, Long.MIN_VALUE); } @Test
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Mon Aug 25 23:22:05 2014 +0200 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Mon Aug 25 21:15:59 2014 -0700 @@ -3433,6 +3433,9 @@ if (UseStackBanging) { pad += StackShadowPages*16 + 32; } +#ifdef GRAAL + pad += 32; // Increase the buffer size when compiling for GRAAL +#endif #ifdef _LP64 CodeBuffer buffer("deopt_blob", 2100+pad, 512); #else @@ -3567,6 +3570,33 @@ // Restore G2_thread __ get_thread(); +#ifdef GRAAL + // load throwing pc from JavaThread and patch it as the return address + // of the current frame. Then clear the field in JavaThread + __ block_comment("load throwing pc and patch return"); + Address exception_pc(G2_thread, JavaThread::exception_pc_offset()); + Label has_no_pc; + // TODO: Remove this weird check if we should patch the return pc + // This is because when graal decides to deoptimize and the ExceptionHandlerStub.java + // jumps back to this code and the I7 register contains the pc pointing to the begin + // of this code. If this is the case (PC within a certain range) then we need to patch + // the return pc. + // THIS NEEDS REWORK! (sa) + __ rdpc(L0); + __ sub(L0, I7, L0); + __ cmp(L0, 0xFFF); + __ br(Assembler::greater, false, Assembler::pt, has_no_pc); + __ delayed() -> nop(); + __ cmp(L0, -0xFFF); + __ br(Assembler::less, false, Assembler::pt, has_no_pc); + __ delayed() -> nop(); + __ ld_ptr(exception_pc, I7); + __ sub(I7, 8, I7); + __ st_ptr(G0, exception_pc); + __ bind(has_no_pc); + __ block_comment("/load throwing pc and patch return"); +#endif // GAAL + #ifdef ASSERT { // verify that there is really an exception oop in exception_oop
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Mon Aug 25 23:22:05 2014 +0200 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Mon Aug 25 21:15:59 2014 -0700 @@ -199,6 +199,22 @@ address InterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { address entry = __ pc(); __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache +#ifdef GRAAL + // Check if we need to take lock at entry of synchronized method. + { + Label L; + + //__ cmp(, 0); + Address pending_monitor_enter_addr(G2_thread, Thread::pending_monitorenter_offset()); + __ ldbool(pending_monitor_enter_addr, Gtemp); // Load if pending monitor enter + __ cmp_and_br_short(Gtemp, G0, Assembler::equal, Assembler::pn, L); + // Clear flag. + __ stbool(G0, pending_monitor_enter_addr); + // Take lock. + lock_method(); + __ bind(L); + } +#endif { Label L; Address exception_addr(G2_thread, Thread::pending_exception_offset()); __ ld_ptr(exception_addr, Gtemp); // Load pending exception. @@ -1689,8 +1705,13 @@ // make sure I5_savedSP and the entry frames notion of saved SP // agree. This assertion duplicate a check in entry frame code // but catches the failure earlier. - assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP), + /* + * Sanzinger: This does not make sense to me, since when we call stub_call -> i2c, the i2c may change the + * sp, which then is not in sync with Lscratch anymore. + */ + /**assert(*caller->register_addr(Lscratch) == *interpreter_frame->register_addr(I5_savedSP), "would change callers SP"); + */ } if (caller->is_entry_frame()) { tty->print("entry ");
--- a/src/share/vm/graal/graalCodeInstaller.cpp Mon Aug 25 23:22:05 2014 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Mon Aug 25 21:15:59 2014 -0700 @@ -231,6 +231,8 @@ Location::Type locationType; if (type == T_INT) { locationType = reference ? Location::narrowoop : Location::int_in_long; + } else if(type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) { + locationType = Location::int_in_long; } else if (type == T_FLOAT) { locationType = Location::int_in_long; } else if (type == T_LONG) { @@ -264,7 +266,7 @@ #ifdef TARGET_ARCH_sparc ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_FloatRegister(encoding)->as_VMReg())); if (type == T_DOUBLE) { - second = new ConstantIntValue(0); + second = value; } return value; #else @@ -278,6 +280,8 @@ locationType = reference ? Location::oop : Location::lng; } else if (type == T_INT) { locationType = reference ? Location::narrowoop : Location::normal; + } else if(type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) { + locationType = Location::normal; } else if (type == T_FLOAT) { assert(!reference, "unexpected type in stack slot"); locationType = Location::normal; @@ -289,6 +293,11 @@ locationType = Location::oop; } jint offset = StackSlot::offset(value); +#ifdef TARGET_ARCH_sparc + if(offset >= 0) { + offset += 128; + } +#endif if (StackSlot::addFrameSize(value)) { offset += total_frame_size; }