# HG changeset patch # User Christos Kotselidis # Date 1370336480 -7200 # Node ID 4249a351041380274561963814df05c962a2e945 # Parent 6e0c6526334bc675143e2744436c1b382841de1b# Parent e876c2a6954fbddef137f601136670214232d4a2 Merge diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java Tue Jun 04 11:01:20 2013 +0200 @@ -259,6 +259,7 @@ public Assumptions(boolean useOptimisticAssumptions) { this.useOptimisticAssumptions = useOptimisticAssumptions; + list = new Assumption[4]; } /** @@ -362,6 +363,10 @@ count++; } + public Assumption[] getAssumptions() { + return list; + } + public void record(Assumptions assumptions) { for (int i = 0; i < assumptions.count; i++) { record(assumptions.list[i]); diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Tue Jun 04 11:01:20 2013 +0200 @@ -198,7 +198,8 @@ * Resolves the method implementation for virtual dispatches on objects of this dynamic type. * * @param method the method to select the implementation of - * @return the method implementation that would be selected at runtime + * @return the method implementation that would be selected at runtime, or {@code null} if the + * runtime cannot resolve the method at this point in time. */ ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method); diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java Tue Jun 04 11:01:20 2013 +0200 @@ -28,8 +28,7 @@ public class SPARCAddress extends AbstractAddress { private final Register base; - private final Register index; - private final int displacement; + private final int displacement; // need Register offset / displacement CompositeValue? /** * Creates an {@link SPARCAddress} with given base register, no scaling and a given @@ -41,35 +40,16 @@ public SPARCAddress(Register base, int displacement) { this.base = base; this.displacement = displacement; - this.index = null; - } - - /** - * Creates an {@link SPARCAddress} with given base and index registers, scaling and - * displacement. This is the most general constructor. - * - * @param base the base register - * @param index the index register - */ - public SPARCAddress(Register base, Register index, int disp) { - this.base = base; - this.index = index; - this.displacement = disp; } @Override public String toString() { StringBuilder s = new StringBuilder(); s.append("["); - String sep = ""; if (!getBase().equals(Register.None)) { s.append(getBase()); - sep = " + "; } - if (!getIndex().equals(Register.None)) { - s.append(sep).append(getIndex()).append(" * "); - sep = " + "; - } + // later: displacement CompositeValue? s.append("]"); return s.toString(); } @@ -83,14 +63,6 @@ } /** - * @return Index register, the value of which is added to {@link #getBase}. If not present, is - * denoted by {@link Register#None}. - */ - public Register getIndex() { - return index; - } - - /** * @return Optional additive displacement. */ public int getDisplacement() { diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Tue Jun 04 11:01:20 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.api.meta.Kind; import com.oracle.graal.asm.*; import com.oracle.graal.hotspot.HotSpotGraalRuntime; +import com.oracle.graal.sparc.SPARC; /** * This class implements an assembler that can encode most SPARC instructions. @@ -189,7 +190,27 @@ assert rs1 >= 0 && rs1 < 0x20; assert rd >= 0 && rd < 0x20; - masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14); + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14); + } + } + + public static class Fmt3r { + public Fmt3r(SPARCAssembler masm, int op, int fcn, int op3) { + assert op == 23; + assert op3 >= 0 && op3 < 0x40; + assert fcn >= 0 && fcn < 0x40; + + masm.emitInt(op << 30 | fcn << 25 | op3 << 19); + } + } + + public static class Fmt4a { + public Fmt4a(SPARCAssembler masm, int op, int op3, int cc, int rs1, int regOrImmediate, int rd) { + assert op == 2; + assert rs1 >= 0 && rs1 < 0x20; + assert rd >= 0 && rd < 0x10; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | ((cc << 11) & 0x000001800) | regOrImmediate); } } @@ -328,6 +349,20 @@ Done(0x3e, "done"), Retry(0x3e, "retry"), + Lduw(0x00, "lduw"), + Ldub(0x01, "ldub"), + Lduh(0x02, "lduh"), + Ldd(0x03, "ldd"), + Stw(0x04, "stw"), + Stb(0x05, "stb"), + Sth(0x06, "sth"), + Std(0x07, "std"), + Ldsw(0x08, "ldsw"), + Ldsb(0x09, "ldsb"), + Ldsh(0x0A, "ldsh"), + Ldx(0x0b, "ldx"), + Stx(0x0e, "stx"), + Ldf(0x20, "ldf"), Ldfsr(0x21, "ldfsr"), Ldaf(0x22, "ldaf"), @@ -376,6 +411,10 @@ Fdivd(0x4D, "fdivd"), Fdivq(0x4E, "fdivq"), + Fsqrts(0x29, "fsqrts"), + Fsqrtd(0x2A, "fsqrtd"), + Fsqrtq(0x2B, "fsqrtq"), + Fsmuld(0x69, "fsmuld"), Fmulq(0x6B, "fmulq"), Fdmuldq(0x6E, "fdmulq"), @@ -452,7 +491,7 @@ } } - public enum Condition { + public enum ConditionFlag { // for FBfcc & FBPfcc instruction F_Never(0, "f_never"), @@ -499,7 +538,7 @@ private final int value; private final String operator; - private Condition(int value, String op) { + private ConditionFlag(int value, String op) { this.value = value; this.operator = op; } @@ -567,9 +606,25 @@ return x & ((1 << nbits) - 1); } - private static int fcn(int val) { - assert val < 0x20; - return (val << 25); + private static final int max13 = ((1 << 12) - 1); + private static final int min13 = -(1 << 12); + + public static boolean isSimm13(int src) { + return min13 <= src && src <= max13; + } + + public static final int hi22(int x) { + return x >> 10; + } + + public static final int lo10(int x) { + return x & ((1 << 10) - 1); + } + + @Override + @SuppressWarnings("unused") + public void jmp(Label l) { + new Bpa(this, l); } public static class Add extends Fmt3b { @@ -646,23 +701,119 @@ public static class Bpa extends Fmt2c { public Bpa(SPARCAssembler masm, int simmm19) { - super(masm, Ops.BranchOp.getValue(), 0, Condition.Always.getValue(), + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Always.getValue(), Op2s.Bp.getValue(), CC.Icc.getValue(), 1, simmm19); } public Bpa(SPARCAssembler masm, Label label) { - super(masm, Ops.BranchOp.getValue(), 0, Condition.Always.getValue(), + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Always.getValue(), Op2s.Bp.getValue(), CC.Icc.getValue(), 1, label.isBound() ? label.position() : patchUnbound(masm, label)); } } + public static class Bpcc extends Fmt2c { + public Bpcc(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarryClear.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpcc(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarryClear.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpcs extends Fmt2c { + public Bpcs(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarrySet.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpcs(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.CarrySet.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + public static class Bpe extends Fmt2c { public Bpe(SPARCAssembler masm, CC cc, int simmm19) { - super(masm, Ops.BranchOp.getValue(), 0, Condition.Equal.getValue(), + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Equal.getValue(), Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); } public Bpe(SPARCAssembler masm, CC cc, Label label) { - super(masm, Ops.BranchOp.getValue(), 0, Condition.Equal.getValue(), + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Equal.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpg extends Fmt2c { + public Bpg(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Greater.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpg(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Greater.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpge extends Fmt2c { + public Bpge(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterEqual.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpge(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterEqual.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpgu extends Fmt2c { + public Bpgu(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterUnsigned.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpgu(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.GreaterUnsigned.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpl extends Fmt2c { + public Bpl(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Less.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpl(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Less.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bple extends Fmt2c { + public Bple(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqual.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bple(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqual.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpleu extends Fmt2c { + public Bpleu(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqualUnsigned.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpleu(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.LessEqualUnsigned.getValue(), Op2s.Bp.getValue(), cc.getValue(), 1, label.isBound() ? label.position() : patchUnbound(masm, label)); } @@ -670,11 +821,11 @@ public static class Bpn extends Fmt2c { public Bpn(SPARCAssembler masm, CC cc, int simmm19) { - super(masm, Ops.BranchOp.getValue(), 0, Condition.Never.getValue(), + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Never.getValue(), Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); } public Bpn(SPARCAssembler masm, CC cc, Label label) { - super(masm, Ops.BranchOp.getValue(), 0, Condition.Never.getValue(), + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Never.getValue(), Op2s.Bp.getValue(), cc.getValue(), 1, label.isBound() ? label.position() : patchUnbound(masm, label)); } @@ -682,11 +833,59 @@ public static class Bpne extends Fmt2c { public Bpne(SPARCAssembler masm, CC cc, int simmm19) { - super(masm, Ops.BranchOp.getValue(), 0, Condition.NotZero.getValue(), + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.NotZero.getValue(), Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); } public Bpne(SPARCAssembler masm, CC cc, Label label) { - super(masm, Ops.BranchOp.getValue(), 0, Condition.NotZero.getValue(), + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.NotZero.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpneg extends Fmt2c { + public Bpneg(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Negative.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpneg(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Negative.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bppos extends Fmt2c { + public Bppos(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Positive.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bppos(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Positive.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpvc extends Fmt2c { + public Bpvc(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowClear.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpvc(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowClear.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpvs extends Fmt2c { + public Bpvs(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowSet.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpvs(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.OverflowSet.getValue(), Op2s.Bp.getValue(), cc.getValue(), 1, label.isBound() ? label.position() : patchUnbound(masm, label)); } @@ -774,10 +973,20 @@ } } - public final void flushw() { - emitInt(Ops.ArithOp.getValue() | Op3s.Flushw.getValue()); + public static class Flushw extends Fmt3r { + public Flushw(SPARCAssembler masm) { + super(masm, Ops.ArithOp.getValue(), 0, Op3s.Flushw.getValue()); + } } + public static class Fsqrtd extends Fmt3p { + public Fsqrtd(SPARCAssembler masm, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fsqrtd.getValue(), + 0, src2.encoding(), dst.encoding()); + } + } + + public static class Fsubs extends Fmt3p { public Fsubs(SPARCAssembler masm, Register src1, Register src2, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fsubs.getValue(), @@ -799,32 +1008,75 @@ } } - @Override - @SuppressWarnings("unused") - public void jmp(Label l) { - new Bpa(this, l); + public static class Jmpl extends Fmt3b { + public Jmpl(SPARCAssembler asm, SPARCAddress src, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Jmpl.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } } + public static class Lddf extends Fmt3b { + public Lddf(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Lddf.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } - public static class Ld extends Fmt3b { - public Ld(SPARCAssembler masm, SPARCAddress src, Register dst) { + public static class Ldf extends Fmt3b { + public Ldf(SPARCAssembler masm, SPARCAddress src, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Ldf.getValue(), src.getBase().encoding(), src.getDisplacement(), dst.encoding()); } } + public static class Ldsb extends Fmt3b { + public Ldsb(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldsb.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } + + public static class Ldsh extends Fmt3b { + public Ldsh(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldsh.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } + + public static class Ldsw extends Fmt3b { + public Ldsw(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldsw.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } + + public static class Lduw extends Fmt3b { + public Lduw(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Lduw.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } + + public static class Ldx extends Fmt3b { + public Ldx(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldx.getValue(), + src.getBase().encoding(), src.getDisplacement(), dst.encoding()); + } + } + public static class Membar extends Fmt3b { - public Membar(SPARCAssembler masm, MembarMask mask) { - super(masm, Ops.ArithOp.getValue(), 0, Op3s.Membar.getValue(), 0xf, mask.getValue()); + public Membar(SPARCAssembler masm, int barriers) { + super(masm, Ops.ArithOp.getValue(), Op3s.Membar.getValue(), + SPARC.r15.encoding(), ImmedTrue | barriers, SPARC.r0.encoding()); } } public static class Movcc extends Fmt4c { - public Movcc(SPARCAssembler masm, Condition cond, CC cca, Register src2, Register dst) { + public Movcc(SPARCAssembler masm, ConditionFlag cond, CC cca, Register src2, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Movcc.getValue(), cond.getValue(), cca.getValue(), src2.encoding(), dst.encoding()); } - public Movcc(SPARCAssembler masm, Condition cond, CC cca, int simm11a, Register dst) { + public Movcc(SPARCAssembler masm, ConditionFlag cond, CC cca, int simm11a, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Movcc.getValue(), cond.getValue(), cca.getValue(), simm11a, dst.encoding()); } @@ -862,6 +1114,13 @@ } } + public static class NullCheck extends Fmt3b { + public NullCheck(SPARCAssembler masm, SPARCAddress src) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldx.getValue(), + src.getBase().encoding(), src.getDisplacement(), SPARC.r0.encoding()); + } + } + public static class Or extends Fmt3b { public Or(SPARCAssembler masm, Register src1, int simm13, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Or.getValue(), src1.encoding(), simm13, dst.encoding()); @@ -946,6 +1205,19 @@ } } + public static class Restore extends Fmt3b { + public Restore(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Restore.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Restored extends Fmt3r { + public Restored(SPARCAssembler asm) { + super(asm, Ops.ArithOp.getValue(), 1, Op3s.Saved.getValue()); + } + } + public static class Return extends Fmt3d { public Return(SPARCAssembler masm, Register src1, int simm13) { super(masm, Ops.ArithOp.getValue(), Op3s.Rett.getValue(), src1.encoding(), simm13); @@ -955,12 +1227,17 @@ } } - public final void restored() { - emitInt(Ops.ArithOp.getValue() | Op3s.Saved.getValue() | fcn(1)); + public static class Save extends Fmt3b { + public Save(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Save.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } } - public final void saved() { - emitInt(Ops.ArithOp.getValue() | Op3s.Saved.getValue() | fcn(0)); + public static class Saved extends Fmt3r { + public Saved(SPARCAssembler asm) { + super(asm, Ops.ArithOp.getValue(), 0, Op3s.Saved.getValue()); + } } @Deprecated @@ -996,8 +1273,17 @@ } } - public final void sir(int simm13a) { - emitInt(Ops.ArithOp.getValue() | Op3s.Sir.getValue() | ImmedTrue | simm(simm13a, 13)); + public static class Sethi extends Fmt2a { + public Sethi(SPARCAssembler masm, int simm22, Register dst) { + super(masm, Ops.BranchOp.getValue(), Op2s.Sethi.getValue(), simm22, dst.encoding()); + } + } + + public static class Sir extends Fmt3b { + public Sir(SPARCAssembler asm, int simm13) { + super(asm, Ops.ArithOp.getValue(), Op3s.Sir.getValue(), + SPARC.r0.encoding(), simm13, SPARC.r15.encoding()); + } } public static class Sll extends Fmt3b { @@ -1074,8 +1360,39 @@ } @Deprecated - public final void stbar() { - emitInt(Ops.ArithOp.getValue() | Op3s.Membar.getValue() | 0x0003C000); + public static class Stbar extends Fmt3b { + public Stbar(SPARCAssembler masm) { + super(masm, Ops.ArithOp.getValue(), Op3s.Membar.getValue(), + SPARC.r15.encoding(), 0, SPARC.r0.encoding()); + } + } + + public static class Stb extends Fmt3b { + public Stb(SPARCAssembler masm, Register dst, SPARCAddress addr) { + super(masm, Ops.ArithOp.getValue(), Op3s.Stb.getValue(), + addr.getBase().encoding(), addr.getDisplacement(), dst.encoding()); + } + } + + public static class Sth extends Fmt3b { + public Sth(SPARCAssembler masm, Register dst, SPARCAddress addr) { + super(masm, Ops.ArithOp.getValue(), Op3s.Sth.getValue(), + addr.getBase().encoding(), addr.getDisplacement(), dst.encoding()); + } + } + + public static class Stw extends Fmt3b { + public Stw(SPARCAssembler masm, Register dst, SPARCAddress addr) { + super(masm, Ops.ArithOp.getValue(), Op3s.Stw.getValue(), + addr.getBase().encoding(), addr.getDisplacement(), dst.encoding()); + } + } + + public static class Stx extends Fmt3b { + public Stx(SPARCAssembler masm, Register dst, SPARCAddress addr) { + super(masm, Ops.ArithOp.getValue(), Op3s.Stx.getValue(), + addr.getBase().encoding(), addr.getDisplacement(), dst.encoding()); + } } public static class Sub extends Fmt3b { @@ -1114,6 +1431,17 @@ } } + public static class Ta extends Fmt4a { + public Ta(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.Always.getValue()); + } + public Ta(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.Always.getValue()); + } + } + public static class Taddcc extends Fmt3b { public Taddcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Taddcc.getValue(), src1.encoding(), simm13, dst.encoding()); diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2013, 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.asm.sparc; + +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.sparc.*; + +public class SPARCMacroAssembler extends SPARCAssembler { + + public SPARCMacroAssembler(TargetDescription target, RegisterConfig registerConfig) { + super(target, registerConfig); + } + + @SuppressWarnings("unused") + public static class Bclr { + + public Bclr(SPARCAssembler asm, Register src, Register dst) { + new Andn(asm, dst, src, dst); + } + + public Bclr(SPARCAssembler asm, int simm13, Register dst) { + new Andn(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Bset { + + public Bset(SPARCAssembler asm, Register src, Register dst) { + new Or(asm, dst, src, dst); + } + + public Bset(SPARCAssembler asm, int simm13, Register dst) { + new Or(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Btog { + + public Btog(SPARCAssembler asm, Register src, Register dst) { + new Xor(asm, dst, src, dst); + } + + public Btog(SPARCAssembler asm, int simm13, Register dst) { + new Xor(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Btst { + + public Btst(SPARCAssembler asm, Register src1, Register src2) { + new Andcc(asm, src1, src2, SPARC.g0); + } + + public Btst(SPARCAssembler asm, Register src1, int simm13) { + new Andcc(asm, src1, simm13, SPARC.g0); + } + } + + @SuppressWarnings("unused") + public static class Clr { + + public Clr(SPARCAssembler asm, Register dst) { + new Or(asm, SPARC.g0, SPARC.g0, dst); + } + + public Clr(SPARCAssembler asm, SPARCAddress addr) { + new Stw(asm, SPARC.g0, addr); + } + } + + @SuppressWarnings("unused") + public static class Clrb { + + public Clrb(SPARCAssembler asm, SPARCAddress addr) { + new Stb(asm, SPARC.g0, addr); + } + } + + @SuppressWarnings("unused") + public static class Clrh { + + public Clrh(SPARCAssembler asm, SPARCAddress addr) { + new Sth(asm, SPARC.g0, addr); + } + } + + @SuppressWarnings("unused") + public static class Clrx { + + public Clrx(SPARCAssembler asm, SPARCAddress addr) { + new Stx(asm, SPARC.g0, addr); + } + } + + @SuppressWarnings("unused") + public static class Clruw { + + public Clruw(SPARCAssembler asm, Register src1, Register dst) { + assert src1.encoding() != dst.encoding(); + new Srl(asm, src1, SPARC.g0, dst); + } + + public Clruw(SPARCAssembler asm, Register dst) { + new Srl(asm, dst, SPARC.g0, dst); + } + } + + @SuppressWarnings("unused") + public static class Cmp { + + public Cmp(SPARCAssembler asm, Register a, Register b) { + new Subcc(asm, a, b, SPARC.g0); + } + + public Cmp(SPARCAssembler asm, Register a, int simm13) { + new Subcc(asm, a, simm13, SPARC.g0); + } + } + + @SuppressWarnings("unused") + public static class Dec { + + public Dec(SPARCAssembler asm, Register dst) { + new Sub(asm, dst, 1, dst); + } + + public Dec(SPARCAssembler asm, int simm13, Register dst) { + new Sub(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Deccc { + + public Deccc(SPARCAssembler asm, Register dst) { + new Subcc(asm, dst, 1, dst); + } + + public Deccc(SPARCAssembler asm, int simm13, Register dst) { + new Subcc(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Inc { + + public Inc(SPARCAssembler asm, Register dst) { + new Add(asm, dst, 1, dst); + } + + public Inc(SPARCAssembler asm, int simm13, Register dst) { + new Add(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Inccc { + + public Inccc(SPARCAssembler asm, Register dst) { + new Addcc(asm, dst, 1, dst); + } + + public Inccc(SPARCAssembler asm, int simm13, Register dst) { + new Addcc(asm, dst, simm13, dst); + } + } + + @SuppressWarnings("unused") + public static class Jmp { + + public Jmp(SPARCAssembler asm, SPARCAddress address) { + new Jmpl(asm, address, SPARC.g0); + } + } + + @SuppressWarnings("unused") + public static class Neg { + + public Neg(SPARCAssembler asm, Register src2, Register dst) { + assert src2.encoding() != dst.encoding(); + new Sub(asm, SPARC.g0, src2, dst); + } + + public Neg(SPARCAssembler asm, Register dst) { + new Sub(asm, SPARC.g0, dst, dst); + } + } + + @SuppressWarnings("unused") + public static class Not { + + public Not(SPARCAssembler asm, Register src1, Register dst) { + assert src1.encoding() != dst.encoding(); + new Xnor(asm, src1, SPARC.g0, dst); + } + + public Not(SPARCAssembler asm, Register dst) { + new Xnor(asm, dst, SPARC.g0, dst); + } + } + + @SuppressWarnings("unused") + public static class RestoreWindow { + + public RestoreWindow(SPARCAssembler asm) { + new Restore(asm, SPARC.g0, SPARC.g0, SPARC.g0); + } + } + + @SuppressWarnings("unused") + public static class Ret { + + public Ret(SPARCAssembler asm) { + new Jmpl(asm, new SPARCAddress(SPARC.i0, 8), SPARC.g0); + + } + } + + @SuppressWarnings("unused") + public static class SaveWindow { + + public SaveWindow(SPARCAssembler asm) { + new Save(asm, SPARC.g0, SPARC.g0, SPARC.g0); + } + } + + @SuppressWarnings("unused") + public static class Setuw { + + public Setuw(SPARCAssembler asm, int value, Register dst) { + if (value >= 0 && ((value & 0x3FFF) == 0)) { + new Sethi(asm, hi22(value), dst); + } else if (-4095 <= value && value <= 4096) { + new Or(asm, SPARC.g0, value, dst); + } else { + new Sethi(asm, hi22(value), dst); + new Or(asm, dst, lo10(value), dst); + } + } + } + + @SuppressWarnings("unused") + public static class Setx { + + public Setx(SPARCAssembler asm, long value, Register tmp, Register dst) { + int hi = (int) (value >> 32); + int lo = (int) (value & ~0); + + if (isSimm13(lo) && value == lo) { + new Or(asm, SPARC.g0, lo, dst); + } else if (hi == 0) { + new Sethi(asm, lo, dst); // hardware version zero-extends to upper 32 + if (lo10(lo) != 0) { + new Or(asm, dst, lo10(lo), dst); + } + } else if (hi == -1) { + new Sethi(asm, ~lo, dst); // hardware version zero-extends to upper 32 + new Xor(asm, dst, lo10(lo) ^ ~lo10(~0), dst); + } else if (lo == 0) { + if (isSimm13(hi)) { + new Or(asm, SPARC.g0, hi, dst); + } else { + new Sethi(asm, hi, dst); // hardware version zero-extends to upper 32 + if (lo10(hi) != 0) { + new Or(asm, dst, lo10(hi), dst); + } + } + new Sllx(asm, dst, 32, dst); + } else { + new Sethi(asm, hi, tmp); + new Sethi(asm, lo, dst); // macro assembler version sign-extends + if (lo10(hi) != 0) { + new Or(asm, tmp, lo10(hi), tmp); + } + if (lo10(lo) != 0) { + new Or(asm, dst, lo10(lo), dst); + } + new Sllx(asm, tmp, 32, tmp); + new Or(asm, dst, tmp, dst); + } + } + } + + @SuppressWarnings("unused") + public static class Signx { + + public Signx(SPARCAssembler asm, Register src1, Register dst) { + assert src1.encoding() != dst.encoding(); + new Sra(asm, src1, SPARC.g0, dst); + } + + public Signx(SPARCAssembler asm, Register dst) { + new Sra(asm, dst, SPARC.g0, dst); + } + } + + @SuppressWarnings("unused") + public static class Trap { + + public Trap(SPARCAssembler asm, int trap) { + assert trap >= 0 && trap <= 0x7f; + new Ta(asm, Icc, SPARC.g0, trap); + } + } +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/ArraySPARCTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/ArraySPARCTest.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2013, 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.compiler.sparc.test; + +import java.lang.reflect.*; + +import org.junit.*; + +public class ArraySPARCTest extends SPARCTestBase { + + @Test + public void testArray() { + compile("testArray1I"); + compile("testArray1J"); + compile("testArray1B"); + compile("testArray1S"); + compile("testArray1C"); + compile("testArray1F"); + compile("testArray1D"); + compile("testArray1L"); + compile("testStoreArray1I"); + compile("testStoreArray1J"); + compile("testStoreArray1B"); + compile("testStoreArray1S"); + compile("testStoreArray1F"); + compile("testStoreArray1D"); + } + + public static int testArray1I(int[] array, int i) { + return array[i]; + } + + public static long testArray1J(long[] array, int i) { + return array[i]; + } + + public static byte testArray1B(byte[] array, int i) { + return array[i]; + } + + public static short testArray1S(short[] array, int i) { + return array[i]; + } + + public static char testArray1C(char[] array, int i) { + return array[i]; + } + + public static float testArray1F(float[] array, int i) { + return array[i]; + } + + public static double testArray1D(double[] array, int i) { + return array[i]; + } + + public static Object testArray1L(Object[] array, int i) { + return array[i]; + } + + public static void testStoreArray1I(int[] array, int i, int val) { + array[i] = val; + } + + public static void testStoreArray1B(byte[] array, int i, byte val) { + array[i] = val; + } + + public static void testStoreArray1S(short[] array, int i, short val) { + array[i] = val; + } + + public static void testStoreArray1J(long[] array, int i, long val) { + array[i] = val; + } + + public static void testStoreArray1F(float[] array, int i, float val) { + array[i] = val; + } + + public static void testStoreArray1D(double[] array, int i, double val) { + array[i] = val; + } + + public static void main(String[] args) { + ArraySPARCTest test = new ArraySPARCTest(); + for (Method m : ArraySPARCTest.class.getMethods()) { + String name = m.getName(); + if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { + // CheckStyle: stop system..print check + System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); + // CheckStyle: resume system..print check + } + } + } +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/LogicSPARCTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/LogicSPARCTest.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013, 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.compiler.sparc.test; + +import java.lang.reflect.Method; + +import org.junit.Test; + +public class LogicSPARCTest extends SPARCTestBase { + + @Test + public void testAnd() { + compile("testAnd2I"); + compile("testAnd2L"); + } + + public static int testAnd2I(int a, int b) { + return a & b; + } + + public static long testAnd2L(long a, long b) { + return a & b; + } + + @Test + public void testOr() { + compile("testOr2I"); + compile("testOr2L"); + } + + public static int testOr2I(int a, int b) { + return a | b; + } + + public static long testOr2L(long a, long b) { + return a | b; + } + + @Test + public void testXor() { + compile("testXor2I"); + compile("testXor2L"); + } + + public static int testXor2I(int a, int b) { + return a ^ b; + } + + public static long testXor2L(long a, long b) { + return a ^ b; + } + + @Test + public void testNot() { + compile("testNot1I"); + compile("testNot1L"); + } + + public static int testNot1I(int a) { + return ~a; + } + + public static long testNot1L(long a) { + return ~a; + } + + @Test + public void testShiftLeft() { + compile("testShiftLeft2I"); + compile("testShiftLeft2L"); + } + + public static int testShiftLeft2I(int a, int b) { + return a << b; + } + + public static long testShiftLeft2L(long a, int b) { + return a << b; + } + + @Test + public void testShiftRight() { + compile("testShiftRight2I"); + compile("testShiftRight2L"); + compile("testUnsignedShiftRight2I"); + compile("testUnsignedShiftRight2L"); + } + + public static int testShiftRight2I(int a, int b) { + return a >> b; + } + + public static long testShiftRight2L(long a, int b) { + return a >> b; + } + + public static int testUnsignedShiftRight2I(int a, int b) { + return a >>> b; + } + + public static long testUnsignedShiftRight2L(long a, long b) { + return a >>> b; + } + + public static void main(String[] args) { + LogicSPARCTest test = new LogicSPARCTest(); + for (Method m : LogicSPARCTest.class.getMethods()) { + String name = m.getName(); + if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { + // CheckStyle: stop system..print check + System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); + // CheckStyle: resume system..print check + } + } + } +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Jun 04 11:01:20 2013 +0200 @@ -24,7 +24,11 @@ package com.oracle.graal.compiler.sparc; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRValueUtil.*; +import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.*; +import static com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp.IntrinsicOpcode.*; import static com.oracle.graal.lir.sparc.SPARCArithmetic.*; +import static com.oracle.graal.lir.sparc.SPARCCompare.*; import com.oracle.graal.api.code.CallingConvention; import com.oracle.graal.api.code.CodeCacheProvider; @@ -32,33 +36,41 @@ import com.oracle.graal.api.code.ForeignCallLinkage; import com.oracle.graal.api.code.StackSlot; import com.oracle.graal.api.code.TargetDescription; -import com.oracle.graal.api.meta.AllocatableValue; -import com.oracle.graal.api.meta.Constant; -import com.oracle.graal.api.meta.Kind; -import com.oracle.graal.api.meta.Value; +import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.NumUtil; import com.oracle.graal.compiler.gen.LIRGenerator; import com.oracle.graal.compiler.target.LIRGenLowerable; import com.oracle.graal.graph.GraalInternalError; -import com.oracle.graal.lir.FrameMap; -import com.oracle.graal.lir.LIR; -import com.oracle.graal.lir.LIRFrameState; -import com.oracle.graal.lir.LIRInstruction; -import com.oracle.graal.lir.LabelRef; -import com.oracle.graal.lir.Variable; +import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.*; -import com.oracle.graal.lir.sparc.*; +import com.oracle.graal.lir.sparc.SPARCAddressValue; +import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegConst; +import com.oracle.graal.lir.sparc.SPARCArithmetic.Op1Stack; +import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Stack; +import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Reg; +import com.oracle.graal.lir.sparc.SPARCArithmetic.ShiftOp; +import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary1Op; +import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary2Op; +import com.oracle.graal.lir.sparc.SPARCBitManipulationOp; +import com.oracle.graal.lir.sparc.SPARCBreakpointOp; +import com.oracle.graal.lir.sparc.SPARCByteSwapOp; +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.SequentialSwitchOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.SwitchRangesOp; import com.oracle.graal.lir.sparc.SPARCControlFlow.TableSwitchOp; +import com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp; import com.oracle.graal.lir.sparc.SPARCMove.LoadOp; +import com.oracle.graal.lir.sparc.SPARCMove.MembarOp; import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp; import com.oracle.graal.lir.sparc.SPARCMove.MoveToRegOp; +import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp; +import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp; import com.oracle.graal.lir.sparc.SPARCMove.StoreOp; -import com.oracle.graal.lir.sparc.SPARCArithmetic.Op1Stack; -import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Stack; -import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary1Op; -import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary2Op; +import com.oracle.graal.lir.sparc.SPARCTestOp; import com.oracle.graal.nodes.BreakpointNode; import com.oracle.graal.nodes.DeoptimizingNode; import com.oracle.graal.nodes.DirectCallTargetNode; @@ -67,7 +79,7 @@ import com.oracle.graal.nodes.SafepointNode; import com.oracle.graal.nodes.StructuredGraph; import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.calc.Condition; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.calc.ConvertNode.Op; import com.oracle.graal.nodes.java.CompareAndSwapNode; @@ -133,6 +145,26 @@ @Override public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) { switch (left.getKind().getStackKind()) { + case Int: + append(new CompareOp(ICMP, left, right)); + append(new BranchOp(cond, label)); + break; + case Long: + append(new CompareOp(LCMP, left, right)); + append(new BranchOp(cond, label)); + break; + case Float: + append(new CompareOp(FCMP, left, right)); + append(new BranchOp(cond, label)); + break; + case Double: + append(new CompareOp(DCMP, left, right)); + append(new BranchOp(cond, label)); + break; + case Object: + append(new CompareOp(ACMP, left, right)); + append(new BranchOp(cond, label)); + break; default: throw GraalInternalError.shouldNotReachHere("" + left.getKind()); } @@ -140,22 +172,112 @@ @Override public void emitOverflowCheckBranch(LabelRef label, boolean negated) { - throw new InternalError("NYI"); + // append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, label)); + throw GraalInternalError.shouldNotReachHere("emitOverflowCheckBranch: unimp"); } @Override public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) { - throw new InternalError("NYI"); + emitIntegerTest(left, right); + append(new BranchOp(negated ? Condition.NE : Condition.EQ, label)); + } + + private void emitIntegerTest(Value a, Value b) { + assert a.getKind().getStackKind() == Kind.Int || a.getKind() == Kind.Long; + if (LIRValueUtil.isVariable(b)) { + append(new SPARCTestOp(load(b), loadNonConst(a))); + } else { + append(new SPARCTestOp(load(a), loadNonConst(b))); + } + } + + @Override + public Variable load(Value value) { + if (!isVariable(value)) { + return emitMove(value); + } + return (Variable) value; + } + + @Override + public Value loadNonConst(Value value) { + if (isConstant(value) && !canInlineConstant((Constant) value)) { + return emitMove(value); + } + return value; } @Override - public Variable emitConditionalMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { - throw new InternalError("NYI"); + public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { + boolean mirrored = emitCompare(left, right); + Condition finalCondition = mirrored ? cond.mirror() : cond; + + Variable result = newVariable(trueValue.getKind()); + switch (left.getKind().getStackKind()) { + case Int: + case Long: + case Object: + append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue))); + break; + case Float: + case Double: + append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue))); + break; + default: + throw GraalInternalError.shouldNotReachHere("" + left.getKind()); + } + return result; + } + + /** + * This method emits the compare instruction, and may reorder the operands. It returns true if + * it did so. + * + * @param a the left operand of the comparison + * @param b the right operand of the comparison + * @return true if the left and right operands were switched, false otherwise + */ + private boolean emitCompare(Value a, Value b) { + Variable left; + Value right; + boolean mirrored; + if (LIRValueUtil.isVariable(b)) { + left = load(b); + right = loadNonConst(a); + mirrored = true; + } else { + left = load(a); + right = loadNonConst(b); + mirrored = false; + } + switch (left.getKind().getStackKind()) { + case Int: + append(new CompareOp(ICMP, left, right)); + break; + case Long: + append(new CompareOp(LCMP, left, right)); + break; + case Object: + append(new CompareOp(ACMP, left, right)); + break; + case Float: + append(new CompareOp(FCMP, left, right)); + break; + case Double: + append(new CompareOp(DCMP, left, right)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return mirrored; } @Override - public Variable emitIntegerTestMove(Value leftVal, Value right, Value trueValue, Value falseValue) { - throw new InternalError("NYI"); + public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { + emitIntegerTest(left, right); + Variable result = newVariable(trueValue.getKind()); + append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue))); + return result; } @Override @@ -187,7 +309,7 @@ @Override protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) { - throw new InternalError("NYI"); + append(new SwitchRangesOp(lowKeys, highKeys, targets, defaultTarget, key)); } @Override @@ -200,52 +322,60 @@ @Override public void emitBitCount(Variable result, Value operand) { - throw new InternalError("NYI"); + if (operand.getKind().getStackKind() == Kind.Int) { + append(new SPARCBitManipulationOp(IPOPCNT, result, asAllocatable(operand))); + } else { + append(new SPARCBitManipulationOp(LPOPCNT, result, asAllocatable(operand))); + } } @Override public void emitBitScanForward(Variable result, Value operand) { - throw new InternalError("NYI"); + append(new SPARCBitManipulationOp(BSF, result, asAllocatable(operand))); } @Override public void emitBitScanReverse(Variable result, Value operand) { - throw new InternalError("NYI"); + if (operand.getKind().getStackKind() == Kind.Int) { + append(new SPARCBitManipulationOp(IBSR, result, asAllocatable(operand))); + } else { + append(new SPARCBitManipulationOp(LBSR, result, asAllocatable(operand))); + } } @Override public void emitMathAbs(Variable result, Variable input) { - throw new InternalError("NYI"); + append(new BinaryRegConst(DAND, result, input, Constant.forDouble(Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL)))); } @Override public void emitMathSqrt(Variable result, Variable input) { - throw new InternalError("NYI"); + append(new SPARCMathIntrinsicOp(SQRT, result, input)); } @Override public void emitMathLog(Variable result, Variable input, boolean base10) { - throw new InternalError("NYI"); + append(new SPARCMathIntrinsicOp(LOG, result, input)); } @Override public void emitMathCos(Variable result, Variable input) { - throw new InternalError("NYI"); + append(new SPARCMathIntrinsicOp(COS, result, input)); } @Override public void emitMathSin(Variable result, Variable input) { - throw new InternalError("NYI"); + append(new SPARCMathIntrinsicOp(SIN, result, input)); } @Override public void emitMathTan(Variable result, Variable input) { - throw new InternalError("NYI"); + append(new SPARCMathIntrinsicOp(TAN, result, input)); } @Override - public void emitByteSwap(Variable result, Value operand) { - throw new InternalError("NYI"); + public void emitByteSwap(Variable result, Value input) { + append(new SPARCByteSwapOp(result, input)); } @Override @@ -332,7 +462,9 @@ @Override public Value emitAddress(StackSlot address) { - throw new InternalError("NYI"); + Variable result = newVariable(target().wordKind); + append(new StackLoadAddressOp(result, address)); + return result; } @Override @@ -460,27 +592,83 @@ @Override public Value emitUDiv(Value a, Value b, DeoptimizingNode deopting) { - throw new InternalError("NYI"); + @SuppressWarnings("unused") + LIRFrameState state = state(deopting); + switch (a.getKind()) { + case Int: + // emitDivRem(IUDIV, a, b, state); + // return emitMove(RAX_I); + case Long: + // emitDivRem(LUDIV, a, b, state); + // return emitMove(RAX_L); + default: + throw GraalInternalError.shouldNotReachHere(); + } } @Override public Value emitURem(Value a, Value b, DeoptimizingNode deopting) { - throw new InternalError("NYI"); + @SuppressWarnings("unused") + LIRFrameState state = state(deopting); + switch (a.getKind()) { + case Int: + // emitDivRem(IUREM, a, b, state); + // return emitMove(RDX_I); + case Long: + // emitDivRem(LUREM, a, b, state); + // return emitMove(RDX_L); + default: + throw GraalInternalError.shouldNotReachHere(); + } } @Override public Value emitAnd(Value a, Value b) { - throw new InternalError("NYI"); + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(IAND, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Stack(LAND, result, a, loadNonConst(b))); + break; + + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override public Value emitOr(Value a, Value b) { - throw new InternalError("NYI"); + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(IOR, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Stack(LOR, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override public Value emitXor(Value a, Value b) { - throw new InternalError("NYI"); + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(IXOR, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Stack(LXOR, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override @@ -607,12 +795,15 @@ @Override public void emitMembar(int barriers) { - throw new InternalError("NYI"); + int necessaryBarriers = target.arch.requiredBarriers(barriers); + if (target.isMP && necessaryBarriers != 0) { + append(new MembarOp(necessaryBarriers)); + } } @Override public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) { - throw new InternalError("NYI"); + append(new ReturnOp(Value.ILLEGAL)); } @Override @@ -626,8 +817,14 @@ } @Override - public void visitBreakpointNode(BreakpointNode i) { - throw new InternalError("NYI"); + public void visitBreakpointNode(BreakpointNode node) { + JavaType[] sig = new JavaType[node.arguments().size()]; + for (int i = 0; i < sig.length; i++) { + sig[i] = node.arguments().get(i).stamp().javaType(runtime); + } + + Value[] parameters = visitInvokeArguments(frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments()); + append(new SPARCBreakpointOp(parameters)); } @Override @@ -637,7 +834,8 @@ @Override public void emitNullCheck(ValueNode v, DeoptimizingNode deopting) { - throw new InternalError("NYI"); + assert v.kind() == Kind.Object; + append(new NullCheckOp(load(operand(v)), state(deopting))); } @Override diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Tue Jun 04 11:01:20 2013 +0200 @@ -27,11 +27,11 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; -import com.oracle.graal.phases.*; /** - * Implements the filter specified by the {@link GraalOptions#Dump}, {@link GraalOptions#Log}, - * {@link GraalOptions#Meter} and {@link GraalOptions#Time} options. + * Implements the filter specified by the {@link GraalDebugConfig#Dump}, + * {@link GraalDebugConfig#Log}, {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time} + * options. *

* These options enable the associated debug facility if their filter matches the * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Jun 04 11:01:20 2013 +0200 @@ -38,6 +38,7 @@ import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.common.*; @@ -52,6 +53,11 @@ */ public class GraalCompiler { + // @formatter:off + @Option(help = "") + public static final OptionValue VerifyUsageWithEquals = new OptionValue<>(true); + // @formatter:on + /** * Requests compilation of a given graph. * @@ -125,8 +131,10 @@ } else { Debug.dump(graph, "initial state"); } - new VerifyUsageWithEquals(runtime, Value.class).apply(graph); - new VerifyUsageWithEquals(runtime, Register.class).apply(graph); + if (VerifyUsageWithEquals.getValue()) { + new VerifyUsageWithEquals(runtime, Value.class).apply(graph); + new VerifyUsageWithEquals(runtime, Register.class).apply(graph); + } if (GraalOptions.OptCanonicalizer) { new CanonicalizerPhase.Instance(runtime, assumptions).apply(graph); diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Jun 04 11:01:20 2013 +0200 @@ -31,10 +31,33 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; -import com.oracle.graal.phases.*; +import com.oracle.graal.options.*; public class GraalDebugConfig implements DebugConfig { + // @formatter:off + @Option(help = "Enable scope-based debugging", name = "Debug") + public static final OptionValue DebugEnabled = new OptionValue<>(true); + @Option(help = "Scopes to be dumped") + public static final OptionValue Dump = new OptionValue<>(null); + @Option(help = "Scopes to be metered") + public static final OptionValue Meter = new OptionValue<>(null); + @Option(help = "Scopes to be timed") + public static final OptionValue Time = new OptionValue<>(null); + @Option(help = "Scopes to be logged") + public static final OptionValue Log = new OptionValue<>(null); + @Option(help = "Filters debug scope output by method name/pattern") + public static final OptionValue MethodFilter = new OptionValue<>(null); + @Option(help = "") + public static final OptionValue PerThreadDebugValues = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue SummarizeDebugValues = new OptionValue<>(false); + @Option(help = "") + public static final OptionValue SummarizePerPhase = new OptionValue<>(false); + @Option(help = "Send Graal IR to dump handlers on error") + public static final OptionValue DumpOnError = new OptionValue<>(false); + // @formatter:on + private final DebugFilter logFilter; private final DebugFilter meterFilter; private final DebugFilter timerFilter; @@ -170,7 +193,7 @@ for (Object o : Debug.context()) { if (o instanceof Graph) { Debug.log("Context obj %s", o); - if (GraalOptions.DumpOnError) { + if (DumpOnError.getValue()) { Debug.dump(o, "Exception graph"); } else { Debug.log("Use -G:+DumpOnError to enable dumping of graphs on this error"); diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Tue Jun 04 11:01:20 2013 +0200 @@ -203,7 +203,7 @@ return value; } - protected LabelRef getLIRBlock(FixedNode b) { + public LabelRef getLIRBlock(FixedNode b) { Block result = lir.cfg.blockFor(b); int suxIndex = currentBlock.getSuccessors().indexOf(result); assert suxIndex != -1 : "Block not in successor list of current block"; @@ -259,7 +259,6 @@ } public void append(LIRInstruction op) { - assert LIRVerifier.verify(op); if (GraalOptions.PrintIRWithLIR && !TTY.isSuppressed()) { if (currentInstruction != null && lastInstructionPrinted != currentInstruction) { lastInstructionPrinted = currentInstruction; @@ -269,6 +268,7 @@ TTY.println(op.toStringWithIdPrefix()); TTY.println(); } + assert LIRVerifier.verify(op); lir.lir(currentBlock).add(op); } diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Jun 04 11:01:20 2013 +0200 @@ -37,11 +37,17 @@ import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; public final class CompilationTask implements Runnable, Comparable { + //@formatter:off + @Option(help = "") + public static final OptionValue SlowQueueCutoff = new OptionValue<>(100000); + //@formatter:on + public static final ThreadLocal withinEnqueue = new ThreadLocal() { @Override @@ -109,7 +115,7 @@ } inProgress = true; if (GraalOptions.DynamicCompilePriority) { - int threadPriority = priority < GraalOptions.SlowQueueCutoff ? Thread.NORM_PRIORITY : Thread.MIN_PRIORITY; + int threadPriority = priority < SlowQueueCutoff.getValue() ? Thread.NORM_PRIORITY : Thread.MIN_PRIORITY; if (Thread.currentThread().getPriority() != threadPriority) { Thread.currentThread().setPriority(threadPriority); } diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java Tue Jun 04 11:01:20 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot; +import static com.oracle.graal.compiler.GraalDebugConfig.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import java.io.*; @@ -29,7 +30,6 @@ import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; -import com.oracle.graal.phases.*; import com.oracle.graal.printer.*; public final class CompilerThread extends Thread { @@ -60,7 +60,7 @@ @Override public void run() { GraalDebugConfig hotspotDebugConfig = null; - if (GraalOptions.Debug) { + if (DebugEnabled.getValue()) { PrintStream log = graalRuntime().getVMToCompiler().log(); DebugEnvironment.initialize(log); } diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Tue Jun 04 11:01:20 2013 +0200 @@ -27,10 +27,21 @@ import java.util.*; import com.oracle.graal.hotspot.logging.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; public class HotSpotOptions { + private static final Map options = new HashMap<>(); + + static { + ServiceLoader sl = ServiceLoader.loadInstalled(OptionProvider.class); + for (OptionProvider provider : sl) { + String name = provider.getName(); + options.put(name, provider); + } + } + // Called from VM code public static boolean setOption(String option) { if (option.length() == 0) { @@ -61,6 +72,53 @@ } } + OptionProvider optionProvider = options.get(fieldName); + if (optionProvider == null) { + return setOptionLegacy(option, fieldName, value, valueString); + } + + Class optionType = optionProvider.getType(); + + if (value == null) { + if (optionType == Boolean.TYPE || optionType == Boolean.class) { + Logger.info("Value for boolean option '" + fieldName + "' must use '-G:+" + fieldName + "' or '-G:-" + fieldName + "' format"); + return false; + } + + if (valueString == null) { + Logger.info("Value for option '" + fieldName + "' must use '-G:" + fieldName + "=' format"); + return false; + } + + if (optionType == Float.class) { + value = Float.parseFloat(valueString); + } else if (optionType == Double.class) { + value = Double.parseDouble(valueString); + } else if (optionType == Integer.class) { + value = Integer.parseInt(valueString); + } else if (optionType == String.class) { + value = valueString; + } + } else { + if (optionType != Boolean.class) { + Logger.info("Value for option '" + fieldName + "' must use '-G:" + fieldName + "=' format"); + return false; + } + } + + if (value != null) { + optionProvider.getOptionValue().setValue(value); + // Logger.info("Set option " + fieldName + " to " + value); + } else { + Logger.info("Wrong value \"" + valueString + "\" for option " + fieldName); + return false; + } + + return true; + } + + private static boolean setOptionLegacy(String option, String fieldName, Object v, String valueString) { + Object value = v; Field f; try { f = GraalOptions.class.getDeclaredField(fieldName); @@ -116,10 +174,25 @@ } return true; + } private static void printFlags() { Logger.info("[Graal flags]"); + SortedMap sortedOptions = new TreeMap<>(options); + for (Map.Entry e : sortedOptions.entrySet()) { + e.getKey(); + OptionProvider opt = e.getValue(); + Object value = opt.getOptionValue().getValue(); + Logger.info(String.format("%9s %-40s = %-14s %s", opt.getType().getSimpleName(), e.getKey(), value, opt.getHelp())); + } + + printFlagsLegacy(); + + System.exit(0); + } + + protected static void printFlagsLegacy() { Field[] flags = GraalOptions.class.getDeclaredFields(); Arrays.sort(flags, new Comparator() { @@ -137,6 +210,5 @@ } } } - System.exit(0); } } diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Tue Jun 04 11:01:20 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.hotspot.bridge; +import static com.oracle.graal.compiler.GraalDebugConfig.*; import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.CompilationTask.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; @@ -46,10 +47,10 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.common.*; -import com.oracle.graal.printer.*; import com.oracle.graal.replacements.*; /** @@ -57,6 +58,38 @@ */ public class VMToCompilerImpl implements VMToCompiler { + //@formatter:off + @Option(help = "File to which compiler logging is sent") + private static final OptionValue LogFile = new OptionValue<>(null); + + @Option(help = "Use low priority compilation threads") + private static final OptionValue SlowCompileThreads = new OptionValue<>(false); + + @Option(help = "Use priority-based compilation queue") + private static final OptionValue PriorityCompileQueue = new OptionValue<>(true); + + @Option(help = "Print compilation queue activity periodically") + private static final OptionValue PrintQueue = new OptionValue<>(false); + + @Option(help = "Time limit in milliseconds for bootstrap (-1 for no limit)") + private static final OptionValue TimedBootstrap = new OptionValue<>(-1); + + @Option(help = "Number of compilation threads to use") + private static final OptionValue Threads = new OptionValue(1) { + + @Override + public Integer initialValue() { + return Runtime.getRuntime().availableProcessors(); + } + }; + + @Option(help = "") + private static final OptionValue GenericDynamicCounters = new OptionValue<>(false); + + @Option(help = "") + private static final OptionValue BenchmarkDynamicCounters = new OptionValue<>(null); + //@formatter:on + private final HotSpotGraalRuntime graalRuntime; public final HotSpotResolvedPrimitiveType typeBoolean; @@ -117,35 +150,32 @@ initMirror(typeLong, offset); initMirror(typeVoid, offset); - if (GraalOptions.LogFile != null) { + if (LogFile.getValue() != null) { try { final boolean enableAutoflush = true; - log = new PrintStream(new FileOutputStream(GraalOptions.LogFile), enableAutoflush); + log = new PrintStream(new FileOutputStream(LogFile.getValue()), enableAutoflush); } catch (FileNotFoundException e) { - throw new RuntimeException("couldn't open log file: " + GraalOptions.LogFile, e); + throw new RuntimeException("couldn't open log file: " + LogFile.getValue(), e); } } TTY.initialize(log); - if (GraalOptions.Log == null && GraalOptions.Meter == null && GraalOptions.Time == null && GraalOptions.Dump == null) { - if (GraalOptions.MethodFilter != null) { + if (Log.getValue() == null && Meter.getValue() == null && Time.getValue() == null && Dump.getValue() == null) { + if (MethodFilter.getValue() != null) { TTY.println("WARNING: Ignoring MethodFilter option since Log, Meter, Time and Dump options are all null"); } } if (config.ciTime) { - quietMeterAndTime = (GraalOptions.Meter == null && GraalOptions.Time == null); - GraalOptions.Debug = true; - GraalOptions.Meter = ""; - GraalOptions.Time = ""; + quietMeterAndTime = (Meter.getValue() == null && Time.getValue() == null); + DebugEnabled.setValue(true); + Meter.setValue(""); + Time.setValue(""); } - if (GraalOptions.Debug) { + if (DebugEnabled.getValue()) { Debug.enable(); - if (GraalOptions.DebugReplacements) { - DebugEnvironment.initialize(log); - } } // Install intrinsics. @@ -173,21 +203,17 @@ } - if (GraalOptions.DebugReplacements) { - phaseTransition("replacements"); - } + // Create compilation queue. + BlockingQueue queue = PriorityCompileQueue.getValue() ? new PriorityBlockingQueue() : new LinkedBlockingQueue(); + compileQueue = new ThreadPoolExecutor(Threads.getValue(), Threads.getValue(), 0L, TimeUnit.MILLISECONDS, queue, CompilerThread.FACTORY); - // Create compilation queue. - BlockingQueue queue = GraalOptions.PriorityCompileQueue ? new PriorityBlockingQueue() : new LinkedBlockingQueue(); - compileQueue = new ThreadPoolExecutor(GraalOptions.Threads, GraalOptions.Threads, 0L, TimeUnit.MILLISECONDS, queue, CompilerThread.FACTORY); - - if (GraalOptions.SlowCompileThreads) { - BlockingQueue slowQueue = GraalOptions.PriorityCompileQueue ? new PriorityBlockingQueue() : new LinkedBlockingQueue(); - slowCompileQueue = new ThreadPoolExecutor(GraalOptions.Threads, GraalOptions.Threads, 0L, TimeUnit.MILLISECONDS, slowQueue, CompilerThread.LOW_PRIORITY_FACTORY); + if (SlowCompileThreads.getValue()) { + BlockingQueue slowQueue = PriorityCompileQueue.getValue() ? new PriorityBlockingQueue() : new LinkedBlockingQueue(); + slowCompileQueue = new ThreadPoolExecutor(Threads.getValue(), Threads.getValue(), 0L, TimeUnit.MILLISECONDS, slowQueue, CompilerThread.LOW_PRIORITY_FACTORY); } // Create queue status printing thread. - if (GraalOptions.PrintQueue) { + if (PrintQueue.getValue()) { Thread t = new Thread() { @Override @@ -209,8 +235,8 @@ t.start(); } - if (GraalOptions.BenchmarkDynamicCounters != null) { - String[] arguments = GraalOptions.BenchmarkDynamicCounters.split(","); + if (BenchmarkDynamicCounters.getValue() != null) { + String[] arguments = BenchmarkDynamicCounters.getValue().split(","); if (arguments.length == 0 || (arguments.length % 3) != 0) { throw new GraalInternalError("invalid arguments to BenchmarkDynamicCounters: (err|out),start,end,(err|out),start,end,... (~ matches multiple digits)"); } @@ -228,7 +254,7 @@ DynamicCounterNode.excludedClassPrefix = "Lcom/oracle/graal/"; DynamicCounterNode.enabled = true; } - if (GraalOptions.GenericDynamicCounters) { + if (GenericDynamicCounters.getValue()) { DynamicCounterNode.enabled = true; } compilerStartTime = System.nanoTime(); @@ -382,7 +408,7 @@ TTY.flush(); } } - } while ((System.currentTimeMillis() - startTime) <= GraalOptions.TimedBootstrap); + } while ((System.currentTimeMillis() - startTime) <= TimedBootstrap.getValue()); phaseTransition("bootstrap"); @@ -413,7 +439,7 @@ private static void shutdownCompileQueue(ThreadPoolExecutor queue) throws InterruptedException { if (queue != null) { queue.shutdown(); - if (Debug.isEnabled() && GraalOptions.Dump != null) { + if (Debug.isEnabled() && Dump.getValue() != null) { // Wait 2 seconds to flush out all graph dumps that may be of interest queue.awaitTermination(2, TimeUnit.SECONDS); } @@ -437,9 +463,9 @@ ArrayList sortedValues = new ArrayList<>(debugValues); Collections.sort(sortedValues); - if (GraalOptions.SummarizeDebugValues) { + if (SummarizeDebugValues.getValue()) { printSummary(topLevelMaps, sortedValues); - } else if (GraalOptions.PerThreadDebugValues) { + } else if (PerThreadDebugValues.getValue()) { for (DebugValueMap map : topLevelMaps) { TTY.println("Showing the results for thread: " + map.getName()); map.group(); @@ -449,13 +475,13 @@ } else { DebugValueMap globalMap = new DebugValueMap("Global"); for (DebugValueMap map : topLevelMaps) { - if (GraalOptions.SummarizePerPhase) { + if (SummarizePerPhase.getValue()) { flattenChildren(map, globalMap); } else { globalMap.addChild(map); } } - if (!GraalOptions.SummarizePerPhase) { + if (!SummarizePerPhase.getValue()) { globalMap.group(); } globalMap.normalize(); @@ -471,7 +497,7 @@ } SnippetCounter.printGroups(TTY.out().out()); - if (GraalOptions.GenericDynamicCounters) { + if (GenericDynamicCounters.getValue()) { DynamicCounterNode.dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d); } } @@ -581,7 +607,7 @@ return true; } } else { - if (GraalOptions.PriorityCompileQueue) { + if (PriorityCompileQueue.getValue()) { // normally compilation tasks will only be re-queued when they get a // priority boost, so cancel the old task and add a new one current.cancel(); @@ -604,7 +630,7 @@ } else { try { method.setCurrentTask(task); - if (GraalOptions.SlowCompileThreads && priority > GraalOptions.SlowQueueCutoff) { + if (SlowCompileThreads.getValue() && priority > SlowQueueCutoff.getValue()) { slowCompileQueue.execute(task); } else { compileQueue.execute(task); diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Tue Jun 04 11:01:20 2013 +0200 @@ -313,6 +313,7 @@ @Override public boolean isAssignableFrom(ResolvedJavaType other) { + assert other != null; if (other instanceof HotSpotResolvedObjectType) { HotSpotResolvedObjectType otherType = (HotSpotResolvedObjectType) other; return javaMirror.isAssignableFrom(otherType.javaMirror); diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Tue Jun 04 11:01:20 2013 +0200 @@ -129,6 +129,7 @@ @Override public boolean isAssignableFrom(ResolvedJavaType other) { + assert other != null; return other == this; } diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Tue Jun 04 11:01:20 2013 +0200 @@ -77,7 +77,7 @@ } private static boolean isCloneableType(ResolvedJavaType type, MetaAccessProvider metaAccess) { - return metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); + return type != null && metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); } private static ResolvedJavaType getConcreteType(ObjectStamp stamp, Assumptions assumptions) { diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Tue Jun 04 11:01:20 2013 +0200 @@ -260,7 +260,7 @@ if (kind == Kind.Object) { stamp = StampFactory.declared(type); } else { - stamp = StampFactory.forKind(kind); + stamp = StampFactory.forKind(type.getKind()); } LocalNode local = builder.add(new LocalNode(i, stamp)); locals[i] = local; diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Tue Jun 04 11:01:20 2013 +0200 @@ -82,7 +82,7 @@ if (kind == Kind.Object && type instanceof ResolvedJavaType) { stamp = StampFactory.declared((ResolvedJavaType) type); } else { - stamp = StampFactory.forKind(kind); + stamp = StampFactory.forKind(type.getKind()); } LocalNode local = graph.unique(new LocalNode(index, stamp)); storeLocal(javaIndex, local); diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Jun 04 11:01:20 2013 +0200 @@ -1107,8 +1107,11 @@ } if (exact != null) { // either the holder class is exact, or the receiver object has an exact type - invokeDirect(exact.resolveMethod(target), args); - return; + ResolvedJavaMethod exactMethod = exact.resolveMethod(target); + if (exactMethod != null) { + invokeDirect(exactMethod, args); + return; + } } // devirtualization failed, produce an actual invokevirtual appendInvoke(invokeKind, target, args); diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java Tue Jun 04 11:01:20 2013 +0200 @@ -36,8 +36,6 @@ @Component({ REG, OperandFlag.ILLEGAL }) protected AllocatableValue base; - @Component({ REG, OperandFlag.ILLEGAL }) - protected AllocatableValue index; protected final int displacement; public SPARCAddressValue(PlatformKind kind, AllocatableValue baseRegister, @@ -57,8 +55,7 @@ } public SPARCAddress toAddress() { - return new SPARCAddress(toRegister(base), toRegister(index), - displacement); + return new SPARCAddress(toRegister(base), displacement); } } diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Tue Jun 04 11:01:20 2013 +0200 @@ -41,10 +41,13 @@ import static com.oracle.graal.asm.sparc.SPARCAssembler.Or; import static com.oracle.graal.asm.sparc.SPARCAssembler.Sdivx; import static com.oracle.graal.asm.sparc.SPARCAssembler.Sll; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Sllx; import static com.oracle.graal.asm.sparc.SPARCAssembler.Srl; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Srlx; import static com.oracle.graal.asm.sparc.SPARCAssembler.Sra; import static com.oracle.graal.asm.sparc.SPARCAssembler.Sub; import static com.oracle.graal.asm.sparc.SPARCAssembler.Xor; +import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.CONST; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.HINT; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG; @@ -56,83 +59,60 @@ import com.oracle.graal.lir.LIRFrameState; import com.oracle.graal.lir.asm.TargetMethodAssembler; +//@formatter:off public enum SPARCArithmetic { - IADD, - ISUB, - IMUL, - IDIV, - IDIVREM, - IREM, - IUDIV, - IUREM, - IAND, - IOR, - IXOR, - ISHL, - ISHR, - IUSHR, - LADD, - LSUB, - LMUL, - LDIV, - LDIVREM, - LREM, - LUDIV, - LUREM, - LAND, - LOR, - LXOR, - LSHL, - LSHR, - LUSHR, - FADD, - FSUB, - FMUL, - FDIV, - FREM, - FAND, - FOR, - FXOR, - DADD, - DSUB, - DMUL, - DDIV, - DREM, - DAND, - DOR, - DXOR, - INEG, - LNEG, - FNEG, - DNEG, - I2L, - L2I, - I2B, - I2C, - I2S, - F2D, - D2F, - I2F, - I2D, - F2I, - D2I, - L2F, - L2D, - F2L, - D2L, - MOV_I2F, - MOV_L2D, - MOV_F2I, - MOV_D2L; + // @formatter:off + IADD, ISUB, IMUL, IDIV, IDIVREM, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR, + LADD, LSUB, LMUL, LDIV, LDIVREM, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, + FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR, + DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR, + INEG, LNEG, FNEG, DNEG, + I2L, L2I, I2B, I2C, I2S, + F2D, D2F, + I2F, I2D, F2I, D2I, + L2F, L2D, F2L, D2L, + MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L; + + /** + * Binary operation with single source/destination operand and one constant. + */ + public static class BinaryRegConst extends SPARCLIRInstruction { + @Opcode private final SPARCArithmetic opcode; + @Def({REG, HINT}) protected AllocatableValue result; + @Use({REG, STACK}) protected AllocatableValue x; + protected Constant y; + + public BinaryRegConst(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x, Constant y) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + SPARCMove.move(tasm, masm, result, x); + emit(tasm, masm, opcode, result, y, null); + } + + @Override + public void verify() { + super.verify(); + verifyKind(opcode, result, x, y); + } + } /** * Unary operation with separate source and destination operand. */ public static class Unary2Op extends SPARCLIRInstruction { - @Opcode private final SPARCArithmetic opcode; - @Def({REG}) protected AllocatableValue result; - @Use({REG, STACK}) protected AllocatableValue x; + @Opcode + private final SPARCArithmetic opcode; + @Def({ REG }) + protected AllocatableValue result; + @Use({ REG, STACK }) + protected AllocatableValue x; public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) { this.opcode = opcode; @@ -152,9 +132,12 @@ */ public static class Unary1Op extends SPARCLIRInstruction { - @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected AllocatableValue result; - @Use({REG, STACK}) protected AllocatableValue x; + @Opcode + private final SPARCArithmetic opcode; + @Def({ REG, HINT }) + protected AllocatableValue result; + @Use({ REG, STACK }) + protected AllocatableValue x; public Unary1Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) { this.opcode = opcode; @@ -170,9 +153,12 @@ public static class Op1Stack extends SPARCLIRInstruction { - @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected Value result; - @Use({REG, STACK, CONST}) protected Value x; + @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; @@ -188,10 +174,14 @@ public static class Op2Stack extends SPARCLIRInstruction { - @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected Value result; - @Use({REG, STACK, CONST}) protected Value x; - @Alive({REG, STACK, CONST}) protected Value y; + @Opcode + private final SPARCArithmetic opcode; + @Def({ REG, HINT }) + protected Value result; + @Use({ REG, STACK, CONST }) + protected Value x; + @Alive({ REG, STACK, CONST }) + protected Value y; public Op2Stack(SPARCArithmetic opcode, Value result, Value x, Value y) { this.opcode = opcode; @@ -214,10 +204,14 @@ public static class Op2Reg extends SPARCLIRInstruction { - @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected Value result; - @Use({REG, STACK, CONST}) protected Value x; - @Alive({REG, CONST}) protected Value y; + @Opcode + private final SPARCArithmetic opcode; + @Def({ REG, HINT }) + protected Value result; + @Use({ REG, STACK, CONST }) + protected Value x; + @Alive({ REG, CONST }) + protected Value y; public Op2Reg(SPARCArithmetic opcode, Value result, Value x, Value y) { this.opcode = opcode; @@ -240,10 +234,14 @@ public static class ShiftOp extends SPARCLIRInstruction { - @Opcode private final SPARCArithmetic opcode; - @Def({REG, HINT}) protected Value result; - @Use({REG, STACK, CONST}) protected Value x; - @Alive({REG, CONST}) protected Value y; + @Opcode + private final SPARCArithmetic opcode; + @Def({ REG, HINT }) + protected Value result; + @Use({ REG, STACK, CONST }) + protected Value x; + @Alive({ REG, CONST }) + protected Value y; public ShiftOp(SPARCArithmetic opcode, Value result, Value x, Value y) { this.opcode = opcode; @@ -268,192 +266,210 @@ @SuppressWarnings("unused") protected static void emit(SPARCAssembler masm, SPARCArithmetic opcode, Value result) { switch (opcode) { - case L2I: - new Sra(masm, asLongReg(result), 0, asIntReg(result)); - break; - case I2C: - new Sll(masm, asIntReg(result), 16, asIntReg(result)); - new Srl(masm, asIntReg(result), 16, asIntReg(result)); - break; - default: - throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + case L2I: + new And(masm, asIntReg(result), -1, asIntReg(result)); + break; + case I2C: + new Sll(masm, asIntReg(result), 16, asIntReg(result)); + new Srl(masm, asIntReg(result), 16, asIntReg(result)); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + opcode); } } @SuppressWarnings("unused") - public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) { + public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, + SPARCArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) { int exceptionOffset = -1; if (isConstant(src1)) { switch (opcode) { - case ISUB: - assert is_simm13(tasm.asIntConst(src1)); - new Add(masm, asIntReg(src2), -(tasm.asIntConst(src1)), asIntReg(dst)); - break; - case IAND: - throw new InternalError("NYI"); - case IDIV: - assert is_simm13(tasm.asIntConst(src1)); - throw new InternalError("NYI"); - // new Sdivx(masm, asIntReg(src1), asIntReg(src2), - // asIntReg(dst)); - case FSUB: - throw new InternalError("NYI"); - case FDIV: - throw new InternalError("NYI"); - case DSUB: - throw new InternalError("NYI"); - case DDIV: - throw new InternalError("NYI"); - default: - throw GraalInternalError.shouldNotReachHere(); + case ISUB: + assert isSimm13(tasm.asIntConst(src1)); + new Add(masm, asIntReg(src2), -(tasm.asIntConst(src1)), asIntReg(dst)); + break; + case IAND: + throw new InternalError("NYI"); + case IDIV: + assert isSimm13(tasm.asIntConst(src1)); + throw new InternalError("NYI"); + // new Sdivx(masm, asIntReg(src1), asIntReg(src2), + // asIntReg(dst)); + case FSUB: + throw new InternalError("NYI"); + case FDIV: + throw new InternalError("NYI"); + case DSUB: + throw new InternalError("NYI"); + case DDIV: + throw new InternalError("NYI"); + default: + throw GraalInternalError.shouldNotReachHere(); } } else if (isConstant(src2)) { switch (opcode) { - case IADD: - assert is_simm13(tasm.asIntConst(src2)); - new Add(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case ISUB: - assert is_simm13(tasm.asIntConst(src2)); - new Sub(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case IMUL: - assert is_simm13(tasm.asIntConst(src2)); - new Mulx(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case IAND: - assert is_simm13(tasm.asIntConst(src2)); - new And(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case ISHL: - assert is_simm13(tasm.asIntConst(src2)); - new Sll(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case ISHR: - assert is_simm13(tasm.asIntConst(src2)); - new Srl(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case IUSHR: - assert is_simm13(tasm.asIntConst(src2)); - new Sra(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case IXOR: - throw new InternalError("NYI"); - case LXOR: - throw new InternalError("NYI"); - case LUSHR: - throw new InternalError("NYI"); - case FADD: - throw new InternalError("NYI"); - case FMUL: - throw new InternalError("NYI"); - case FDIV: - throw new InternalError("NYI"); - case DADD: - throw new InternalError("NYI"); - case DMUL: - throw new InternalError("NYI"); - case DDIV: - throw new InternalError("NYI"); - default: - throw GraalInternalError.shouldNotReachHere(); + case IADD: + assert isSimm13(tasm.asIntConst(src2)); + new Add(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case ISUB: + assert isSimm13(tasm.asIntConst(src2)); + new Sub(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case IMUL: + assert isSimm13(tasm.asIntConst(src2)); + new Mulx(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case IAND: + assert isSimm13(tasm.asIntConst(src2)); + new And(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case ISHL: + assert isSimm13(tasm.asIntConst(src2)); + new Sll(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case ISHR: + assert isSimm13(tasm.asIntConst(src2)); + new Srl(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case IUSHR: + assert isSimm13(tasm.asIntConst(src2)); + new Sra(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case IXOR: + assert isSimm13(tasm.asIntConst(src2)); + new Xor(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); + break; + case LXOR: + assert isSimm13(tasm.asIntConst(src2)); + new Add(masm, asLongReg(src1), tasm.asIntConst(src2), asLongReg(dst)); + break; + case LUSHR: + throw new InternalError("NYI"); + case FADD: + throw new InternalError("NYI"); + case FMUL: + throw new InternalError("NYI"); + case FDIV: + throw new InternalError("NYI"); + case DADD: + throw new InternalError("NYI"); + case DMUL: + throw new InternalError("NYI"); + case DDIV: + throw new InternalError("NYI"); + default: + throw GraalInternalError.shouldNotReachHere(); } } else { switch (opcode) { - case IADD: - new Add(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); - break; - case ISUB: - new Sub(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); - break; - case IMUL: - new Mulx(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); - break; - case IDIV: - new Sdivx(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); - break; - case IAND: - new And(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); - break; - case IOR: - new Or(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); - break; - case IXOR: - new Xor(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); - break; - case ISHL: - new Sll(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); - break; - case ISHR: - new Srl(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); - break; - case IUSHR: - new Sra(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); - break; - case IREM: - throw new InternalError("NYI"); - case LADD: - new Add(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); - break; - case LSUB: - new Sub(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); - break; - case LMUL: - new Mulx(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); - break; - case LDIV: - new Sdivx(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); - break; - case LAND: - new And(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); - break; - case LOR: - new Or(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); - break; - case LXOR: - new Xor(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); - break; - case LSHL: - new Sll(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); - break; - case LSHR: - new Srl(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); - break; - case LUSHR: - new Sra(masm, asLongReg(src1), asLongReg(src2), asIntReg(dst)); - break; - case LREM: - throw new InternalError("NYI"); - case FADD: - new Fadds(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)); - break; - case FSUB: - new Fsubs(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)); - break; - case FMUL: - new Fmuls(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)); - break; - case FDIV: - new Fdivs(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)); - break; - case FREM: - throw new InternalError("NYI"); - case DADD: - new Faddd(masm, asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)); - break; - case DSUB: - new Fsubd(masm, asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)); - break; - case DMUL: - new Fmuld(masm, asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)); - break; - case DDIV: - new Fdivd(masm, asDoubleReg(src1), asDoubleReg(src2), asDoubleReg(dst)); - break; - case DREM: - throw new InternalError("NYI"); - default: - throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + case IADD: + new Add(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case ISUB: + new Sub(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IMUL: + new Mulx(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IDIV: + new Sdivx(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IAND: + new And(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IOR: + new Or(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IXOR: + new Xor(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case ISHL: + new Sll(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case ISHR: + new Srl(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IUSHR: + new Sra(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); + break; + case IREM: + throw new InternalError("NYI"); + case LADD: + new Add(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LSUB: + new Sub(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LMUL: + new Mulx(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LDIV: + new Sdivx(masm, asLongReg(src1), asLongReg(src2), + asLongReg(dst)); + break; + case LAND: + new And(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LOR: + new Or(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LXOR: + new Xor(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LSHL: + new Sll(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LSHR: + new Srl(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + break; + case LUSHR: + new Sra(masm, asLongReg(src1), asIntReg(src2), asLongReg(dst)); + break; + case LDIVREM: + case LUDIV: + case LUREM: + case LREM: + throw new InternalError("NYI"); + case FADD: + new Fadds(masm, asFloatReg(src1), asFloatReg(src2), + asFloatReg(dst)); + break; + case FSUB: + new Fsubs(masm, asFloatReg(src1), asFloatReg(src2), + asFloatReg(dst)); + break; + case FMUL: + new Fmuls(masm, asFloatReg(src1), asFloatReg(src2), + asFloatReg(dst)); + break; + case FDIV: + new Fdivs(masm, asFloatReg(src1), asFloatReg(src2), + asFloatReg(dst)); + break; + case FREM: + throw new InternalError("NYI"); + case DADD: + new Faddd(masm, asDoubleReg(src1), asDoubleReg(src2), + asDoubleReg(dst)); + break; + case DSUB: + new Fsubd(masm, asDoubleReg(src1), asDoubleReg(src2), + asDoubleReg(dst)); + break; + case DMUL: + new Fmuld(masm, asDoubleReg(src1), asDoubleReg(src2), + asDoubleReg(dst)); + break; + case DDIV: + new Fdivd(masm, asDoubleReg(src1), asDoubleReg(src2), + asDoubleReg(dst)); + break; + case DREM: + throw new InternalError("NYI"); + default: + throw GraalInternalError.shouldNotReachHere("missing: " + + opcode); } } @@ -464,41 +480,51 @@ } @SuppressWarnings("unused") - public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info) { + public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, + SPARCArithmetic opcode, Value dst, Value src, LIRFrameState info) { int exceptionOffset = -1; if (isRegister(src)) { switch (opcode) { - case I2L: - new Sra(masm, asIntReg(src), 0, asLongReg(dst)); - break; - case I2B: - new Sll(masm, asIntReg(src), 24, asIntReg(src)); - new Srl(masm, asIntReg(dst), 24, asIntReg(src)); - break; - case I2F: - new Fstoi(masm, asIntReg(src), asFloatReg(dst)); - break; - case I2D: - new Fdtoi(masm, asIntReg(src), asDoubleReg(dst)); - break; - case FNEG: - new Fnegs(masm, asFloatReg(src), asFloatReg(dst)); - break; - case DNEG: - new Fnegd(masm, asDoubleReg(src), asDoubleReg(dst)); - break; - default: - throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + case I2L: + new Sra(masm, asIntReg(src), 0, asLongReg(dst)); + break; + case I2B: + new Sll(masm, asIntReg(src), 24, asIntReg(src)); + new Srl(masm, asIntReg(dst), 24, asIntReg(src)); + break; + case I2F: + new Fstoi(masm, asIntReg(src), asFloatReg(dst)); + break; + case I2D: + new Fdtoi(masm, asIntReg(src), asDoubleReg(dst)); + break; + case FNEG: + new Fnegs(masm, asFloatReg(src), asFloatReg(dst)); + break; + case DNEG: + new Fnegd(masm, asDoubleReg(src), asDoubleReg(dst)); + break; + case LSHL: + new Sllx(masm, asLongReg(dst), asIntReg(src), asLongReg(dst)); + break; + case LSHR: + new Srlx(masm, asLongReg(dst), asIntReg(src), asLongReg(dst)); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + + opcode); } } else if (isConstant(src)) { switch (opcode) { - default: - throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + default: + throw GraalInternalError.shouldNotReachHere("missing: " + + opcode); } } else { switch (opcode) { - default: - throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + default: + throw GraalInternalError.shouldNotReachHere("missing: " + + opcode); } } @@ -508,19 +534,72 @@ } } - private static final int max13 = ((1 << 12) - 1); - private static final int min13 = -(1 << 12); + private static void verifyKind(SPARCArithmetic opcode, Value result, Value x, Value y) { + Kind rk; + Kind xk; + Kind yk; + Kind xsk; + Kind ysk; - private static boolean is_simm13(int src) { - return min13 <= src && src <= max13; - } + switch (opcode) { + case IADD: + case ISUB: + case IMUL: + case IDIV: + case IREM: + case IAND: + case IOR: + case IXOR: + case ISHL: + case ISHR: + case IUSHR: + rk = result.getKind(); + xsk = x.getKind().getStackKind(); + ysk = y.getKind().getStackKind(); - private static void verifyKind(SPARCArithmetic opcode, Value result, Value x, Value y) { - if (((opcode.name().startsWith("I") && result.getKind() == Kind.Int && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || - (opcode.name().startsWith("L") && result.getKind() == Kind.Long && x.getKind() == Kind.Long && y.getKind() == Kind.Long) || - (opcode.name().startsWith("F") && result.getKind() == Kind.Float && x.getKind() == Kind.Float && y.getKind() == Kind.Float) || (opcode.name().startsWith("D") && - result.getKind() == Kind.Double && x.getKind() == Kind.Double && y.getKind() == Kind.Double)) == false) { - throw GraalInternalError.shouldNotReachHere("opcode: " + opcode.name() + " x: " + x.getKind() + " y: " + y.getKind()); + assert rk == Kind.Int && xsk == Kind.Int && ysk == Kind.Int; + break; + case LADD: + case LSUB: + case LMUL: + case LDIV: + case LREM: + case LAND: + case LOR: + case LXOR: + case LSHL: + case LSHR: + case LUSHR: + rk = result.getKind(); + xk = x.getKind(); + yk = y.getKind(); + + assert rk == Kind.Long && xk == Kind.Long && yk == Kind.Long; + break; + case FADD: + case FSUB: + case FMUL: + case FDIV: + case FREM: + rk = result.getKind(); + xk = x.getKind(); + yk = y.getKind(); + + assert rk == Kind.Float && xk == Kind.Float && yk == Kind.Float; + break; + case DADD: + case DSUB: + case DMUL: + case DDIV: + case DREM: + rk = result.getKind(); + xk = x.getKind(); + yk = y.getKind(); + + assert rk == Kind.Double && xk == Kind.Double && yk == Kind.Double; + break; + default: + throw new InternalError("NYI: " + opcode); } } } diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.asm.sparc.SPARCAssembler.Popc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Srl; +import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.sparc.SPARC; + +public class SPARCBitManipulationOp extends SPARCLIRInstruction { + + public enum IntrinsicOpcode { + IPOPCNT, LPOPCNT, IBSR, LBSR, BSF; + } + + @Opcode private final IntrinsicOpcode opcode; + @Def protected AllocatableValue result; + @Use({OperandFlag.REG, OperandFlag.STACK}) protected AllocatableValue input; + + public SPARCBitManipulationOp(IntrinsicOpcode opcode, AllocatableValue result, AllocatableValue input) { + this.opcode = opcode; + this.result = result; + this.input = input; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + Register dst = ValueUtil.asIntReg(result); + if (ValueUtil.isRegister(input)) { + Register src = ValueUtil.asRegister(input); + switch (opcode) { + case IPOPCNT: + // clear upper word for 64 bit POPC + new Srl(masm, src, SPARC.g0, dst); + new Popc(masm, src, dst); + break; + case LPOPCNT: + new Popc(masm, src, dst); + break; + case BSF: // masm.bsfq(dst, src); + case IBSR: // masm.bsrl(dst, src); + case LBSR: // masm.bsrq(dst, src); + default: + throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + + } + } else if (ValueUtil.isConstant(input) && isSimm13(tasm.asIntConst(input))) { + switch (opcode) { + case IPOPCNT: + new Popc(masm, tasm.asIntConst(input), dst); + break; + case LPOPCNT: + new Popc(masm, tasm.asIntConst(input), dst); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + } + } else { + SPARCAddress src = (SPARCAddress) tasm.asAddress(input); + switch (opcode) { + case IPOPCNT: + // masm.popcntl(dst, src); + break; + case LPOPCNT: + // masm.popcntq(dst, src); + break; + case BSF: + // masm.bsfq(dst, src); + break; + case IBSR: + // masm.bsrl(dst, src); + break; + case LBSR: + // masm.bsrq(dst, src); + break; + } + } + } + +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.SPARCAssembler; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Trap; +import com.oracle.graal.lir.LIRInstruction.*; +import com.oracle.graal.lir.asm.*; + +/** + * Emits a breakpoint. + */ +@Opcode("BREAKPOINT") +public class SPARCBreakpointOp extends SPARCLIRInstruction { + + // historical - from hotspot src/cpu/sparc/vm + // promises that the system will not use traps 16-31 + // We want to use ST_BREAKPOINT here, but the debugger is confused by it. + public static final int ST_RESERVED_FOR_USER_0 = 0x10; + + /** + * A set of values loaded into the Java ABI parameter locations (for inspection by a debugger). + */ + @Use({REG, STACK}) protected Value[] parameters; + + public SPARCBreakpointOp(Value[] parameters) { + this.parameters = parameters; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) { + new Trap(asm, ST_RESERVED_FOR_USER_0); + } +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013, 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.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.asm.*; + +@Opcode("BSWAP") +public class SPARCByteSwapOp extends SPARCLIRInstruction { + + @Def({OperandFlag.REG, OperandFlag.HINT}) protected Value result; + @Use protected Value input; + + public SPARCByteSwapOp(Value result, Value input) { + this.result = result; + this.input = input; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + SPARCMove.move(tasm, masm, result, input); + switch (input.getKind()) { + // case Int: + // masm.bswapl(ValueUtil.asIntReg(result)); + // case Long: + // masm.bswapq(ValueUtil.asLongReg(result)); + } + } +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2013, 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 static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.SPARCAssembler; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.asm.*; + +//@formatter:off +public enum SPARCCompare { + ICMP, LCMP, ACMP, FCMP, DCMP; + + public static class CompareOp extends SPARCLIRInstruction { + + @Opcode private final SPARCCompare opcode; + @Use({REG, STACK, CONST}) protected Value x; + @Use({REG, STACK, CONST}) protected Value y; + + public CompareOp(SPARCCompare opcode, Value x, Value y) { + this.opcode = opcode; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + emit(tasm, masm, opcode, x, y); + } + + @Override + protected void verify() { + super.verify(); + assert (name().startsWith("I") && x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) + || (name().startsWith("L") && x.getKind() == Kind.Long && y.getKind() == Kind.Long) + || (name().startsWith("A") && x.getKind() == Kind.Object && y.getKind() == Kind.Object) + || (name().startsWith("F") && x.getKind() == Kind.Float && y.getKind() == Kind.Float) + || (name().startsWith("D") && x.getKind() == Kind.Double && y.getKind() == Kind.Double); + } + } + + @SuppressWarnings("unused") + public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCCompare opcode, Value x, Value y) { + if (isRegister(y)) { + switch (opcode) { + case ICMP: + new Cmp(masm, asIntReg(x), asIntReg(y)); + break; + case LCMP: + new Cmp(masm, asLongReg(x), asLongReg(y)); + break; + case ACMP: + // masm.cmpptr(asObjectReg(x), asObjectReg(y)); + break; + case FCMP: + // masm.ucomiss(asFloatReg(x), asFloatReg(y)); + break; + case DCMP: + // masm.ucomisd(asDoubleReg(x), asDoubleReg(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else if (isConstant(y)) { + switch (opcode) { + case ICMP: + assert isSimm13(tasm.asIntConst(y)); + new Cmp(masm, asIntReg(x), tasm.asIntConst(y)); + break; + case LCMP: + assert isSimm13(tasm.asIntConst(y)); + new Cmp(masm, asLongReg(x), tasm.asIntConst(y)); + break; + case ACMP: + if (((Constant) y).isNull()) { + // masm.cmpq(asObjectReg(x), 0); + break; + } else { + throw GraalInternalError.shouldNotReachHere("Only null object constants are allowed in comparisons"); + } + case FCMP: + // masm.ucomiss(asFloatReg(x), (AMD64Address) tasm.asFloatConstRef(y)); + break; + case DCMP: + // masm.ucomisd(asDoubleReg(x), (AMD64Address) tasm.asDoubleConstRef(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else { + switch (opcode) { + case ICMP: + // masm.cmpl(asIntReg(x), (AMD64Address) tasm.asIntAddr(y)); + break; + case LCMP: + // masm.cmpq(asLongReg(x), (AMD64Address) tasm.asLongAddr(y)); + break; + case ACMP: + // masm.cmpptr(asObjectReg(x), (AMD64Address) tasm.asObjectAddr(y)); + break; + case FCMP: + // masm.ucomiss(asFloatReg(x), (AMD64Address) tasm.asFloatAddr(y)); + break; + case DCMP: + // masm.ucomisd(asDoubleReg(x), (AMD64Address) tasm.asDoubleAddr(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Jun 04 11:01:20 2013 +0200 @@ -31,20 +31,195 @@ import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.asm.sparc.SPARCAssembler.CC; +import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; import com.oracle.graal.asm.sparc.SPARCAssembler.Bpe; import com.oracle.graal.asm.sparc.SPARCAssembler.Subcc; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.*; import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.calc.Condition; import com.oracle.graal.sparc.SPARC; public class SPARCControlFlow { + public static class BranchOp extends SPARCLIRInstruction implements StandardOp.BranchOp { + + protected Condition condition; + protected LabelRef destination; + + public BranchOp(Condition condition, LabelRef destination) { + this.condition = condition; + this.destination = destination; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + // masm.at(); + Label l = destination.label(); + // l.addPatchAt(tasm.asm.codeBuffer.position()); + String target = l.isBound() ? "L" + l.toString() : AbstractSPARCAssembler.UNBOUND_TARGET; + // masm.bra(target); + } + + @Override + public LabelRef destination() { + return destination; + } + + @Override + public void negate(LabelRef newDestination) { + destination = newDestination; + condition = condition.negate(); + } + } + + @Opcode("CMOVE") + public static class CondMoveOp extends SPARCLIRInstruction { + + @Def({REG, HINT}) protected Value result; + @Alive({REG}) protected Value trueValue; + @Use({REG, STACK, CONST}) protected Value falseValue; + + private final ConditionFlag condition; + + public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue) { + this.result = result; + this.condition = intCond(condition); + this.trueValue = trueValue; + this.falseValue = falseValue; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + cmove(tasm, masm, result, false, condition, false, trueValue, falseValue); + } + } + + @Opcode("CMOVE") + public static class FloatCondMoveOp extends SPARCLIRInstruction { + + @Def({REG}) protected Value result; + @Alive({REG}) protected Value trueValue; + @Alive({REG}) protected Value falseValue; + private final ConditionFlag condition; + private final boolean unorderedIsTrue; + + public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue) { + this.result = result; + this.condition = floatCond(condition); + this.unorderedIsTrue = unorderedIsTrue; + this.trueValue = trueValue; + this.falseValue = falseValue; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue); + } + } + + private static void cmove(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, boolean isFloat, ConditionFlag condition, boolean unorderedIsTrue, Value trueValue, Value falseValue) { + // check that we don't overwrite an input operand before it is used. + assert !result.equals(trueValue); + + SPARCMove.move(tasm, masm, result, falseValue); + cmove(tasm, masm, result, condition, trueValue); + + if (isFloat) { + if (unorderedIsTrue && !trueOnUnordered(condition)) { + // cmove(tasm, masm, result, ConditionFlag.Parity, trueValue); + } else if (!unorderedIsTrue && trueOnUnordered(condition)) { + // cmove(tasm, masm, result, ConditionFlag.Parity, falseValue); + } + } + } + + @SuppressWarnings("unused") + private static void cmove(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, ConditionFlag cond, Value other) { + if (isRegister(other)) { + assert !asRegister(other).equals(asRegister(result)) : "other already overwritten by previous move"; + switch (other.getKind()) { + case Int: + // masm.cmovl(cond, asRegister(result), asRegister(other)); + break; + case Long: + // masm.cmovq(cond, asRegister(result), asRegister(other)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else { + SPARCAddress addr = (SPARCAddress) tasm.asAddress(other); + switch (other.getKind()) { + case Int: + // masm.cmovl(cond, asRegister(result), addr); + break; + case Long: + // masm.cmovq(cond, asRegister(result), addr); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + + private static ConditionFlag intCond(Condition cond) { + switch (cond) { + case EQ: + return ConditionFlag.Equal; + case NE: + return ConditionFlag.NotEqual; + case LT: + return ConditionFlag.Less; + case LE: + return ConditionFlag.LessEqual; + case GE: + return ConditionFlag.GreaterEqual; + case GT: + return ConditionFlag.Greater; + case BE: + case AE: + case AT: + case BT: + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + private static ConditionFlag floatCond(Condition cond) { + switch (cond) { + case EQ: + return ConditionFlag.Equal; + case NE: + return ConditionFlag.NotEqual; + case LT: + case LE: + case GE: + case GT: + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + private static boolean trueOnUnordered(ConditionFlag condition) { + switch (condition) { + case NotEqual: + case Less: + return false; + case Equal: + case GreaterEqual: + return true; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + public static class ReturnOp extends SPARCLIRInstruction { - @Use({ REG, ILLEGAL }) - protected Value x; + @Use({REG, ILLEGAL}) protected Value x; public ReturnOp(Value x) { this.x = x; @@ -59,21 +234,15 @@ } } - public static class SequentialSwitchOp extends SPARCLIRInstruction - implements FallThroughOp { + public static class SequentialSwitchOp extends SPARCLIRInstruction implements FallThroughOp { - @Use({ CONST }) - protected Constant[] keyConstants; + @Use({CONST}) protected Constant[] keyConstants; private final LabelRef[] keyTargets; private LabelRef defaultTarget; - @Alive({ REG }) - protected Value key; - @Temp({ REG, ILLEGAL }) - protected Value scratch; + @Alive({REG}) protected Value key; + @Temp({REG, ILLEGAL}) protected Value scratch; - public SequentialSwitchOp(Constant[] keyConstants, - LabelRef[] keyTargets, LabelRef defaultTarget, Value key, - Value scratch) { + public SequentialSwitchOp(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) { assert keyConstants.length == keyTargets.length; this.keyConstants = keyConstants; this.keyTargets = keyTargets; @@ -112,14 +281,12 @@ Register intKey = asObjectReg(key); Register temp = asObjectReg(scratch); for (int i = 0; i < keyConstants.length; i++) { - SPARCMove.move(tasm, masm, temp.asValue(Kind.Object), - keyConstants[i]); + SPARCMove.move(tasm, masm, temp.asValue(Kind.Object), keyConstants[i]); new Subcc(masm, intKey, temp, SPARC.r0); // CMP new Bpe(masm, CC.Icc, keyTargets[i].label()); } } else { - throw new GraalInternalError( - "sequential switch only supported for int, long and object"); + throw new GraalInternalError("sequential switch only supported for int, long and object"); } if (defaultTarget != null) { masm.jmp(defaultTarget.label()); @@ -139,18 +306,93 @@ } } + public static class SwitchRangesOp extends SPARCLIRInstruction implements FallThroughOp { + + private final LabelRef[] keyTargets; + private LabelRef defaultTarget; + private final int[] lowKeys; + private final int[] highKeys; + @Alive protected Value key; + + public SwitchRangesOp(int[] lowKeys, int[] highKeys, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { + this.lowKeys = lowKeys; + this.highKeys = highKeys; + this.keyTargets = keyTargets; + this.defaultTarget = defaultTarget; + this.key = key; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + assert isSorted(lowKeys) && isSorted(highKeys); + + @SuppressWarnings("unused") + Label actualDefaultTarget = defaultTarget == null ? new Label() : defaultTarget.label(); + int prevHighKey = 0; + boolean skipLowCheck = false; + for (int i = 0; i < lowKeys.length; i++) { + int lowKey = lowKeys[i]; + int highKey = highKeys[i]; + if (lowKey == highKey) { + // masm.cmpl(asIntReg(key), lowKey); + // masm.jcc(ConditionFlag.Equal, keyTargets[i].label()); + skipLowCheck = false; + } else { + if (!skipLowCheck || (prevHighKey + 1) != lowKey) { + // masm.cmpl(asIntReg(key), lowKey); + // masm.jcc(ConditionFlag.Less, actualDefaultTarget); + } + // masm.cmpl(asIntReg(key), highKey); + // masm.jcc(ConditionFlag.LessEqual, keyTargets[i].label()); + skipLowCheck = true; + } + prevHighKey = highKey; + } + if (defaultTarget != null) { + // masm.jmp(defaultTarget.label()); + } else { + // masm.bind(actualDefaultTarget); + // masm.hlt(); + } + } + + @Override + protected void verify() { + super.verify(); + assert lowKeys.length == keyTargets.length; + assert highKeys.length == keyTargets.length; + assert key.getKind() == Kind.Int; + } + + @Override + public LabelRef fallThroughTarget() { + return defaultTarget; + } + + @Override + public void setFallThroughTarget(LabelRef target) { + defaultTarget = target; + } + + private static boolean isSorted(int[] values) { + for (int i = 1; i < values.length; i++) { + if (values[i - 1] >= values[i]) { + return false; + } + } + return true; + } + } + public static class TableSwitchOp extends SPARCLIRInstruction { private final int lowKey; private final LabelRef defaultTarget; private final LabelRef[] targets; - @Alive - protected Value index; - @Temp - protected Value scratch; + @Alive protected Value index; + @Temp protected Value scratch; - public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, - final LabelRef[] targets, Variable index, Variable scratch) { + public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) { this.lowKey = lowKey; this.defaultTarget = defaultTarget; this.targets = targets; @@ -160,15 +402,12 @@ @Override public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { - tableswitch(tasm, masm, lowKey, defaultTarget, targets, - asIntReg(index), asLongReg(scratch)); + tableswitch(tasm, masm, lowKey, defaultTarget, targets, asIntReg(index), asLongReg(scratch)); } } @SuppressWarnings("unused") - private static void tableswitch(TargetMethodAssembler tasm, - SPARCAssembler masm, int lowKey, LabelRef defaultTarget, - LabelRef[] targets, Register value, Register scratch) { + private static void tableswitch(TargetMethodAssembler tasm, SPARCAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Register value, Register scratch) { Buffer buf = masm.codeBuffer; // Compare index against jump table bounds int highKey = lowKey + targets.length - 1; diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.SPARCAssembler; +import com.oracle.graal.asm.sparc.SPARCAssembler.Fsqrtd; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.asm.*; + +public class SPARCMathIntrinsicOp extends SPARCLIRInstruction { + + public enum IntrinsicOpcode { + SQRT, SIN, COS, TAN, LOG, LOG10 + } + + @Opcode private final IntrinsicOpcode opcode; + @Def protected Value result; + @Use protected Value input; + + public SPARCMathIntrinsicOp(IntrinsicOpcode opcode, Value result, Value input) { + this.opcode = opcode; + this.result = result; + this.input = input; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) { + switch (opcode) { + case SQRT: + new Fsqrtd(asm, asDoubleReg(result), asDoubleReg(input)); + break; + case LOG: + case LOG10: + case SIN: + case COS: + case TAN: + default: + throw GraalInternalError.shouldNotReachHere(); + } + } +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Jun 04 11:01:20 2013 +0200 @@ -22,18 +22,35 @@ */ package com.oracle.graal.lir.sparc; -import static com.oracle.graal.api.code.ValueUtil.asRegister; -import static com.oracle.graal.api.code.ValueUtil.isConstant; -import static com.oracle.graal.api.code.ValueUtil.isRegister; +import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCAddress; +import com.oracle.graal.asm.sparc.SPARCAssembler; +import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldf; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsb; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsh; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Lduw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; +import com.oracle.graal.asm.sparc.SPARCAssembler.Membar; +import com.oracle.graal.asm.sparc.SPARCAssembler.Or; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stb; +import com.oracle.graal.asm.sparc.SPARCAssembler.Sth; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; +import com.oracle.graal.asm.sparc.SPARCAssembler.NullCheck; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setuw; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.graph.GraalInternalError; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.*; import com.oracle.graal.lir.StandardOp.MoveOp; import com.oracle.graal.lir.asm.TargetMethodAssembler; +import com.oracle.graal.sparc.SPARC; public class SPARCMove { @@ -52,32 +69,33 @@ } @Override + @SuppressWarnings("unused") public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { - @SuppressWarnings("unused") SPARCAddress addr = address.toAddress(); + SPARCAddress addr = address.toAddress(); switch (kind) { case Byte: - // masm.ld_global_s8(asRegister(result), addr.getBase(), addr.getDisplacement()); + new Ldsb(masm, addr, asRegister(result)); break; case Short: - // masm.ld_global_s16(asRegister(result), addr.getBase(), addr.getDisplacement()); + new Ldsh(masm, addr, asRegister(result)); break; case Char: - // masm.ld_global_u16(asRegister(result), addr.getBase(), addr.getDisplacement()); + new Lduw(masm, addr, asRegister(result)); break; case Int: - // masm.ld_global_s32(asRegister(result), addr.getBase(), addr.getDisplacement()); + new Ldsw(masm, addr, asRegister(result)); break; case Long: - // masm.ld_global_s64(asRegister(result), addr.getBase(), addr.getDisplacement()); + new Ldx(masm, addr, asRegister(result)); break; case Float: - // masm.ld_global_f32(asRegister(result), addr.getBase(), addr.getDisplacement()); + new Ldf(masm, addr, asRegister(result)); break; case Double: - // masm.ld_global_f64(asRegister(result), addr.getBase(), addr.getDisplacement()); + new Lddf(masm, addr, asRegister(result)); break; case Object: - // masm.ld_global_u32(asRegister(result), addr.getBase(), addr.getDisplacement()); + new Ldx(masm, addr, asRegister(result)); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -85,49 +103,18 @@ } } - public static class StoreOp extends SPARCLIRInstruction { + @SuppressWarnings("unused") + public static class MembarOp extends SPARCLIRInstruction { - private final Kind kind; - @Use({COMPOSITE}) protected SPARCAddressValue address; - @Use({REG}) protected AllocatableValue input; - @State protected LIRFrameState state; + private final int barriers; - public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) { - this.kind = kind; - this.address = address; - this.input = input; - this.state = state; + public MembarOp(final int barriers) { + this.barriers = barriers; } @Override - public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { - assert isRegister(input); - @SuppressWarnings("unused") SPARCAddress addr = address.toAddress(); - switch (kind) { - case Byte: - // masm.st_global_s8(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Short: - // masm.st_global_s8(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Int: - // masm.st_global_s32(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Long: - // masm.st_global_s64(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Float: - // masm.st_global_f32(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Double: - // masm.st_global_f64(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Object: - // masm.st_global_s32(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - default: - throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind()); - } + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) { + new Membar(asm, barriers); } } @@ -185,6 +172,88 @@ } } + public static class NullCheckOp extends SPARCLIRInstruction { + + @Use({REG}) protected AllocatableValue input; + @State protected LIRFrameState state; + + public NullCheckOp(Variable input, LIRFrameState state) { + this.input = input; + this.state = state; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + tasm.recordImplicitException(masm.codeBuffer.position(), state); + new NullCheck(masm, new SPARCAddress(asRegister(input), 0)); + } + } + + @SuppressWarnings("unused") + public static class StackLoadAddressOp extends SPARCLIRInstruction { + + @Def({REG}) protected AllocatableValue result; + @Use({STACK, UNINITIALIZED}) protected StackSlot slot; + + public StackLoadAddressOp(AllocatableValue result, StackSlot slot) { + this.result = result; + this.slot = slot; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) { + new Ldx(asm, (SPARCAddress) tasm.asAddress(slot), asLongReg(result)); + } + } + + public static class StoreOp extends SPARCLIRInstruction { + + private final Kind kind; + @Use({COMPOSITE}) protected SPARCAddressValue address; + @Use({REG}) protected AllocatableValue input; + @State protected LIRFrameState state; + + public StoreOp(Kind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) { + this.kind = kind; + this.address = address; + this.input = input; + this.state = state; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + assert isRegister(input); + SPARCAddress addr = address.toAddress(); + switch (kind) { + case Byte: + new Stb(masm, asRegister(input), addr); + break; + case Short: + new Sth(masm, asRegister(input), addr); + break; + case Int: + new Stw(masm, asRegister(input), addr); + break; + case Long: + new Stx(masm, asRegister(input), addr); + break; + case Float: + new Stx(masm, asRegister(input), addr); + break; + case Double: + new Stx(masm, asRegister(input), addr); + break; + case Object: + new Stx(masm, asRegister(input), addr); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind()); + } + } + } + public static void move(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, Value input) { if (isRegister(input)) { if (isRegister(result)) { @@ -203,25 +272,26 @@ } } - private static void reg2reg(@SuppressWarnings("unused") SPARCAssembler masm, Value result, Value input) { + @SuppressWarnings("unused") + private static void reg2reg(SPARCAssembler masm, Value result, Value input) { if (asRegister(input).equals(asRegister(result))) { return; } switch (input.getKind()) { case Int: - // masm.mov_s32(asRegister(result), asRegister(input)); + new Or(masm, SPARC.r0, asRegister(input), asRegister(result)); break; case Long: - // masm.mov_s64(asRegister(result), asRegister(input)); + new Or(masm, SPARC.r0, asRegister(input), asRegister(result)); break; case Float: - // masm.mov_f32(asRegister(result), asRegister(input)); + new Or(masm, SPARC.r0, asRegister(input), asRegister(result)); break; case Double: - // masm.mov_f64(asRegister(result), asRegister(input)); + new Or(masm, SPARC.r0, asRegister(input), asRegister(result)); break; case Object: - // masm.mov_u64(asRegister(result), asRegister(input)); + new Or(masm, SPARC.r0, asRegister(input), asRegister(result)); break; default: throw GraalInternalError.shouldNotReachHere("missing: " + input.getKind()); @@ -235,22 +305,22 @@ if (tasm.runtime.needsDataPatch(input)) { tasm.recordDataReferenceInCode(input, 0, true); } - // masm.mov_s32(asRegister(result), input.asInt()); + new Setuw(masm, input.asInt(), asRegister(result)); break; case Long: if (tasm.runtime.needsDataPatch(input)) { tasm.recordDataReferenceInCode(input, 0, true); } - // masm.mov_s64(asRegister(result), input.asLong()); + new Setx(masm, input.asInt(), null, asRegister(result)); break; case Object: if (input.isNull()) { - // masm.mov_u64(asRegister(result), 0x0L); + new Setx(masm, 0x0L, null, asRegister(result)); } else if (tasm.target.inlineObjects) { tasm.recordDataReferenceInCode(input, 0, true); - // masm.mov_u64(asRegister(result), 0xDEADDEADDEADDEADL); + new Setx(masm, 0xDEADDEADDEADDEADL, null, asRegister(result)); } else { - // masm.mov_u64(asRegister(result), tasm.recordDataReferenceInCode(input, 0, false)); + throw new InternalError("NYI"); } break; default: diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.sparc; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.asm.*; + +public class SPARCTestOp extends SPARCLIRInstruction { + + @Use({REG}) protected Value x; + @Use({REG, STACK, CONST}) protected Value y; + + public SPARCTestOp(Value x, Value y) { + this.x = x; + this.y = y; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) { + if (isRegister(y)) { + switch (x.getKind()) { + case Int: + new Cmp(asm, asIntReg(x), asIntReg(y)); + break; + case Long: + new Cmp(asm, asLongReg(x), asLongReg(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else if (isConstant(y)) { + switch (x.getKind()) { + case Int: + new Cmp(asm, asIntReg(x), tasm.asIntConst(y)); + break; + case Long: + new Cmp(asm, asLongReg(x), tasm.asIntConst(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } else { + switch (x.getKind()) { + case Int: + new Ldsw(asm, (SPARCAddress) tasm.asIntAddr(y), asIntReg(y)); + new Cmp(asm, asIntReg(x), asIntReg(y)); + break; + case Long: + new Ldx(asm, (SPARCAddress) tasm.asLongAddr(y), asLongReg(y)); + new Cmp(asm, asLongReg(x), asLongReg(y)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Tue Jun 04 11:01:20 2013 +0200 @@ -45,12 +45,12 @@ super(object, ConstantLocationNode.create(locationIdentity, kind, displacement, object.graph()), StampFactory.forKind(kind)); } - private ReadNode(ValueNode object, ValueNode location, GuardingNode guard) { + private ReadNode(ValueNode object, ValueNode location, ValueNode guard) { /* * Used by node intrinsics. Since the initial value for location is a parameter, i.e., a * LocalNode, the constructor cannot use the declared type LocationNode. */ - super(object, location, StampFactory.forNodeIntrinsic(), guard, WriteBarrierType.NONE, false); + super(object, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, WriteBarrierType.NONE, false); } @Override diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Tue Jun 04 11:01:20 2013 +0200 @@ -74,7 +74,7 @@ int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1; if (index >= 0 && index < arrayState.getVirtualObject().entryCount()) { ResolvedJavaType componentType = arrayState.getVirtualObject().type().getComponentType(); - if (componentType.isPrimitive() || value.objectStamp().alwaysNull() || componentType.isAssignableFrom(value.objectStamp().type())) { + if (componentType.isPrimitive() || value.objectStamp().alwaysNull() || (value.objectStamp().type() != null && componentType.isAssignableFrom(value.objectStamp().type()))) { tool.setVirtualEntry(arrayState, index, value()); tool.delete(); } diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.options/src/META-INF/services/javax.annotation.processing.Processor --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/META-INF/services/javax.annotation.processing.Processor Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,1 @@ +com.oracle.graal.options.OptionProcessor diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.options/src/com/oracle/graal/options/Option.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/Option.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013, 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.options; + +import java.lang.annotation.*; + +/** + * Describes the attributes of an option whose {@link OptionValue value} is in a static field + * annotated by this annotation type. + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.FIELD) +public @interface Option { + + /** + * Gets a help message for the option. + */ + String help(); + + /** + * The name of the option. By default, the name of the annotated field should be used. + */ + String name() default ""; +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2013, 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.options; + +import java.io.*; +import java.lang.reflect.*; +import java.util.*; + +import javax.annotation.processing.*; +import javax.lang.model.*; +import javax.lang.model.element.*; +import javax.lang.model.element.Modifier; +import javax.lang.model.type.*; +import javax.lang.model.util.*; +import javax.tools.Diagnostic.Kind; +import javax.tools.*; + +/** + * Processes static fields annotated with {@link Option}. An {@link OptionProvider} is generated for + * each such field that can be accessed as a {@linkplain ServiceLoader service} as follows: + * + *

+ * ServiceLoader<OptionProvider> sl = ServiceLoader.loadInstalled(OptionProvider.class);
+ * for (OptionProvider provider : sl) {
+ *     // use provider
+ * }
+ * 
+ */ +@SupportedSourceVersion(SourceVersion.RELEASE_7) +@SupportedAnnotationTypes({"com.oracle.graal.options.Option"}) +public class OptionProcessor extends AbstractProcessor { + + private final Set processed = new HashSet<>(); + + private void processElement(Element element) { + if (processed.contains(element)) { + return; + } + processed.add(element); + + if (!element.getModifiers().contains(Modifier.STATIC)) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element); + return; + } + + Option annotation = element.getAnnotation(Option.class); + assert annotation != null; + assert element instanceof VariableElement; + assert element.getKind() == ElementKind.FIELD; + VariableElement field = (VariableElement) element; + String fieldName = field.getSimpleName().toString(); + + Elements elements = processingEnv.getElementUtils(); + Types types = processingEnv.getTypeUtils(); + + TypeMirror fieldType = field.asType(); + if (fieldType.getKind() != TypeKind.DECLARED) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be of type " + OptionValue.class.getName(), element); + return; + } + DeclaredType declaredFieldType = (DeclaredType) fieldType; + + TypeMirror optionValueType = elements.getTypeElement(OptionValue.class.getName()).asType(); + if (!types.isSubtype(fieldType, types.erasure(optionValueType))) { + String msg = String.format("Option field type %s is not a subclass of %s", fieldType, optionValueType); + processingEnv.getMessager().printMessage(Kind.ERROR, msg, element); + return; + } + + if (!field.getModifiers().contains(Modifier.STATIC)) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element); + return; + } + + String optionName = annotation.name(); + if (optionName.equals("")) { + optionName = fieldName; + } + + String optionType = declaredFieldType.getTypeArguments().get(0).toString(); + if (optionType.startsWith("java.lang.")) { + optionType = optionType.substring("java.lang.".length()); + } + + String pkg = null; + Element enclosing = element.getEnclosingElement(); + String declaringClass = ""; + String separator = ""; + while (enclosing != null) { + if (enclosing.getKind() == ElementKind.CLASS || enclosing.getKind() == ElementKind.INTERFACE) { + if (enclosing.getModifiers().contains(Modifier.PRIVATE)) { + String msg = String.format("Option field cannot be declared in a private %s %s", enclosing.getKind().name().toLowerCase(), enclosing); + processingEnv.getMessager().printMessage(Kind.ERROR, msg, element); + return; + } + declaringClass = enclosing.getSimpleName() + separator + declaringClass; + separator = "."; + } else { + assert enclosing.getKind() == ElementKind.PACKAGE; + pkg = ((PackageElement) enclosing).getQualifiedName().toString(); + } + enclosing = enclosing.getEnclosingElement(); + } + + String providerClassName = declaringClass.replace('.', '_') + "_" + fieldName; + + Filer filer = processingEnv.getFiler(); + try (PrintWriter out = createSourceFile(element, pkg, providerClassName, filer)) { + + out.println("/*"); + out.println(" * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved."); + out.println(" * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER."); + out.println(" *"); + out.println(" * This code is free software; you can redistribute it and/or modify it"); + out.println(" * under the terms of the GNU General Public License version 2 only, as"); + out.println(" * published by the Free Software Foundation."); + out.println(" *"); + out.println(" * This code is distributed in the hope that it will be useful, but WITHOUT"); + out.println(" * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or"); + out.println(" * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License"); + out.println(" * version 2 for more details (a copy is included in the LICENSE file that"); + out.println(" * accompanied this code)."); + out.println(" *"); + out.println(" * You should have received a copy of the GNU General Public License version"); + out.println(" * 2 along with this work; if not, write to the Free Software Foundation,"); + out.println(" * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA."); + out.println(" *"); + out.println(" * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA"); + out.println(" * or visit www.oracle.com if you need additional information or have any"); + out.println(" * questions."); + out.println(" */"); + + out.println("package " + pkg + ";"); + out.println(""); + if (element.getModifiers().contains(Modifier.PRIVATE)) { + out.println("import " + Field.class.getName() + ";"); + } + out.println("import " + OptionValue.class.getName() + ";"); + out.println("import " + OptionProvider.class.getName() + ";"); + out.println(""); + out.println("public class " + providerClassName + " implements " + OptionProvider.class.getSimpleName() + " {"); + out.println(" public String getHelp() {"); + out.println(" return \"" + annotation.help() + "\";"); + out.println(" }"); + out.println(" public String getName() {"); + out.println(" return \"" + optionName + "\";"); + out.println(" }"); + out.println(" public Class getType() {"); + out.println(" return " + optionType + ".class;"); + out.println(" }"); + out.println(" public " + OptionValue.class.getSimpleName() + " getOptionValue() {"); + if (!element.getModifiers().contains(Modifier.PRIVATE)) { + out.println(" return " + declaringClass + "." + fieldName + ";"); + } else { + out.println(" try {"); + out.println(" Field field = " + declaringClass + ".class.getDeclaredField(\"" + fieldName + "\");"); + out.println(" field.setAccessible(true);"); + out.println(" return (" + OptionValue.class.getSimpleName() + ") field.get(null);"); + out.println(" } catch (Exception e) {"); + out.println(" throw (InternalError) new InternalError().initCause(e);"); + out.println(" }"); + } + out.println(" }"); + out.println("}"); + } + + try { + createProviderFile(field, pkg, providerClassName); + } catch (IOException e) { + processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), field); + } + } + + private void createProviderFile(Element field, String pkg, String providerClassName) throws IOException { + String filename = "META-INF/providers/" + pkg + "." + providerClassName; + FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, field); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8")); + writer.println(OptionProvider.class.getName()); + writer.close(); + } + + protected PrintWriter createSourceFile(Element element, String pkg, String relativeName, Filer filer) { + try { + // Ensure Unix line endings to comply with Graal code style guide checked by Checkstyle + JavaFileObject sourceFile = filer.createSourceFile(pkg + "." + relativeName, element); + return new PrintWriter(sourceFile.openWriter()) { + + @Override + public void println() { + print("\n"); + } + }; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + return true; + } + + for (Element element : roundEnv.getElementsAnnotatedWith(Option.class)) { + processElement(element); + } + + return true; + } +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProvider.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013, 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.options; + +import java.util.*; + +/** + * Describes the attributes of an {@linkplain Option option} and provides access to its + * {@linkplain OptionValue value}. The {@link OptionProcessor} auto-generates instances of this + * interface that are accessible as a {@linkplain ServiceLoader service}. + */ +public interface OptionProvider { + + /** + * Gets the type of values stored in the option. + */ + Class getType(); + + /** + * Gets a descriptive help message for the option. + */ + String getHelp(); + + /** + * Gets the name of the option. It's up to the client of this object how to use the name to get + * a user specified value for the option from the environment. + */ + String getName(); + + /** + * Gets the boxed option value. + */ + OptionValue getOptionValue(); +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java Tue Jun 04 11:01:20 2013 +0200 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2013, 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.options; + +import java.util.*; + +/** + * A settable option value. + *

+ * To access {@link OptionProvider} instances via a {@link ServiceLoader} for working with options, + * instances of this class should be assigned to static final fields that are annotated with + * {@link Option}. + */ +public class OptionValue { + + /** + * The raw option value. + */ + protected T value; + + /** + * Guards whether {@link #initialValue()} should be called to give a subclass an opportunity to + * provide a context-sensitive initial value for this option. + */ + protected boolean initialValueCalled; + + /** + * Create an option. + * + * @param value the initial/default value of the option + */ + public OptionValue(T value) { + this.value = value; + } + + protected T initialValue() { + return value; + } + + /** + * Gets the value of this option. + */ + public final T getValue() { + if (!initialValueCalled) { + value = initialValue(); + initialValueCalled = true; + } + return value; + } + + /** + * Sets the value of this option. + */ + @SuppressWarnings("unchecked") + public final void setValue(Object v) { + this.value = (T) v; + this.initialValueCalled = true; + } +} diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Tue Jun 04 11:01:20 2013 +0200 @@ -1033,20 +1033,29 @@ holder = receiverType; if (receiverStamp.isExactType()) { assert targetMethod.getDeclaringClass().isAssignableFrom(holder) : holder + " subtype of " + targetMethod.getDeclaringClass() + " for " + targetMethod; - return getExactInlineInfo(data, invoke, replacements, optimisticOpts, holder.resolveMethod(targetMethod)); + ResolvedJavaMethod resolvedMethod = holder.resolveMethod(targetMethod); + if (resolvedMethod != null) { + return getExactInlineInfo(data, invoke, replacements, optimisticOpts, resolvedMethod); + } } } } if (holder.isArray()) { // arrays can be treated as Objects - return getExactInlineInfo(data, invoke, replacements, optimisticOpts, holder.resolveMethod(targetMethod)); + ResolvedJavaMethod resolvedMethod = holder.resolveMethod(targetMethod); + if (resolvedMethod != null) { + return getExactInlineInfo(data, invoke, replacements, optimisticOpts, resolvedMethod); + } } if (assumptions.useOptimisticAssumptions()) { ResolvedJavaType uniqueSubtype = holder.findUniqueConcreteSubtype(); if (uniqueSubtype != null) { - return getAssumptionInlineInfo(data, invoke, replacements, optimisticOpts, uniqueSubtype.resolveMethod(targetMethod), new Assumptions.ConcreteSubtype(holder, uniqueSubtype)); + ResolvedJavaMethod resolvedMethod = uniqueSubtype.resolveMethod(targetMethod); + if (resolvedMethod != null) { + return getAssumptionInlineInfo(data, invoke, replacements, optimisticOpts, resolvedMethod, new Assumptions.ConcreteSubtype(holder, uniqueSubtype)); + } } ResolvedJavaMethod concrete = holder.findUniqueConcreteMethod(targetMethod); @@ -1122,6 +1131,9 @@ ArrayList concreteMethodsProbabilities = new ArrayList<>(); for (int i = 0; i < ptypes.length; i++) { ResolvedJavaMethod concrete = ptypes[i].getType().resolveMethod(targetMethod); + if (concrete == null) { + return logNotInlinedMethodAndReturnNull(invoke, data.inliningDepth(), targetMethod, "could not resolve method"); + } int index = concreteMethods.indexOf(concrete); double curProbability = ptypes[i].getProbability(); if (index < 0) { diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Tue Jun 04 11:01:20 2013 +0200 @@ -34,11 +34,6 @@ private static final boolean ____ = false; // Checkstyle: resume - public static int Threads; - static { - Threads = Runtime.getRuntime().availableProcessors(); - } - public static String CompilerConfiguration = "basic"; public static String GraalRuntime = "basic"; @@ -80,10 +75,6 @@ public static int MatureExecutionsTypeProfile = 1; // comilation queue - public static int TimedBootstrap = -1; - public static boolean PriorityCompileQueue = true; - public static int SlowQueueCutoff = 100000; - public static boolean SlowCompileThreads = ____; public static boolean DynamicCompilePriority = ____; public static String CompileTheWorld = null; public static int CompileTheWorldStartAt = 1; @@ -115,21 +106,7 @@ public static String PrintFilter = null; // Debug settings: - public static boolean Debug = true; - public static boolean DebugReplacements = ____; public static boolean BootstrapReplacements = ____; - public static boolean PerThreadDebugValues = ____; - public static boolean SummarizeDebugValues = ____; - public static boolean SummarizePerPhase = ____; - public static String Dump = null; - public static String Meter = null; - public static String Time = null; - public static String Log = null; - public static String LogFile = null; - public static String MethodFilter = null; - public static boolean DumpOnError = ____; - public static boolean GenericDynamicCounters = ____; - public static String BenchmarkDynamicCounters = null; // Ideal graph visualizer output settings public static boolean PrintBinaryGraphs = true; @@ -140,7 +117,6 @@ public static int PrintBinaryGraphPort = 4445; // Other printing settings - public static boolean PrintQueue = ____; public static boolean PrintCompilation = ____; public static boolean PrintProfilingInformation = ____; public static boolean PrintIRWithLIR = ____; @@ -212,7 +188,6 @@ public static boolean OptDevirtualizeInvokesOptimistically = true; public static boolean OptPushThroughPi = true; - // Intrinsification settings public static boolean IntrinsifyObjectClone = ____; public static boolean IntrinsifyArrayCopy = true; diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Tue Jun 04 11:01:20 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.printer; +import static com.oracle.graal.compiler.GraalDebugConfig.*; + import java.io.*; import java.util.*; @@ -41,7 +43,7 @@ } dumpHandlers.add(new CFGPrinterObserver()); } - GraalDebugConfig hotspotDebugConfig = new GraalDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, log, dumpHandlers); + GraalDebugConfig hotspotDebugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), Time.getValue(), Dump.getValue(), MethodFilter.getValue(), log, dumpHandlers); Debug.setConfig(hotspotDebugConfig); } } diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java Tue Jun 04 11:01:20 2013 +0200 @@ -92,6 +92,9 @@ } } if (!couldSet) { + if (isSubstitutionGraph()) { + return this; + } throw new GraalInternalError("Wrong usage of branch probability injection!"); } return condition; @@ -99,6 +102,10 @@ return this; } + private boolean isSubstitutionGraph() { + return usages().count() == 1 && usages().first() instanceof ReturnNode; + } + /** * This intrinsic should only be used for the condition of an if statement. The parameter * condition should also only denote a simple condition and not a combined condition involving diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java --- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Tue Jun 04 11:01:20 2013 +0200 @@ -74,6 +74,33 @@ public static final Register r30 = new Register(30, 30, "r30", CPU); public static final Register r31 = new Register(31, 31, "r31", CPU); + public static final Register g0 = r0; + public static final Register g1 = r1; + public static final Register g2 = r2; + public static final Register g3 = r3; + public static final Register g4 = r4; + public static final Register g5 = r5; + public static final Register g6 = r6; + public static final Register g7 = r7; + + public static final Register i0 = r24; + public static final Register i1 = r25; + public static final Register i2 = r26; + public static final Register i3 = r27; + public static final Register i4 = r28; + public static final Register i5 = r29; + public static final Register i6 = r30; + public static final Register i7 = r31; + + public static final Register o0 = r8; + public static final Register o1 = r9; + public static final Register o2 = r10; + public static final Register o3 = r11; + public static final Register o4 = r12; + public static final Register o5 = r13; + public static final Register o6 = r14; + public static final Register o7 = r15; + public static final Register[] gprRegisters = { r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Tue Jun 04 11:01:20 2013 +0200 @@ -1843,19 +1843,29 @@ builder.startCall(execType.getMethodName()); - List signatureParameters = getModel().getSignatureParameters(); int index = 0; for (ActualParameter parameter : execType.getParameters()) { if (!parameter.getSpecification().isSignature()) { builder.string(parameter.getLocalName()); } else { - if (index < signatureParameters.size()) { - ActualParameter specializationParam = signatureParameters.get(index); + if (index < targetField.getExecuteWith().size()) { + NodeChildData child = targetField.getExecuteWith().get(index); + + ParameterSpec spec = getModel().getSpecification().findParameterSpec(child.getName()); + List specializationParams = getModel().findParameters(spec); + + if (specializationParams.isEmpty()) { + builder.defaultValue(parameter.getType()); + continue; + } + + ActualParameter specializationParam = specializationParams.get(0); TypeData targetType = parameter.getTypeSystemType(); TypeData sourceType = specializationParam.getTypeSystemType(); String localName = specializationParam.getLocalName(); + if (unexpectedParameter != null && unexpectedParameter.getLocalName().equals(specializationParam.getLocalName())) { localName = "ex.getResult()"; sourceType = getModel().getNode().getTypeSystem().getGenericTypeData(); diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java Tue Jun 04 11:01:20 2013 +0200 @@ -133,6 +133,16 @@ return parameters; } + public List findParameters(ParameterSpec spec) { + List foundParameters = new ArrayList<>(); + for (ActualParameter param : getReturnTypeAndParameters()) { + if (param.getSpecification().equals(spec)) { + foundParameters.add(param); + } + } + return foundParameters; + } + public ActualParameter findParameter(String valueName) { for (ActualParameter param : getReturnTypeAndParameters()) { if (param.getLocalName().equals(valueName)) { diff -r 6e0c6526334b -r 4249a3510413 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java Tue Jun 04 10:55:13 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java Tue Jun 04 11:01:20 2013 +0200 @@ -61,6 +61,6 @@ @Override public String toString() { - return "Function " + name + "@" + Integer.toHexString(hashCode()); + return "Function " + name; } } diff -r 6e0c6526334b -r 4249a3510413 make/build-graal.xml --- a/make/build-graal.xml Tue Jun 04 10:55:13 2013 +0200 +++ b/make/build-graal.xml Tue Jun 04 11:01:20 2013 +0200 @@ -42,6 +42,7 @@ + @@ -59,8 +60,8 @@ + - @@ -80,9 +81,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 6e0c6526334b -r 4249a3510413 mx/projects --- a/mx/projects Tue Jun 04 10:55:13 2013 +0200 +++ b/mx/projects Tue Jun 04 11:01:20 2013 +0200 @@ -100,7 +100,7 @@ project@com.oracle.graal.hotspot@sourceDirs=src project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.replacements,com.oracle.graal.printer project@com.oracle.graal.hotspot@checkstyle=com.oracle.graal.graph -project@com.oracle.graal.hotspot@annotationProcessors=com.oracle.graal.replacements.verifier, com.oracle.graal.service.processor +project@com.oracle.graal.hotspot@annotationProcessors=com.oracle.graal.replacements.verifier,com.oracle.graal.service.processor,com.oracle.graal.options project@com.oracle.graal.hotspot@javaCompliance=1.7 # graal.hotspot.amd64 @@ -138,6 +138,12 @@ project@com.oracle.graal.hotspot.amd64.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.amd64.test@javaCompliance=1.7 +# graal.options +project@com.oracle.graal.options@subDir=graal +project@com.oracle.graal.options@sourceDirs=src +project@com.oracle.graal.options@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.options@javaCompliance=1.7 + # graal.graph project@com.oracle.graal.graph@subDir=graal project@com.oracle.graal.graph@sourceDirs=src @@ -188,7 +194,7 @@ # graal.lir.sparc project@com.oracle.graal.lir.sparc@subDir=graal project@com.oracle.graal.lir.sparc@sourceDirs=src -project@com.oracle.graal.lir.sparc@dependencies=com.oracle.graal.asm.sparc,com.oracle.graal.sparc +project@com.oracle.graal.lir.sparc@dependencies=com.oracle.graal.asm.sparc project@com.oracle.graal.lir.sparc@checkstyle=com.oracle.graal.graph project@com.oracle.graal.lir.sparc@javaCompliance=1.7 @@ -273,10 +279,10 @@ # graal.compiler project@com.oracle.graal.compiler@subDir=graal project@com.oracle.graal.compiler@sourceDirs=src -project@com.oracle.graal.compiler@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.virtual,com.oracle.graal.loop,com.oracle.graal.alloc,com.oracle.graal.lir +project@com.oracle.graal.compiler@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.virtual,com.oracle.graal.options,com.oracle.graal.loop,com.oracle.graal.alloc,com.oracle.graal.lir project@com.oracle.graal.compiler@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler@javaCompliance=1.7 -project@com.oracle.graal.compiler@annotationProcessors=com.oracle.graal.service.processor +project@com.oracle.graal.compiler@annotationProcessors=com.oracle.graal.service.processor,com.oracle.graal.options # graal.compiler.amd64 project@com.oracle.graal.compiler.amd64@subDir=graal @@ -399,7 +405,7 @@ # graal.asm.sparc project@com.oracle.graal.asm.sparc@subDir=graal project@com.oracle.graal.asm.sparc@sourceDirs=src -project@com.oracle.graal.asm.sparc@dependencies=com.oracle.graal.hotspot +project@com.oracle.graal.asm.sparc@dependencies=com.oracle.graal.hotspot,com.oracle.graal.sparc project@com.oracle.graal.asm.sparc@checkstyle=com.oracle.graal.graph project@com.oracle.graal.asm.sparc@javaCompliance=1.7 diff -r 6e0c6526334b -r 4249a3510413 mxtool/mx --- a/mxtool/mx Tue Jun 04 10:55:13 2013 +0200 +++ b/mxtool/mx Tue Jun 04 11:01:20 2013 +0200 @@ -43,7 +43,7 @@ python_exe=python2.7 else type python2 > /dev/null 2>&1 - if [ $? -eq 0]; then + if [ $? -eq 0 ]; then python_exe=python2 else python_exe=python diff -r 6e0c6526334b -r 4249a3510413 mxtool/mx.py --- a/mxtool/mx.py Tue Jun 04 10:55:13 2013 +0200 +++ b/mxtool/mx.py Tue Jun 04 11:01:20 2013 +0200 @@ -1700,6 +1700,11 @@ try: zf = zipfile.ZipFile(tmp, 'w') for p in sorted_deps(d.deps): + # skip a Java project if its Java compliance level is "higher" than the configured JDK + if java().javaCompliance < p.javaCompliance: + log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, d.path)) + continue + outputDir = p.output_dir() for root, _, files in os.walk(outputDir): relpath = root[len(outputDir) + 1:]