112121Sar4jc@virginia.edu/*
212121Sar4jc@virginia.edu * Copyright (c) 2017 The University of Virginia
312121Sar4jc@virginia.edu * All rights reserved.
412121Sar4jc@virginia.edu *
512121Sar4jc@virginia.edu * Redistribution and use in source and binary forms, with or without
612121Sar4jc@virginia.edu * modification, are permitted provided that the following conditions are
712121Sar4jc@virginia.edu * met: redistributions of source code must retain the above copyright
812121Sar4jc@virginia.edu * notice, this list of conditions and the following disclaimer;
912121Sar4jc@virginia.edu * redistributions in binary form must reproduce the above copyright
1012121Sar4jc@virginia.edu * notice, this list of conditions and the following disclaimer in the
1112121Sar4jc@virginia.edu * documentation and/or other materials provided with the distribution;
1212121Sar4jc@virginia.edu * neither the name of the copyright holders nor the names of its
1312121Sar4jc@virginia.edu * contributors may be used to endorse or promote products derived from
1412121Sar4jc@virginia.edu * this software without specific prior written permission.
1512121Sar4jc@virginia.edu *
1612121Sar4jc@virginia.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712121Sar4jc@virginia.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812121Sar4jc@virginia.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912121Sar4jc@virginia.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012121Sar4jc@virginia.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112121Sar4jc@virginia.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212121Sar4jc@virginia.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312121Sar4jc@virginia.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412121Sar4jc@virginia.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512121Sar4jc@virginia.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612121Sar4jc@virginia.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712121Sar4jc@virginia.edu *
2812121Sar4jc@virginia.edu * Authors: Alec Roelke
2912121Sar4jc@virginia.edu */
3012121Sar4jc@virginia.edu
3112121Sar4jc@virginia.edu#include <limits>
3212121Sar4jc@virginia.edu
3312121Sar4jc@virginia.edu#include "insttest.h"
3412121Sar4jc@virginia.edu#include "rv64c.h"
3512121Sar4jc@virginia.edu#include "rv64d.h"
3612121Sar4jc@virginia.edu
3712121Sar4jc@virginia.eduint main()
3812121Sar4jc@virginia.edu{
3912121Sar4jc@virginia.edu    using namespace insttest;
4012121Sar4jc@virginia.edu    using namespace std;
4112121Sar4jc@virginia.edu
4212121Sar4jc@virginia.edu    // C.LWSP
4312121Sar4jc@virginia.edu    expect<bool>(true, []{
4412121Sar4jc@virginia.edu        uint64_t lw = 0, lwsp = -1;
4512121Sar4jc@virginia.edu        int64_t i = 16;
4612121Sar4jc@virginia.edu        asm volatile("lw %0,%2(sp);"
4712121Sar4jc@virginia.edu                     "c.lwsp %1,%2(sp);"
4812121Sar4jc@virginia.edu                     : "=r" (lw), "=r" (lwsp)
4912121Sar4jc@virginia.edu                     : "i" (i));
5012121Sar4jc@virginia.edu        return lw == lwsp;
5112121Sar4jc@virginia.edu    }, "c.lwsp");
5212121Sar4jc@virginia.edu
5312121Sar4jc@virginia.edu    // C.LDSP
5412121Sar4jc@virginia.edu    expect<bool>(true, []{
5512121Sar4jc@virginia.edu        uint64_t ld = 0, ldsp = -1;
5612121Sar4jc@virginia.edu        int64_t i = 8;
5712121Sar4jc@virginia.edu        asm volatile("ld %0,%2(sp);"
5812121Sar4jc@virginia.edu                     "c.ldsp %1,%2(sp);"
5912121Sar4jc@virginia.edu                     : "=r" (ld), "=r" (ldsp)
6012121Sar4jc@virginia.edu                     : "i" (i));
6112121Sar4jc@virginia.edu        return ld == ldsp;
6212121Sar4jc@virginia.edu    }, "c.ldsp");
6312121Sar4jc@virginia.edu
6412121Sar4jc@virginia.edu    // C.FLDSP
6512121Sar4jc@virginia.edu    expect<bool>(true, []{
6612121Sar4jc@virginia.edu        double fld = 0.0, fldsp = -1.0;
6712121Sar4jc@virginia.edu        int64_t i = 32;
6812121Sar4jc@virginia.edu        asm volatile("fld %0,%2(sp);"
6912121Sar4jc@virginia.edu                     "c.fldsp %1,%2(sp);"
7012121Sar4jc@virginia.edu                     : "=f" (fld), "=f" (fldsp)
7112121Sar4jc@virginia.edu                     : "i" (i));
7212121Sar4jc@virginia.edu        return D::bits(fld) == D::bits(fldsp);
7312121Sar4jc@virginia.edu    }, "c.fldsp");
7412121Sar4jc@virginia.edu
7512121Sar4jc@virginia.edu    // C.SWSP
7612121Sar4jc@virginia.edu    expect<bool>(true, []{
7712121Sar4jc@virginia.edu        int64_t value = -1, result = 0;
7812121Sar4jc@virginia.edu        asm volatile("addi sp,sp,-8;"
7912121Sar4jc@virginia.edu                     "c.swsp %1,8(sp);"
8012121Sar4jc@virginia.edu                     "lw %0,8(sp);"
8112121Sar4jc@virginia.edu                     "addi sp,sp,8;"
8212121Sar4jc@virginia.edu                     : "=r" (result)
8312121Sar4jc@virginia.edu                     : "r" (value)
8412121Sar4jc@virginia.edu                     : "memory");
8512121Sar4jc@virginia.edu        return value == result;
8612121Sar4jc@virginia.edu    }, "c.swsp");
8712121Sar4jc@virginia.edu
8812121Sar4jc@virginia.edu    // C.SDSP
8912121Sar4jc@virginia.edu    expect<bool>(true, []{
9012121Sar4jc@virginia.edu        int64_t value = -1, result = 0;
9112121Sar4jc@virginia.edu        asm volatile("addi sp,sp,-8;"
9212121Sar4jc@virginia.edu                     "c.sdsp %1,8(sp);"
9312121Sar4jc@virginia.edu                     "ld %0,8(sp);"
9412121Sar4jc@virginia.edu                     "addi sp,sp,8;"
9512121Sar4jc@virginia.edu                     : "=r" (result)
9612121Sar4jc@virginia.edu                     : "r" (value)
9712121Sar4jc@virginia.edu                     : "memory");
9812121Sar4jc@virginia.edu        return value == result;
9912121Sar4jc@virginia.edu    }, "c.sdsp");
10012121Sar4jc@virginia.edu
10112121Sar4jc@virginia.edu    // C.FSDSP
10212121Sar4jc@virginia.edu    expect<bool>(true, []{
10312121Sar4jc@virginia.edu        double value = 0.1, result = numeric_limits<double>::signaling_NaN();
10412121Sar4jc@virginia.edu        asm volatile("addi sp,sp,-8;"
10512121Sar4jc@virginia.edu                     "c.fsdsp %1,8(sp);"
10612121Sar4jc@virginia.edu                     "fld %0,8(sp);"
10712121Sar4jc@virginia.edu                     "addi sp,sp,8;"
10812121Sar4jc@virginia.edu                     : "=f" (result)
10912121Sar4jc@virginia.edu                     : "f" (value)
11012121Sar4jc@virginia.edu                     : "memory");
11112121Sar4jc@virginia.edu        return value == result;
11212121Sar4jc@virginia.edu    }, "c.fsdsp");
11312121Sar4jc@virginia.edu
11412121Sar4jc@virginia.edu    // C.LW, C.LD, C.FLD
11512121Sar4jc@virginia.edu    expect<int64_t>(458752,
11612121Sar4jc@virginia.edu            []{return C::c_load<int32_t, int64_t>(0x00070000);},
11712121Sar4jc@virginia.edu            "c.lw, positive");
11812121Sar4jc@virginia.edu    expect<int64_t>(numeric_limits<int32_t>::min(),
11912121Sar4jc@virginia.edu            []{return C::c_load<int32_t, int64_t>(0x80000000);},
12012121Sar4jc@virginia.edu            "c.lw, negative");
12112121Sar4jc@virginia.edu    expect<int64_t>(30064771072,
12212121Sar4jc@virginia.edu            []{return C::c_load<int64_t, int64_t>(30064771072);}, "c.ld");
12312121Sar4jc@virginia.edu    expect<double>(3.1415926, []{return C::c_load<double, double>(3.1415926);},
12412121Sar4jc@virginia.edu        "c.fld");
12512121Sar4jc@virginia.edu
12612121Sar4jc@virginia.edu    // C.SW, C.SD, C.FSD
12712121Sar4jc@virginia.edu    expect<uint32_t>(0xFFFFFFFF, []{return C::c_store<int32_t>(-1);}, "c.sw");
12812121Sar4jc@virginia.edu    expect<uint64_t>(-1, []{return C::c_store<int64_t>(-1);}, "c.sd");
12912121Sar4jc@virginia.edu    expect<double>(1.61803398875,
13012121Sar4jc@virginia.edu            []{return C::c_store<double>(1.61803398875);}, "c.fsd");
13112121Sar4jc@virginia.edu
13212121Sar4jc@virginia.edu    // C.J, C.JR, C.JALR
13312121Sar4jc@virginia.edu    expect<bool>(true, []{return C::c_j();}, "c.j");
13412121Sar4jc@virginia.edu    expect<bool>(true, []{return C::c_jr();}, "c.jr");
13512121Sar4jc@virginia.edu    expect<bool>(true, []{return C::c_jalr();}, "c.jalr");
13612121Sar4jc@virginia.edu
13712121Sar4jc@virginia.edu    // C.BEQZ
13812121Sar4jc@virginia.edu    expect<bool>(true, []{return C::c_beqz(0);}, "c.beqz, zero");
13912121Sar4jc@virginia.edu    expect<bool>(false, []{return C::c_beqz(7);}, "c.beqz, not zero");
14012121Sar4jc@virginia.edu
14112121Sar4jc@virginia.edu    // C.BNEZ
14212121Sar4jc@virginia.edu    expect<bool>(true, []{return C::c_bnez(15);}, "c.bnez, not zero");
14312121Sar4jc@virginia.edu    expect<bool>(false, []{return C::c_bnez(0);}, "c.bnez, zero");
14412121Sar4jc@virginia.edu
14512121Sar4jc@virginia.edu    // C.LI
14612121Sar4jc@virginia.edu    expect<int64_t>(1, []{return C::c_li(1);}, "c.li");
14712121Sar4jc@virginia.edu    expect<int64_t>(-1, []{return C::c_li(-1);}, "c.li, sign extend");
14812121Sar4jc@virginia.edu
14912121Sar4jc@virginia.edu    // C.LUI
15012121Sar4jc@virginia.edu    expect<int64_t>(4096, []{return C::c_lui(1);}, "c.lui");
15112121Sar4jc@virginia.edu    // Note that sign extension can't be tested here because apparently the
15212121Sar4jc@virginia.edu    // compiler doesn't allow the 6th (sign) bit of the immediate to be 1
15312121Sar4jc@virginia.edu
15412121Sar4jc@virginia.edu    // C.ADDI
15512121Sar4jc@virginia.edu    expect<int64_t>(15, []{return C::c_addi(7, 8);}, "c.addi");
15612121Sar4jc@virginia.edu
15712121Sar4jc@virginia.edu    // C.ADDIW
15812121Sar4jc@virginia.edu    expect<int64_t>(15, []{return C::c_addiw(8, 7);}, "c.addiw");
15912121Sar4jc@virginia.edu    expect<int64_t>(1, []{return C::c_addiw(0xFFFFFFFF, 2);},
16012121Sar4jc@virginia.edu            "c.addiw, overflow");
16112121Sar4jc@virginia.edu    expect<int64_t>(1, []{return C::c_addiw(0x100000001, 0);},
16212121Sar4jc@virginia.edu            "c.addiw, truncate");
16312121Sar4jc@virginia.edu
16412121Sar4jc@virginia.edu    // C.ADDI16SP
16512121Sar4jc@virginia.edu    expect<bool>(true, []{
16612121Sar4jc@virginia.edu        uint64_t sp = 0, rd = 0;
16712121Sar4jc@virginia.edu        const int16_t i = 4;
16812121Sar4jc@virginia.edu        asm volatile("mv %0,sp;"
16912121Sar4jc@virginia.edu                     "c.addi16sp sp,%2;"
17012121Sar4jc@virginia.edu                     "mv %1,sp;"
17112121Sar4jc@virginia.edu                     "mv sp,%0;"
17212121Sar4jc@virginia.edu                     : "+r" (sp), "=r" (rd)
17312121Sar4jc@virginia.edu                     : "i" (i*16));
17412121Sar4jc@virginia.edu        return rd == sp + i*16;
17512121Sar4jc@virginia.edu    }, "c.addi16sp");
17612121Sar4jc@virginia.edu
17712121Sar4jc@virginia.edu    // C.ADDI4SPN
17812121Sar4jc@virginia.edu    expect<bool>(true, []{
17912121Sar4jc@virginia.edu        uint64_t sp = 0, rd = 0;
18012121Sar4jc@virginia.edu        const int16_t i = 3;
18112121Sar4jc@virginia.edu        asm volatile("mv %0,sp;"
18212121Sar4jc@virginia.edu                     "c.addi4spn %1,sp,%2;"
18312121Sar4jc@virginia.edu                     : "=r" (sp), "=r" (rd)
18412121Sar4jc@virginia.edu                     : "i" (i*4));
18512121Sar4jc@virginia.edu        return rd == sp + i*4;
18612121Sar4jc@virginia.edu    }, "c.addi4spn");
18712121Sar4jc@virginia.edu
18812121Sar4jc@virginia.edu    // C.SLLI
18912121Sar4jc@virginia.edu    expect<uint64_t>(16, []{return C::c_slli(1, 4);}, "c.slli");
19012121Sar4jc@virginia.edu    expect<uint64_t>(0, []{return C::c_slli(8, 61);}, "c.slli, overflow");
19112121Sar4jc@virginia.edu
19212121Sar4jc@virginia.edu    // C.SRLI
19312121Sar4jc@virginia.edu    expect<uint64_t>(4, []{return C::c_srli(128, 5);}, "c.srli");
19412121Sar4jc@virginia.edu    expect<uint64_t>(0, []{return C::c_srli(128, 8);}, "c.srli, overflow");
19512121Sar4jc@virginia.edu    expect<uint64_t>(1, []{return C::c_srli(-1, 63);}, "c.srli, -1");
19612121Sar4jc@virginia.edu
19712121Sar4jc@virginia.edu    // C.SRAI
19812121Sar4jc@virginia.edu    expect<uint64_t>(4, []{return C::c_srai(128, 5);}, "c.srai");
19912121Sar4jc@virginia.edu    expect<uint64_t>(0, []{return C::c_srai(128, 8);}, "c.srai, overflow");
20012121Sar4jc@virginia.edu    expect<uint64_t>(-1, []{return C::c_srai(-2, 63);}, "c.srai, -1");
20112121Sar4jc@virginia.edu
20212121Sar4jc@virginia.edu    // C.ANDI
20312121Sar4jc@virginia.edu    expect<uint64_t>(0, []{return C::c_andi(-1, 0);}, "c.andi (0)");
20412121Sar4jc@virginia.edu    expect<uint64_t>(0x1234567812345678ULL,
20512121Sar4jc@virginia.edu            []{return C::c_andi(0x1234567812345678ULL, -1);}, "c.andi (1)");
20612121Sar4jc@virginia.edu
20712121Sar4jc@virginia.edu    // C.MV
20812121Sar4jc@virginia.edu    expect<int64_t>(1024, []{return C::c_mv(1024);}, "c.mv");
20912121Sar4jc@virginia.edu
21012121Sar4jc@virginia.edu    // C.ADD
21112121Sar4jc@virginia.edu    expect<int64_t>(15, []{return C::c_add(10, 5);}, "c.add");
21212121Sar4jc@virginia.edu
21312121Sar4jc@virginia.edu    // C.AND
21412121Sar4jc@virginia.edu    expect<uint64_t>(0, []{return C::c_and(-1, 0);}, "c.and (0)");
21512121Sar4jc@virginia.edu    expect<uint64_t>(0x1234567812345678ULL,
21612121Sar4jc@virginia.edu            []{return C::c_and(0x1234567812345678ULL, -1);}, "c.and (-1)");
21712121Sar4jc@virginia.edu
21812121Sar4jc@virginia.edu    // C.OR
21912121Sar4jc@virginia.edu    expect<uint64_t>(-1,
22012121Sar4jc@virginia.edu            []{return C::c_or(0xAAAAAAAAAAAAAAAAULL,
22112121Sar4jc@virginia.edu                    0x5555555555555555ULL);},
22212121Sar4jc@virginia.edu            "c.or (1)");
22312121Sar4jc@virginia.edu    expect<uint64_t>(0xAAAAAAAAAAAAAAAAULL,
22412121Sar4jc@virginia.edu            []{return C::c_or(0xAAAAAAAAAAAAAAAAULL,
22512121Sar4jc@virginia.edu                    0xAAAAAAAAAAAAAAAAULL);},
22612121Sar4jc@virginia.edu            "c.or (A)");
22712121Sar4jc@virginia.edu
22812121Sar4jc@virginia.edu    // C.XOR
22912121Sar4jc@virginia.edu    expect<uint64_t>(-1,
23012121Sar4jc@virginia.edu            []{return C::c_xor(0xAAAAAAAAAAAAAAAAULL,
23112121Sar4jc@virginia.edu                    0x5555555555555555ULL);},
23212121Sar4jc@virginia.edu            "c.xor (1)");
23312121Sar4jc@virginia.edu    expect<uint64_t>(0,
23412121Sar4jc@virginia.edu            []{return C::c_xor(0xAAAAAAAAAAAAAAAAULL,
23512121Sar4jc@virginia.edu                    0xAAAAAAAAAAAAAAAAULL);},
23612121Sar4jc@virginia.edu            "c.xor (0)");
23712121Sar4jc@virginia.edu
23812121Sar4jc@virginia.edu    // C.SUB
23912121Sar4jc@virginia.edu    expect<int64_t>(65535, []{return C::c_sub(65536, 1);}, "c.sub");
24012121Sar4jc@virginia.edu
24112121Sar4jc@virginia.edu    // C.ADDW
24212121Sar4jc@virginia.edu    expect<int64_t>(1073742078, []{return C::c_addw(0x3FFFFFFF, 255);},
24312121Sar4jc@virginia.edu            "c.addw");
24412121Sar4jc@virginia.edu    expect<int64_t>(-1, []{return C::c_addw(0x7FFFFFFF, 0x80000000);},
24512121Sar4jc@virginia.edu            "c.addw, overflow");
24612121Sar4jc@virginia.edu    expect<int64_t>(65536, []{return C::c_addw(0xFFFFFFFF0000FFFFLL, 1);},
24712121Sar4jc@virginia.edu            "c.addw, truncate");
24812121Sar4jc@virginia.edu
24912121Sar4jc@virginia.edu    // C.SUBW
25012121Sar4jc@virginia.edu    expect<int64_t>(65535, []{return C::c_subw(65536, 1);}, "c.subw");
25112121Sar4jc@virginia.edu    expect<int64_t>(-1, []{return C::c_subw(0x7FFFFFFF, 0x80000000);},
25212121Sar4jc@virginia.edu            "c.subw, \"overflow\"");
25312121Sar4jc@virginia.edu    expect<int64_t>(0,
25412121Sar4jc@virginia.edu            []{return C::c_subw(0xAAAAAAAAFFFFFFFFULL,0x55555555FFFFFFFFULL);},
25512121Sar4jc@virginia.edu            "c.subw, truncate");
25612121Sar4jc@virginia.edu}