# HG changeset patch # User Doug Simon # Date 1411716165 -7200 # Node ID c1d10773331fcabc73a213d029d9b765f2ae9a2f # Parent 5d03b4a472c679f2d10607192e091bc28b8be0e5# Parent 5b8f316bdb9ea2444989b0bccbde973e3bb8138b Merge. diff -r 5d03b4a472c6 -r c1d10773331f graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java --- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java Fri Sep 26 00:18:43 2014 +0200 +++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Assembler.java Fri Sep 26 09:22:45 2014 +0200 @@ -33,7 +33,7 @@ public abstract class Assembler { public final TargetDescription target; - private Set jumpDisplacementHints; + private List jumpDisplacementHints; /** * Backing code buffer. @@ -206,7 +206,7 @@ public LabelHint requestLabelHint(Label label) { if (jumpDisplacementHints == null) { - jumpDisplacementHints = new HashSet<>(); + jumpDisplacementHints = new ArrayList<>(); } LabelHint hint = new LabelHint(label, position()); this.jumpDisplacementHints.add(hint); @@ -216,8 +216,7 @@ public static class LabelHint { private Label label; private int forPosition; - private int capturedTarget; - private boolean captured = false; + private int capturedTarget = -1; protected LabelHint(Label label, int lastPosition) { super(); @@ -227,7 +226,6 @@ protected void capture() { this.capturedTarget = label.position(); - this.captured = true; } public int getTarget() { @@ -241,7 +239,7 @@ } public boolean isValid() { - return captured; + return capturedTarget >= 0; } } } diff -r 5d03b4a472c6 -r c1d10773331f graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java Fri Sep 26 00:18:43 2014 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCNodeLIRBuilder.java Fri Sep 26 09:22:45 2014 +0200 @@ -25,12 +25,16 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.match.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.sparc.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.extended.*; /** * This class implements the SPARC specific portion of the LIR generator. @@ -62,4 +66,54 @@ protected JumpOp newJumpOp(LabelRef ref) { return new SPARCJumpOp(ref); } + + protected LIRFrameState getState(Access access) { + if (access instanceof DeoptimizingNode) { + return state((DeoptimizingNode) access); + } + return null; + } + + private ComplexMatchResult emitSignExtendMemory(Access access, int fromBits, int toBits) { + assert fromBits <= toBits && toBits <= 64; + Kind toKind = null; + Kind fromKind = null; + if (fromBits == toBits) { + return null; + } else if (toBits > 32) { + toKind = Kind.Long; + } else if (toBits > 16) { + toKind = Kind.Int; + } else { + toKind = Kind.Short; + } + switch (fromBits) { + case 8: + fromKind = Kind.Byte; + break; + case 16: + fromKind = Kind.Short; + break; + case 32: + fromKind = Kind.Int; + break; + default: + throw GraalInternalError.unimplemented("unsupported sign extension (" + fromBits + " bit -> " + toBits + " bit)"); + } + { + Kind localFromKind = fromKind; + Kind localToKind = toKind; + return builder -> { + Value address = access.accessLocation().generateAddress(builder, gen, operand(access.object())); + Value v = getLIRGeneratorTool().emitLoad(LIRKind.value(localFromKind), address, getState(access)); + return getLIRGeneratorTool().emitReinterpret(LIRKind.value(localToKind), v); + }; + } + } + + @MatchRule("(SignExtend Read=access)") + @MatchRule("(SignExtend FloatingRead=access)") + public ComplexMatchResult signExtend(SignExtendNode root, Access access) { + return emitSignExtendMemory(access, root.getInputBits(), root.getResultBits()); + } } diff -r 5d03b4a472c6 -r c1d10773331f graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java Fri Sep 26 00:18:43 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java Fri Sep 26 09:22:45 2014 +0200 @@ -498,6 +498,12 @@ out.println("import " + p + ".*;"); } out.println(""); + + // FIXME: Ugly hack, don't know how to work this problem around (import + // com.oracle.graal.nodes.*; is unused, but cannot be avoided + if (matchStatementClassName.contains("SPARCNodeLIRBuilder")) { + out.println("@SuppressWarnings(\"unused\")"); + } out.println("public class " + matchStatementClassName + " implements " + MatchStatementSet.class.getSimpleName() + " {"); out.println(); diff -r 5d03b4a472c6 -r c1d10773331f 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 Fri Sep 26 00:18:43 2014 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Fri Sep 26 09:22:45 2014 +0200 @@ -54,7 +54,7 @@ public static class Unary2Op extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { @Opcode private final SPARCArithmetic opcode; - @Def({REG}) protected AllocatableValue result; + @Def({REG, HINT}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue x; public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) { @@ -76,7 +76,7 @@ public static class BinaryRegReg extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { @Opcode private final SPARCArithmetic opcode; - @Def({REG}) protected Value result; + @Def({REG, HINT}) protected Value result; @Use({REG}) protected Value x; @Alive({REG}) protected Value y; @State LIRFrameState state; @@ -111,7 +111,7 @@ public static class BinaryRegConst extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction { @Opcode private final SPARCArithmetic opcode; - @Def({REG}) protected AllocatableValue result; + @Def({REG, HINT}) protected AllocatableValue result; @Use({REG}) protected Value x; @State protected LIRFrameState state; protected Constant y; @@ -575,24 +575,24 @@ new Signx(asLongReg(src), asIntReg(dst)).emit(masm); break; case B2L: - new Sllx(asIntReg(src), 56, asLongReg(dst)).emit(masm); + new Sll(asIntReg(src), 24, asLongReg(dst)).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); - new Srax(asLongReg(dst), 56, asLongReg(dst)).emit(masm); + new Sra(asLongReg(dst), 24, asLongReg(dst)).emit(masm); break; case B2I: - new Sllx(asIntReg(src), 56, asIntReg(dst)).emit(masm); + new Sll(asIntReg(src), 24, asIntReg(dst)).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); - new Srax(asIntReg(dst), 56, asIntReg(dst)).emit(masm); + new Sra(asIntReg(dst), 24, asIntReg(dst)).emit(masm); break; case S2L: - new Sllx(asIntReg(src), 48, asLongReg(dst)).emit(masm); + new Sll(asIntReg(src), 16, asLongReg(dst)).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); - new Srax(asLongReg(dst), 48, asLongReg(dst)).emit(masm); + new Sra(asLongReg(dst), 16, asLongReg(dst)).emit(masm); break; case S2I: - new Sllx(asIntReg(src), 48, asIntReg(dst)).emit(masm); + new Sll(asIntReg(src), 16, asIntReg(dst)).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); - new Srax(asIntReg(dst), 48, asIntReg(dst)).emit(masm); + new Sra(asIntReg(dst), 16, asIntReg(dst)).emit(masm); break; case I2F: delaySlotLir.emitControlTransfer(crb, masm); diff -r 5d03b4a472c6 -r c1d10773331f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java Fri Sep 26 00:18:43 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java Fri Sep 26 09:22:45 2014 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.spi.*; @@ -53,6 +54,25 @@ if (getOp().isNeutral(c)) { return forX; } + if (c.getKind().isNumericInteger()) { + long i = c.asLong(); + boolean signFlip = false; + if (i < 0) { + i = -i; + signFlip = true; + } + ValueNode divResult = null; + if (CodeUtil.isPowerOf2(i)) { + divResult = RightShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(i))); + } + if (divResult != null) { + if (signFlip) { + return NegateNode.create(divResult); + } else { + return divResult; + } + } + } } return this; } diff -r 5d03b4a472c6 -r c1d10773331f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Fri Sep 26 00:18:43 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Fri Sep 26 09:22:45 2014 +0200 @@ -60,13 +60,32 @@ if (c.getKind().isNumericInteger()) { long i = c.asLong(); - long abs = Math.abs(i); - if (abs > 0 && CodeUtil.isPowerOf2(abs)) { - LeftShiftNode shift = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(abs))); - if (i < 0) { - return NegateNode.create(shift); - } else { - return shift; + boolean signFlip = false; + if (i < 0) { + i = -i; + signFlip = true; + } + if (i > 0) { + ValueNode mulResult = null; + long bit1 = i & -i; + long bit2 = i - bit1; + bit2 = bit2 & -bit2; // Extract 2nd bit + if (CodeUtil.isPowerOf2(i)) { // + mulResult = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(i))); + } else if (bit2 + bit1 == i) { // We can work with two shifts and add + ValueNode shift1 = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(bit1))); + ValueNode shift2 = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(bit2))); + mulResult = AddNode.create(shift1, shift2); + } else if (CodeUtil.isPowerOf2(i + 1)) { // shift and subtract + ValueNode shift1 = LeftShiftNode.create(forX, ConstantNode.forInt(CodeUtil.log2(i + 1))); + mulResult = SubNode.create(shift1, forX); + } + if (mulResult != null) { + if (signFlip) { + return NegateNode.create(mulResult); + } else { + return mulResult; + } } } }