Mercurial > hg > truffle
changeset 17082:f8586d059f9d
[SPARC] make compatible for CPU without VIS3 and do some cleanup
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Fri Sep 05 18:28:11 2014 -0700 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Tue Sep 09 12:09:58 2014 -0700 @@ -3136,6 +3136,15 @@ } } + public static class Fxtos extends Fmt3n { + + public Fxtos(Register src2, Register dst) { + super(Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fxtos.getValue(), src2.encoding(), dst.encoding()); + assert isDoubleFloatRegister(src2); + assert isSingleFloatRegister(dst); + } + } + public static class Fxtod extends Fmt3n { public Fxtod(Register src2, Register dst) {
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Fri Sep 05 18:28:11 2014 -0700 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Tue Sep 09 12:09:58 2014 -0700 @@ -27,6 +27,9 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.asm.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.sparc.*; +import com.oracle.graal.sparc.SPARC.CPUFeature; public class SPARCMacroAssembler extends SPARCAssembler { @@ -64,6 +67,10 @@ fmt.write(this, branch); } + protected boolean hasFeature(CPUFeature feature) { + return ((SPARC) this.target.arch).features.contains(feature); + } + @Override public AbstractAddress makeAddress(Register base, int displacement) { return new SPARCAddress(base, displacement); @@ -338,6 +345,27 @@ } } + public static class MoveXtoDouble { + private final Register src; + private final Register dst; + private final StackSlot tmp; + + public MoveXtoDouble(Register src, Register dst, StackSlot tmp) { + super(); + this.src = src; + this.dst = dst; + this.tmp = tmp; + } + + public void emit(SPARCMacroAssembler masm) { + if (masm.hasFeature(CPUFeature.VIS3)) { + new Movxtod(src, dst).emit(masm); + } else { + GraalInternalError.unimplemented(); + } + } + } + /** * This instruction is like sethi but for 64-bit values. */
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Sep 05 18:28:11 2014 -0700 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Sep 09 12:09:58 2014 -0700 @@ -27,15 +27,12 @@ import static com.oracle.graal.lir.sparc.SPARCArithmetic.*; import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.*; import static com.oracle.graal.lir.sparc.SPARCCompare.*; -import static com.oracle.graal.lir.sparc.SPARCControlFlow.*; import static com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp.IntrinsicOpcode.*; -import static com.oracle.graal.lir.sparc.SPARCMove.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCAssembler.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; @@ -43,7 +40,29 @@ import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.gen.*; import com.oracle.graal.lir.sparc.*; +import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegConst; +import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegReg; +import com.oracle.graal.lir.sparc.SPARCArithmetic.MulHighOp; +import com.oracle.graal.lir.sparc.SPARCArithmetic.RemOp; +import com.oracle.graal.lir.sparc.SPARCArithmetic.ShiftOp; +import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary2Op; +import com.oracle.graal.lir.sparc.SPARCCompare.CompareOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.BranchOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.CondMoveOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.FloatCondMoveOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.ReturnOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.StrategySwitchOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.TableSwitchOp; +import com.oracle.graal.lir.sparc.SPARCMove.LoadAddressOp; +import com.oracle.graal.lir.sparc.SPARCMove.LoadDataAddressOp; +import com.oracle.graal.lir.sparc.SPARCMove.MembarOp; +import com.oracle.graal.lir.sparc.SPARCMove.MoveFpGp; +import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp; +import com.oracle.graal.lir.sparc.SPARCMove.MoveToRegOp; +import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp; import com.oracle.graal.phases.util.*; +import com.oracle.graal.sparc.*; +import com.oracle.graal.sparc.SPARC.*; /** * This class implements the SPARC specific portion of the LIR generator. @@ -149,15 +168,6 @@ } else { indexRegister = asAllocatable(index); } - - // if (baseRegister.equals(Value.ILLEGAL)) { - // baseRegister = asAllocatable(indexRegister); - // } else { - // Variable newBase = newVariable(Kind.Long); - // emitMove(newBase, baseRegister); - // baseRegister = newBase; - // baseRegister = emitAdd(baseRegister, indexRegister); - // } } } else { indexRegister = Value.ILLEGAL; @@ -453,53 +463,53 @@ @Override public Value emitNegate(Value input) { - Variable result = newVariable(LIRKind.derive(input)); switch (input.getKind().getStackKind()) { case Long: - append(new Unary2Op(LNEG, result, load(input))); - break; + return emitUnary(LNEG, input); case Int: - append(new Unary2Op(INEG, result, load(input))); - break; + return emitUnary(INEG, input); case Float: - append(new Unary2Op(FNEG, result, load(input))); - break; + return emitUnary(FNEG, input); case Double: - append(new Unary2Op(DNEG, result, load(input))); - break; + return emitUnary(DNEG, input); default: throw GraalInternalError.shouldNotReachHere(); } - return result; } @Override public Value emitNot(Value input) { - Variable result = newVariable(LIRKind.derive(input)); switch (input.getKind().getStackKind()) { case Int: - append(new Unary2Op(INOT, result, load(input))); - break; + return emitUnary(INOT, input); case Long: - append(new Unary2Op(LNOT, result, load(input))); - break; + return emitUnary(LNOT, input); default: throw GraalInternalError.shouldNotReachHere(); } + } + + private Variable emitUnary(SPARCArithmetic op, Value input) { + Variable result = newVariable(LIRKind.derive(input)); + append(new Unary2Op(op, result, load(input))); return result; } + private Variable emitBinary(SPARCArithmetic op, boolean commutative, Value a, Value b) { + return emitBinary(op, commutative, a, b, null); + } + private Variable emitBinary(SPARCArithmetic op, boolean commutative, Value a, Value b, LIRFrameState state) { - if (isConstant(b)) { - return emitBinaryConst(op, commutative, asAllocatable(a), asConstant(b), state); - } else if (commutative && isConstant(a)) { - return emitBinaryConst(op, commutative, asAllocatable(b), asConstant(a), state); + if (isConstant(b) && canInlineConstant(asConstant(b))) { + return emitBinaryConst(op, load(a), asConstant(b), state); + } else if (commutative && isConstant(a) && canInlineConstant(asConstant(a))) { + return emitBinaryConst(op, load(b), asConstant(a), state); } else { - return emitBinaryVar(op, commutative, asAllocatable(a), asAllocatable(b), state); + return emitBinaryVar(op, load(a), load(b), state); } } - private Variable emitBinaryConst(SPARCArithmetic op, boolean commutative, AllocatableValue a, Constant b, LIRFrameState state) { + private Variable emitBinaryConst(SPARCArithmetic op, AllocatableValue a, Constant b, LIRFrameState state) { switch (op) { case IADD: case LADD: @@ -513,24 +523,19 @@ case LXOR: case IMUL: case LMUL: - if (NumUtil.isInt(b.asLong())) { + if (canInlineConstant(b)) { Variable result = newVariable(LIRKind.derive(a, b)); append(new BinaryRegConst(op, result, a, b, state)); return result; } break; } - - return emitBinaryVar(op, commutative, a, asAllocatable(b), state); + return emitBinaryVar(op, a, asAllocatable(b), state); } - private Variable emitBinaryVar(SPARCArithmetic op, boolean commutative, AllocatableValue a, AllocatableValue b, LIRFrameState state) { + private Variable emitBinaryVar(SPARCArithmetic op, AllocatableValue a, AllocatableValue b, LIRFrameState state) { Variable result = newVariable(LIRKind.derive(a, b)); - if (commutative) { - append(new BinaryCommutative(op, result, a, b)); - } else { - append(new BinaryRegReg(op, result, a, b, state)); - } + append(new BinaryRegReg(op, result, a, b, state)); return result; } @@ -538,13 +543,13 @@ public Variable emitAdd(Value a, Value b) { switch (a.getKind().getStackKind()) { case Int: - return emitBinary(IADD, true, a, b, null); + return emitBinary(IADD, true, a, b); case Long: - return emitBinary(LADD, true, a, b, null); + return emitBinary(LADD, true, a, b); case Float: - return emitBinary(FADD, true, a, b, null); + return emitBinary(FADD, true, a, b); case Double: - return emitBinary(DADD, true, a, b, null); + return emitBinary(DADD, true, a, b); default: throw GraalInternalError.shouldNotReachHere(); } @@ -552,46 +557,34 @@ @Override public Variable emitSub(Value a, Value b) { - Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind().getStackKind()) { case Int: - append(new Op2Stack(ISUB, result, a, loadNonConst(b))); - break; + return emitBinary(ISUB, false, a, b); case Long: - append(new Op2Stack(LSUB, result, a, loadNonConst(b))); - break; + return emitBinary(LSUB, false, a, b); case Float: - append(new Op2Stack(FSUB, result, a, loadNonConst(b))); - break; + return emitBinary(FSUB, false, a, b); case Double: - append(new Op2Stack(DSUB, result, a, loadNonConst(b))); - break; + return emitBinary(DSUB, false, a, b); default: throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); } - return result; } @Override public Variable emitMul(Value a, Value b) { - Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind().getStackKind()) { case Int: - append(new BinaryRegReg(IMUL, result, a, loadNonConst(b))); - break; + return emitBinary(IMUL, true, a, b); case Long: - append(new BinaryRegReg(LMUL, result, a, loadNonConst(b))); - break; + return emitBinary(LMUL, true, a, b); case Float: - append(new Op2Stack(FMUL, result, a, loadNonConst(b))); - break; + return emitBinary(FMUL, true, a, b); case Double: - append(new Op2Stack(DMUL, result, a, loadNonConst(b))); - break; + return emitBinary(DMUL, true, a, b); default: throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); } - return result; } @Override @@ -627,24 +620,18 @@ @Override public Value emitDiv(Value a, Value b, LIRFrameState state) { - SPARCArithmetic op = null; switch (a.getKind().getStackKind()) { case Int: - op = IDIV; - break; + return emitBinary(IDIV, false, a, b, state); case Long: - op = LDIV; - break; + return emitBinary(LDIV, false, a, b, state); case Float: - op = FDIV; - break; + return emitBinary(FDIV, false, a, b, state); case Double: - op = DDIV; - break; + return emitBinary(DDIV, false, a, b, state); default: throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); } - return emitBinary(op, false, a, b, state); } @Override @@ -660,19 +647,19 @@ break; case Float: q = newVariable(LIRKind.value(Kind.Float)); - append(new Op2Stack(FDIV, q, a, b)); + append(new BinaryRegReg(FDIV, q, a, b)); append(new Unary2Op(F2I, q, q)); append(new Unary2Op(I2F, q, q)); - append(new Op2Stack(FMUL, q, q, b)); - append(new Op2Stack(FSUB, result, a, q)); + append(new BinaryRegReg(FMUL, q, q, b)); + append(new BinaryRegReg(FSUB, result, a, q)); break; case Double: q = newVariable(LIRKind.value(Kind.Double)); - append(new Op2Stack(DDIV, q, a, b)); + append(new BinaryRegReg(DDIV, q, a, b)); append(new Unary2Op(D2L, q, q)); append(new Unary2Op(L2D, q, q)); - append(new Op2Stack(DMUL, q, q, b)); - append(new Op2Stack(DSUB, result, a, q)); + append(new BinaryRegReg(DMUL, q, q, b)); + append(new BinaryRegReg(DSUB, result, a, q)); break; default: throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); @@ -719,60 +706,47 @@ @Override public Variable emitAnd(Value a, Value b) { - Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind().getStackKind()) { case Int: - append(new Op2Stack(IAND, result, a, loadNonConst(b))); - break; + return emitBinary(IAND, true, a, b); case Long: - append(new Op2Stack(LAND, result, a, loadNonConst(b))); - break; + return emitBinary(LAND, true, a, b); default: throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); } - return result; } @Override public Variable emitOr(Value a, Value b) { - Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind().getStackKind()) { case Int: - append(new Op2Stack(IOR, result, a, loadNonConst(b))); - break; + return emitBinary(IOR, true, a, b); case Long: - append(new Op2Stack(LOR, result, a, loadNonConst(b))); - break; + return emitBinary(LOR, true, a, b); default: throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); } - return result; } @Override public Variable emitXor(Value a, Value b) { - Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind().getStackKind()) { case Int: - append(new Op2Stack(IXOR, result, load(a), loadNonConst(b))); - break; + return emitBinary(IXOR, true, a, b); case Long: - append(new Op2Stack(LXOR, result, load(a), loadNonConst(b))); - break; + return emitBinary(LXOR, true, a, b); default: throw GraalInternalError.shouldNotReachHere(); } - return result; } private Variable emitShift(SPARCArithmetic op, Value a, Value b) { Variable result = newVariable(LIRKind.derive(a, b).changeType(a.getPlatformKind())); - AllocatableValue input = asAllocatable(a); - if (isConstant(b)) { - append(new BinaryRegConst(op, result, input, asConstant(b), null)); + if (isConstant(b) && canInlineConstant((Constant) b)) { + append(new BinaryRegConst(op, result, load(a), asConstant(b), null)); } else { - append(new BinaryRegReg(op, result, input, b)); + append(new BinaryRegReg(op, result, load(a), load(b))); } return result; } @@ -833,47 +807,82 @@ return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), D2F, input); case F2D: return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), F2D, input); - case I2F: - return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), I2F, input); - case L2D: - return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), L2D, input); + case I2F: { + AllocatableValue convertedFloatReg = newVariable(LIRKind.derive(input).changeType(Kind.Float)); + moveBetweenFpGp(convertedFloatReg, input); + append(new Unary2Op(I2F, convertedFloatReg, convertedFloatReg)); + return convertedFloatReg; + } + case I2D: { + // Unfortunately we must do int -> float -> double because fitod has float + // and double encoding in one instruction + AllocatableValue convertedFloatReg = newVariable(LIRKind.derive(input).changeType(Kind.Float)); + moveBetweenFpGp(convertedFloatReg, input); + AllocatableValue convertedDoubleReg = newVariable(LIRKind.derive(input).changeType(Kind.Double)); + append(new Unary2Op(I2D, convertedDoubleReg, convertedFloatReg)); + return convertedDoubleReg; + } + case L2D: { + AllocatableValue convertedDoubleReg = newVariable(LIRKind.derive(input).changeType(Kind.Double)); + moveBetweenFpGp(convertedDoubleReg, input); + append(new Unary2Op(L2D, convertedDoubleReg, convertedDoubleReg)); + return convertedDoubleReg; + } case D2I: { AllocatableValue convertedFloatReg = emitConvert2Op(LIRKind.derive(input).changeType(Kind.Float), D2I, input); AllocatableValue convertedIntReg = newVariable(LIRKind.derive(convertedFloatReg).changeType(Kind.Int)); - emitMove(convertedIntReg, convertedFloatReg); + moveBetweenFpGp(convertedIntReg, convertedFloatReg); return convertedIntReg; } case F2L: { AllocatableValue convertedDoubleReg = emitConvert2Op(LIRKind.derive(input).changeType(Kind.Double), F2L, input); AllocatableValue convertedLongReg = newVariable(LIRKind.derive(convertedDoubleReg).changeType(Kind.Long)); - emitMove(convertedLongReg, convertedDoubleReg); + moveBetweenFpGp(convertedLongReg, convertedDoubleReg); return convertedLongReg; } case F2I: { AllocatableValue convertedFloatReg = emitConvert2Op(LIRKind.derive(input).changeType(Kind.Float), F2I, input); AllocatableValue convertedIntReg = newVariable(LIRKind.derive(convertedFloatReg).changeType(Kind.Int)); - emitMove(convertedIntReg, convertedFloatReg); + moveBetweenFpGp(convertedIntReg, convertedFloatReg); return convertedIntReg; } case D2L: { AllocatableValue convertedDoubleReg = emitConvert2Op(LIRKind.derive(input).changeType(Kind.Double), D2L, input); AllocatableValue convertedLongReg = newVariable(LIRKind.derive(convertedDoubleReg).changeType(Kind.Long)); - emitMove(convertedLongReg, convertedDoubleReg); + moveBetweenFpGp(convertedLongReg, convertedDoubleReg); return convertedLongReg; } - case I2D: { - AllocatableValue tmp = emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Long), I2L, input); - return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), L2D, tmp); - } case L2F: { - AllocatableValue tmp = emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), L2D, input); - return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), D2F, tmp); + // long -> double -> float see above + AllocatableValue convertedDoubleReg = newVariable(LIRKind.derive(input).changeType(Kind.Double)); + moveBetweenFpGp(convertedDoubleReg, input); + AllocatableValue convertedFloatReg = newVariable(LIRKind.derive(input).changeType(Kind.Float)); + append(new Unary2Op(L2F, convertedFloatReg, convertedDoubleReg)); + return convertedFloatReg; } default: throw GraalInternalError.shouldNotReachHere(); } } + private void moveBetweenFpGp(AllocatableValue dst, AllocatableValue src) { +// boolean isVis3 = getArchitecture().features.contains(CPUFeature.VIS3); +// if (isVis3) { +// +// } else { + StackSlot tempSlot = getTempSlot(LIRKind.derive(dst)); + append(new MoveFpGp(dst, src, tempSlot)); +// } + } + + private StackSlot getTempSlot(LIRKind kind) { + return getResult().getFrameMap().allocateSpillSlot(kind); + } + + protected SPARC getArchitecture() { + return (SPARC) target().arch; + } + @Override public Value emitNarrow(Value inputVal, int bits) { if (inputVal.getKind() == Kind.Long && bits <= 32) { @@ -954,35 +963,39 @@ public AllocatableValue emitReinterpret(LIRKind to, Value inputVal) { Kind from = inputVal.getKind(); AllocatableValue input = asAllocatable(inputVal); - + Variable result = newVariable(to); // These cases require a move between CPU and FPU registers: switch ((Kind) to.getPlatformKind()) { case Int: switch (from) { case Float: case Double: - return emitConvert2Op(to, MOV_F2I, input); + moveBetweenFpGp(result, input); + return result; } break; case Long: switch (from) { case Float: case Double: - return emitConvert2Op(to, MOV_D2L, input); + moveBetweenFpGp(result, input); + return result; } break; case Float: switch (from) { case Int: case Long: - return emitConvert2Op(to, MOV_I2F, input); + moveBetweenFpGp(result, input); + return result; } break; case Double: switch (from) { case Int: case Long: - return emitConvert2Op(to, MOV_L2D, input); + moveBetweenFpGp(result, input); + return result; } break; }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Fri Sep 05 18:28:11 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Sep 09 12:09:58 2014 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.sparc; +import java.util.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; @@ -30,24 +32,25 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.sparc.*; +import com.oracle.graal.sparc.SPARC.*; @ServiceProvider(HotSpotBackendFactory.class) public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory { - protected static Architecture createArchitecture() { - return new SPARC(); + protected Architecture createArchitecture(HotSpotVMConfig config) { + return new SPARC(computeFeatures(config)); } - protected TargetDescription createTarget() { + protected TargetDescription createTarget(HotSpotVMConfig config) { final int stackFrameAlignment = 16; final int implicitNullCheckLimit = 4096; final boolean inlineObjects = true; - return new HotSpotTargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + return new HotSpotTargetDescription(createArchitecture(config), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); } public HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotBackend host) { assert host == null; - TargetDescription target = createTarget(); + TargetDescription target = createTarget(runtime.getConfig()); HotSpotRegistersProvider registers = createRegisters(); HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime); @@ -71,6 +74,20 @@ return new SPARCHotSpotBackend(runtime, providers); } + protected Set<CPUFeature> computeFeatures(HotSpotVMConfig config) { + Set<CPUFeature> features = EnumSet.noneOf(CPUFeature.class); + if (config.vis1Instructions != 0) { + features.add(CPUFeature.VIS1); + } + if (config.vis2Instructions != 0) { + features.add(CPUFeature.VIS2); + } + if (config.vis3Instructions != 0) { + features.add(CPUFeature.VIS3); + } + return features; + } + protected HotSpotRegistersProvider createRegisters() { return new HotSpotRegisters(SPARC.g2, SPARC.g6, SPARC.sp); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Sep 05 18:28:11 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Sep 09 12:09:58 2014 -0700 @@ -793,6 +793,12 @@ @HotSpotVMConstant(name = "VM_Version::CPU_ERMS", archs = {"amd64"}) @Stable public int cpuERMS; @HotSpotVMConstant(name = "VM_Version::CPU_CLMUL", archs = {"amd64"}) @Stable public int cpuCLMUL; + // SPARC specific values + @HotSpotVMField(name = "VM_Version::_features", type = "int", get = HotSpotVMField.Type.VALUE, archs = {"sparc"}) @Stable public int sparcFeatures; + @HotSpotVMConstant(name = "VM_Version::vis3_instructions_m", archs = {"sparc"}) @Stable public int vis3Instructions; + @HotSpotVMConstant(name = "VM_Version::vis2_instructions_m", archs = {"sparc"}) @Stable public int vis2Instructions; + @HotSpotVMConstant(name = "VM_Version::vis1_instructions_m", archs = {"sparc"}) @Stable public int vis1Instructions; + // offsets, ... @HotSpotVMFlag(name = "StackShadowPages") @Stable public int stackShadowPages; @HotSpotVMFlag(name = "UseStackBanging") @Stable public boolean useStackBanging;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Fri Sep 05 18:28:11 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Tue Sep 09 12:09:58 2014 -0700 @@ -47,8 +47,7 @@ L2I, B2I, S2I, B2L, S2L, I2L, F2D, D2F, I2F, I2D, F2I, D2I, - L2F, L2D, F2L, D2L, - MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L; + L2F, L2D, F2L, D2L; // @formatter:on /** @@ -72,50 +71,6 @@ } } - public static class Op1Stack extends SPARCLIRInstruction { - - @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected Value result; - @Use({REG, STACK, CONST}) protected Value x; - - public Op1Stack(SPARCArithmetic opcode, Value result, Value x) { - this.opcode = opcode; - this.result = result; - this.x = x; - } - - @Override - public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emitUnary(crb, masm, opcode, result, x, null); - } - } - - public static class Op2Stack extends SPARCLIRInstruction { - - @Opcode private final SPARCArithmetic opcode; - @Def({REG}) protected Value result; - @Use({REG, CONST}) protected Value x; - @Alive({REG, CONST}) protected Value y; - - public Op2Stack(SPARCArithmetic opcode, Value result, Value x, Value y) { - this.opcode = opcode; - this.result = result; - this.x = x; - this.y = y; - } - - @Override - public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emit(crb, masm, opcode, result, x, y, null); - } - - @Override - public void verify() { - super.verify(); - verifyKind(opcode, result, x, y); - } - } - /** * Binary operation with two operands. The first source operand is combined with the * destination. The second source operand must be a register. @@ -124,8 +79,8 @@ @Opcode private final SPARCArithmetic opcode; @Def({REG}) protected Value result; - @Use({REG, CONST}) protected Value x; - @Alive({REG, CONST}) protected Value y; + @Use({REG}) protected Value x; + @Alive({REG}) protected Value y; @State LIRFrameState state; public BinaryRegReg(SPARCArithmetic opcode, Value result, Value x, Value y) { @@ -187,41 +142,6 @@ } } - /** - * Commutative binary operation with two operands. - */ - public static class BinaryCommutative extends SPARCLIRInstruction { - - @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected AllocatableValue result; - @Use({REG}) protected AllocatableValue x; - @Use({REG}) protected AllocatableValue y; - @State protected LIRFrameState state; - - public BinaryCommutative(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, AllocatableValue y) { - this(opcode, result, x, y, null); - } - - public BinaryCommutative(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, AllocatableValue y, LIRFrameState state) { - this.opcode = opcode; - this.result = result; - this.x = x; - this.y = y; - this.state = state; - } - - @Override - public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - emit(crb, masm, opcode, result, x, y, null); - } - - @Override - protected void verify() { - super.verify(); - verifyKind(opcode, result, x, y); - } - } - public static class ShiftOp extends SPARCLIRInstruction { @Opcode private final SPARCArithmetic opcode; @@ -713,14 +633,13 @@ new Fdtos(asDoubleReg(src), asFloatReg(dst)).emit(masm); break; case L2D: - if (src.getPlatformKind() == Kind.Long) { - new Movxtod(asLongReg(src), asDoubleReg(dst)).emit(masm); - new Fxtod(asDoubleReg(dst), asDoubleReg(dst)).emit(masm); - } else if (src.getPlatformKind() == Kind.Double) { - new Fxtod(asDoubleReg(src), asDoubleReg(dst)).emit(masm); - } else { - throw GraalInternalError.shouldNotReachHere("cannot handle source register " + src.getPlatformKind()); - } + new Fxtod(asDoubleReg(src), asDoubleReg(dst)).emit(masm); + break; + case L2F: + new Fxtos(asDoubleReg(src), asFloatReg(dst)).emit(masm); + break; + case I2D: + new Fitod(asFloatReg(src), asDoubleReg(dst)).emit(masm); break; case I2L: new Signx(asIntReg(src), asLongReg(dst)).emit(masm); @@ -745,14 +664,7 @@ new Sra(asIntReg(dst), 16, asIntReg(dst)).emit(masm); break; case I2F: - if (src.getPlatformKind() == Kind.Int || src.getPlatformKind() == Kind.Char || src.getPlatformKind() == Kind.Short || src.getPlatformKind() == Kind.Byte) { - new Movwtos(asIntReg(src), asFloatReg(dst)).emit(masm); - new Fitos(asFloatReg(dst), asFloatReg(dst)).emit(masm); - } else if (src.getPlatformKind() == Kind.Float) { - new Fitos(asFloatReg(src), asFloatReg(dst)).emit(masm); - } else { - throw GraalInternalError.shouldNotReachHere("cannot handle source register " + src.getPlatformKind()); - } + new Fitos(asFloatReg(src), asFloatReg(dst)).emit(masm); break; case F2D: new Fstod(asFloatReg(src), asDoubleReg(dst)).emit(masm); @@ -772,18 +684,18 @@ new Fsubs(asFloatReg(dst), asFloatReg(dst), asFloatReg(dst)).emit(masm); masm.bind(notOrdered); break; - case MOV_D2L: - new Movdtox(asDoubleReg(src), asLongReg(dst)).emit(masm); - break; - case MOV_L2D: - new Movxtod(asLongReg(src), asDoubleReg(dst)).emit(masm); - break; - case MOV_F2I: - new Movstosw(asFloatReg(src), asIntReg(dst)).emit(masm); - break; - case MOV_I2F: - new Movwtos(asIntReg(src), asFloatReg(dst)).emit(masm); - break; +// case MOV_D2L: +// new Movdtox(asDoubleReg(src), asLongReg(dst)).emit(masm); +// break; +// case MOV_L2D: +// new Movxtod(asLongReg(src), asDoubleReg(dst)).emit(masm); +// break; +// case MOV_F2I: +// new Movstosw(asFloatReg(src), asIntReg(dst)).emit(masm); +// break; +// case MOV_I2F: +// new Movwtos(asIntReg(src), asFloatReg(dst)).emit(masm); +// break; case D2L: new Fcmp(CC.Fcc0, Opfs.Fcmpd, asDoubleReg(src), asDoubleReg(src)).emit(masm); new Fbo(false, notOrdered).emit(masm);
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Fri Sep 05 18:28:11 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Sep 09 12:09:58 2014 -0700 @@ -96,6 +96,74 @@ } } + /** + * Move between floating-point and general purpose register domain (WITHOUT VIS3) + */ + @Opcode("MOVE") + public static class MoveFpGp extends SPARCLIRInstruction implements MoveOp { + + @Def({REG}) protected AllocatableValue result; + @Use({REG}) protected AllocatableValue input; + @Use({STACK}) protected StackSlot temp; + + public MoveFpGp(AllocatableValue result, AllocatableValue input, StackSlot temp) { + super(); + this.result = result; + this.input = input; + this.temp = temp; + } + + public Value getInput() { + return input; + } + + public AllocatableValue getResult() { + return result; + } + + @Override + public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + PlatformKind inputKind = input.getPlatformKind(); + PlatformKind resultKind = result.getPlatformKind(); + try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + Register scratch = sc.getRegister(); + SPARCAddress tempAddress = guaranueeLoadable((SPARCAddress) crb.asAddress(temp), masm, scratch); + if (inputKind == Kind.Float) { + new Stf(asFloatReg(input), tempAddress).emit(masm); + } else if (inputKind == Kind.Double) { + new Stdf(asDoubleReg(input), tempAddress).emit(masm); + } else if (inputKind == Kind.Int) { + new Stw(asIntReg(input), tempAddress).emit(masm); + } else if (inputKind == Kind.Short || inputKind == Kind.Char) { + new Sth(asIntReg(input), tempAddress).emit(masm); + } else if (inputKind == Kind.Byte) { + new Stb(asIntReg(input), tempAddress).emit(masm); + } else if (inputKind == Kind.Long) { + new Stx(asLongReg(input), tempAddress).emit(masm); + } else { + GraalInternalError.shouldNotReachHere(); + } + if (resultKind == Kind.Int) { + new Ldsw(tempAddress, asIntReg(result)).emit(masm); + } else if (inputKind == Kind.Short) { + new Ldsh(tempAddress, asIntReg(input)).emit(masm); + } else if (inputKind == Kind.Char) { + new Lduh(tempAddress, asIntReg(input)).emit(masm); + } else if (inputKind == Kind.Byte) { + new Ldsb(tempAddress, asIntReg(input)).emit(masm); + } else if (resultKind == Kind.Float) { + new Ldf(tempAddress, asFloatReg(result)).emit(masm); + } else if (resultKind == Kind.Long) { + new Ldx(tempAddress, asLongReg(result)).emit(masm); + } else if (resultKind == Kind.Double) { + new Lddf(tempAddress, asDoubleReg(result)).emit(masm); + } else { + GraalInternalError.shouldNotReachHere(); + } + } + } + } + public abstract static class MemOp extends SPARCLIRInstruction implements ImplicitNullCheck { protected final Kind kind; @@ -408,18 +476,23 @@ throw GraalInternalError.shouldNotReachHere(); } } else if (isConstant(input)) { + Constant constant = asConstant(input); if (isRegister(result)) { - const2reg(crb, masm, result, (Constant) input); + const2reg(crb, masm, result, constant); } else if (isStackSlot(result)) { - try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { - Register scratch = sc.getRegister(); - Constant constant = asConstant(input); - if (constant.isNull()) { - new Clr(scratch).emit(masm); - } else { - new Setx(constant.asLong(), scratch).emit(masm); + if (constant.isDefaultForKind() || constant.isNull()) { + reg2stack(crb, masm, result, g0.asValue(LIRKind.derive(input))); + } else { + try (SPARCScratchRegister sc = SPARCScratchRegister.get()) { + Register scratch = sc.getRegister(); + long value = constant.asLong(); + if (isSimm13(value)) { + new Or(g0, (int) value, scratch).emit(masm); + } else { + new Setx(value, scratch).emit(masm); + } + reg2stack(crb, masm, result, scratch.asValue(LIRKind.derive(input))); } - reg2stack(crb, masm, result, scratch.asValue(LIRKind.derive(input))); } } else { throw GraalInternalError.shouldNotReachHere("Result is a: " + result); @@ -432,10 +505,7 @@ private static void reg2reg(SPARCAssembler masm, Value result, Value input) { final Register src = asRegister(input); final Register dst = asRegister(result); - // implicit conversions between double and float registers can happen in the "same Register" - // f0->d0 - boolean isFloatToDoubleConversion = result.getKind() == Kind.Double && input.getKind() == Kind.Float; - if (src.equals(dst) && !isFloatToDoubleConversion) { + if (src.equals(dst)) { return; } switch (input.getKind()) { @@ -449,30 +519,17 @@ new Mov(src, dst).emit(masm); break; case Float: - switch (result.getKind()) { - case Long: - new Movstosw(src, dst).emit(masm); - break; - case Int: - new Movstouw(src, dst).emit(masm); - break; - case Float: - new Fmovs(src, dst).emit(masm); - break; - case Double: - new Fstod(src, dst).emit(masm); - break; - default: - throw GraalInternalError.shouldNotReachHere(); + if (result.getPlatformKind() == Kind.Float) { + new Fmovs(src, dst).emit(masm); + } else { + throw GraalInternalError.shouldNotReachHere(); } break; case Double: - if (result.getPlatformKind() == Kind.Long) { - new Movdtox(src, dst).emit(masm); - } else if (result.getPlatformKind() == Kind.Int) { - new Movstouw(src, dst).emit(masm); + if (result.getPlatformKind() == Kind.Double) { + new Fmovd(src, dst).emit(masm); } else { - new Fmovd(src, dst).emit(masm); + throw GraalInternalError.shouldNotReachHere(); } break; default: @@ -574,10 +631,22 @@ Register scratch = sc.getRegister(); switch (input.getKind().getStackKind()) { case Int: - new Setx(input.asLong(), asIntReg(result)).emit(masm); + if (input.isDefaultForKind()) { + new Clr(asIntReg(result)).emit(masm); + } else if (isSimm13(input.asLong())) { + new Or(g0, input.asInt(), asIntReg(result)).emit(masm); + } else { + new Setx(input.asLong(), asIntReg(result)).emit(masm); + } break; case Long: - new Setx(input.asLong(), asLongReg(result)).emit(masm); + if (input.isDefaultForKind()) { + new Clr(asLongReg(result)).emit(masm); + } else if (isSimm13(input.asLong())) { + new Or(g0, input.asInt(), asLongReg(result)).emit(masm); + } else { + new Setx(input.asLong(), asLongReg(result)).emit(masm); + } break; case Float: // TODO: Handle it the same way, as in the double case with Movwtos @@ -591,9 +660,15 @@ // instead loading this from memory and do the complicated lookup, // just load it directly into a scratch register // First load the address into the scratch register - new Setx(Double.doubleToLongBits(input.asDouble()), scratch, true).emit(masm); + // new Setx(Double.doubleToLongBits(input.asDouble()), scratch, + // true).emit(masm); // Now load the float value - new Movxtod(scratch, asDoubleReg(result)).emit(masm); + // new Movxtod(scratch, asDoubleReg(result)).emit(masm); + crb.asDoubleConstRef(input); + // First load the address into the scratch register + new Setx(0, scratch, true).emit(masm); + // Now load the float value + new Lddf(scratch, asDoubleReg(result)).emit(masm); break; case Object: if (input.isNull()) {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java Fri Sep 05 18:28:11 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCSaveRegistersOp.java Tue Sep 09 12:09:58 2014 -0700 @@ -27,8 +27,11 @@ import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf; import com.oracle.graal.asm.sparc.SPARCAssembler.Movxtod; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.SaveRegistersOp; import com.oracle.graal.lir.asm.*; @@ -75,12 +78,20 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + // Can be used with VIS3 + // new Movxtod(SPARC.i0, RETURN_REGISTER_STORAGE).emit(masm); + // We abuse the first stackslot for transferring i0 to return_register_storage + // assert slots.length >= 1; + SPARCAddress slot0Address = (SPARCAddress) crb.asAddress(slots[0]); + new Stx(SPARC.i0, slot0Address).emit(masm); + new Lddf(slot0Address, RETURN_REGISTER_STORAGE).emit(masm); + + // Now save the registers for (int i = 0; i < savedRegisters.length; i++) { if (savedRegisters[i] != null) { saveRegister(crb, masm, slots[i], savedRegisters[i]); } } - new Movxtod(SPARC.i0, RETURN_REGISTER_STORAGE).emit(masm); } public StackSlot[] getSlots() {
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Fri Sep 05 18:28:11 2014 -0700 +++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Tue Sep 09 12:09:58 2014 -0700 @@ -25,6 +25,7 @@ import static com.oracle.graal.api.code.MemoryBarriers.*; import java.nio.*; +import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.Register.RegisterCategory; @@ -222,8 +223,11 @@ */ public static final int MEMORY_ACCESS_ALIGN = 4; - public SPARC() { + public final Set<CPUFeature> features; + + public SPARC(Set<CPUFeature> features) { super("SPARC", 8, ByteOrder.BIG_ENDIAN, false, allRegisters, LOAD_STORE | STORE_STORE, 1, r31.encoding + FLOAT_REGISTER_COUNT + 1, 8); + this.features = features; } @Override @@ -282,4 +286,14 @@ public static boolean isDoubleFloatRegister(Register r) { return r.name.startsWith("d"); } + + public Set<CPUFeature> getFeatures() { + return features; + } + + public enum CPUFeature { + VIS1, + VIS2, + VIS3 + } }