/* * 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 #include #include "insttest.h" #include "rv64a.h" int main() { using namespace std; using namespace insttest; // Memory (LR.W, SC.W) expect>({-1, 256}, []{ int32_t mem = -1; int64_t rs2 = 256; int64_t rd; pair result; do { rd = A::lr_w(mem); result = A::sc_w(rs2, mem); } while (result.second == 1); return pair(rd, result.first); }, "lr.w/sc.w"); expect>({true, 200}, []{ int32_t mem = 200; pair result = A::sc_w(50, mem); return pair(result.second == 1, mem); }, "sc.w, no preceding lr.d"); // AMOSWAP.W expect>({65535, 255}, []{return A::amoswap_w(255, 65535);}, "amoswap.w"); expect>({0xFFFFFFFF, -1}, []{return A::amoswap_w(0xFFFFFFFF, 0xFFFFFFFF);}, "amoswap.w, sign extend"); expect>({0x0000000180000000LL, -1}, []{return A::amoswap_w(0x00000001FFFFFFFFLL, 0x7FFFFFFF80000000LL);}, "amoswap.w, truncate"); // AMOADD.W expect>({256, 255}, []{return A::amoadd_w(255, 1);}, "amoadd.w"); expect>({0, -1}, []{return A::amoadd_w(0xFFFFFFFF, 1);}, "amoadd.w, truncate/overflow"); expect>({0xFFFFFFFF, 0x7FFFFFFF}, []{return A::amoadd_w(0x7FFFFFFF, 0x80000000);}, "amoadd.w, sign extend"); // AMOXOR.W expect>({0xFFFFFFFFAAAAAAAALL, -1}, []{return A::amoxor_w(-1, 0x5555555555555555LL);}, "amoxor.w, truncate"); expect>({0x80000000, -1}, []{return A::amoxor_w(0xFFFFFFFF, 0x7FFFFFFF);}, "amoxor.w, sign extend"); // AMOAND.W expect>({0xFFFFFFFF00000000LL, -1}, []{return A::amoand_w(-1, 0);}, "amoand.w, truncate"); expect>({0x0000000080000000LL, -1}, []{return A::amoand_w(0xFFFFFFFF,numeric_limits::min());}, "amoand.w, sign extend"); // AMOOR.W expect>({0x00000000FFFFFFFFLL, 0}, []{return A::amoor_w(0, -1);}, "amoor.w, truncate"); expect>({0x0000000080000000LL, 0}, []{return A::amoor_w(0, numeric_limits::min());}, "amoor.w, sign extend"); // AMOMIN.W expect>({0x7FFFFFFF00000001LL, 1}, []{return A::amomin_w(0x7FFFFFFF00000001LL, 0xFFFFFFFF000000FF);}, "amomin.w, truncate"); expect>({0x00000000FFFFFFFELL, -1}, []{return A::amomin_w(0xFFFFFFFF, -2);}, "amomin.w, sign extend"); // AMOMAX.W expect>({0x70000000000000FFLL, 1}, []{return A::amomax_w(0x7000000000000001LL,0x7FFFFFFF000000FFLL);}, "amomax.w, truncate"); expect>({-1, numeric_limits::min()}, []{return A::amomax_w(numeric_limits::min(), -1);}, "amomax.w, sign extend"); // AMOMINU.W expect>({0x0FFFFFFF000000FFLL, -1}, []{return A::amominu_w(0x0FFFFFFFFFFFFFFFLL, 0xFFFFFFFF000000FF);}, "amominu.w, truncate"); expect>({0x0000000080000000LL, -1}, []{return A::amominu_w(0x00000000FFFFFFFFLL, 0x80000000);}, "amominu.w, sign extend"); // AMOMAXU.W expect>({-1, 0}, []{return A::amomaxu_w(0xFFFFFFFF00000000LL, 0x00000000FFFFFFFFLL);}, "amomaxu.w, truncate"); expect>( {0xFFFFFFFF, numeric_limits::min()}, []{return A::amomaxu_w(0x80000000, 0xFFFFFFFF);}, "amomaxu.w, sign extend"); // Memory (LR.D, SC.D) expect>({-1, 256}, []{ int64_t mem = -1; int64_t rs2 = 256; int64_t rd; pair result; do { rd = A::lr_d(mem); result = A::sc_d(rs2, mem); } while (result.second == 1); return pair(rd, result.first); }, "lr.d/sc.d"); expect>({true, 200}, []{ int64_t mem = 200; pair result = A::sc_d(50, mem); return pair(result.second == 1, mem); }, "sc.d, no preceding lr.d"); // AMOSWAP.D expect>({1, -1}, []{return A::amoswap_d(-1, 1);}, "amoswap.d"); // AMOADD.D expect>({0x7000000000000000LL,0x0FFFFFFFFFFFFFFFLL}, []{return A::amoadd_d(0x0FFFFFFFFFFFFFFFLL,0x6000000000000001LL);}, "amoadd.d"); expect>({0, 0x7FFFFFFFFFFFFFFFLL}, []{return A::amoadd_d(0x7FFFFFFFFFFFFFFFLL,0x8000000000000001LL);}, "amoadd.d, overflow"); // AMOXOR.D expect>({-1, 0xAAAAAAAAAAAAAAAALL}, []{return A::amoxor_d(0xAAAAAAAAAAAAAAAALL,0x5555555555555555LL);}, "amoxor.d (1)"); expect>({0, 0xAAAAAAAAAAAAAAAALL}, []{return A::amoxor_d(0xAAAAAAAAAAAAAAAALL,0xAAAAAAAAAAAAAAAALL);}, "amoxor.d (0)"); // AMOAND.D expect>({0xAAAAAAAAAAAAAAAALL, -1}, []{return A::amoand_d(-1, 0xAAAAAAAAAAAAAAAALL);}, "amoand.d"); // AMOOR.D expect>({-1, 0xAAAAAAAAAAAAAAAALL}, []{return A::amoor_d(0xAAAAAAAAAAAAAAAALL, 0x5555555555555555LL);}, "amoor.d"); // AMOMIN.D expect>({-1, -1}, []{return A::amomin_d(-1, 0);}, "amomin.d"); // AMOMAX.D expect>({0, -1}, []{return A::amomax_d(-1, 0);}, "amomax.d"); // AMOMINU.D expect>({0, -1}, []{return A::amominu_d(-1, 0);}, "amominu.d"); // AMOMAXU.D expect>({-1, -1}, []{return A::amomaxu_d(-1, 0);}, "amomaxu.d"); return 0; }