Add math routines with defined wrapping behavior for the interpreter.
Add a RSUB_INT_LIT16 instruction alias to make instruction opcode switch
statements easier to read.
Change-Id: I3bac07c9518665abf0b05b5c3105a90be22f780a
diff --git a/runtime/dex_instruction.h b/runtime/dex_instruction.h
index b913220..72802e4 100644
--- a/runtime/dex_instruction.h
+++ b/runtime/dex_instruction.h
@@ -88,6 +88,7 @@
DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM)
#undef DEX_INSTRUCTION_LIST
#undef INSTRUCTION_ENUM
+ RSUB_INT_LIT16 = RSUB_INT,
};
enum Format {
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 6a0aaf2..7f6303a 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -216,7 +216,7 @@
static inline bool DoIntDivide(ShadowFrame& shadow_frame, size_t result_reg,
int32_t dividend, int32_t divisor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const int32_t kMinInt = std::numeric_limits<int32_t>::min();
+ constexpr int32_t kMinInt = std::numeric_limits<int32_t>::min();
if (UNLIKELY(divisor == 0)) {
ThrowArithmeticExceptionDivideByZero();
return false;
@@ -234,7 +234,7 @@
static inline bool DoIntRemainder(ShadowFrame& shadow_frame, size_t result_reg,
int32_t dividend, int32_t divisor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const int32_t kMinInt = std::numeric_limits<int32_t>::min();
+ constexpr int32_t kMinInt = std::numeric_limits<int32_t>::min();
if (UNLIKELY(divisor == 0)) {
ThrowArithmeticExceptionDivideByZero();
return false;
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index 3a177eb..6350c56 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -15,6 +15,7 @@
*/
#include "interpreter_common.h"
+#include "safe_math.h"
namespace art {
namespace interpreter {
@@ -1634,22 +1635,22 @@
HANDLE_INSTRUCTION_START(ADD_INT)
shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
- shadow_frame.GetVReg(inst->VRegB_23x()) +
- shadow_frame.GetVReg(inst->VRegC_23x()));
+ SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
+ shadow_frame.GetVReg(inst->VRegC_23x())));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
HANDLE_INSTRUCTION_START(SUB_INT)
shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
- shadow_frame.GetVReg(inst->VRegB_23x()) -
- shadow_frame.GetVReg(inst->VRegC_23x()));
+ SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
+ shadow_frame.GetVReg(inst->VRegC_23x())));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
HANDLE_INSTRUCTION_START(MUL_INT)
shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
- shadow_frame.GetVReg(inst->VRegB_23x()) *
- shadow_frame.GetVReg(inst->VRegC_23x()));
+ SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
+ shadow_frame.GetVReg(inst->VRegC_23x())));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
@@ -1713,22 +1714,22 @@
HANDLE_INSTRUCTION_START(ADD_LONG)
shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
- shadow_frame.GetVRegLong(inst->VRegB_23x()) +
- shadow_frame.GetVRegLong(inst->VRegC_23x()));
+ SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
+ shadow_frame.GetVRegLong(inst->VRegC_23x())));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
HANDLE_INSTRUCTION_START(SUB_LONG)
shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
- shadow_frame.GetVRegLong(inst->VRegB_23x()) -
- shadow_frame.GetVRegLong(inst->VRegC_23x()));
+ SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
+ shadow_frame.GetVRegLong(inst->VRegC_23x())));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
HANDLE_INSTRUCTION_START(MUL_LONG)
shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
- shadow_frame.GetVRegLong(inst->VRegB_23x()) *
- shadow_frame.GetVRegLong(inst->VRegC_23x()));
+ SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
+ shadow_frame.GetVRegLong(inst->VRegC_23x())));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
@@ -1863,8 +1864,8 @@
HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
uint32_t vregA = inst->VRegA_12x(inst_data);
shadow_frame.SetVReg(vregA,
- shadow_frame.GetVReg(vregA) +
- shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
+ SafeAdd(shadow_frame.GetVReg(vregA),
+ shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
ADVANCE(1);
}
HANDLE_INSTRUCTION_END();
@@ -1872,8 +1873,8 @@
HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
uint32_t vregA = inst->VRegA_12x(inst_data);
shadow_frame.SetVReg(vregA,
- shadow_frame.GetVReg(vregA) -
- shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
+ SafeSub(shadow_frame.GetVReg(vregA),
+ shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
ADVANCE(1);
}
HANDLE_INSTRUCTION_END();
@@ -1881,8 +1882,8 @@
HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
uint32_t vregA = inst->VRegA_12x(inst_data);
shadow_frame.SetVReg(vregA,
- shadow_frame.GetVReg(vregA) *
- shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
+ SafeMul(shadow_frame.GetVReg(vregA),
+ shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
ADVANCE(1);
}
HANDLE_INSTRUCTION_END();
@@ -1960,8 +1961,8 @@
HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
uint32_t vregA = inst->VRegA_12x(inst_data);
shadow_frame.SetVRegLong(vregA,
- shadow_frame.GetVRegLong(vregA) +
- shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
+ SafeAdd(shadow_frame.GetVRegLong(vregA),
+ shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
ADVANCE(1);
}
HANDLE_INSTRUCTION_END();
@@ -1969,8 +1970,8 @@
HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
uint32_t vregA = inst->VRegA_12x(inst_data);
shadow_frame.SetVRegLong(vregA,
- shadow_frame.GetVRegLong(vregA) -
- shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
+ SafeSub(shadow_frame.GetVRegLong(vregA),
+ shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
ADVANCE(1);
}
HANDLE_INSTRUCTION_END();
@@ -1978,8 +1979,8 @@
HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
uint32_t vregA = inst->VRegA_12x(inst_data);
shadow_frame.SetVRegLong(vregA,
- shadow_frame.GetVRegLong(vregA) *
- shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
+ SafeMul(shadow_frame.GetVRegLong(vregA),
+ shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
ADVANCE(1);
}
HANDLE_INSTRUCTION_END();
@@ -2146,22 +2147,22 @@
HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
- shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) +
- inst->VRegC_22s());
+ SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
+ inst->VRegC_22s()));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
HANDLE_INSTRUCTION_START(RSUB_INT)
shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
- inst->VRegC_22s() -
- shadow_frame.GetVReg(inst->VRegB_22s(inst_data)));
+ SafeSub(inst->VRegC_22s(),
+ shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
- shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) *
- inst->VRegC_22s());
+ SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
+ inst->VRegC_22s()));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
@@ -2202,22 +2203,22 @@
HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
- shadow_frame.GetVReg(inst->VRegB_22b()) +
- inst->VRegC_22b());
+ SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
+ inst->VRegC_22b()));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
- inst->VRegC_22b() -
- shadow_frame.GetVReg(inst->VRegB_22b()));
+ SafeSub(inst->VRegC_22b(),
+ shadow_frame.GetVReg(inst->VRegB_22b())));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
- shadow_frame.GetVReg(inst->VRegB_22b()) *
- inst->VRegC_22b());
+ SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
+ inst->VRegC_22b()));
ADVANCE(2);
HANDLE_INSTRUCTION_END();
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 9fb90f1..1b6f53e 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -15,6 +15,7 @@
*/
#include "interpreter_common.h"
+#include "safe_math.h"
namespace art {
namespace interpreter {
@@ -1495,25 +1496,26 @@
static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
inst = inst->Next_1xx();
break;
- case Instruction::ADD_INT:
+ case Instruction::ADD_INT: {
PREAMBLE();
shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
- shadow_frame.GetVReg(inst->VRegB_23x()) +
- shadow_frame.GetVReg(inst->VRegC_23x()));
+ SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
+ shadow_frame.GetVReg(inst->VRegC_23x())));
inst = inst->Next_2xx();
break;
+ }
case Instruction::SUB_INT:
PREAMBLE();
shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
- shadow_frame.GetVReg(inst->VRegB_23x()) -
- shadow_frame.GetVReg(inst->VRegC_23x()));
+ SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
+ shadow_frame.GetVReg(inst->VRegC_23x())));
inst = inst->Next_2xx();
break;
case Instruction::MUL_INT:
PREAMBLE();
shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
- shadow_frame.GetVReg(inst->VRegB_23x()) *
- shadow_frame.GetVReg(inst->VRegC_23x()));
+ SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
+ shadow_frame.GetVReg(inst->VRegC_23x())));
inst = inst->Next_2xx();
break;
case Instruction::DIV_INT: {
@@ -1577,29 +1579,29 @@
case Instruction::ADD_LONG:
PREAMBLE();
shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
- shadow_frame.GetVRegLong(inst->VRegB_23x()) +
- shadow_frame.GetVRegLong(inst->VRegC_23x()));
+ SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
+ shadow_frame.GetVRegLong(inst->VRegC_23x())));
inst = inst->Next_2xx();
break;
case Instruction::SUB_LONG:
PREAMBLE();
shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
- shadow_frame.GetVRegLong(inst->VRegB_23x()) -
- shadow_frame.GetVRegLong(inst->VRegC_23x()));
+ SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
+ shadow_frame.GetVRegLong(inst->VRegC_23x())));
inst = inst->Next_2xx();
break;
case Instruction::MUL_LONG:
PREAMBLE();
shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
- shadow_frame.GetVRegLong(inst->VRegB_23x()) *
- shadow_frame.GetVRegLong(inst->VRegC_23x()));
+ SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
+ shadow_frame.GetVRegLong(inst->VRegC_23x())));
inst = inst->Next_2xx();
break;
case Instruction::DIV_LONG:
PREAMBLE();
DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
shadow_frame.GetVRegLong(inst->VRegB_23x()),
- shadow_frame.GetVRegLong(inst->VRegC_23x()));
+ shadow_frame.GetVRegLong(inst->VRegC_23x()));
POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
break;
case Instruction::REM_LONG:
@@ -1724,9 +1726,8 @@
case Instruction::ADD_INT_2ADDR: {
PREAMBLE();
uint4_t vregA = inst->VRegA_12x(inst_data);
- shadow_frame.SetVReg(vregA,
- shadow_frame.GetVReg(vregA) +
- shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
+ shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
+ shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
inst = inst->Next_1xx();
break;
}
@@ -1734,8 +1735,8 @@
PREAMBLE();
uint4_t vregA = inst->VRegA_12x(inst_data);
shadow_frame.SetVReg(vregA,
- shadow_frame.GetVReg(vregA) -
- shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
+ SafeSub(shadow_frame.GetVReg(vregA),
+ shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
inst = inst->Next_1xx();
break;
}
@@ -1743,8 +1744,8 @@
PREAMBLE();
uint4_t vregA = inst->VRegA_12x(inst_data);
shadow_frame.SetVReg(vregA,
- shadow_frame.GetVReg(vregA) *
- shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
+ SafeMul(shadow_frame.GetVReg(vregA),
+ shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
inst = inst->Next_1xx();
break;
}
@@ -1822,8 +1823,8 @@
PREAMBLE();
uint4_t vregA = inst->VRegA_12x(inst_data);
shadow_frame.SetVRegLong(vregA,
- shadow_frame.GetVRegLong(vregA) +
- shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
+ SafeAdd(shadow_frame.GetVRegLong(vregA),
+ shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
inst = inst->Next_1xx();
break;
}
@@ -1831,8 +1832,8 @@
PREAMBLE();
uint4_t vregA = inst->VRegA_12x(inst_data);
shadow_frame.SetVRegLong(vregA,
- shadow_frame.GetVRegLong(vregA) -
- shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
+ SafeSub(shadow_frame.GetVRegLong(vregA),
+ shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
inst = inst->Next_1xx();
break;
}
@@ -1840,8 +1841,8 @@
PREAMBLE();
uint4_t vregA = inst->VRegA_12x(inst_data);
shadow_frame.SetVRegLong(vregA,
- shadow_frame.GetVRegLong(vregA) *
- shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
+ SafeMul(shadow_frame.GetVRegLong(vregA),
+ shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
inst = inst->Next_1xx();
break;
}
@@ -2008,22 +2009,22 @@
case Instruction::ADD_INT_LIT16:
PREAMBLE();
shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
- shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) +
- inst->VRegC_22s());
+ SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
+ inst->VRegC_22s()));
inst = inst->Next_2xx();
break;
- case Instruction::RSUB_INT:
+ case Instruction::RSUB_INT_LIT16:
PREAMBLE();
shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
- inst->VRegC_22s() -
- shadow_frame.GetVReg(inst->VRegB_22s(inst_data)));
+ SafeSub(inst->VRegC_22s(),
+ shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
inst = inst->Next_2xx();
break;
case Instruction::MUL_INT_LIT16:
PREAMBLE();
shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
- shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) *
- inst->VRegC_22s());
+ SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
+ inst->VRegC_22s()));
inst = inst->Next_2xx();
break;
case Instruction::DIV_INT_LIT16: {
@@ -2064,22 +2065,19 @@
case Instruction::ADD_INT_LIT8:
PREAMBLE();
shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
- shadow_frame.GetVReg(inst->VRegB_22b()) +
- inst->VRegC_22b());
+ SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
inst = inst->Next_2xx();
break;
case Instruction::RSUB_INT_LIT8:
PREAMBLE();
shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
- inst->VRegC_22b() -
- shadow_frame.GetVReg(inst->VRegB_22b()));
+ SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
inst = inst->Next_2xx();
break;
case Instruction::MUL_INT_LIT8:
PREAMBLE();
shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
- shadow_frame.GetVReg(inst->VRegB_22b()) *
- inst->VRegC_22b());
+ SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
inst = inst->Next_2xx();
break;
case Instruction::DIV_INT_LIT8: {
diff --git a/runtime/interpreter/safe_math.h b/runtime/interpreter/safe_math.h
new file mode 100644
index 0000000..78b3539
--- /dev/null
+++ b/runtime/interpreter/safe_math.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_INTERPRETER_SAFE_MATH_H_
+#define ART_RUNTIME_INTERPRETER_SAFE_MATH_H_
+
+#include <functional>
+#include <type_traits>
+
+namespace art {
+namespace interpreter {
+
+// Declares a type which is the larger in bit size of the two template parameters.
+template <typename T1, typename T2>
+struct select_bigger {
+ typedef typename std::conditional<sizeof(T1) >= sizeof(T2), T1, T2>::type type;
+};
+
+// Perform signed arithmetic Op on 'a' and 'b' with defined wrapping behavior.
+template<template <typename OpT> class Op, typename T1, typename T2>
+static inline typename select_bigger<T1, T2>::type SafeMath(T1 a, T2 b) {
+ typedef typename select_bigger<T1, T2>::type biggest_T;
+ typedef typename std::make_unsigned<biggest_T>::type unsigned_biggest_T;
+ static_assert(std::is_signed<T1>::value, "Expected T1 to be signed");
+ static_assert(std::is_signed<T2>::value, "Expected T2 to be signed");
+ unsigned_biggest_T val1 = static_cast<unsigned_biggest_T>(static_cast<biggest_T>(a));
+ unsigned_biggest_T val2 = static_cast<unsigned_biggest_T>(b);
+ return static_cast<biggest_T>(Op<unsigned_biggest_T>()(val1, val2));
+}
+
+// Perform signed a signed add on 'a' and 'b' with defined wrapping behavior.
+template<typename T1, typename T2>
+static inline typename select_bigger<T1, T2>::type SafeAdd(T1 a, T2 b) {
+ return SafeMath<std::plus>(a, b);
+}
+
+// Perform signed a signed substract on 'a' and 'b' with defined wrapping behavior.
+template<typename T1, typename T2>
+static inline typename select_bigger<T1, T2>::type SafeSub(T1 a, T2 b) {
+ return SafeMath<std::minus>(a, b);
+}
+
+// Perform signed a signed multiply on 'a' and 'b' with defined wrapping behavior.
+template<typename T1, typename T2>
+static inline typename select_bigger<T1, T2>::type SafeMul(T1 a, T2 b) {
+ return SafeMath<std::multiplies>(a, b);
+}
+
+} // namespace interpreter
+} // namespace art
+
+#endif // ART_RUNTIME_INTERPRETER_SAFE_MATH_H_
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 6e792d4..7380a50 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2650,7 +2650,7 @@
reg_types_.DoubleLo(), reg_types_.DoubleHi());
break;
case Instruction::ADD_INT_LIT16:
- case Instruction::RSUB_INT:
+ case Instruction::RSUB_INT_LIT16:
case Instruction::MUL_INT_LIT16:
case Instruction::DIV_INT_LIT16:
case Instruction::REM_INT_LIT16: