# HG changeset patch # User Stefan Anzinger # Date 1408465289 25200 # Node ID 4d77f938aa028bf2c78bdfdca2a14205e18d77ca # Parent 71ec66af2e12a7c6fbd89ccc899b1e1e5aff23db [SPARC] Exclude AMD64 tests from SPARC testrun, always use tmp register when using StrategySwitch, using registerSaver in EnterUnpackStackFrame, LeaveCurrentStackframe, adding guarantee to load offsets when doing load reg+imm13 when the imm value does not fit in 13 bit, assertions for scratch register usage (tmp/def) diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java --- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Tue Aug 19 09:21:29 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() { diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java --- a/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java Tue Aug 19 09:21:29 2014 -0700 @@ -32,7 +32,7 @@ @Before public void setUp() { - assumeTrue(isArchitecture("AMD64")); + assumeTrue(isArchitecture("x86_64")); } @Test diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Aug 19 09:21:29 2014 -0700 @@ -357,9 +357,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 @@ -938,7 +936,7 @@ 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.forInt((int) mask); diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java Tue Aug 19 09:21:29 2014 -0700 @@ -30,9 +30,11 @@ 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.hotspot.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.sparc.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.asm.*; /** @@ -48,14 +50,17 @@ @Alive(REG) AllocatableValue framePc; @Alive(REG) AllocatableValue senderSp; @Temp(REG) AllocatableValue scratch; + private SaveRegistersOp saveRegisterOp; - SPARCHotSpotEnterUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, AllocatableValue framePc, AllocatableValue senderSp, AllocatableValue scratch) { + SPARCHotSpotEnterUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, AllocatableValue framePc, AllocatableValue senderSp, AllocatableValue scratch, + SaveRegistersOp saveRegisterOp) { this.thread = thread; this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.threadLastJavaPcOffset = threadLastJavaPcOffset; this.framePc = framePc; this.senderSp = senderSp; this.scratch = scratch; + this.saveRegisterOp = saveRegisterOp; } @Override diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Aug 19 09:21:29 2014 -0700 @@ -268,7 +268,7 @@ } public void emitLeaveCurrentStackFrame(SaveRegistersOp saveRegisterOp) { - append(new SPARCHotSpotLeaveCurrentStackFrameOp()); + append(new SPARCHotSpotLeaveCurrentStackFrameOp(saveRegisterOp)); } public void emitLeaveDeoptimizedStackFrame(Value frameSize, Value initialInfo) { @@ -280,12 +280,13 @@ Variable framePcVariable = load(framePc); Variable senderSpVariable = load(senderSp); Variable scratchVariable = newVariable(LIRKind.value(getHostWordKind())); - append(new SPARCHotSpotEnterUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), framePcVariable, senderSpVariable, scratchVariable)); + append(new SPARCHotSpotEnterUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), framePcVariable, senderSpVariable, scratchVariable, + saveRegisterOp)); } public void emitLeaveUnpackFramesStackFrame(SaveRegistersOp saveRegisterOp) { Register thread = getProviders().getRegisters().getThreadRegister(); - append(new SPARCHotSpotLeaveUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset())); + append(new SPARCHotSpotLeaveUnpackFramesStackFrameOp(thread, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadJavaFrameAnchorFlagsOffset(), saveRegisterOp)); } public void emitPushInterpreterFrame(Value frameSize, Value framePc, Value senderSp, Value initialInfo) { diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java Tue Aug 19 09:21:29 2014 -0700 @@ -24,11 +24,16 @@ import static com.oracle.graal.sparc.SPARC.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.SaveRegistersOp; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; +import com.oracle.graal.sparc.*; /** * Pops the current frame off the stack. @@ -36,6 +41,12 @@ @Opcode("LEAVE_CURRENT_STACK_FRAME") final class SPARCHotSpotLeaveCurrentStackFrameOp extends SPARCLIRInstruction { + private final SaveRegistersOp saveRegisterOp; + + public SPARCHotSpotLeaveCurrentStackFrameOp(SaveRegistersOp saveRegisterOp) { + this.saveRegisterOp = saveRegisterOp; + } + @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { // Save O registers over restore. diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java Tue Aug 19 09:21:29 2014 -0700 @@ -24,13 +24,18 @@ import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import static com.oracle.graal.sparc.SPARC.*; +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.sparc.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.sparc.*; /** * Emits code that leaves a stack frame which is tailored to call the C++ method @@ -44,11 +49,14 @@ private final int threadLastJavaPcOffset; private final int threadJavaFrameAnchorFlagsOffset; - SPARCHotSpotLeaveUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadJavaFrameAnchorFlagsOffset) { + private final SaveRegistersOp saveRegisterOp; + + SPARCHotSpotLeaveUnpackFramesStackFrameOp(Register thread, int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadJavaFrameAnchorFlagsOffset, SaveRegistersOp saveRegisterOp) { this.thread = thread; this.threadLastJavaSpOffset = threadLastJavaSpOffset; this.threadLastJavaPcOffset = threadLastJavaPcOffset; this.threadJavaFrameAnchorFlagsOffset = threadJavaFrameAnchorFlagsOffset; + this.saveRegisterOp = saveRegisterOp; } @Override @@ -63,5 +71,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); } } diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Tue Aug 19 09:21:29 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.*; @@ -244,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; } diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Tue Aug 19 09:21:29 2014 -0700 @@ -32,7 +32,6 @@ import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.sparc.*; @@ -254,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; @@ -424,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; @@ -582,6 +582,10 @@ } 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)); exceptionOffset = masm.position(); new Sdivx(asIntReg(src1), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm); @@ -593,6 +597,10 @@ 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); @@ -600,6 +608,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); @@ -616,6 +628,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); @@ -626,6 +641,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); @@ -636,12 +653,16 @@ 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: + 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(); @@ -817,7 +838,7 @@ case IUSHR: case IUDIV: case IUREM: - rk = result.getKind(); + rk = result.getKind().getStackKind(); xsk = x.getKind().getStackKind(); ysk = y.getKind().getStackKind(); boolean valid = false; @@ -900,12 +921,14 @@ 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); diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Tue Aug 19 09:21:29 2014 -0700 @@ -96,6 +96,7 @@ 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); @@ -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); diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Aug 19 09:21:29 2014 -0700 @@ -200,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) { @@ -212,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 @@ -228,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: { diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Aug 19 09:21:29 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,20 @@ @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() == Register.None) { + if (isSimm13(address.getDisplacement())) { + new Add(address.getBase(), address.getDisplacement(), result).emit(masm); + } else { + 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 +310,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 +355,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 +463,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() == 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 +516,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: diff -r 71ec66af2e12 -r 4d77f938aa02 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java Tue Aug 12 08:58:38 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java Tue Aug 19 09:21:29 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() {