| // Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| package com.android.tools.r8.smali; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertTrue; |
| |
| import com.android.tools.r8.code.Const16; |
| import com.android.tools.r8.code.Format22b; |
| import com.android.tools.r8.code.Format22s; |
| import com.android.tools.r8.code.Return; |
| import com.android.tools.r8.dex.Constants; |
| import com.android.tools.r8.graph.DexCode; |
| import com.android.tools.r8.graph.DexEncodedMethod; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.List; |
| import org.junit.Test; |
| |
| public class BinopLiteralTest extends SmaliTestBase { |
| |
| int[] lit8Values = new int[]{ |
| Constants.S8BIT_MIN, |
| Constants.S8BIT_MIN + 1, |
| Constants.S4BIT_MIN - 1, |
| Constants.S4BIT_MIN, |
| Constants.S4BIT_MIN + 1, |
| 1, |
| 0, |
| 1, |
| Constants.S4BIT_MAX - 1, |
| Constants.S4BIT_MAX, |
| Constants.S4BIT_MAX + 1, |
| Constants.S8BIT_MAX - 1, |
| Constants.S8BIT_MAX, |
| }; |
| |
| int[] lit16Values = new int[]{ |
| Short.MIN_VALUE, |
| Short.MIN_VALUE + 1, |
| Constants.S8BIT_MIN - 1, |
| Constants.S8BIT_MAX + 1, |
| Short.MAX_VALUE - 1, |
| Short.MAX_VALUE, |
| }; |
| |
| @Test |
| public void lit8PassthroughTest() { |
| List<String> lit8Binops = Arrays.asList( |
| "add", "rsub", "mul", "div", "rem", "and", "or", "xor", "shl", "shr", "ushr" |
| ); |
| |
| for (String binop : lit8Binops) { |
| for (int lit8Value : lit8Values) { |
| DexEncodedMethod method = oneMethodApplication( |
| "int", Collections.singletonList("int"), |
| 0, |
| // E.g. add-int/lit8 p0, p0, -128 |
| " " + binop + "-int/lit8 p0, p0, " + lit8Value, |
| " return p0" |
| ); |
| DexCode code = method.getCode().asDexCode(); |
| assertEquals(2, code.instructions.length); |
| assertTrue(code.instructions[0] instanceof Format22b); |
| assertEquals(lit8Value, ((Format22b) code.instructions[0]).CC); |
| assertTrue(code.instructions[1] instanceof Return); |
| } |
| } |
| } |
| |
| @Test |
| public void lit16PassthroughTest() { |
| List<String> lit16Binops = Arrays.asList( |
| "add", "rsub", "mul", "div", "rem", "and", "or", "xor" |
| ); |
| |
| for (String binop : lit16Binops) { |
| for (int lit16Value : lit16Values) { |
| String lit16Postfix = !binop.equals("rsub") ? "/lit16" : ""; |
| DexEncodedMethod method = oneMethodApplication( |
| "int", Collections.singletonList("int"), |
| 0, |
| // E.g. add-int/lit16 p0, p0, -32768 |
| " " + binop + "-int" + lit16Postfix + " p0, p0, " + lit16Value, |
| " return p0" |
| ); |
| DexCode code = method.getCode().asDexCode(); |
| assertEquals(2, code.instructions.length); |
| assertTrue(code.instructions[0] instanceof Format22s); |
| assertEquals(lit16Value, ((Format22s) code.instructions[0]).CCCC); |
| assertTrue(code.instructions[1] instanceof Return); |
| } |
| } |
| } |
| |
| @Test |
| public void lit16NotSupported() { |
| String[] lit8OnlyBinops = new String[]{ |
| "shl", "shr", "ushr", |
| }; |
| for (String binop : lit8OnlyBinops) { |
| for (int lit16Value : lit16Values) { |
| DexEncodedMethod method = oneMethodApplication( |
| "int", Collections.singletonList("int"), |
| 1, |
| " const/16 v0, " + lit16Value, |
| " " + binop + "-int/2addr p0, v0 ", |
| " return p0" |
| ); |
| DexCode code = method.getCode().asDexCode(); |
| assertEquals(3, code.instructions.length); |
| assertTrue(code.instructions[0] instanceof Const16); |
| assertEquals(lit16Value, ((Const16) code.instructions[0]).BBBB); |
| assertTrue(code.instructions[2] instanceof Return); |
| } |
| } |
| } |
| } |