# HG changeset patch # User Morris Meyer # Date 1369606588 14400 # Node ID 5aedcaed6ccf47d23a870ac7aa27b4b4f7148363 # Parent 26a4433252a301e89cc36c6870102dda7d686e02 Initial SPARC control instructions diff -r 26a4433252a3 -r 5aedcaed6ccf graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/AbstractSPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/AbstractSPARCAssembler.java Sun May 26 22:49:23 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/AbstractSPARCAssembler.java Sun May 26 18:16:28 2013 -0400 @@ -26,10 +26,11 @@ import com.oracle.graal.api.code.Register; import com.oracle.graal.api.code.TargetDescription; import com.oracle.graal.asm.AbstractAssembler; -import com.oracle.graal.asm.Label; public abstract class AbstractSPARCAssembler extends AbstractAssembler { + public static final String UNBOUND_TARGET = "L" + Integer.MAX_VALUE; + public AbstractSPARCAssembler(TargetDescription target) { super(target); } @@ -40,11 +41,6 @@ } @Override - public void jmp(Label l) { - // SPARC: Implement jump. - } - - @Override protected void patchJumpTarget(int branch, int jumpTarget) { // SPARC: Implement patching of jump target. } diff -r 26a4433252a3 -r 5aedcaed6ccf 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 Sun May 26 22:49:23 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java Sun May 26 18:16:28 2013 -0400 @@ -32,15 +32,6 @@ private final int displacement; /** - * Creates an {@link SPARCAddress} with given base register,and no displacement. - * - * @param base the base register - */ - public SPARCAddress(Register base) { - this(base, Register.None, 0); - } - - /** * Creates an {@link SPARCAddress} with given base register, no scaling and a given * displacement. * @@ -48,7 +39,9 @@ * @param displacement the displacement */ public SPARCAddress(Register base, int displacement) { - this(base, Register.None, displacement); + this.base = base; + this.displacement = displacement; + this.index = null; } /** @@ -57,12 +50,11 @@ * * @param base the base register * @param index the index register - * @param displacement the displacement */ - public SPARCAddress(Register base, Register index, int displacement) { + public SPARCAddress(Register base, Register index, int disp) { this.base = base; this.index = index; - this.displacement = displacement; + this.displacement = disp; } @Override diff -r 26a4433252a3 -r 5aedcaed6ccf 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 Sun May 26 22:49:23 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Sun May 26 18:16:28 2013 -0400 @@ -26,6 +26,7 @@ import com.oracle.graal.api.code.RegisterConfig; import com.oracle.graal.api.code.TargetDescription; import com.oracle.graal.api.meta.Kind; +import com.oracle.graal.asm.*; import com.oracle.graal.hotspot.HotSpotGraalRuntime; /** @@ -236,6 +237,26 @@ } } + public enum Op2s { + Bpr(3), + Fb(6), + Fbp(5), + Br(2), + Bp(1), + Cb(7), + Sethi(4); + + private final int value; + + private Op2s(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + public enum Op3s { Add(0x00, "add"), And(0x01, "and"), @@ -623,6 +644,59 @@ } } + public static class Bpa extends Fmt2c { + public Bpa(SPARCAssembler masm, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, Condition.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(), + Op2s.Bp.getValue(), CC.Icc.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(), + Op2s.Bp.getValue(), cc.getValue(), 1, simmm19); + } + public Bpe(SPARCAssembler masm, CC cc, Label label) { + super(masm, Ops.BranchOp.getValue(), 0, Condition.Equal.getValue(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpn extends Fmt2c { + public Bpn(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, Condition.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(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + public static class Bpne extends Fmt2c { + public Bpne(SPARCAssembler masm, CC cc, int simmm19) { + super(masm, Ops.BranchOp.getValue(), 0, Condition.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(), + Op2s.Bp.getValue(), cc.getValue(), 1, + label.isBound() ? label.position() : patchUnbound(masm, label)); + } + } + + private static int patchUnbound(SPARCAssembler masm, Label label) { + label.addPatchAt(masm.codeBuffer.position()); + return 0; + } + public static class Fadds extends Fmt3p { public Fadds(SPARCAssembler masm, Register src1, Register src2, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fadds.getValue(), @@ -725,6 +799,13 @@ } } + @Override + @SuppressWarnings("unused") + public void jmp(Label l) { + new Bpa(this, l); + } + + public static class Ld extends Fmt3b { public Ld(SPARCAssembler masm, SPARCAddress src, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Ldf.getValue(), diff -r 26a4433252a3 -r 5aedcaed6ccf graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/ControlSPARCTest.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/ControlSPARCTest.java Sun May 26 18:16:28 2013 -0400 @@ -0,0 +1,107 @@ +/* + * 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 org.junit.Test; + +import java.lang.reflect.Method; + +public class ControlSPARCTest extends SPARCTestBase { + + @Test + public void testControl() { + compile("testSwitch1I"); + // compile("testStatic"); + compile("testCall"); + compile("testLookupSwitch1I"); + } + + public static int testSwitch1I(int a) { + switch (a) { + case 1: + return 2; + case 2: + return 3; + default: + return 4; + } + } + + public static int testLookupSwitch1I(int a) { + switch (a) { + case 0: + return 1; + case 1: + return 2; + case 2: + return 3; + case 3: + return 1; + case 4: + return 2; + case 5: + return 3; + case 6: + return 1; + case 7: + return 2; + case 8: + return 3; + case 9: + return 1; + case 10: + return 2; + case 11: + return 3; + default: + return -1; + } + } + + @SuppressWarnings("unused") private static Object foo = null; + + public static boolean testStatic(Object o) { + foo = o; + return true; + } + + private static int method(int a, int b) { + return a + b; + } + + public static int testCall(@SuppressWarnings("unused") Object o, int a, int b) { + return method(a, b); + } + + public static void main(String[] args) { + ControlSPARCTest test = new ControlSPARCTest(); + for (Method m : ControlSPARCTest.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 26a4433252a3 -r 5aedcaed6ccf 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 Sun May 26 22:49:23 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Sun May 26 18:16:28 2013 -0400 @@ -23,8 +23,7 @@ package com.oracle.graal.compiler.sparc; -import static com.oracle.graal.api.code.ValueUtil.isRegister; -import static com.oracle.graal.api.code.ValueUtil.isStackSlot; +import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.sparc.SPARCArithmetic.*; import com.oracle.graal.api.code.CallingConvention; @@ -47,9 +46,15 @@ import com.oracle.graal.lir.LIRInstruction; import com.oracle.graal.lir.LabelRef; import com.oracle.graal.lir.Variable; +import com.oracle.graal.lir.StandardOp.*; +import com.oracle.graal.lir.sparc.*; import com.oracle.graal.lir.sparc.SPARCControlFlow.ReturnOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.SequentialSwitchOp; +import com.oracle.graal.lir.sparc.SPARCControlFlow.TableSwitchOp; +import com.oracle.graal.lir.sparc.SPARCMove.LoadOp; import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp; import com.oracle.graal.lir.sparc.SPARCMove.MoveToRegOp; +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; @@ -122,7 +127,7 @@ @Override public void emitJump(LabelRef label) { - throw new InternalError("NYI"); + append(new JumpOp(label)); } @Override @@ -170,7 +175,14 @@ @Override protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { - throw new InternalError("NYI"); + // Making a copy of the switch value is necessary because jump table destroys the input + // value + if (key.getKind() == Kind.Int || key.getKind() == Kind.Long) { + append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL)); + } else { + assert key.getKind() == Kind.Object : key.getKind(); + append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object))); + } } @Override @@ -180,7 +192,10 @@ @Override protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) { - throw new InternalError("NYI"); + // Making a copy of the switch value is necessary because jump table destroys the input + // value + Variable tmp = emitMove(key); + append(new TableSwitchOp(lowKey, defaultTarget, targets, tmp, newVariable(target.wordKind))); } @Override @@ -251,18 +266,68 @@ } @Override - public Value emitAddress(Value base, long displacement, Value index, int scale) { - throw new InternalError("NYI"); + public SPARCAddressValue emitAddress(Value base, long displacement, Value index, int scale) { + AllocatableValue baseRegister; + long finalDisp = displacement; + if (isConstant(base)) { + if (asConstant(base).isNull()) { + baseRegister = Value.ILLEGAL; + } else if (asConstant(base).getKind() != Kind.Object) { + finalDisp += asConstant(base).asLong(); + baseRegister = Value.ILLEGAL; + } else { + baseRegister = load(base); + } + } else { + baseRegister = asAllocatable(base); + } + + if (index != Value.ILLEGAL && scale != 0) { + if (isConstant(index)) { + finalDisp += asConstant(index).asLong() * scale; + } else { + Value indexRegister; + if (scale != 1) { + indexRegister = emitMul(index, Constant.forInt(scale)); + } else { + indexRegister = index; + } + + if (baseRegister == Value.ILLEGAL) { + baseRegister = asAllocatable(indexRegister); + } else { + Variable newBase = newVariable(Kind.Int); + emitMove(newBase, baseRegister); + baseRegister = newBase; + baseRegister = emitAdd(baseRegister, indexRegister); + } + } + } + + return new SPARCAddressValue(target().wordKind, baseRegister, (int) finalDisp); + } + + private SPARCAddressValue asAddress(Value address) { + if (address instanceof SPARCAddressValue) { + return (SPARCAddressValue) address; + } else { + return emitAddress(address, 0, Value.ILLEGAL, 0); + } } @Override - public Value emitLoad(Kind kind, Value address, DeoptimizingNode canTrap) { - throw new InternalError("NYI"); + public Variable emitLoad(Kind kind, Value address, DeoptimizingNode deopting) { + SPARCAddressValue loadAddress = asAddress(address); + Variable result = newVariable(kind); + append(new LoadOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); + return result; } @Override - public void emitStore(Kind kind, Value address, Value input, DeoptimizingNode canTrap) { - throw new InternalError("NYI"); + public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) { + SPARCAddressValue storeAddress = asAddress(address); + Variable input = load(inputVal); + append(new StoreOp(kind, storeAddress, input, deopting != null ? state(deopting) : null)); } @Override @@ -290,7 +355,7 @@ } @Override - public Value emitAdd(Value a, Value b) { + public Variable emitAdd(Value a, Value b) { Variable result = newVariable(a.getKind()); switch (a.getKind()) { case Int: diff -r 26a4433252a3 -r 5aedcaed6ccf graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCAddressValue.java Sun May 26 18:16:28 2013 -0400 @@ -0,0 +1,64 @@ +/* + * 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.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.lir.*; +import com.oracle.graal.lir.LIRInstruction.*; + +public class SPARCAddressValue extends CompositeValue { + + private static final long serialVersionUID = -3583286416638228207L; + + @Component({ REG, OperandFlag.ILLEGAL }) + protected AllocatableValue base; + @Component({ REG, OperandFlag.ILLEGAL }) + protected AllocatableValue index; + protected final int displacement; + + public SPARCAddressValue(PlatformKind kind, AllocatableValue baseRegister, + int finalDisp) { + super(kind); + this.base = baseRegister; + this.displacement = finalDisp; + } + + private static Register toRegister(AllocatableValue value) { + if (value.equals(Value.ILLEGAL)) { + return Register.None; + } else { + RegisterValue reg = (RegisterValue) value; + return reg.getRegister(); + } + } + + public SPARCAddress toAddress() { + return new SPARCAddress(toRegister(base), toRegister(index), + displacement); + } + +} diff -r 26a4433252a3 -r 5aedcaed6ccf 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 Sun May 26 22:49:23 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Sun May 26 18:16:28 2013 -0400 @@ -22,17 +22,29 @@ */ 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.code.*; +import com.oracle.graal.api.code.CompilationResult.*; import com.oracle.graal.api.meta.*; +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.Bpe; +import com.oracle.graal.asm.sparc.SPARCAssembler.Subcc; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.sparc.SPARC; public class SPARCControlFlow { 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; @@ -46,4 +58,140 @@ // masm.return(); } } + + public static class SequentialSwitchOp extends SPARCLIRInstruction + implements FallThroughOp { + + @Use({ CONST }) + protected Constant[] keyConstants; + private final LabelRef[] keyTargets; + private LabelRef defaultTarget; + @Alive({ REG }) + protected Value key; + @Temp({ REG, ILLEGAL }) + protected 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; + this.defaultTarget = defaultTarget; + this.key = key; + this.scratch = scratch; + } + + @Override + @SuppressWarnings("unused") + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + if (key.getKind() == Kind.Int) { + Register intKey = asIntReg(key); + for (int i = 0; i < keyConstants.length; i++) { + if (tasm.runtime.needsDataPatch(keyConstants[i])) { + tasm.recordDataReferenceInCode(keyConstants[i], 0, true); + } + long lc = keyConstants[i].asLong(); + assert NumUtil.isInt(lc); + new Subcc(masm, intKey, (int) lc, SPARC.r0); // CMP + Label l = keyTargets[i].label(); + l.addPatchAt(tasm.asm.codeBuffer.position()); + new Bpe(masm, CC.Icc, l); + } + } else if (key.getKind() == Kind.Long) { + Register longKey = asLongReg(key); + for (int i = 0; i < keyConstants.length; i++) { + // masm.setp_eq_s64(tasm.asLongConst(keyConstants[i]), + // longKey); + // masm.at(); + Label l = keyTargets[i].label(); + l.addPatchAt(tasm.asm.codeBuffer.position()); + new Bpe(masm, CC.Xcc, l); + } + } else if (key.getKind() == Kind.Object) { + 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]); + 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"); + } + if (defaultTarget != null) { + masm.jmp(defaultTarget.label()); + } else { + // masm.hlt(); + } + } + + @Override + public LabelRef fallThroughTarget() { + return defaultTarget; + } + + @Override + public void setFallThroughTarget(LabelRef target) { + defaultTarget = target; + } + } + + 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; + + public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, + final LabelRef[] targets, Variable index, Variable scratch) { + this.lowKey = lowKey; + this.defaultTarget = defaultTarget; + this.targets = targets; + this.index = index; + this.scratch = scratch; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + 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) { + Buffer buf = masm.codeBuffer; + // Compare index against jump table bounds + int highKey = lowKey + targets.length - 1; + if (lowKey != 0) { + // subtract the low value from the switch value + // masm.sub_s32(value, value, lowKey); + // masm.setp_gt_s32(value, highKey - lowKey); + } else { + // masm.setp_gt_s32(value, highKey); + } + + // Jump to default target if index is not within the jump table + if (defaultTarget != null) { + // masm.at(); + // masm.bra(defaultTarget.label().toString()); + } + + // address of jump table + int tablePos = buf.position(); + + JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4); + tasm.compilationResult.addAnnotation(jt); + + // SPARC: unimp: tableswitch extract + } } diff -r 26a4433252a3 -r 5aedcaed6ccf 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 Sun May 26 22:49:23 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Sun May 26 18:16:28 2013 -0400 @@ -25,22 +25,112 @@ 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.lir.LIRInstruction.OperandFlag.CONST; -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.HINT; -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG; -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.STACK; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import com.oracle.graal.api.meta.AllocatableValue; -import com.oracle.graal.api.meta.Constant; -import com.oracle.graal.api.meta.Value; -import com.oracle.graal.asm.sparc.SPARCAssembler; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.*; import com.oracle.graal.graph.GraalInternalError; -import com.oracle.graal.lir.LIRInstruction.Opcode; +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; public class SPARCMove { + public static class LoadOp extends SPARCLIRInstruction { + + private final Kind kind; + @Def({REG}) protected AllocatableValue result; + @Use({COMPOSITE}) protected SPARCAddressValue address; + @State protected LIRFrameState state; + + public LoadOp(Kind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state) { + this.kind = kind; + this.result = result; + this.address = address; + this.state = state; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + @SuppressWarnings("unused") SPARCAddress addr = address.toAddress(); + switch (kind) { + case Byte: + // masm.ld_global_s8(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Short: + // masm.ld_global_s16(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Char: + // masm.ld_global_u16(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Int: + // masm.ld_global_s32(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Long: + // masm.ld_global_s64(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Float: + // masm.ld_global_f32(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Double: + // masm.ld_global_f64(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Object: + // masm.ld_global_u32(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + + 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 + 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()); + } + } + } + @Opcode("MOVE") public static class MoveToRegOp extends SPARCLIRInstruction implements MoveOp { diff -r 26a4433252a3 -r 5aedcaed6ccf make/build-graal.xml --- a/make/build-graal.xml Sun May 26 22:49:23 2013 +0200 +++ b/make/build-graal.xml Sun May 26 18:16:28 2013 -0400 @@ -60,6 +60,7 @@ + diff -r 26a4433252a3 -r 5aedcaed6ccf mx/projects --- a/mx/projects Sun May 26 22:49:23 2013 +0200 +++ b/mx/projects Sun May 26 18:16:28 2013 -0400 @@ -188,7 +188,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 +project@com.oracle.graal.lir.sparc@dependencies=com.oracle.graal.asm.sparc,com.oracle.graal.sparc project@com.oracle.graal.lir.sparc@checkstyle=com.oracle.graal.graph project@com.oracle.graal.lir.sparc@javaCompliance=1.7 @@ -316,7 +316,7 @@ # graal.compiler.sparc.test project@com.oracle.graal.compiler.sparc.test@subDir=graal project@com.oracle.graal.compiler.sparc.test@sourceDirs=src -project@com.oracle.graal.compiler.sparc.test@dependencies=com.oracle.graal.compiler.sparc,com.oracle.graal.compiler.test,com.oracle.graal.sparc +project@com.oracle.graal.compiler.sparc.test@dependencies=com.oracle.graal.compiler.sparc,com.oracle.graal.compiler.test project@com.oracle.graal.compiler.sparc.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler.sparc.test@javaCompliance=1.7