/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library 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 Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.vm.compiler.ir; /** * @author Madhu Siddalingaiah * @author Levente S\u00e1ntha */ public abstract class Constant<T> extends Operand<T> { public Constant(int type) { super(type); } public static <T> Constant<T> getInstance(int value) { return new IntConstant<T>(value); } public static <T> Constant<T> getInstance(long value) { return new LongConstant<T>(value); } public static <T> Constant<T> getInstance(float value) { return new FloatConstant<T>(value); } public static <T> Constant<T> getInstance(double value) { return new DoubleConstant<T>(value); } public static final <T> Constant<T> getInstance(Object value) { return new ReferenceConstant<T>(value); } ///////////////// UNARY OPERATIONS //////////////////// public Constant<T> i2l() { int i = ((IntConstant<T>) this).getValue(); return new LongConstant<T>(i); } public Constant<T> i2f() { int i = ((IntConstant<T>) this).getValue(); return new FloatConstant<T>(i); } public Constant<T> i2d() { int i = ((IntConstant<T>) this).getValue(); return new DoubleConstant<T>(i); } public Constant<T> l2i() { long l = ((LongConstant<T>) this).getValue(); return new IntConstant<T>((int) l); } public Constant<T> l2f() { long l = ((LongConstant<T>) this).getValue(); return new FloatConstant<T>(l); } public Constant<T> l2d() { long l = ((LongConstant<T>) this).getValue(); return new DoubleConstant<T>(l); } public Constant<T> f2i() { float f = ((FloatConstant<T>) this).getValue(); return new IntConstant<T>((int) f); } public Constant<T> f2l() { float f = ((FloatConstant<T>) this).getValue(); return new LongConstant<T>((long) f); } public Constant<T> f2d() { float f = ((FloatConstant<T>) this).getValue(); return new DoubleConstant<T>(f); } public Constant<T> d2i() { double d = ((DoubleConstant<T>) this).getValue(); return new IntConstant<T>((int) d); } public Constant<T> d2l() { double d = ((DoubleConstant<T>) this).getValue(); return new LongConstant<T>((long) d); } public Constant<T> d2f() { double d = ((DoubleConstant<T>) this).getValue(); return new FloatConstant<T>((float) d); } public Constant<T> i2b() { int i = ((IntConstant<T>) this).getValue(); return new IntConstant<T>((byte) i); } public Constant<T> i2c() { int i = ((IntConstant<T>) this).getValue(); return new IntConstant<T>((char) i); } public Constant<T> i2s() { int i = ((IntConstant<T>) this).getValue(); return new IntConstant<T>((short) i); } public Constant<T> iNeg() { int i = ((IntConstant<T>) this).getValue(); return new IntConstant<T>(-i); } public Constant<T> fNeg() { float f = ((FloatConstant<T>) this).getValue(); return new FloatConstant<T>(-f); } public Constant<T> lNeg() { long l = ((LongConstant<T>) this).getValue(); return new LongConstant<T>(-l); } public Constant<T> dNeg() { double d = ((DoubleConstant<T>) this).getValue(); return new DoubleConstant<T>(-d); } ///////////////// BINARY OPERATIONS //////////////////// public Constant<T> iAdd(Constant<T> c2) { int i1 = ((IntConstant<T>) this).getValue(); int i2 = ((IntConstant<T>) c2).getValue(); return new IntConstant<T>(i1 + i2); } public Constant<T> iSub(Constant<T> c2) { int i1 = ((IntConstant<T>) this).getValue(); int i2 = ((IntConstant<T>) c2).getValue(); return new IntConstant<T>(i1 - i2); } public Constant<T> iMul(Constant<T> c2) { int i1 = ((IntConstant<T>) this).getValue(); int i2 = ((IntConstant<T>) c2).getValue(); return new IntConstant<T>(i1 * i2); } public Constant<T> iDiv(Constant<T> c2) { int i1 = ((IntConstant<T>) this).getValue(); int i2 = ((IntConstant<T>) c2).getValue(); return new IntConstant<T>(i1 / i2); } public Constant<T> iRem(Constant<T> c2) { int i1 = ((IntConstant<T>) this).getValue(); int i2 = ((IntConstant<T>) c2).getValue(); return new IntConstant<T>(i1 % i2); } public Constant<T> iAnd(Constant<T> c2) { int i1 = ((IntConstant<T>) this).getValue(); int i2 = ((IntConstant<T>) c2).getValue(); return new IntConstant<T>(i1 & i2); } public Constant<T> iOr(Constant<T> c2) { int i1 = ((IntConstant<T>) this).getValue(); int i2 = ((IntConstant<T>) c2).getValue(); return new IntConstant<T>(i1 | i2); } public Constant<T> iXor(Constant<T> c2) { int i1 = ((IntConstant<T>) this).getValue(); int i2 = ((IntConstant<T>) c2).getValue(); return new IntConstant<T>(i1 ^ i2); } public Constant<T> iShl(Constant<T> c2) { int i1 = ((IntConstant<T>) this).getValue(); int i2 = ((IntConstant<T>) c2).getValue(); return new IntConstant<T>(i1 << i2); } public Constant<T> iShr(Constant<T> c2) { int i1 = ((IntConstant<T>) this).getValue(); int i2 = ((IntConstant<T>) c2).getValue(); return new IntConstant<T>(i1 >> i2); } public Constant<T> iUshr(Constant<T> c2) { int i1 = ((IntConstant<T>) this).getValue(); int i2 = ((IntConstant<T>) c2).getValue(); return new IntConstant<T>(i1 >>> i2); } public Constant<T> lAdd(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new LongConstant<T>(l1 + l2); } public Constant<T> lSub(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new LongConstant<T>(l1 - l2); } public Constant<T> lMul(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new LongConstant<T>(l1 * l2); } public Constant<T> lDiv(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new LongConstant<T>(l1 / l2); } public Constant<T> lRem(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new LongConstant<T>(l1 % l2); } public Constant<T> lAnd(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new LongConstant<T>(l1 & l2); } public Constant<T> lOr(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new LongConstant<T>(l1 | l2); } public Constant<T> lXor(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new LongConstant<T>(l1 ^ l2); } public Constant<T> lShl(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new LongConstant<T>(l1 << l2); } public Constant<T> lShr(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new LongConstant<T>(l1 >> l2); } public Constant<T> lUshr(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new LongConstant<T>(l1 >>> l2); } public Constant<T> lCmp(Constant<T> c2) { long l1 = ((LongConstant<T>) this).getValue(); long l2 = ((LongConstant<T>) c2).getValue(); return new IntConstant<T>(l1 < l2 ? -1 : l1 > l2 ? 1 : 0); } public Constant<T> fAdd(Constant<T> c2) { float f1 = ((FloatConstant<T>) this).getValue(); float f2 = ((FloatConstant<T>) c2).getValue(); return new FloatConstant<T>(f1 + f2); } public Constant<T> fSub(Constant<T> c2) { float f1 = ((FloatConstant<T>) this).getValue(); float f2 = ((FloatConstant<T>) c2).getValue(); return new FloatConstant<T>(f1 - f2); } public Constant<T> fMul(Constant<T> c2) { float f1 = ((FloatConstant<T>) this).getValue(); float f2 = ((FloatConstant<T>) c2).getValue(); return new FloatConstant<T>(f1 * f2); } public Constant<T> fDiv(Constant<T> c2) { float f1 = ((FloatConstant<T>) this).getValue(); float f2 = ((FloatConstant<T>) c2).getValue(); return new FloatConstant<T>(f1 / f2); } public Constant<T> fRem(Constant<T> c2) { float f1 = ((FloatConstant<T>) this).getValue(); float f2 = ((FloatConstant<T>) c2).getValue(); return new FloatConstant<T>(f1 / f2); } public Constant<T> dAdd(Constant<T> c2) { double d1 = ((DoubleConstant<T>) this).getValue(); double d2 = ((DoubleConstant<T>) c2).getValue(); return new DoubleConstant<T>(d1 + d2); } public Constant<T> dSub(Constant<T> c2) { double d1 = ((DoubleConstant<T>) this).getValue(); double d2 = ((DoubleConstant<T>) c2).getValue(); return new DoubleConstant<T>(d1 - d2); } public Constant<T> dMul(Constant<T> c2) { double d1 = ((DoubleConstant<T>) this).getValue(); double d2 = ((DoubleConstant<T>) c2).getValue(); return new DoubleConstant<T>(d1 * d2); } public Constant<T> dDiv(Constant<T> c2) { double d1 = ((DoubleConstant<T>) this).getValue(); double d2 = ((DoubleConstant<T>) c2).getValue(); return new DoubleConstant<T>(d1 / d2); } public Constant<T> dRem(Constant<T> c2) { double d1 = ((DoubleConstant<T>) this).getValue(); double d2 = ((DoubleConstant<T>) c2).getValue(); return new DoubleConstant<T>(d1 % d2); } /** * @see org.jnode.vm.compiler.ir.Operand#simplify() */ public Operand<T> simplify() { return this; } /** * @see org.jnode.vm.compiler.ir.Operand#getAddressingMode() */ public AddressingMode getAddressingMode() { return AddressingMode.CONSTANT; } }