1418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file 2418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// for details. All rights reserved. Use of this source code is governed by a 3418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager// BSD-style license that can be found in the LICENSE file. 4418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerpackage com.android.tools.r8.ir.code; 5418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 6418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.code.NegDouble; 7418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.code.NegFloat; 8418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.code.NegInt; 9418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.code.NegLong; 10418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.errors.Unreachable; 11418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerimport com.android.tools.r8.ir.conversion.DexBuilder; 12418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 13418d1ca139ea11316113beafbb3b3dd3fd5587aMads Agerpublic class Neg extends Unop { 14418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 15418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public final NumericType type; 16418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 17418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public Neg(NumericType type, Value dest, Value source) { 18418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager super(dest, source); 19418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager this.type = type; 20418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 21418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 22418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Override 23418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public boolean canBeFolded() { 24418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return (type == NumericType.INT || type == NumericType.LONG || type == NumericType.FLOAT 25418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager || type == NumericType.DOUBLE) 26418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager && source().isConstant(); 27418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 28418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 29418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Override 30fda18f74bf4e484a70c0dff0ef04d4571ee6cd8fSøren Gjesse public ConstInstruction fold(IRCode code) { 31418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager assert canBeFolded(); 32418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager if (type == NumericType.INT) { 33418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager int result = -source().getConstInstruction().asConstNumber().getIntValue(); 34fda18f74bf4e484a70c0dff0ef04d4571ee6cd8fSøren Gjesse Value value = code.createValue(MoveType.SINGLE, getDebugInfo()); 35418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return new ConstNumber(ConstType.INT, value, result); 36418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } else if (type == NumericType.LONG) { 37418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager long result = -source().getConstInstruction().asConstNumber().getLongValue(); 38fda18f74bf4e484a70c0dff0ef04d4571ee6cd8fSøren Gjesse Value value = code.createValue(MoveType.WIDE, getDebugInfo()); 39418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return new ConstNumber(ConstType.LONG, value, result); 40418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } else if (type == NumericType.FLOAT) { 41418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager float result = -source().getConstInstruction().asConstNumber().getFloatValue(); 42fda18f74bf4e484a70c0dff0ef04d4571ee6cd8fSøren Gjesse Value value = code.createValue(MoveType.SINGLE, getDebugInfo()); 43418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return new ConstNumber(ConstType.FLOAT, value, Float.floatToIntBits(result)); 44418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } else { 45418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager assert type == NumericType.DOUBLE; 46418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager double result = -source().getConstInstruction().asConstNumber().getDoubleValue(); 47fda18f74bf4e484a70c0dff0ef04d4571ee6cd8fSøren Gjesse Value value = code.createValue(MoveType.WIDE, getDebugInfo()); 48418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return new ConstNumber(ConstType.DOUBLE, value, Double.doubleToLongBits(result)); 49418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 50418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 51418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 52418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Override 53418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public boolean identicalNonValueParts(Instruction other) { 54418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return other.asNeg().type == type; 55418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 56418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 57418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Override 58418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public int compareNonValueParts(Instruction other) { 59418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return type.ordinal() - other.asNeg().type.ordinal(); 60418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 61418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 62418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Override 63418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public void buildDex(DexBuilder builder) { 64418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager com.android.tools.r8.code.Instruction instruction; 65418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager int dest = builder.allocatedRegister(dest(), getNumber()); 66418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager int src = builder.allocatedRegister(source(), getNumber()); 67418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager switch (type) { 68418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager case INT: 69418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager instruction = new NegInt(dest, src); 70418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager break; 71418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager case LONG: 72418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager instruction = new NegLong(dest, src); 73418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager break; 74418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager case FLOAT: 75418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager instruction = new NegFloat(dest, src); 76418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager break; 77418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager case DOUBLE: 78418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager instruction = new NegDouble(dest, src); 79418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager break; 80418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager default: 81418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager throw new Unreachable("Unexpected type " + type); 82418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 83418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager builder.add(this, instruction); 84418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 85418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 86418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Override 87418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public boolean isNeg() { 88418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return true; 89418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 90418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager 91418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager @Override 92418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager public Neg asNeg() { 93418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager return this; 94418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager } 95418d1ca139ea11316113beafbb3b3dd3fd5587aMads Ager} 96