diff options
Diffstat (limited to 'tests/test-progs/insttest/src/riscv/rv64a.cpp')
-rw-r--r-- | tests/test-progs/insttest/src/riscv/rv64a.cpp | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/tests/test-progs/insttest/src/riscv/rv64a.cpp b/tests/test-progs/insttest/src/riscv/rv64a.cpp new file mode 100644 index 000000000..55150fbc3 --- /dev/null +++ b/tests/test-progs/insttest/src/riscv/rv64a.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2016 The University of Virginia + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Alec Roelke + */ + +#include <cstdint> +#include <limits> + +#include "insttest.h" +#include "rv64a.h" + +int main() +{ + using namespace std; + using namespace insttest; + + // Memory (LR.W, SC.W) + expect<pair<int64_t, uint64_t>>({-1, 0}, []{ + int32_t mem = -1; + int64_t rs2 = 256; + int64_t rd = A::lr_w(mem); + pair<int64_t, uint64_t> result = A::sc_w(rs2, mem); + return pair<int64_t, uint64_t>(rd, result.second); + }, "lr.w/sc.w"); + expect<pair<bool, int64_t>>({true, 200}, []{ + int32_t mem = 200; + pair<int64_t, uint64_t> result = A::sc_w(50, mem); + return pair<bool, int64_t>(result.second == 1, mem); + }, "sc.w, no preceding lr.d"); + + // AMOSWAP.W + expect<pair<int64_t, int64_t>>({65535, 255}, + []{return A::amoswap_w(255, 65535);}, "amoswap.w"); + expect<pair<int64_t, int64_t>>({0xFFFFFFFF, -1}, + []{return A::amoswap_w(0xFFFFFFFF, 0xFFFFFFFF);}, + "amoswap.w, sign extend"); + expect<pair<int64_t, int64_t>>({0x0000000180000000LL, -1}, + []{return A::amoswap_w(0x00000001FFFFFFFFLL, + 0x7FFFFFFF80000000LL);}, + "amoswap.w, truncate"); + + // AMOADD.W + expect<pair<int64_t, int64_t>>({256, 255}, + []{return A::amoadd_w(255, 1);}, "amoadd.w"); + expect<pair<int64_t, int64_t>>({0, -1}, + []{return A::amoadd_w(0xFFFFFFFF, 1);}, + "amoadd.w, truncate/overflow"); + expect<pair<int64_t, int64_t>>({0xFFFFFFFF, 0x7FFFFFFF}, + []{return A::amoadd_w(0x7FFFFFFF, 0x80000000);}, + "amoadd.w, sign extend"); + + // AMOXOR.W + expect<pair<uint64_t, uint64_t>>({0xFFFFFFFFAAAAAAAALL, -1}, + []{return A::amoxor_w(-1, 0x5555555555555555LL);}, + "amoxor.w, truncate"); + expect<pair<uint64_t, uint64_t>>({0x80000000, -1}, + []{return A::amoxor_w(0xFFFFFFFF, 0x7FFFFFFF);}, + "amoxor.w, sign extend"); + + // AMOAND.W + expect<pair<uint64_t, uint64_t>>({0xFFFFFFFF00000000LL, -1}, + []{return A::amoand_w(-1, 0);}, "amoand.w, truncate"); + expect<pair<uint64_t, uint64_t>>({0x0000000080000000LL, -1}, + []{return A::amoand_w(0xFFFFFFFF,numeric_limits<int32_t>::min());}, + "amoand.w, sign extend"); + + // AMOOR.W + expect<pair<uint64_t, uint64_t>>({0x00000000FFFFFFFFLL, 0}, + []{return A::amoor_w(0, -1);}, "amoor.w, truncate"); + expect<pair<uint64_t, uint64_t>>({0x0000000080000000LL, 0}, + []{return A::amoor_w(0, numeric_limits<int32_t>::min());}, + "amoor.w, sign extend"); + + // AMOMIN.W + expect<pair<int64_t, int64_t>>({0x7FFFFFFF00000001LL, 1}, + []{return A::amomin_w(0x7FFFFFFF00000001LL, 0xFFFFFFFF000000FF);}, + "amomin.w, truncate"); + expect<pair<int64_t, int64_t>>({0x00000000FFFFFFFELL, -1}, + []{return A::amomin_w(0xFFFFFFFF, -2);}, "amomin.w, sign extend"); + + // AMOMAX.W + expect<pair<int64_t, int64_t>>({0x70000000000000FFLL, 1}, + []{return A::amomax_w(0x7000000000000001LL,0x7FFFFFFF000000FFLL);}, + "amomax.w, truncate"); + expect<pair<int64_t, int64_t>>({-1, numeric_limits<int32_t>::min()}, + []{return A::amomax_w(numeric_limits<int32_t>::min(), -1);}, + "amomax.w, sign extend"); + + // AMOMINU.W + expect<pair<uint64_t, uint64_t>>({0x0FFFFFFF000000FFLL, -1}, + []{return A::amominu_w(0x0FFFFFFFFFFFFFFFLL, 0xFFFFFFFF000000FF);}, + "amominu.w, truncate"); + expect<pair<uint64_t, uint64_t>>({0x0000000080000000LL, -1}, + []{return A::amominu_w(0x00000000FFFFFFFFLL, 0x80000000);}, + "amominu.w, sign extend"); + + // AMOMAXU.W + expect<pair<uint64_t, uint64_t>>({-1, 0}, + []{return A::amomaxu_w(0xFFFFFFFF00000000LL, + 0x00000000FFFFFFFFLL);}, + "amomaxu.w, truncate"); + expect<pair<uint64_t, uint64_t>>( + {0xFFFFFFFF, numeric_limits<int32_t>::min()}, + []{return A::amomaxu_w(0x80000000, 0xFFFFFFFF);}, + "amomaxu.w, sign extend"); + + // Memory (LR.D, SC.D) + expect<pair<int64_t, uint64_t>>({-1, 0}, []{ + int64_t mem = -1; + int64_t rs2 = 256; + int64_t rd = A::lr_d(mem); + pair<int64_t, uint64_t> result = A::sc_d(rs2, mem); + return pair<int64_t, uint64_t>(rd, result.second); + }, "lr.d/sc.d"); + expect<pair<bool, int64_t>>({true, 200}, []{ + int64_t mem = 200; + pair<int64_t, uint64_t> result = A::sc_d(50, mem); + return pair<bool, int64_t>(result.second == 1, mem); + }, "sc.d, no preceding lr.d"); + + // AMOSWAP.D + expect<pair<int64_t, int64_t>>({1, -1}, []{return A::amoswap_d(-1, 1);}, + "amoswap.d"); + + // AMOADD.D + expect<pair<int64_t, int64_t>>({0x7000000000000000LL,0x0FFFFFFFFFFFFFFFLL}, + []{return A::amoadd_d(0x0FFFFFFFFFFFFFFFLL,0x6000000000000001LL);}, + "amoadd.d"); + expect<pair<int64_t, int64_t>>({0, 0x7FFFFFFFFFFFFFFFLL}, + []{return A::amoadd_d(0x7FFFFFFFFFFFFFFFLL,0x8000000000000001LL);}, + "amoadd.d, overflow"); + + // AMOXOR.D + expect<pair<int64_t, int64_t>>({-1, 0xAAAAAAAAAAAAAAAALL}, + []{return A::amoxor_d(0xAAAAAAAAAAAAAAAALL,0x5555555555555555LL);}, + "amoxor.d (1)"); + expect<pair<int64_t, int64_t>>({0, 0xAAAAAAAAAAAAAAAALL}, + []{return A::amoxor_d(0xAAAAAAAAAAAAAAAALL,0xAAAAAAAAAAAAAAAALL);}, + "amoxor.d (0)"); + + // AMOAND.D + expect<pair<int64_t, int64_t>>({0xAAAAAAAAAAAAAAAALL, -1}, + []{return A::amoand_d(-1, 0xAAAAAAAAAAAAAAAALL);}, "amoand.d"); + + // AMOOR.D + expect<pair<int64_t, int64_t>>({-1, 0xAAAAAAAAAAAAAAAALL}, + []{return A::amoor_d(0xAAAAAAAAAAAAAAAALL, 0x5555555555555555LL);}, + "amoor.d"); + + // AMOMIN.D + expect<pair<int64_t, int64_t>>({-1, -1}, + []{return A::amomin_d(-1, 0);}, "amomin.d"); + + // AMOMAX.D + expect<pair<int64_t, int64_t>>({0, -1}, []{return A::amomax_d(-1, 0);}, + "amomax.d"); + + // AMOMINU.D + expect<pair<uint64_t, uint64_t>>({0, -1}, + []{return A::amominu_d(-1, 0);}, "amominu.d"); + + // AMOMAXU.D + expect<pair<uint64_t, uint64_t>>({-1, -1}, []{return A::amomaxu_d(-1, 0);}, + "amomaxu.d"); + + return 0; +} |