# HG changeset patch # User Stefan Anzinger # Date 1411499546 25200 # Node ID 2d401b9ca70d60324123fb8f05362d61eae69b9d # Parent 6d8ae4c6725f8d6051293c75d3bddf3d9089ee90 [SPARC] Improve the lookup for delayable candidates, renaming interfaces/methods diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Tue Sep 23 12:12:26 2014 -0700 @@ -53,7 +53,6 @@ import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.sparc.*; -import com.oracle.graal.lir.sparc.SPARCCall.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.sparc.*; @@ -209,7 +208,7 @@ @Override public void emitCode(CompilationResultBuilder crb, LIR lir, ResolvedJavaMethod installedCodeOwner) { - fixupDelayedInstructions(lir); + stuffDelayedControlTransfers(lir); SPARCMacroAssembler masm = (SPARCMacroAssembler) crb.asm; FrameMap frameMap = crb.frameMap; RegisterConfig regConfig = frameMap.registerConfig; @@ -264,82 +263,105 @@ } } - private static void fixupDelayedInstructions(LIR l) { + /** + * Fix-up over whole LIR. + * + * @see #stuffDelayedControlTransfers(LIR, AbstractBlock) + * @param l + */ + private static void stuffDelayedControlTransfers(LIR l) { for (AbstractBlock b : l.codeEmittingOrder()) { - fixupDelayedInstructions(l, b); + stuffDelayedControlTransfers(l, b); } } - private static void fixupDelayedInstructions(LIR l, AbstractBlock block) { - TailDelayedLIRInstruction lastDelayable = null; - for (LIRInstruction inst : l.getLIRforBlock(block)) { - if (lastDelayable != null && inst instanceof DelaySlotHolder) { - if (isDelayable(inst, (LIRInstruction) lastDelayable)) { - lastDelayable.setDelaySlotHolder((DelaySlotHolder) inst); + /** + * Tries to put DelayedControlTransfer instructions and DelayableLIRInstructions together. Also + * it tries to move the DelayedLIRInstruction to the DelayedControlTransfer instruction, if + * possible. + */ + private static void stuffDelayedControlTransfers(LIR l, AbstractBlock block) { + List instructions = l.getLIRforBlock(block); + if (instructions.size() >= 2) { + LIRDependencyAccumulator acc = new LIRDependencyAccumulator(); + SPARCDelayedControlTransfer delayedTransfer = null; + int delayTransferPosition = -1; + for (int i = instructions.size() - 1; i >= 0; i--) { + LIRInstruction inst = instructions.get(i); + boolean adjacent = delayTransferPosition - i == 1; + + if ((!adjacent && inst.hasState()) || inst.destroysCallerSavedRegisters() || leavesRegisterWindow(inst)) { + delayedTransfer = null; } - lastDelayable = null; // We must not pull over other delay slot holder. - } else if (inst instanceof TailDelayedLIRInstruction) { - lastDelayable = (TailDelayedLIRInstruction) inst; - } else { - lastDelayable = null; + if (inst instanceof SPARCDelayedControlTransfer) { + delayedTransfer = (SPARCDelayedControlTransfer) inst; + acc.start(inst); + delayTransferPosition = i; + } else if (delayedTransfer != null) { + boolean overlap = acc.add(inst); + if (inst instanceof SPARCTailDelayedLIRInstruction && !overlap) { + // We have found a non overlapping LIR instruction which can be delayed + ((SPARCTailDelayedLIRInstruction) inst).setDelayedControlTransfer(delayedTransfer); + delayedTransfer = null; + if (!adjacent) { + // If not adjacent, we make it adjacent + instructions.remove(i); + instructions.add(delayTransferPosition - 1, inst); + } + } + } } } } - public static boolean isDelayable(final LIRInstruction delaySlotHolder, final LIRInstruction other) { - final Set delaySlotHolderInputs = new HashSet<>(2); - final Set otherFrameStates = new HashSet<>(2); - other.forEachState(new InstructionStateProcedure() { - @Override - protected void doState(LIRInstruction instruction, LIRFrameState state) { - otherFrameStates.add(state); - } - }); - int frameStatesBefore = otherFrameStates.size(); - delaySlotHolder.forEachState(new InstructionStateProcedure() { - @Override - protected void doState(LIRInstruction instruction, LIRFrameState state) { - otherFrameStates.add(state); - } - }); - if (frameStatesBefore != otherFrameStates.size() && otherFrameStates.size() >= 2) { - // both have framestates, the instruction is not delayable - return false; - } - // Direct calls do not have dependencies to data before - if (delaySlotHolder instanceof DirectCallOp) { - return true; - } - delaySlotHolder.visitEachInput(new InstructionValueConsumer() { + private static boolean leavesRegisterWindow(LIRInstruction inst) { + return inst instanceof SPARCLIRInstruction && ((SPARCLIRInstruction) inst).leavesRegisterWindow(); + } + + /** + * Accumulates inputs/outputs/temp/alive in a set along we walk back the LIRInstructions and + * detects, if there is any overlap. In this way LIRInstructions can be detected, which can be + * moved nearer to the DelayedControlTransfer instruction. + */ + private static class LIRDependencyAccumulator { + private final Set inputs = new HashSet<>(10); + private boolean overlap = false; + + private final InstructionValueConsumer valueConsumer = new InstructionValueConsumer() { @Override protected void visitValue(LIRInstruction instruction, Value value) { - delaySlotHolderInputs.add(value); + Object valueObject = value; + if (isRegister(value)) { // Canonicalize registers + valueObject = asRegister(value); + } + if (!inputs.add(valueObject)) { + overlap = true; + } } - }); - delaySlotHolder.visitEachTemp(new InstructionValueConsumer() { - @Override - protected void visitValue(LIRInstruction instruction, Value value) { - delaySlotHolderInputs.add(value); - } - }); - if (delaySlotHolderInputs.size() == 0) { - return true; + }; + + public void start(LIRInstruction initial) { + inputs.clear(); + overlap = false; + initial.visitEachInput(valueConsumer); + initial.visitEachTemp(valueConsumer); + initial.visitEachAlive(valueConsumer); } - final Set otherOutputs = new HashSet<>(); - other.visitEachOutput(new InstructionValueConsumer() { - @Override - protected void visitValue(LIRInstruction instruction, Value value) { - otherOutputs.add(value); - } - }); - other.visitEachTemp(new InstructionValueConsumer() { - @Override - protected void visitValue(LIRInstruction instruction, Value value) { - otherOutputs.add(value); - } - }); - int sizeBefore = otherOutputs.size(); - otherOutputs.removeAll(delaySlotHolderInputs); - return otherOutputs.size() == sizeBefore; + + /** + * Adds the inputs of lir instruction to the accumulator and returns, true if there was any + * overlap of parameters. + * + * @param inst + * @return true if an overlap was found + */ + public boolean add(LIRInstruction inst) { + overlap = false; + inst.visitEachOutput(valueConsumer); + inst.visitEachTemp(valueConsumer); + inst.visitEachInput(valueConsumer); + inst.visitEachAlive(valueConsumer); + return overlap; + } } } diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Tue Sep 23 12:12:26 2014 -0700 @@ -55,7 +55,7 @@ public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { // Restore the thread register when coming back from the runtime. - SPARCMove.move(crb, masm, thread.asValue(LIRKind.value(Kind.Long)), threadTemp, DelaySlotHolder.DUMMY); + SPARCMove.move(crb, masm, thread.asValue(LIRKind.value(Kind.Long)), threadTemp, SPARCDelayedControlTransfer.DUMMY); // Reset last Java frame, last Java PC and flags. new Stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm); diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Tue Sep 23 12:12:26 2014 -0700 @@ -35,13 +35,12 @@ import com.oracle.graal.lir.sparc.*; @Opcode("CRUNTIME_CALL_PROLOGUE") -final class SPARCHotSpotCRuntimeCallPrologueOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction { +final class SPARCHotSpotCRuntimeCallPrologueOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { private final int threadLastJavaSpOffset; private final Register thread; private final Register stackPointer; @Def({REG, STACK}) protected Value threadTemp; - private DelaySlotHolder delayHolder = DelaySlotHolder.DUMMY; public SPARCHotSpotCRuntimeCallPrologueOp(int threadLastJavaSpOffset, Register thread, Register stackPointer, Value threadTemp) { this.threadLastJavaSpOffset = threadLastJavaSpOffset; @@ -57,10 +56,6 @@ new Stx(g4, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm); // Save the thread register when calling out to the runtime. - SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(Kind.Long)), delayHolder); - } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delayHolder = holder; + SPARCMove.move(crb, masm, threadTemp, thread.asValue(LIRKind.value(Kind.Long)), delayedControlTransfer); } } diff -r 6d8ae4c6725f -r 2d401b9ca70d 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 Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java Tue Sep 23 12:12:26 2014 -0700 @@ -93,4 +93,9 @@ */ new Mov(thread, l7).emit(masm); } + + @Override + public boolean leavesRegisterWindow() { + return true; + } } diff -r 6d8ae4c6725f -r 2d401b9ca70d 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 Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveCurrentStackFrameOp.java Tue Sep 23 12:12:26 2014 -0700 @@ -50,4 +50,9 @@ crb.frameContext.leave(crb); } + + @Override + public boolean leavesRegisterWindow() { + return true; + } } diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveDeoptimizedStackFrameOp.java Tue Sep 23 12:12:26 2014 -0700 @@ -47,4 +47,9 @@ new RestoreWindow().emit(masm); } + + @Override + public boolean leavesRegisterWindow() { + return true; + } } diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPushInterpreterFrameOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPushInterpreterFrameOp.java Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotPushInterpreterFrameOp.java Tue Sep 23 12:12:26 2014 -0700 @@ -75,4 +75,9 @@ // Move frame's new PC into i7 new Mov(framePcRegister, i7).emit(masm); } + + @Override + public boolean leavesRegisterWindow() { + return true; + } } diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/DelaySlotHolder.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/DelaySlotHolder.java Mon Sep 22 11:20:35 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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.lir.sparc; - -import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.asm.*; - -/** - * This interface can be used for {@link LIRInstruction}s which may provide a delay slot. If a delay - * slot for this LIRInstruction is requrested, the requester just calls the method - * {@link #emitForDelay(CompilationResultBuilder, SPARCMacroAssembler)}. - * - * @see TailDelayedLIRInstruction - */ -public interface DelaySlotHolder { - - DelaySlotHolder DUMMY = new DelaySlotHolder() { - public void emitForDelay(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - // do nothing - } - - @Override - public String toString() { - return "null"; - } - }; - - public void emitForDelay(CompilationResultBuilder crb, SPARCMacroAssembler masm); - -} diff -r 6d8ae4c6725f -r 2d401b9ca70d 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 Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Tue Sep 23 12:12:26 2014 -0700 @@ -51,12 +51,11 @@ /** * Unary operation with separate source and destination operand. */ - public static class Unary2Op extends SPARCLIRInstruction implements TailDelayedLIRInstruction { + public static class Unary2Op extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { @Opcode private final SPARCArithmetic opcode; @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue x; - private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY; public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) { this.opcode = opcode; @@ -66,11 +65,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emitUnary(crb, masm, opcode, result, x, null, delaySlotLir); - } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotLir = holder; + emitUnary(crb, masm, opcode, result, x, null, delayedControlTransfer); } } @@ -78,14 +73,13 @@ * Binary operation with two operands. The first source operand is combined with the * destination. The second source operand must be a register. */ - public static class BinaryRegReg extends SPARCLIRInstruction implements TailDelayedLIRInstruction { + public static class BinaryRegReg extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { @Opcode private final SPARCArithmetic opcode; @Def({REG}) protected Value result; @Use({REG}) protected Value x; @Alive({REG}) protected Value y; @State LIRFrameState state; - private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY; public BinaryRegReg(SPARCArithmetic opcode, Value result, Value x, Value y) { this(opcode, result, x, y, null); @@ -101,7 +95,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emitRegReg(crb, masm, opcode, result, x, y, state, delaySlotLir); + emitRegReg(crb, masm, opcode, result, x, y, state, delayedControlTransfer); } @Override @@ -109,23 +103,18 @@ super.verify(); verifyKind(opcode, result, x, y); } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotLir = holder; - } } /** * Binary operation with single source/destination operand and one constant. */ - public static class BinaryRegConst extends SPARCLIRInstruction implements TailDelayedLIRInstruction { + public static class BinaryRegConst extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { @Opcode private final SPARCArithmetic opcode; @Def({REG}) protected AllocatableValue result; @Use({REG}) protected Value x; @State protected LIRFrameState state; protected Constant y; - private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY; public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, Value x, Constant y) { this(opcode, result, x, y, null); @@ -141,7 +130,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emitRegConstant(crb, masm, opcode, result, x, y, null, delaySlotLir); + emitRegConstant(crb, masm, opcode, result, x, y, null, delayedControlTransfer); } @Override @@ -149,16 +138,12 @@ super.verify(); verifyKind(opcode, result, x, y); } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotLir = holder; - } } /** * Special LIR instruction as it requires a bunch of scratch registers. */ - public static class RemOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction { + public static class RemOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { @Opcode private final SPARCArithmetic opcode; @Def({REG}) protected Value result; @@ -167,7 +152,6 @@ @Temp({REG}) protected Value scratch1; @Temp({REG}) protected Value scratch2; @State protected LIRFrameState state; - private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY; public RemOp(SPARCArithmetic opcode, Value result, Value x, Value y, LIRFrameState state, LIRGeneratorTool gen) { this.opcode = opcode; @@ -181,7 +165,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emitRem(crb, masm, opcode, result, x, y, scratch1, scratch2, state, delaySlotLir); + emitRem(crb, masm, opcode, result, x, y, scratch1, scratch2, state, delayedControlTransfer); } @Override @@ -189,18 +173,14 @@ super.verify(); verifyKind(opcode, result, x, y); } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotLir = holder; - } } private static void emitRegConstant(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Constant src2, LIRFrameState info, - DelaySlotHolder delaySlotLir) { + SPARCDelayedControlTransfer delaySlotLir) { assert isSimm13(crb.asIntConst(src2)) : src2; int constant = crb.asIntConst(src2); int exceptionOffset = -1; - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); switch (opcode) { case IADD: new Add(asIntReg(src1), constant, asIntReg(dst)).emit(masm); @@ -286,119 +266,119 @@ } } - public static void emitRegReg(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info, DelaySlotHolder delaySlotLir) { + public static void emitRegReg(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info, SPARCDelayedControlTransfer delaySlotLir) { int exceptionOffset = -1; assert !isConstant(src1) : src1; assert !isConstant(src2) : src2; switch (opcode) { case IADD: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Add(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case ISUB: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sub(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case IMUL: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case IDIV: new Signx(asIntReg(src1), asIntReg(src1)).emit(masm); new Signx(asIntReg(src2), asIntReg(src2)).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); new Sdivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case IUDIV: new Signx(asIntReg(src1), asIntReg(src1)).emit(masm); new Signx(asIntReg(src2), asIntReg(src2)).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); new Udivx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case IAND: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new And(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case IOR: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Or(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case IXOR: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Xor(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case ISHL: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sll(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case ISHR: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sra(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case IUSHR: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Srl(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; case IREM: throw GraalInternalError.unimplemented(); case LADD: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Add(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; case LSUB: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sub(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; case LMUL: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Mulx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; case LDIV: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); new Sdivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; case LUDIV: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); new Udivx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; case LAND: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new And(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; case LOR: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Or(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; case LXOR: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Xor(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; case LSHL: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sllx(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm); break; case LSHR: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Srax(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm); break; case LUSHR: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Srlx(asLongReg(src1), asIntReg(src2), asLongReg(dst)).emit(masm); break; case FADD: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fadds(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); break; case FSUB: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fsubs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); break; case FMUL: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); if (dst.getPlatformKind() == Kind.Double) { new Fsmuld(asFloatReg(src1), asFloatReg(src2), asDoubleReg(dst)).emit(masm); } else if (dst.getPlatformKind() == Kind.Float) { @@ -406,33 +386,33 @@ } break; case FDIV: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); new Fdivs(asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)).emit(masm); break; case FREM: throw GraalInternalError.unimplemented(); case DADD: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Faddd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm); break; case DSUB: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fsubd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm); break; case DMUL: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fmuld(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm); break; case DDIV: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); new Fdivd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm); break; case DREM: throw GraalInternalError.unimplemented(); case DAND: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fandd(asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)).emit(masm); break; default: @@ -445,7 +425,7 @@ } public static void emitRem(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, Value scratch1, Value scratch2, LIRFrameState info, - DelaySlotHolder delaySlotLir) { + SPARCDelayedControlTransfer delaySlotLir) { int exceptionOffset = -1; if (!isConstant(src1) && isConstant(src2)) { assert isSimm13(crb.asIntConst(src2)); @@ -458,21 +438,21 @@ exceptionOffset = masm.position(); new Sdivx(asIntReg(dst), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm); new Mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch2)).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sub(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)).emit(masm); break; case LREM: 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); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm); break; case LUREM: 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); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm); break; case IUREM: @@ -495,7 +475,7 @@ exceptionOffset = masm.position(); new Sdivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm); new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm); break; case LUREM: @@ -508,7 +488,7 @@ exceptionOffset = masm.position(); new Udivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm); new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm); break; case IREM: @@ -523,7 +503,7 @@ exceptionOffset = masm.position(); new Sdivx(asIntReg(scratch1), asIntReg(scratch2), asIntReg(dst)).emit(masm); new Mulx(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm); break; case IUREM: @@ -534,7 +514,7 @@ exceptionOffset = masm.position(); new Udivx(asIntReg(scratch1), asIntReg(dst), asIntReg(scratch2)).emit(masm); new Mulx(asIntReg(scratch2), asIntReg(dst), asIntReg(dst)).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm); break; default: @@ -549,76 +529,76 @@ } } - public static void emitUnary(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info, DelaySlotHolder delaySlotLir) { + public static void emitUnary(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info, SPARCDelayedControlTransfer delaySlotLir) { int exceptionOffset = -1; Label notOrdered = new Label(); switch (opcode) { case INEG: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Neg(asIntReg(src), asIntReg(dst)).emit(masm); break; case LNEG: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Neg(asLongReg(src), asLongReg(dst)).emit(masm); break; case INOT: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Not(asIntReg(src), asIntReg(dst)).emit(masm); break; case LNOT: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Not(asLongReg(src), asLongReg(dst)).emit(masm); break; case D2F: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fdtos(asDoubleReg(src), asFloatReg(dst)).emit(masm); break; case L2D: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fxtod(asDoubleReg(src), asDoubleReg(dst)).emit(masm); break; case L2F: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fxtos(asDoubleReg(src), asFloatReg(dst)).emit(masm); break; case I2D: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fitod(asFloatReg(src), asDoubleReg(dst)).emit(masm); break; case I2L: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Signx(asIntReg(src), asLongReg(dst)).emit(masm); break; case L2I: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Signx(asLongReg(src), asIntReg(dst)).emit(masm); break; case B2L: new Sllx(asIntReg(src), 56, asLongReg(dst)).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Srax(asLongReg(dst), 56, asLongReg(dst)).emit(masm); break; case B2I: new Sllx(asIntReg(src), 56, asIntReg(dst)).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Srax(asIntReg(dst), 56, asIntReg(dst)).emit(masm); break; case S2L: new Sllx(asIntReg(src), 48, asLongReg(dst)).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Srax(asLongReg(dst), 48, asLongReg(dst)).emit(masm); break; case S2I: new Sllx(asIntReg(src), 48, asIntReg(dst)).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Srax(asIntReg(dst), 48, asIntReg(dst)).emit(masm); break; case I2F: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fitos(asFloatReg(src), asFloatReg(dst)).emit(masm); break; case F2D: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fstod(asFloatReg(src), asDoubleReg(dst)).emit(masm); break; case F2L: @@ -653,11 +633,11 @@ masm.bind(notOrdered); break; case FNEG: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fnegs(asFloatReg(src), asFloatReg(dst)).emit(masm); break; case DNEG: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fnegd(asDoubleReg(src), asDoubleReg(dst)).emit(masm); break; default: diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Tue Sep 23 12:12:26 2014 -0700 @@ -35,13 +35,12 @@ import com.oracle.graal.lir.gen.*; @Opcode("BSWAP") -public class SPARCByteSwapOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction { +public class SPARCByteSwapOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { @Def({REG, HINT}) protected Value result; @Use({REG}) protected Value input; @Temp({REG}) protected Value tempIndex; @Use({STACK}) protected StackSlot tmpSlot; - private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY; public SPARCByteSwapOp(LIRGeneratorTool tool, Value result, Value input) { this.result = result; @@ -52,14 +51,14 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - SPARCMove.move(crb, masm, tmpSlot, input, DelaySlotHolder.DUMMY); + SPARCMove.move(crb, masm, tmpSlot, input, SPARCDelayedControlTransfer.DUMMY); SPARCAddress addr = (SPARCAddress) crb.asAddress(tmpSlot); if (addr.getIndex().equals(Register.None)) { Register tempReg = ValueUtil.asLongReg(tempIndex); new SPARCMacroAssembler.Setx(addr.getDisplacement(), tempReg, false).emit(masm); addr = new SPARCAddress(addr.getBase(), tempReg); } - delaySlotLir.emitForDelay(crb, masm); + delayedControlTransfer.emitControlTransfer(crb, masm); switch (input.getKind()) { case Int: new SPARCAssembler.Lduwa(addr.getBase(), addr.getIndex(), asIntReg(result), Asi.ASI_PRIMARY_LITTLE).emit(masm); @@ -71,8 +70,4 @@ throw GraalInternalError.shouldNotReachHere(); } } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotLir = holder; - } } diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java Tue Sep 23 12:12:26 2014 -0700 @@ -73,7 +73,7 @@ } @Opcode("CALL_DIRECT") - public static class DirectCallOp extends MethodCallOp implements DelaySlotHolder { + public static class DirectCallOp extends MethodCallOp implements SPARCDelayedControlTransfer { private boolean emitted = false; private int before = -1; @@ -107,7 +107,7 @@ // } - public void emitForDelay(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) { assert !emitted; emitCallPrefixCode(crb, masm); before = masm.position(); diff -r 6d8ae4c6725f -r 2d401b9ca70d 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 Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Sep 23 12:12:26 2014 -0700 @@ -62,7 +62,7 @@ } } - public static class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, DelaySlotHolder { + public static class CompareBranchOp extends SPARCLIRInstruction implements BlockEndOp, SPARCDelayedControlTransfer { private final SPARCCompare opcode; @Use({REG}) protected Value x; @@ -73,6 +73,7 @@ protected final Kind kind; protected final boolean unorderedIsTrue; private boolean emitted = false; + private int delaySlotPosition = -1; private double trueDestinationProbability; public CompareBranchOp(SPARCCompare opcode, Value x, Value y, Condition condition, LabelRef trueDestination, LabelRef falseDestination, Kind kind, boolean unorderedIsTrue, @@ -90,14 +91,18 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + if (emitted) { // Only if delayed control transfer is used we must check this + assert masm.position() - delaySlotPosition == 4 : "Only one instruction can be stuffed into the delay slot"; + } if (!emitted) { SPARCCompare.emit(crb, masm, opcode, x, y); emitted = emitBranch(crb, masm, true); } + assert emitted; } - public void emitForDelay(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) { SPARCCompare.emit(crb, masm, opcode, x, y); emitted = emitBranch(crb, masm, false); } @@ -132,6 +137,7 @@ assert actualCondition != null; SPARCControlFlow.emitBranch(masm, actualTarget, actualCondition, cc, predictBranchTaken); } + delaySlotPosition = masm.position(); if (withDelayedNop) { new Nop().emit(masm); // delay slot } @@ -356,13 +362,13 @@ emitBranch(masm, target, condition, CC.Icc, false); break; case Long: { - SPARCMove.move(crb, masm, scratch, keyConstants[index], DelaySlotHolder.DUMMY); + SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY); new Cmp(keyRegister, asLongReg(scratch)).emit(masm); emitBranch(masm, target, condition, CC.Xcc, false); break; } case Object: { - SPARCMove.move(crb, masm, scratch, keyConstants[index], DelaySlotHolder.DUMMY); + SPARCMove.move(crb, masm, scratch, keyConstants[index], SPARCDelayedControlTransfer.DUMMY); new Cmp(keyRegister, asObjectReg(scratch)).emit(masm); emitBranch(masm, target, condition, CC.Ptrcc, false); break; @@ -486,7 +492,7 @@ actualTrueValue = falseValue; actualFalseValue = trueValue; } - SPARCMove.move(crb, masm, result, actualFalseValue, DelaySlotHolder.DUMMY); + SPARCMove.move(crb, masm, result, actualFalseValue, SPARCDelayedControlTransfer.DUMMY); cmove(masm, cc, kind, result, actualCondition, actualTrueValue); } } diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCDelayedControlTransfer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCDelayedControlTransfer.java Tue Sep 23 12:12:26 2014 -0700 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013, 2014, 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.lir.sparc; + +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +/** + * This interface is used for {@link LIRInstruction}s which provide a delay slot for one instruction + * from another {@link LIRInstruction}. + * + * @see SPARCTailDelayedLIRInstruction + */ +public interface SPARCDelayedControlTransfer { + + SPARCDelayedControlTransfer DUMMY = new SPARCDelayedControlTransfer() { + public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + // do nothing + } + + @Override + public String toString() { + return "null"; + } + }; + + /** + * This method must be called, to generate the control transfer, but without any Nop in the + * delay slot. + * + * @param crb + * @param masm + */ + public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm); +} diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCJumpOp.java Tue Sep 23 12:12:26 2014 -0700 @@ -29,18 +29,20 @@ import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.asm.*; -public class SPARCJumpOp extends JumpOp implements DelaySlotHolder { +public class SPARCJumpOp extends JumpOp implements SPARCDelayedControlTransfer { private boolean emitDone = false; + private int delaySlotPosition = -1; public SPARCJumpOp(LabelRef destination) { super(destination); } - public void emitForDelay(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + public void emitControlTransfer(CompilationResultBuilder crb, SPARCMacroAssembler masm) { assert !emitDone; if (!crb.isSuccessorEdge(destination())) { new Bpa(destination().label()).emit(masm); } + delaySlotPosition = masm.position(); emitDone = true; } @@ -52,6 +54,8 @@ new Bpa(destination().label()).emit(masm); new Nop().emit(masm); } + } else { + assert crb.asm.position() - delaySlotPosition == 4; } } } diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java Tue Sep 23 12:12:26 2014 -0700 @@ -30,6 +30,7 @@ * Convenience class to provide SPARCMacroAssembler for the {@link #emitCode} method. */ public abstract class SPARCLIRInstruction extends LIRInstruction { + protected SPARCDelayedControlTransfer delayedControlTransfer = SPARCDelayedControlTransfer.DUMMY; @Override public final void emitCode(CompilationResultBuilder crb) { @@ -37,4 +38,12 @@ } public abstract void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm); + + public boolean leavesRegisterWindow() { + return false; + } + + public void setDelayedControlTransfer(SPARCDelayedControlTransfer holder) { + this.delayedControlTransfer = holder; + } } diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java Tue Sep 23 12:12:26 2014 -0700 @@ -31,7 +31,7 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; -public class SPARCMathIntrinsicOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction { +public class SPARCMathIntrinsicOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { public enum IntrinsicOpcode { SQRT, @@ -46,7 +46,6 @@ @Opcode private final IntrinsicOpcode opcode; @Def protected Value result; @Use protected Value input; - private DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY; public SPARCMathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) { this.opcode = opcode; @@ -57,7 +56,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { Kind inputKind = (Kind) input.getLIRKind().getPlatformKind(); - delaySlotHolder.emitForDelay(crb, masm); + delayedControlTransfer.emitControlTransfer(crb, masm); switch (opcode) { case SQRT: switch (inputKind) { @@ -93,8 +92,4 @@ } } - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotHolder = holder; - } - } diff -r 6d8ae4c6725f -r 2d401b9ca70d 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 Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Sep 23 12:12:26 2014 -0700 @@ -43,11 +43,10 @@ public class SPARCMove { @Opcode("MOVE_TOREG") - public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp, TailDelayedLIRInstruction { + public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { @Def({REG, HINT}) protected AllocatableValue result; @Use({REG, STACK, CONST}) protected Value input; - private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY; public MoveToRegOp(AllocatableValue result, Value input) { this.result = result; @@ -56,12 +55,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - move(crb, masm, getResult(), getInput(), delaySlotLir); - } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - assert delaySlotLir == DelaySlotHolder.DUMMY : "Should be set only once"; - this.delaySlotLir = holder; + move(crb, masm, getResult(), getInput(), delayedControlTransfer); } @Override @@ -76,11 +70,10 @@ } @Opcode("MOVE_FROMREG") - public static class MoveFromRegOp extends SPARCLIRInstruction implements MoveOp, TailDelayedLIRInstruction { + public static class MoveFromRegOp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { @Def({REG, STACK}) protected AllocatableValue result; @Use({REG, CONST, HINT}) protected Value input; - private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY; public MoveFromRegOp(AllocatableValue result, Value input) { this.result = result; @@ -89,11 +82,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - move(crb, masm, getResult(), getInput(), delaySlotLir); - } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotLir = holder; + move(crb, masm, getResult(), getInput(), delayedControlTransfer); } @Override @@ -111,12 +100,11 @@ * Move between floating-point and general purpose register domain (WITHOUT VIS3) */ @Opcode("MOVE") - public static class MoveFpGp extends SPARCLIRInstruction implements MoveOp, TailDelayedLIRInstruction { + public static class MoveFpGp extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; @Use({STACK}) protected StackSlot temp; - private DelaySlotHolder delaySlotLir = DelaySlotHolder.DUMMY; public MoveFpGp(AllocatableValue result, AllocatableValue input, StackSlot temp) { super(); @@ -134,10 +122,6 @@ return result; } - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotLir = holder; - } - @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { Kind inputKind = (Kind) input.getPlatformKind(); @@ -175,7 +159,7 @@ default: GraalInternalError.shouldNotReachHere(); } - delaySlotLir.emitForDelay(crb, masm); + delayedControlTransfer.emitControlTransfer(crb, masm); switch (resultKind) { case Long: new Ldx(tempAddress, asLongReg(result)).emit(masm); @@ -210,11 +194,10 @@ * Move between floating-point and general purpose register domain (WITH VIS3) */ @Opcode("MOVE") - public static class MoveFpGpVIS3 extends SPARCLIRInstruction implements MoveOp, TailDelayedLIRInstruction { + public static class MoveFpGpVIS3 extends SPARCLIRInstruction implements MoveOp, SPARCTailDelayedLIRInstruction { @Def({REG}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; - private DelaySlotHolder delayHolder = DelaySlotHolder.DUMMY; public MoveFpGpVIS3(AllocatableValue result, AllocatableValue input) { super(); @@ -234,7 +217,7 @@ public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { Kind inputKind = (Kind) input.getPlatformKind(); Kind resultKind = (Kind) result.getPlatformKind(); - delayHolder.emitForDelay(crb, masm); + delayedControlTransfer.emitControlTransfer(crb, masm); if (resultKind == Float) { if (inputKind == Int || inputKind == Short || inputKind == Char || inputKind == Byte) { new Movwtos(asIntReg(input), asFloatReg(result)).emit(masm); @@ -261,10 +244,6 @@ } } } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delayHolder = holder; - } } public abstract static class MemOp extends SPARCLIRInstruction implements ImplicitNullCheck { @@ -295,10 +274,9 @@ } } - public static class LoadOp extends MemOp implements TailDelayedLIRInstruction { + public static class LoadOp extends MemOp implements SPARCTailDelayedLIRInstruction { @Def({REG}) protected AllocatableValue result; - DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY; public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state) { super(kind, address, state); @@ -311,7 +289,7 @@ Register scratch = sc.getRegister(); final SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch); final Register dst = asRegister(result); - delaySlotHolder.emitForDelay(crb, masm); + delayedControlTransfer.emitControlTransfer(crb, masm); if (state != null) { crb.recordImplicitException(masm.position(), state); } @@ -346,17 +324,12 @@ } } } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotHolder = holder; - } } - public static class LoadAddressOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction { + public static class LoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { @Def({REG}) protected AllocatableValue result; @Use({COMPOSITE, UNINITIALIZED}) protected SPARCAddressValue addressValue; - private DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY; public LoadAddressOp(AllocatableValue result, SPARCAddressValue address) { this.result = result; @@ -366,11 +339,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { SPARCAddress address = addressValue.toAddress(); - loadEffectiveAddress(crb, masm, address, asLongReg(result), delaySlotHolder); - } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotHolder = holder; + loadEffectiveAddress(crb, masm, address, asLongReg(result), delayedControlTransfer); } } @@ -409,11 +378,10 @@ } } - public static class NullCheckOp extends SPARCLIRInstruction implements NullCheck, TailDelayedLIRInstruction { + public static class NullCheckOp extends SPARCLIRInstruction implements NullCheck, SPARCTailDelayedLIRInstruction { @Use({REG}) protected AllocatableValue input; @State protected LIRFrameState state; - private DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY; public NullCheckOp(Variable input, LIRFrameState state) { this.input = input; @@ -422,7 +390,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - delaySlotHolder.emitForDelay(crb, masm); + delayedControlTransfer.emitControlTransfer(crb, masm); crb.recordImplicitException(masm.position(), state); new Ldx(new SPARCAddress(asRegister(input), 0), r0).emit(masm); } @@ -434,10 +402,6 @@ public LIRFrameState getState() { return state; } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotHolder = holder; - } } @Opcode("CAS") @@ -460,11 +424,10 @@ } } - public static class StackLoadAddressOp extends SPARCLIRInstruction implements TailDelayedLIRInstruction { + public static class StackLoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { @Def({REG}) protected AllocatableValue result; @Use({STACK, UNINITIALIZED}) protected StackSlot slot; - private DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY; public StackLoadAddressOp(AllocatableValue result, StackSlot slot) { this.result = result; @@ -474,36 +437,31 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { SPARCAddress address = (SPARCAddress) crb.asAddress(slot); - loadEffectiveAddress(crb, masm, address, asLongReg(result), delaySlotHolder); - } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotHolder = holder; + loadEffectiveAddress(crb, masm, address, asLongReg(result), delayedControlTransfer); } } - private static void loadEffectiveAddress(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCAddress address, Register result, DelaySlotHolder delaySlotHolder) { + private static void loadEffectiveAddress(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCAddress address, Register result, SPARCDelayedControlTransfer delaySlotHolder) { if (address.getIndex().equals(Register.None)) { if (isSimm13(address.getDisplacement())) { - delaySlotHolder.emitForDelay(crb, masm); + delaySlotHolder.emitControlTransfer(crb, masm); new Add(address.getBase(), address.getDisplacement(), result).emit(masm); } else { assert result.encoding() != address.getBase().encoding(); new Setx(address.getDisplacement(), result).emit(masm); // No relocation, therefore, the add can be delayed as well - delaySlotHolder.emitForDelay(crb, masm); + delaySlotHolder.emitControlTransfer(crb, masm); new Add(address.getBase(), result, result).emit(masm); } } else { - delaySlotHolder.emitForDelay(crb, masm); + delaySlotHolder.emitControlTransfer(crb, masm); new Add(address.getBase(), address.getIndex(), result).emit(masm); } } - public static class StoreOp extends MemOp implements TailDelayedLIRInstruction { + public static class StoreOp extends MemOp implements SPARCTailDelayedLIRInstruction { @Use({REG}) protected AllocatableValue input; - DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY; public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) { super(kind, address, state); @@ -516,7 +474,7 @@ try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { Register scratch = sc.getRegister(); SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch); - delaySlotHolder.emitForDelay(crb, masm); + delayedControlTransfer.emitControlTransfer(crb, masm); if (state != null) { crb.recordImplicitException(masm.position(), state); } @@ -549,16 +507,11 @@ } } } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotHolder = holder; - } } - public static class StoreConstantOp extends MemOp implements TailDelayedLIRInstruction { + public static class StoreConstantOp extends MemOp implements SPARCTailDelayedLIRInstruction { protected final Constant input; - DelaySlotHolder delaySlotHolder = DelaySlotHolder.DUMMY; public StoreConstantOp(Kind kind, SPARCAddressValue address, Constant input, LIRFrameState state) { super(kind, address, state); @@ -573,7 +526,7 @@ try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { Register scratch = sc.getRegister(); SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch); - delaySlotHolder.emitForDelay(crb, masm); + delayedControlTransfer.emitControlTransfer(crb, masm); if (state != null) { crb.recordImplicitException(masm.position(), state); } @@ -601,13 +554,9 @@ } } } - - public void setDelaySlotHolder(DelaySlotHolder holder) { - this.delaySlotHolder = holder; - } } - public static void move(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, DelaySlotHolder delaySlotLir) { + public static void move(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) { if (isRegister(input)) { if (isRegister(result)) { reg2reg(crb, masm, result, input, delaySlotLir); @@ -649,7 +598,7 @@ } } - private static void reg2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, DelaySlotHolder delaySlotLir) { + private static void reg2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) { final Register src = asRegister(input); final Register dst = asRegister(result); if (src.equals(dst)) { @@ -663,7 +612,7 @@ case Int: case Long: case Object: - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Mov(src, dst).emit(masm); break; case Float: @@ -705,13 +654,13 @@ } } - private static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, DelaySlotHolder delaySlotLir) { + private static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) { SPARCAddress dst = (SPARCAddress) crb.asAddress(result); try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { Register scratch = sc.getRegister(); dst = generateSimm13OffsetLoad(dst, masm, scratch); Register src = asRegister(input); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); switch (input.getKind()) { case Byte: case Boolean: @@ -740,13 +689,13 @@ } } - private static void stack2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, DelaySlotHolder delaySlotLir) { + private static void stack2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) { SPARCAddress src = (SPARCAddress) crb.asAddress(input); try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { Register scratch = sc.getRegister(); src = generateSimm13OffsetLoad(src, masm, scratch); Register dst = asRegister(result); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); switch (input.getKind()) { case Boolean: case Byte: @@ -777,36 +726,36 @@ } } - private static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Constant input, DelaySlotHolder delaySlotLir) { + private static void const2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Constant input, SPARCDelayedControlTransfer delaySlotLir) { try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { Register scratch = sc.getRegister(); boolean hasVIS3 = ((SPARC) masm.target.arch).getFeatures().contains(CPUFeature.VIS3); switch (input.getKind().getStackKind()) { case Int: if (input.isDefaultForKind()) { - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Clr(asIntReg(result)).emit(masm); } else if (isSimm13(input.asLong())) { - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Or(g0, input.asInt(), asIntReg(result)).emit(masm); } else { Setx set = new Setx(input.asLong(), asIntReg(result), false, true); set.emitFirstPartOfDelayed(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); set.emitSecondPartOfDelayed(masm); } break; case Long: if (input.isDefaultForKind()) { - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Clr(asLongReg(result)).emit(masm); } else if (isSimm13(input.asLong())) { - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Or(g0, (int) input.asLong(), asLongReg(result)).emit(masm); } else { Setx setx = new Setx(input.asLong(), asLongReg(result), false, true); setx.emitFirstPartOfDelayed(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); setx.emitSecondPartOfDelayed(masm); } break; @@ -814,7 +763,7 @@ float constant = input.asFloat(); int constantBits = java.lang.Float.floatToIntBits(constant); if (constantBits == 0) { - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fzeros(asFloatReg(result)).emit(masm); } else { if (hasVIS3) { @@ -823,7 +772,7 @@ } else { new Setx(constantBits, scratch, false).emit(masm); } - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); // Now load the float value new Movwtos(scratch, asFloatReg(result)).emit(masm); } else { @@ -831,7 +780,7 @@ // First load the address into the scratch register new Setx(0, scratch, true).emit(masm); // Now load the float value - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Ldf(scratch, asFloatReg(result)).emit(masm); } } @@ -841,7 +790,7 @@ double constant = input.asDouble(); long constantBits = java.lang.Double.doubleToLongBits(constant); if (constantBits == 0) { - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Fzerod(asDoubleReg(result)).emit(masm); } else { if (hasVIS3) { @@ -850,14 +799,14 @@ } else { new Setx(constantBits, scratch, false).emit(masm); } - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); // Now load the float value new Movxtod(scratch, asDoubleReg(result)).emit(masm); } else { crb.asDoubleConstRef(input); // First load the address into the scratch register new Setx(0, scratch, true).emit(masm); - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); // Now load the float value new Lddf(scratch, asDoubleReg(result)).emit(masm); } @@ -866,7 +815,7 @@ } case Object: if (input.isNull()) { - delaySlotLir.emitForDelay(crb, masm); + delaySlotLir.emitControlTransfer(crb, masm); new Clr(asRegister(result)).emit(masm); } else if (crb.target.inlineObjects) { crb.recordInlineDataInCode(input); // relocatable cannot be delayed diff -r 6d8ae4c6725f -r 2d401b9ca70d 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 Mon Sep 22 11:20:35 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java Tue Sep 23 12:12:26 2014 -0700 @@ -70,7 +70,7 @@ private static void saveRegister(CompilationResultBuilder crb, SPARCMacroAssembler masm, StackSlot result, Register register) { RegisterValue input = register.asValue(result.getLIRKind()); - SPARCMove.move(crb, masm, result, input, DelaySlotHolder.DUMMY); + SPARCMove.move(crb, masm, result, input, SPARCDelayedControlTransfer.DUMMY); } @Override diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTailDelayedLIRInstruction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTailDelayedLIRInstruction.java Tue Sep 23 12:12:26 2014 -0700 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013, 2014, 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.lir.sparc; + +import com.oracle.graal.lir.*; + +/** + * Implementors of this interface are able to place its last instruction into the delay slot of a + * {@link SPARCDelayedControlTransfer} instruction. + * + * The implementor has to do following steps to emit code into the delay slot for the + * DelayedControlTransfer instruction: + *
    + *
  1. Emit everything up to the second last instruction.
  2. + *
  3. Call + * {@link SPARCDelayedControlTransfer#emitControlTransfer(com.oracle.graal.lir.asm.CompilationResultBuilder, com.oracle.graal.asm.sparc.SPARCMacroAssembler)} + * to let the DelayedControlTransfer instruction emit its own code (But must not stuff the delay + * slot with Nop)
  4. + *
  5. emit the last instruction for this {@link LIRInstruction}
  6. + *
+ * + * Note: If this instruction decides not to use the delay slot, it can skip the call of + * {@link SPARCDelayedControlTransfer#emitControlTransfer(com.oracle.graal.lir.asm.CompilationResultBuilder, com.oracle.graal.asm.sparc.SPARCMacroAssembler)} + * . The DelayedControlTransfer instruction will emit the code just with Nop in the delay slot. + */ +public interface SPARCTailDelayedLIRInstruction { + public void setDelayedControlTransfer(SPARCDelayedControlTransfer holder); +} diff -r 6d8ae4c6725f -r 2d401b9ca70d graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/TailDelayedLIRInstruction.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/TailDelayedLIRInstruction.java Mon Sep 22 11:20:35 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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.lir.sparc; - -import com.oracle.graal.lir.*; - -/** - * Implementors of this interface are able to place the last instruction to the delay slot of the - * given {@link DelaySlotHolder}. - * - * This LIR instruction is still emitted in the usual way. But when emitting code for this LIR - * instruction before the last instruction, it can transfer control over to the delay slot holder - * LIR instruction, which then can emit code in order to get to the delay slot. - * - * Steps for emit delayed code - *
    - *
  1. If this instruction contains more than one instruction, emit everything up to the second last - * instruction.
  2. - *
  3. Then call the - * {@link DelaySlotHolder#emitForDelay(com.oracle.graal.lir.asm.CompilationResultBuilder, com.oracle.graal.asm.sparc.SPARCMacroAssembler)} - * to let the delay-slot holder emit its code.
  4. - *
  5. emit the last instruction for this {@link LIRInstruction}
  6. - *
- * - * Note: If this instruction decides not to use the delay slot, it can skip the call of - * {@link DelaySlotHolder#emitForDelay(com.oracle.graal.lir.asm.CompilationResultBuilder, com.oracle.graal.asm.sparc.SPARCMacroAssembler)} - * and the code generation will continue without using the delay slot. Nothing other steps are - * required. - */ -public interface TailDelayedLIRInstruction { - public void setDelaySlotHolder(DelaySlotHolder holder); -}