15ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers/*
25ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers * Copyright (C) 2014 The Android Open Source Project
35ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers *
45ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers * Licensed under the Apache License, Version 2.0 (the "License");
55ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers * you may not use this file except in compliance with the License.
65ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers * You may obtain a copy of the License at
75ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers *
85ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers *      http://www.apache.org/licenses/LICENSE-2.0
95ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers *
105ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers * Unless required by applicable law or agreed to in writing, software
115ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers * distributed under the License is distributed on an "AS IS" BASIS,
125ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers * See the License for the specific language governing permissions and
145ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers * limitations under the License.
155ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers */
165ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
175ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers#include "safe_math.h"
185ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
195ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers#include <limits>
205ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
215ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers#include "gtest/gtest.h"
225ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
235ac814a0a789161cd1e797179cfad1ba6401366aIan Rogersnamespace art {
245ac814a0a789161cd1e797179cfad1ba6401366aIan Rogersnamespace interpreter {
255ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
265ac814a0a789161cd1e797179cfad1ba6401366aIan RogersTEST(SafeMath, Add) {
275ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  // Adding 1 overflows 0x7ff... to 0x800... aka max and min.
285ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(std::numeric_limits<int32_t>::max(), 1),
295ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int32_t>::min());
305ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(std::numeric_limits<int64_t>::max(), 1),
315ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int64_t>::min());
325ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
335ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  // Vanilla arithmetic should work too.
345ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(std::numeric_limits<int32_t>::max() - 1, 1),
355ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int32_t>::max());
365ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(std::numeric_limits<int64_t>::max() - 1, 1),
375ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int64_t>::max());
385ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
395ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(std::numeric_limits<int32_t>::min() + 1, -1),
405ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int32_t>::min());
415ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(std::numeric_limits<int64_t>::min() + 1, -1),
425ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int64_t>::min());
435ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
445ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int32_t(-1), -1), -2);
455ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int64_t(-1), -1), -2);
465ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
475ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int32_t(1), 1), 2);
485ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int64_t(1), 1), 2);
495ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
505ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int32_t(-1), 1), 0);
515ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int64_t(-1), 1), 0);
525ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
535ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int32_t(1), -1), 0);
545ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int64_t(1), -1), 0);
555ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
565ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  // Test sign extension of smaller operand sizes.
575ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int32_t(1), int8_t(-1)), 0);
585ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int64_t(1), int8_t(-1)), 0);
595ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers}
605ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
615ac814a0a789161cd1e797179cfad1ba6401366aIan RogersTEST(SafeMath, Sub) {
625ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  // Subtracting 1 underflows 0x800... to 0x7ff... aka min and max.
635ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(std::numeric_limits<int32_t>::min(), 1),
645ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int32_t>::max());
655ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(std::numeric_limits<int64_t>::min(), 1),
665ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int64_t>::max());
675ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
685ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  // Vanilla arithmetic should work too.
695ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(std::numeric_limits<int32_t>::max() - 1, -1),
705ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int32_t>::max());
715ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(std::numeric_limits<int64_t>::max() - 1, -1),
725ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int64_t>::max());
735ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
745ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(std::numeric_limits<int32_t>::min() + 1, 1),
755ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int32_t>::min());
765ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(std::numeric_limits<int64_t>::min() + 1, 1),
775ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int64_t>::min());
785ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
795ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(int32_t(-1), -1), 0);
805ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(int64_t(-1), -1), 0);
815ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
825ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(int32_t(1), 1), 0);
835ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(int64_t(1), 1), 0);
845ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
855ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(int32_t(-1), 1), -2);
865ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(int64_t(-1), 1), -2);
875ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
885ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(int32_t(1), -1), 2);
895ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeSub(int64_t(1), -1), 2);
905ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
915ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  // Test sign extension of smaller operand sizes.
925ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int32_t(1), int8_t(-1)), 0);
935ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeAdd(int64_t(1), int8_t(-1)), 0);
945ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers}
955ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
965ac814a0a789161cd1e797179cfad1ba6401366aIan RogersTEST(SafeMath, Mul) {
975ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  // Multiplying by 2 overflows 0x7ff...f to 0xfff...e aka max and -2.
985ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(std::numeric_limits<int32_t>::max(), 2),
995ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            -2);
1005ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(std::numeric_limits<int64_t>::max(), 2),
1015ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            -2);
1025ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
1035ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  // Vanilla arithmetic should work too.
1045ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(std::numeric_limits<int32_t>::max() / 2, 2),
1055ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int32_t>::max() - 1);  // -1 as LSB is lost by division.
1065ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(std::numeric_limits<int64_t>::max() / 2, 2),
1075ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int64_t>::max() - 1);  // -1 as LSB is lost by division.
1085ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
1095ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(std::numeric_limits<int32_t>::min() / 2, 2),
1105ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int32_t>::min());
1115ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(std::numeric_limits<int64_t>::min() / 2, 2),
1125ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers            std::numeric_limits<int64_t>::min());
1135ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
1145ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(int32_t(-1), -1), 1);
1155ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(int64_t(-1), -1), 1);
1165ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
1175ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(int32_t(1), 1), 1);
1185ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(int64_t(1), 1), 1);
1195ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
1205ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(int32_t(-1), 1), -1);
1215ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(int64_t(-1), 1), -1);
1225ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
1235ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(int32_t(1), -1), -1);
1245ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(int64_t(1), -1), -1);
1255ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
1265ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  // Test sign extension of smaller operand sizes.
1275ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(int32_t(1), int8_t(-1)), -1);
1285ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers  EXPECT_EQ(SafeMul(int64_t(1), int8_t(-1)), -1);
1295ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers}
1305ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers
1315ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers}  // namespace interpreter
1325ac814a0a789161cd1e797179cfad1ba6401366aIan Rogers}  // namespace art
133