# HG changeset patch # User Morris Meyer # Date 1369513445 14400 # Node ID 26960d32552c962d8f17c3b8d52bb7ff18b23941 # Parent 4e98540865326c4b2b60777855dd675a1d5696c9 SPARC integer arithmetic diff -r 4e9854086532 -r 26960d32552c 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 Fri May 24 22:51:36 2013 -0400 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Sat May 25 16:24:05 2013 -0400 @@ -169,6 +169,18 @@ } } + public static class Fmt3n { + public Fmt3n(SPARCAssembler masm, int op, int op3, int opf, int rs2, int rd) { + assert op == 2 || op == 3; + assert op3 >= 0 && op3 < 0x40; + assert opf >= 0 && opf < 0x200; + assert rs2 >= 0 && rs2 < 0x20; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | opf << 5 | rs2); + } + } + public static class Fmt3q { public Fmt3q(SPARCAssembler masm, int op, int op3, int rs1, int rd) { assert op == 2 || op == 3; @@ -313,12 +325,14 @@ } public enum Opfs { - Fadds((0x41 << 5) & 0x00003FE0, "fadds"), - Faddd((0x42 << 5) & 0x00003FE0, "faddd"), - Faddq((0x43 << 5) & 0x00003FE0, "faddq"), - Fsubs((0x45 << 5) & 0x00003FE0, "fsubs"), - Fsubd((0x46 << 5) & 0x00003FE0, "fsubd"), - Fsubq((0x47 << 5) & 0x00003FE0, "fsubq"); + Fadds(0x41, "fadds"), + Faddd(0x42, "faddd"), + Faddq(0x43, "faddq"), + Fsubs(0x45, "fsubs"), + Fsubd(0x46, "fsubd"), + Fsubq(0x47, "fsubq"), + Fstoi(0xD1, "fstoi"), + Fdtoi(0xD2, "fdtoi"); private final int value; private final String operator; @@ -602,6 +616,20 @@ } } + 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(), + src2.encoding(), dst.encoding()); + } + } + + public static class Fdtoi extends Fmt3n { + public Fdtoi(SPARCAssembler masm, Register src2, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdtoi.getValue(), + src2.encoding(), dst.encoding()); + } + } + public final void flushw() { emitInt(Ops.ArithOp.getValue() | Op3s.Flushw.getValue()); } diff -r 4e9854086532 -r 26960d32552c graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/IntegerSPARCTest.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/IntegerSPARCTest.java Sat May 25 16:24:05 2013 -0400 @@ -0,0 +1,182 @@ +/* + * 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.Ignore; +import org.junit.Test; + +import java.lang.reflect.Method; + +public class IntegerSPARCTest extends SPARCTestBase { + + @Test + public void testAdd() { + compile("testAdd2I"); + compile("testAdd2L"); + compile("testAdd2B"); + compile("testAddIConst"); + compile("testAddConstI"); + } + + public static int testAdd2I(int a, int b) { + return a + b; + } + + public static long testAdd2L(long a, long b) { + return a + b; + } + + public static int testAdd2B(byte a, byte b) { + return a + b; + } + + public static int testAddIConst(int a) { + return a + 32; + } + + public static int testAddConstI(int a) { + return 32 + a; + } + + @Test + public void testSub() { + compile("testSub2I"); + compile("testSub2L"); + compile("testSubIConst"); + compile("testSubConstI"); + } + + public static int testSub2I(int a, int b) { + return a - b; + } + + public static long testSub2L(long a, long b) { + return a - b; + } + + public static int testSubIConst(int a) { + return a - 32; + } + + public static int testSubConstI(int a) { + return 32 - a; + } + + @Test + public void testMul() { + compile("testMul2I"); + compile("testMul2L"); + compile("testMulIConst"); + compile("testMulConstI"); + } + + public static int testMul2I(int a, int b) { + return a * b; + } + + public static long testMul2L(long a, long b) { + return a * b; + } + + public static int testMulIConst(int a) { + return a * 32; + } + + public static int testMulConstI(int a) { + return 32 * a; + } + + @Test + public void testDiv() { + compile("testDiv2I"); + compile("testDiv2L"); + compile("testDivIConst"); + } + + public static int testDiv2I(int a, int b) { + return a / b; + } + + public static long testDiv2L(long a, long b) { + return a / b; + } + + public static int testDivIConst(int a) { + return a / 32; + } + + @Ignore + public void testRem() { + compile("testRem2I"); + compile("testRem2L"); + } + + public static int testRem2I(int a, int b) { + return a % b; + } + + public static long testRem2L(long a, long b) { + return a % b; + } + + @Test + public void testIntConversion() { + compile("testI2L"); + compile("testI2C"); + compile("testI2B"); + compile("testI2F"); + compile("testI2D"); + } + + public static long testI2L(int a) { + return a; + } + + public static char testI2C(int a) { + return (char) a; + } + + public static byte testI2B(int a) { + return (byte) a; + } + + public static float testI2F(int a) { + return a; + } + + public static double testI2D(int a) { + return a; + } + + public static void main(String[] args) { + IntegerSPARCTest test = new IntegerSPARCTest(); + for (Method m : IntegerSPARCTest.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 4e9854086532 -r 26960d32552c 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 Fri May 24 22:51:36 2013 -0400 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Sat May 25 16:24:05 2013 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -25,10 +25,7 @@ import static com.oracle.graal.api.code.ValueUtil.isRegister; import static com.oracle.graal.api.code.ValueUtil.isStackSlot; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.DADD; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.FADD; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.IADD; -import static com.oracle.graal.lir.sparc.SPARCArithmetic.LADD; +import static com.oracle.graal.lir.sparc.SPARCArithmetic.*; import com.oracle.graal.api.code.CallingConvention; import com.oracle.graal.api.code.CodeCacheProvider; @@ -40,7 +37,7 @@ 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.asm.*; +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; @@ -53,7 +50,10 @@ import com.oracle.graal.lir.sparc.SPARCControlFlow.ReturnOp; import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp; import com.oracle.graal.lir.sparc.SPARCMove.MoveToRegOp; +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.nodes.BreakpointNode; import com.oracle.graal.nodes.DeoptimizingNode; import com.oracle.graal.nodes.DirectCallTargetNode; @@ -296,23 +296,84 @@ @Override public Value emitSub(Value a, Value b) { - throw new InternalError("NYI"); + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(ISUB, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Stack(LSUB, result, a, loadNonConst(b))); + break; + case Float: + append(new Op2Stack(FSUB, result, a, loadNonConst(b))); + break; + case Double: + append(new Op2Stack(DSUB, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override public Value emitMul(Value a, Value b) { - throw new InternalError("NYI"); + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Reg(IMUL, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Reg(LMUL, result, a, loadNonConst(b))); + break; + case Float: + append(new Op2Stack(FMUL, result, a, loadNonConst(b))); + break; + case Double: + append(new Op2Stack(DMUL, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override public Value emitDiv(Value a, Value b, DeoptimizingNode deopting) { - // SPARC: Auto-generated method stub - return null; + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Reg(IDIV, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Reg(LDIV, result, a, loadNonConst(b))); + break; + case Float: + append(new Op2Stack(FDIV, result, a, loadNonConst(b))); + break; + case Double: + append(new Op2Stack(DDIV, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override public Value emitRem(Value a, Value b, DeoptimizingNode deopting) { - throw new InternalError("NYI"); + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Reg(IREM, result, a, loadNonConst(b))); + break; + case Long: + append(new Op2Reg(LREM, result, a, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + a.getKind()); + } + return result; } @Override @@ -342,22 +403,124 @@ @Override public Value emitShl(Value a, Value b) { - throw new InternalError("NYI"); + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(ISHL, result, a, loadNonConst(b))); + break; + case Long: + append(new Op1Stack(LSHL, result, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override public Value emitShr(Value a, Value b) { - throw new InternalError("NYI"); + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new Op2Stack(ISHR, result, a, loadNonConst(b))); + break; + case Long: + append(new Op1Stack(LSHR, result, loadNonConst(b))); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override public Value emitUShr(Value a, Value b) { - throw new InternalError("NYI"); + Variable result = newVariable(a.getKind()); + switch (a.getKind()) { + case Int: + append(new ShiftOp(IUSHR, result, a, b)); + break; + case Long: + append(new ShiftOp(LUSHR, result, a, b)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override public Value emitConvert(Op opcode, Value inputVal) { - throw new InternalError("NYI"); + Variable input = load(inputVal); + Variable result = newVariable(opcode.to); + switch (opcode) { + case I2L: + append(new Unary2Op(I2L, result, input)); + break; + case L2I: + append(new Unary1Op(L2I, result, input)); + break; + case I2B: + append(new Unary2Op(I2B, result, input)); + break; + case I2C: + append(new Unary1Op(I2C, result, input)); + break; + case I2S: + append(new Unary2Op(I2S, result, input)); + break; + case F2D: + append(new Unary2Op(F2D, result, input)); + break; + case D2F: + append(new Unary2Op(D2F, result, input)); + break; + case I2F: + append(new Unary2Op(I2F, result, input)); + break; + case I2D: + append(new Unary2Op(I2D, result, input)); + break; + case F2I: + append(new Unary2Op(F2I, result, input)); + break; + case D2I: + append(new Unary2Op(D2I, result, input)); + break; + case L2F: + append(new Unary2Op(L2F, result, input)); + break; + case L2D: + append(new Unary2Op(L2D, result, input)); + break; + case F2L: + append(new Unary2Op(F2L, result, input)); + break; + case D2L: + append(new Unary2Op(D2L, result, input)); + break; + case MOV_I2F: + append(new Unary2Op(MOV_I2F, result, input)); + break; + case MOV_L2D: + append(new Unary2Op(MOV_L2D, result, input)); + break; + case MOV_F2I: + append(new Unary2Op(MOV_F2I, result, input)); + break; + case MOV_D2L: + append(new Unary2Op(MOV_D2L, result, input)); + break; + case UNSIGNED_I2L: + // Instructions that move or generate 32-bit register values also set the upper 32 + // bits of the register to zero. + // Consequently, there is no need for a special zero-extension move. + emitMove(result, input); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return result; } @Override diff -r 4e9854086532 -r 26960d32552c graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Fri May 24 22:51:36 2013 -0400 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Sat May 25 16:24:05 2013 -0400 @@ -22,21 +22,12 @@ */ package com.oracle.graal.lir.sparc; -import static com.oracle.graal.api.code.ValueUtil.asFloatReg; -import static com.oracle.graal.api.code.ValueUtil.asIntReg; -import static com.oracle.graal.api.code.ValueUtil.asLongReg; -import static com.oracle.graal.api.code.ValueUtil.isConstant; -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 com.oracle.graal.api.meta.Kind; -import com.oracle.graal.api.meta.Value; -import com.oracle.graal.asm.sparc.SPARCAssembler; +import static com.oracle.graal.api.code.ValueUtil.*; 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.Fdtoi; +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.Mulx; import static com.oracle.graal.asm.sparc.SPARCAssembler.Or; @@ -46,7 +37,13 @@ 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.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 com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.SPARCAssembler; import com.oracle.graal.graph.GraalInternalError; import com.oracle.graal.lir.LIRFrameState; import com.oracle.graal.lir.asm.TargetMethodAssembler; @@ -64,6 +61,65 @@ L2F, L2D, F2L, D2L, MOV_I2F, MOV_L2D, MOV_F2I, MOV_D2L; + + /** + * 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; + + public Unary2Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) { + this.opcode = opcode; + this.result = result; + this.x = x; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + SPARCMove.move(tasm, masm, result, x); + emit(tasm, masm, opcode, result, x, null); + } + } + + /** + * 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; + + public Unary1Op(SPARCArithmetic opcode, AllocatableValue result, AllocatableValue x) { + this.opcode = opcode; + this.result = result; + this.x = x; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + emit(masm, opcode, result); + } + } + + public static class Op1Stack extends SPARCLIRInstruction { + @Opcode private final SPARCArithmetic opcode; + @Def({REG, HINT}) protected Value result; + @Use({REG, STACK, CONST}) protected Value x; + + public Op1Stack(SPARCArithmetic opcode, Value result, Value x) { + this.opcode = opcode; + this.result = result; + this.x = x; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + emit(tasm, masm, opcode, result, x, null); + } + } + public static class Op2Stack extends SPARCLIRInstruction { @Opcode private final SPARCArithmetic opcode; @Def({REG, HINT}) protected Value result; @@ -89,19 +145,92 @@ } } + 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; + + public Op2Reg(SPARCArithmetic opcode, Value result, Value x, Value y) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + emit(tasm, masm, opcode, result, x, y, null); + } + + @Override + public void verify() { + super.verify(); + verifyKind(opcode, result, x, y); + } + } + + 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; + + public ShiftOp(SPARCArithmetic opcode, Value result, Value x, Value y) { + this.opcode = opcode; + this.result = result; + this.x = x; + this.y = y; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { + emit(tasm, masm, opcode, result, x, y, null); + } + + @Override + public void verify() { + super.verify(); + verifyKind(opcode, result, x, x); + assert y.getKind().getStackKind() == Kind.Int; + } + } + 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); + } + } + + 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: throw new InternalError("NYI"); - case IAND: throw new InternalError("NYI"); - case IDIV: throw new InternalError("NYI"); - 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(); + 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 { + throw new InternalError("NYI"); } } else if (isConstant(src2)) { if (is_simm13(tasm.asIntConst(src2))) { @@ -118,9 +247,15 @@ case IAND: new And(masm, asIntReg(src1), tasm.asIntConst(src2), asIntReg(dst)); break; - case ISHL: throw new InternalError("NYI"); - case ISHR: throw new InternalError("NYI"); - case IUSHR: throw new InternalError("NYI"); + 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"); @@ -225,6 +360,45 @@ } } + 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); + } + } else if (isConstant(src)) { + switch (opcode) { + default: + throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + } + } else { + switch (opcode) { + default: + throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + } + } + + if (info != null) { + assert exceptionOffset != -1; + tasm.recordImplicitException(exceptionOffset, info); + } + } + private static final int max13 = ((1 << 12) - 1); private static final int min13 = -(1 << 12);