Mercurial > hg > graal-jvmci-8
view graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java @ 9818:a9517aa587c7
SPARC unused object allocation fix
author | Morris Meyer <morris.meyer@oracle.com> |
---|---|
date | Sat, 25 May 2013 17:24:37 -0400 |
parents | 26960d32552c |
children | 81d5d8089cda |
line wrap: on
line source
/* * 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.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; 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.Srl; 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; // @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; /** * 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; @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; 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 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; } } @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); } } @SuppressWarnings("unused") 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 { throw new InternalError("NYI"); } } 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 { throw new InternalError("NYI"); } } 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: 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"); default: throw GraalInternalError.shouldNotReachHere("missing: " + opcode); } } if (info != null) { assert exceptionOffset != -1; tasm.recordImplicitException(exceptionOffset, info); } } @SuppressWarnings("unused") 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); 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()); } } }