# HG changeset patch # User Morris Meyer # Date 1369590256 14400 # Node ID 81d5d8089cda070c4620df51e3703b4041048253 # Parent 6fa4b4933892ab23361929bc7a0db6849eeb86ac SPARC float arithmetic diff -r 6fa4b4933892 -r 81d5d8089cda graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java Sun May 26 13:44:16 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.asm.sparc; + +import com.oracle.graal.api.code.AbstractAddress; +import com.oracle.graal.api.code.Register; + +public class SPARCAddress extends AbstractAddress { + + private final Register base; + private final Register index; + 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. + * + * @param base the base register + * @param displacement the displacement + */ + public SPARCAddress(Register base, int displacement) { + this(base, Register.None, displacement); + } + + /** + * 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 + * @param displacement the displacement + */ + public SPARCAddress(Register base, Register index, int displacement) { + this.base = base; + this.index = index; + this.displacement = displacement; + } + + @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 = " + "; + } + s.append("]"); + return s.toString(); + } + + /** + * @return Base register that defines the start of the address computation. If not present, is + * denoted by {@link Register#None}. + */ + public Register getBase() { + return base; + } + + /** + * @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() { + return displacement; + } +} diff -r 6fa4b4933892 -r 81d5d8089cda 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 13:15:51 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Sun May 26 13:44:16 2013 -0400 @@ -305,7 +305,16 @@ Save(0x3c, "save"), Restore(0x3d, "restore"), Done(0x3e, "done"), - Retry(0x3e, "retry"); + Retry(0x3e, "retry"), + + Ldf(0x20, "ldf"), + Ldfsr(0x21, "ldfsr"), + Ldaf(0x22, "ldaf"), + Lddf(0x23, "lddf"), + Stf(0x24, "stf"), + Stfsr(0x25, "stfsr"), + Staf(0x26, "staf"), + Stdf(0x27, "stdf"); private final int value; private final String operator; @@ -325,12 +334,31 @@ } public enum Opfs { + Fmovs(0x01, "fmovs"), + Fmovd(0x02, "fmovd"), + Fmovq(0x03, "fmovq"), + Fnegs(0x05, "fnegs"), + Fnegd(0x06, "fnegd"), + Fnegq(0x07, "fnegq"), + Fabss(0x09, "fabss"), + Fabsd(0x0A, "fabsd"), + Fabsq(0x0B, "fabsq"), Fadds(0x41, "fadds"), Faddd(0x42, "faddd"), Faddq(0x43, "faddq"), Fsubs(0x45, "fsubs"), Fsubd(0x46, "fsubd"), Fsubq(0x47, "fsubq"), + Fmuls(0x49, "fmuls"), + Fmuld(0x4A, "fmuld"), + Fdivs(0x4C, "fdivs"), + Fdivd(0x4D, "fdivd"), + Fdivq(0x4E, "fdivq"), + + Fsmuld(0x69, "fsmuld"), + Fmulq(0x6B, "fmulq"), + Fdmuldq(0x6E, "fdmulq"), + Fstoi(0xD1, "fstoi"), Fdtoi(0xD2, "fdtoi"); @@ -616,6 +644,48 @@ } } + public static class Fdivs extends Fmt3p { + public Fdivs(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdivs.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fdivd extends Fmt3p { + public Fdivd(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdivd.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fmuls extends Fmt3p { + public Fmuls(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fmuls.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fmuld extends Fmt3p { + public Fmuld(SPARCAssembler masm, Register src1, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fmuld.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fnegs extends Fmt3n { + public Fnegs(SPARCAssembler masm, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegs.getValue(), + src2.encoding(), dst.encoding()); + } + } + + public static class Fnegd extends Fmt3n { + public Fnegd(SPARCAssembler masm, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegd.getValue(), + src2.encoding(), dst.encoding()); + } + } + public static class Fstoi extends Fmt3n { public Fstoi(SPARCAssembler masm, Register src2, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fstoi.getValue(), @@ -655,6 +725,13 @@ } } + public static class Ld extends Fmt3b { + public Ld(SPARCAssembler masm, SPARCAddress src, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Ldf.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()); diff -r 6fa4b4933892 -r 81d5d8089cda graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/FloatSPARCTest.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/FloatSPARCTest.java Sun May 26 13:44:16 2013 -0400 @@ -0,0 +1,241 @@ +/* + * 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 FloatSPARCTest extends SPARCTestBase { + + @Test + public void testAdd() { + compile("testAdd2F"); + compile("testAdd2D"); + // compile("testAddFConst"); + // compile("testAddConstF"); + // compile("testAddDConst"); + // compile("testAddConstD"); + } + + public static float testAdd2F(float a, float b) { + return a + b; + } + + public static double testAdd2D(double a, double b) { + return a + b; + } + + public static float testAddFConst(float a) { + return a + 32.0F; + } + + public static float testAddConstF(float a) { + return 32.0F + a; + } + + public static double testAddDConst(double a) { + return a + 32.0; + } + + public static double testAddConstD(double a) { + return 32.0 + a; + } + + @Test + public void testSub() { + compile("testSub2F"); + compile("testSub2D"); + // compile("testSubFConst"); + // compile("testSubConstF"); + // compile("testSubDConst"); + // compile("testSubConstD"); + } + + public static float testSub2F(float a, float b) { + return a - b; + } + + public static double testSub2D(double a, double b) { + return a - b; + } + + public static float testSubFConst(float a) { + return a - 32.0F; + } + + public static float testSubConstF(float a) { + return 32.0F - a; + } + + public static double testSubDConst(double a) { + return a - 32.0; + } + + public static double testSubConstD(double a) { + return 32.0 - a; + } + + @Test + public void testMul() { + compile("testMul2F"); + compile("testMul2D"); + // compile("testMulFConst"); + // compile("testMulConstF"); + // compile("testMulDConst"); + // compile("testMulConstD"); + } + + public static float testMul2F(float a, float b) { + return a * b; + } + + public static double testMul2D(double a, double b) { + return a * b; + } + + public static float testMulFConst(float a) { + return a * 32.0F; + } + + public static float testMulConstF(float a) { + return 32.0F * a; + } + + public static double testMulDConst(double a) { + return a * 32.0; + } + + public static double testMulConstD(double a) { + return 32.0 * a; + } + + @Test + public void testDiv() { + compile("testDiv2F"); + compile("testDiv2D"); + // compile("testDivFConst"); + // compile("testDivConstF"); + // compile("testDivDConst"); + // compile("testDivConstD"); + } + + public static float testDiv2F(float a, float b) { + return a / b; + } + + public static double testDiv2D(double a, double b) { + return a / b; + } + + public static float testDivFConst(float a) { + return a / 32.0F; + } + + public static float testDivConstF(float a) { + return 32.0F / a; + } + + public static double testDivDConst(double a) { + return a / 32.0; + } + + public static double testDivConstD(double a) { + return 32.0 / a; + } + + @Test + public void testNeg() { + compile("testNeg2F"); + compile("testNeg2D"); + } + + public static float testNeg2F(float a) { + return -a; + } + + public static double testNeg2D(double a) { + return -a; + } + + @Test + public void testRem() { + // need linkage to PTX remainder() + // compile("testRem2F"); + // compile("testRem2D"); + } + + public static float testRem2F(float a, float b) { + return a % b; + } + + public static double testRem2D(double a, double b) { + return a % b; + } + + @Test + public void testFloatConversion() { + // compile("testF2I"); + // compile("testF2L"); + // compile("testF2D"); + // compile("testD2I"); + // compile("testD2L"); + // compile("testD2F"); + } + + public static int testF2I(float a) { + return (int) a; + } + + public static long testF2L(float a) { + return (long) a; + } + + public static double testF2D(float a) { + return a; + } + + public static int testD2I(double a) { + return (int) a; + } + + public static long testD2L(double a) { + return (long) a; + } + + public static float testD2F(double a) { + return (float) a; + } + + public static void main(String[] args) { + FloatSPARCTest test = new FloatSPARCTest(); + for (Method m : FloatSPARCTest.class.getMethods()) { + String name = m.getName(); + if (m.getAnnotation(Test.class) == null && name.startsWith("test") && name.startsWith("testRem") == false) { + // CheckStyle: stop system..print check + System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); + // CheckStyle: resume system..print check + } + } + } +} diff -r 6fa4b4933892 -r 81d5d8089cda 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 13:15:51 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Sun May 26 13:44:16 2013 -0400 @@ -127,7 +127,10 @@ @Override public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) { - throw new InternalError("NYI"); + switch (left.getKind().getStackKind()) { + default: + throw GraalInternalError.shouldNotReachHere("" + left.getKind()); + } } @Override @@ -269,7 +272,21 @@ @Override public Value emitNegate(Value input) { - throw new InternalError("NYI"); + Variable result = newVariable(input.getKind()); + switch (input.getKind()) { + case Int: + append(new Op1Stack(INEG, result, input)); + break; + case Float: + append(new Op1Stack(FNEG, result, input)); + break; + case Double: + append(new Op1Stack(DNEG, result, input)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override diff -r 6fa4b4933892 -r 81d5d8089cda 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 Sun May 26 13:15:51 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Sun May 26 13:44:16 2013 -0400 @@ -26,9 +26,17 @@ import static com.oracle.graal.asm.sparc.SPARCAssembler.Add; import static com.oracle.graal.asm.sparc.SPARCAssembler.And; import static com.oracle.graal.asm.sparc.SPARCAssembler.Fadds; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Faddd; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fdivs; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fdivd; import static com.oracle.graal.asm.sparc.SPARCAssembler.Fdtoi; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fmuls; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fmuld; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fnegs; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fnegd; import static com.oracle.graal.asm.sparc.SPARCAssembler.Fstoi; import static com.oracle.graal.asm.sparc.SPARCAssembler.Fsubs; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Fsubd; import static com.oracle.graal.asm.sparc.SPARCAssembler.Mulx; import static com.oracle.graal.asm.sparc.SPARCAssembler.Or; import static com.oracle.graal.asm.sparc.SPARCAssembler.Sdivx; @@ -48,29 +56,26 @@ 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, + 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; - /** - * Unary operation with separate source and destination operand. + * 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) { + public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, + AllocatableValue x) { this.opcode = opcode; this.result = result; this.x = x; @@ -84,14 +89,18 @@ } /** - * Unary operation with single operand for source and destination. + * Unary operation with single operand for source and destination. */ 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) { + public Unary1Op(SPARCArithmetic opcode, AllocatableValue result, + AllocatableValue x) { this.opcode = opcode; this.result = result; this.x = x; @@ -104,9 +113,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; @@ -121,10 +133,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; @@ -146,10 +162,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; @@ -171,10 +191,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; @@ -197,81 +221,108 @@ } @SuppressWarnings("unused") - protected static void emit(SPARCAssembler masm, SPARCArithmetic opcode, Value result) { + 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 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); } } @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)) { - if (is_simm13(tasm.asIntConst(src1))) { - switch (opcode) { - case ISUB: - new Add(masm, asIntReg(src2), -(tasm.asIntConst(src1)), asIntReg(dst)); - break; - case IAND: throw new InternalError("NYI"); - case IDIV: - 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 { + 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(); } } else if (isConstant(src2)) { - if (is_simm13(tasm.asIntConst(src2))) { - switch (opcode) { - case IADD: - new Add(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case ISUB: - new Sub(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case IMUL: - new Mulx(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case IAND: - new And(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case ISHL: - new Sll(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case ISHR: - new Srl(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); - break; - case IUSHR: - 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(); - } - } else { + 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(); } } else { switch (opcode) { @@ -305,7 +356,8 @@ case IUSHR: new Sra(masm, asIntReg(src1), asIntReg(src2), asIntReg(dst)); break; - case IREM: throw new InternalError("NYI"); + case IREM: + throw new InternalError("NYI"); case LADD: new Add(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; @@ -316,7 +368,8 @@ new Mulx(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); break; case LDIV: - new Sdivx(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); + new Sdivx(masm, asLongReg(src1), asLongReg(src2), + asLongReg(dst)); break; case LAND: new And(masm, asLongReg(src1), asLongReg(src2), asLongReg(dst)); @@ -336,23 +389,47 @@ case LUSHR: new Sra(masm, asLongReg(src1), asLongReg(src2), asIntReg(dst)); break; - case LREM: throw new InternalError("NYI"); + case LREM: + throw new InternalError("NYI"); case FADD: - new Fadds(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)); + new Fadds(masm, asFloatReg(src1), asFloatReg(src2), + asFloatReg(dst)); break; case FSUB: - new Fsubs(masm, asFloatReg(src1), asFloatReg(src2), asFloatReg(dst)); + 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 FMUL: throw new InternalError("NYI"); - case FDIV: throw new InternalError("NYI"); - case FREM: throw new InternalError("NYI"); - case DADD: throw new InternalError("NYI"); - case DSUB: throw new InternalError("NYI"); - case DMUL: throw new InternalError("NYI"); - case DDIV: throw new InternalError("NYI"); - case DREM: throw new InternalError("NYI"); + 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); + throw GraalInternalError.shouldNotReachHere("missing: " + + opcode); } } @@ -363,36 +440,45 @@ } @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; - 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; + 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); } } @@ -402,19 +488,34 @@ } } - private static final int max13 = ((1 << 12) - 1); + private static final int max13 = ((1 << 12) - 1); private static final int min13 = -(1 << 12); private static boolean is_simm13(int src) { return min13 <= src && src <= max13; } - 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()); + private static void verifyKind(SPARCArithmetic opcode, Value result, + Value x, Value y) { + String name = opcode.name(); + if (((name.startsWith("I") && result.getKind() == Kind.Int + && x.getKind().getStackKind() == Kind.Int + && y.getKind().getStackKind() == Kind.Int) + || (name.startsWith("L") + && result.getKind() == Kind.Long + && x.getKind() == Kind.Long + && y.getKind() == Kind.Long) + || (name.startsWith("F") + && result.getKind() == Kind.Float + && x.getKind() == Kind.Float + && y.getKind() == Kind.Float) + || (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()); } } }