111730Sar4jc@virginia.edu/*
211730Sar4jc@virginia.edu * Copyright (c) 2016 The University of Virginia
311730Sar4jc@virginia.edu * All rights reserved.
411730Sar4jc@virginia.edu *
511730Sar4jc@virginia.edu * Redistribution and use in source and binary forms, with or without
611730Sar4jc@virginia.edu * modification, are permitted provided that the following conditions are
711730Sar4jc@virginia.edu * met: redistributions of source code must retain the above copyright
811730Sar4jc@virginia.edu * notice, this list of conditions and the following disclaimer;
911730Sar4jc@virginia.edu * redistributions in binary form must reproduce the above copyright
1011730Sar4jc@virginia.edu * notice, this list of conditions and the following disclaimer in the
1111730Sar4jc@virginia.edu * documentation and/or other materials provided with the distribution;
1211730Sar4jc@virginia.edu * neither the name of the copyright holders nor the names of its
1311730Sar4jc@virginia.edu * contributors may be used to endorse or promote products derived from
1411730Sar4jc@virginia.edu * this software without specific prior written permission.
1511730Sar4jc@virginia.edu *
1611730Sar4jc@virginia.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711730Sar4jc@virginia.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811730Sar4jc@virginia.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911730Sar4jc@virginia.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011730Sar4jc@virginia.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111730Sar4jc@virginia.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211730Sar4jc@virginia.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311730Sar4jc@virginia.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411730Sar4jc@virginia.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511730Sar4jc@virginia.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611730Sar4jc@virginia.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711730Sar4jc@virginia.edu *
2811730Sar4jc@virginia.edu * Authors: Alec Roelke
2911730Sar4jc@virginia.edu */
3011730Sar4jc@virginia.edu
3111730Sar4jc@virginia.edu#include <fcntl.h>
3211730Sar4jc@virginia.edu#include <sys/stat.h>
3311730Sar4jc@virginia.edu#include <sys/time.h>
3411730Sar4jc@virginia.edu#include <sys/times.h>
3511730Sar4jc@virginia.edu#include <sys/types.h>
3611730Sar4jc@virginia.edu#include <unistd.h>
3711730Sar4jc@virginia.edu
3811730Sar4jc@virginia.edu#include <cstdint>
3911730Sar4jc@virginia.edu#include <cstring>
4011730Sar4jc@virginia.edu#include <iostream>
4111730Sar4jc@virginia.edu#include <limits>
4211730Sar4jc@virginia.edu
4311730Sar4jc@virginia.edu#include "insttest.h"
4411730Sar4jc@virginia.edu#include "rv64i.h"
4511730Sar4jc@virginia.edu
4611730Sar4jc@virginia.eduint main()
4711730Sar4jc@virginia.edu{
4811730Sar4jc@virginia.edu    using namespace std;
4911730Sar4jc@virginia.edu    using namespace insttest;
5011730Sar4jc@virginia.edu
5111730Sar4jc@virginia.edu    // LUI
5211730Sar4jc@virginia.edu    expect<int64_t>(4096, []{return I::lui(1);}, "lui");
5311730Sar4jc@virginia.edu    expect<int64_t>(numeric_limits<int32_t>::min(),
5411730Sar4jc@virginia.edu            []{return I::lui(0x80000);}, "lui, negative");
5511730Sar4jc@virginia.edu
5611730Sar4jc@virginia.edu    // AUIPC
5711730Sar4jc@virginia.edu    expect<bool>(true, []{return I::auipc(3);}, "auipc");
5811730Sar4jc@virginia.edu
5911730Sar4jc@virginia.edu    // Jump (JAL, JALR)
6011730Sar4jc@virginia.edu    expect<bool>(true, []{return I::jal();}, "jal");
6111730Sar4jc@virginia.edu    expect<bool>(true, []{return I::jalr();}, "jalr");
6211730Sar4jc@virginia.edu
6311730Sar4jc@virginia.edu    // BEQ
6411730Sar4jc@virginia.edu    expect<bool>(true, []{return I::beq(5, 5);}, "beq, equal");
6511730Sar4jc@virginia.edu    expect<bool>(false, []{return I::beq(numeric_limits<int64_t>::max(),
6611730Sar4jc@virginia.edu            numeric_limits<int64_t>::min());}, "beq, not equal");
6711730Sar4jc@virginia.edu
6811730Sar4jc@virginia.edu    // BNE
6911730Sar4jc@virginia.edu    expect<bool>(false, []{return I::bne(5, 5);}, "bne, equal");
7011730Sar4jc@virginia.edu    expect<bool>(true, []{return I::bne(numeric_limits<int64_t>::max(),
7111730Sar4jc@virginia.edu            numeric_limits<int64_t>::min());}, "bne, not equal");
7211730Sar4jc@virginia.edu
7311730Sar4jc@virginia.edu    // BLT
7411730Sar4jc@virginia.edu    expect<bool>(true, []{return I::blt(numeric_limits<int64_t>::min(),
7511730Sar4jc@virginia.edu            numeric_limits<int64_t>::max());}, "blt, less");
7611730Sar4jc@virginia.edu    expect<bool>(false, []{return I::blt(numeric_limits<int64_t>::min(),
7711730Sar4jc@virginia.edu            numeric_limits<int64_t>::min());}, "blt, equal");
7811730Sar4jc@virginia.edu    expect<bool>(false, []{return I::blt(numeric_limits<int64_t>::max(),
7911730Sar4jc@virginia.edu            numeric_limits<int64_t>::min());}, "blt, greater");
8011730Sar4jc@virginia.edu
8111730Sar4jc@virginia.edu    // BGE
8211730Sar4jc@virginia.edu    expect<bool>(false, []{return I::bge(numeric_limits<int64_t>::min(),
8311730Sar4jc@virginia.edu            numeric_limits<int64_t>::max());}, "bge, less");
8411730Sar4jc@virginia.edu    expect<bool>(true, []{return I::bge(numeric_limits<int64_t>::min(),
8511730Sar4jc@virginia.edu            numeric_limits<int64_t>::min());}, "bge, equal");
8611730Sar4jc@virginia.edu    expect<bool>(true, []{return I::bge(numeric_limits<int64_t>::max(),
8711730Sar4jc@virginia.edu            numeric_limits<int64_t>::min());}, "bge, greater");
8811730Sar4jc@virginia.edu
8911730Sar4jc@virginia.edu    // BLTU
9011730Sar4jc@virginia.edu    expect<bool>(true, []{return I::blt(numeric_limits<int64_t>::min(),
9111730Sar4jc@virginia.edu            numeric_limits<int64_t>::max());}, "bltu, greater");
9211730Sar4jc@virginia.edu    expect<bool>(false, []{return I::blt(numeric_limits<int64_t>::min(),
9311730Sar4jc@virginia.edu            numeric_limits<int64_t>::min());}, "bltu, equal");
9411730Sar4jc@virginia.edu    expect<bool>(false, []{return I::blt(numeric_limits<int64_t>::max(),
9511730Sar4jc@virginia.edu            numeric_limits<int64_t>::min());}, "bltu, less");
9611730Sar4jc@virginia.edu
9711730Sar4jc@virginia.edu    // BGEU
9811730Sar4jc@virginia.edu    expect<bool>(false, []{return I::bge(numeric_limits<int64_t>::min(),
9911730Sar4jc@virginia.edu            numeric_limits<int64_t>::max());}, "bgeu, greater");
10011730Sar4jc@virginia.edu    expect<bool>(true, []{return I::bge(numeric_limits<int64_t>::min(),
10111730Sar4jc@virginia.edu            numeric_limits<int64_t>::min());}, "bgeu, equal");
10211730Sar4jc@virginia.edu    expect<bool>(true, []{return I::bge(numeric_limits<int64_t>::max(),
10311730Sar4jc@virginia.edu            numeric_limits<int64_t>::min());}, "bgeu, less");
10411730Sar4jc@virginia.edu
10511730Sar4jc@virginia.edu    // Load (LB, LH, LW, LBU, LHU)
10611730Sar4jc@virginia.edu    expect<int64_t>(7, []{return I::load<int8_t, int64_t>(0x07);},
10711730Sar4jc@virginia.edu            "lb, positive");
10811730Sar4jc@virginia.edu    expect<int64_t>(numeric_limits<int8_t>::min(),
10911730Sar4jc@virginia.edu            []{return I::load<int8_t, int64_t>(0x80);}, "lb, negative");
11011730Sar4jc@virginia.edu    expect<int64_t>(1792, []{return I::load<int16_t, int64_t>(0x0700);},
11111730Sar4jc@virginia.edu            "lh, positive");
11211730Sar4jc@virginia.edu    expect<int64_t>(numeric_limits<int16_t>::min(),
11311730Sar4jc@virginia.edu            []{return I::load<int16_t, int64_t>(0x8000);}, "lh, negative");
11411730Sar4jc@virginia.edu    expect<int64_t>(458752, []{return I::load<int32_t, int64_t>(0x00070000);},
11511730Sar4jc@virginia.edu            "lw, positive");
11611730Sar4jc@virginia.edu    expect<int64_t>(numeric_limits<int32_t>::min(),
11711730Sar4jc@virginia.edu            []{return I::load<int32_t, int64_t>(0x80000000);},
11811730Sar4jc@virginia.edu            "lw, negative");
11911730Sar4jc@virginia.edu    expect<uint64_t>(128, []{return I::load<uint8_t, uint64_t>(0x80);}, "lbu");
12011730Sar4jc@virginia.edu    expect<uint64_t>(32768, []{return I::load<uint16_t, uint64_t>(0x8000);},
12111730Sar4jc@virginia.edu            "lhu");
12211730Sar4jc@virginia.edu
12311730Sar4jc@virginia.edu    // Store (SB, SH, SW)
12411730Sar4jc@virginia.edu    expect<uint8_t>(0xFF, []{return I::store<int8_t>(-1);}, "sb");
12511730Sar4jc@virginia.edu    expect<uint16_t>(0xFFFF, []{return I::store<int16_t>(-1);}, "sh");
12611730Sar4jc@virginia.edu    expect<uint32_t>(0xFFFFFFFF, []{return I::store<int32_t>(-1);}, "sw");
12711730Sar4jc@virginia.edu
12811730Sar4jc@virginia.edu    // ADDI
12911730Sar4jc@virginia.edu    expect<int64_t>(1073742078, []{return I::addi(0x3FFFFFFF, 255);},
13011730Sar4jc@virginia.edu            "addi");
13111730Sar4jc@virginia.edu    expect<int64_t>(1, []{return I::addi(-1, 2);}, "addi, overflow");
13211730Sar4jc@virginia.edu
13311730Sar4jc@virginia.edu    // SLTI
13411730Sar4jc@virginia.edu    expect<bool>(true, []{return I::slti(-1, 0);}, "slti, true");
13511730Sar4jc@virginia.edu    expect<bool>(false, []{return I::slti(0, -1);}, "slti, false");
13611730Sar4jc@virginia.edu
13711730Sar4jc@virginia.edu    // SLTIU
13811730Sar4jc@virginia.edu    expect<bool>(false, []{return I::sltiu(-1, 0);}, "sltiu, false");
13911730Sar4jc@virginia.edu    expect<bool>(true, []{return I::sltiu(0, -1);}, "sltiu, true");
14012428Sar4jc@virginia.edu    expect<bool>(true, []{return I::sltiu(0xFFFF, -1);}, "sltiu, sext");
14111730Sar4jc@virginia.edu
14211730Sar4jc@virginia.edu    // XORI
14311730Sar4jc@virginia.edu    expect<uint64_t>(0xFF, []{return I::xori(0xAA, 0x55);}, "xori (1)");
14411730Sar4jc@virginia.edu    expect<uint64_t>(0, []{return I::xori(0xAA, 0xAA);}, "xori (0)");
14511730Sar4jc@virginia.edu
14611730Sar4jc@virginia.edu    // ORI
14711730Sar4jc@virginia.edu    expect<uint64_t>(0xFF, []{return I::ori(0xAA, 0x55);}, "ori (1)");
14811730Sar4jc@virginia.edu    expect<uint64_t>(0xAA, []{return I::ori(0xAA, 0xAA);}, "ori (A)");
14911730Sar4jc@virginia.edu
15011730Sar4jc@virginia.edu    // ANDI
15111730Sar4jc@virginia.edu    expect<uint64_t>(0, []{return I::andi(-1, 0);}, "andi (0)");
15211730Sar4jc@virginia.edu    expect<uint64_t>(0x1234567812345678ULL,
15311730Sar4jc@virginia.edu            []{return I::andi(0x1234567812345678ULL, -1);}, "andi (1)");
15411730Sar4jc@virginia.edu
15511730Sar4jc@virginia.edu    // SLLI
15611730Sar4jc@virginia.edu    expect<int64_t>(65280, []{return I::slli(255, 8);}, "slli, general");
15711730Sar4jc@virginia.edu    expect<int64_t>(numeric_limits<int64_t>::min(),
15811730Sar4jc@virginia.edu            []{return I::slli(255, 63);}, "slli, erase");
15911730Sar4jc@virginia.edu
16011730Sar4jc@virginia.edu    // SRLI
16111730Sar4jc@virginia.edu    expect<int64_t>(255, []{return I::srli(65280, 8);}, "srli, general");
16211730Sar4jc@virginia.edu    expect<int64_t>(0, []{return I::srli(255, 8);}, "srli, erase");
16311730Sar4jc@virginia.edu    expect<int64_t>(1, []{return I::srli(numeric_limits<int64_t>::min(), 63);},
16411730Sar4jc@virginia.edu            "srli, negative");
16511730Sar4jc@virginia.edu
16611730Sar4jc@virginia.edu    // SRAI
16711730Sar4jc@virginia.edu    expect<int64_t>(255, []{return I::srai(65280, 8);}, "srai, general");
16811730Sar4jc@virginia.edu    expect<int64_t>(0, []{return I::srai(255, 8);}, "srai, erase");
16911730Sar4jc@virginia.edu    expect<int64_t>(-1,
17011730Sar4jc@virginia.edu            []{return I::srai(numeric_limits<int64_t>::min(), 63);},
17111730Sar4jc@virginia.edu            "srai, negative");
17211730Sar4jc@virginia.edu
17311730Sar4jc@virginia.edu    // ADD
17411730Sar4jc@virginia.edu    expect<int64_t>(1073742078, []{return I::add(0x3FFFFFFF, 255);}, "add");
17511730Sar4jc@virginia.edu    expect<int64_t>(-1,
17611730Sar4jc@virginia.edu            []{return I::add(0x7FFFFFFFFFFFFFFFLL, 0x8000000000000000LL);},
17711730Sar4jc@virginia.edu            "add, overflow");
17811730Sar4jc@virginia.edu
17911730Sar4jc@virginia.edu    // SUB
18011730Sar4jc@virginia.edu    expect<int64_t>(65535, []{return I::sub(65536, 1);}, "sub");
18111730Sar4jc@virginia.edu    expect<int64_t>(-1,
18211730Sar4jc@virginia.edu            []{return I::sub(0x7FFFFFFFFFFFFFFFLL, 0x8000000000000000LL);},
18311730Sar4jc@virginia.edu            "sub, \"overflow\"");
18411730Sar4jc@virginia.edu
18511730Sar4jc@virginia.edu    // SLL
18611730Sar4jc@virginia.edu    expect<int64_t>(65280, []{return I::sll(255, 8);}, "sll, general");
18711730Sar4jc@virginia.edu    expect<int64_t>(numeric_limits<int64_t>::min(),
18811730Sar4jc@virginia.edu            []{return I::sll(255, 63);}, "sll, erase");
18911730Sar4jc@virginia.edu
19011730Sar4jc@virginia.edu    // SLT
19111730Sar4jc@virginia.edu    expect<bool>(true, []{return I::slt(-1, 0);}, "slt, true");
19211730Sar4jc@virginia.edu    expect<bool>(false, []{return I::slt(0, -1);}, "slt, false");
19311730Sar4jc@virginia.edu
19411730Sar4jc@virginia.edu    // SLTU
19511730Sar4jc@virginia.edu    expect<bool>(false, []{return I::sltu(-1, 0);}, "sltu, false");
19611730Sar4jc@virginia.edu    expect<bool>(true, []{return I::sltu(0, -1);}, "sltu, true");
19711730Sar4jc@virginia.edu
19811730Sar4jc@virginia.edu    // XOR
19911730Sar4jc@virginia.edu    expect<uint64_t>(-1,
20011730Sar4jc@virginia.edu            []{return I::xor_inst(0xAAAAAAAAAAAAAAAAULL,
20111730Sar4jc@virginia.edu                    0x5555555555555555ULL);},
20211730Sar4jc@virginia.edu            "xor (1)");
20311730Sar4jc@virginia.edu    expect<uint64_t>(0,
20411730Sar4jc@virginia.edu            []{return I::xor_inst(0xAAAAAAAAAAAAAAAAULL,
20511730Sar4jc@virginia.edu                    0xAAAAAAAAAAAAAAAAULL);},
20611730Sar4jc@virginia.edu            "xor (0)");
20711730Sar4jc@virginia.edu
20811730Sar4jc@virginia.edu    // SRL
20911730Sar4jc@virginia.edu    expect<uint64_t>(255, []{return I::srl(65280, 8);}, "srl, general");
21011730Sar4jc@virginia.edu    expect<uint64_t>(0, []{return I::srl(255, 8);}, "srl, erase");
21111730Sar4jc@virginia.edu    expect<uint64_t>(1, []{return I::srl(numeric_limits<int64_t>::min(), 63);},
21211730Sar4jc@virginia.edu            "srl, negative");
21311730Sar4jc@virginia.edu
21411730Sar4jc@virginia.edu    // SRA
21511730Sar4jc@virginia.edu    expect<int64_t>(255, []{return I::sra(65280, 8);}, "sra, general");
21611730Sar4jc@virginia.edu    expect<int64_t>(0, []{return I::sra(255, 8);}, "sra, erase");
21711730Sar4jc@virginia.edu    expect<int64_t>(-1, []{return I::sra(numeric_limits<int64_t>::min(), 63);},
21811730Sar4jc@virginia.edu            "sra, negative");
21911730Sar4jc@virginia.edu
22011730Sar4jc@virginia.edu    // OR
22111730Sar4jc@virginia.edu    expect<uint64_t>(-1,
22211730Sar4jc@virginia.edu            []{return I::or_inst(0xAAAAAAAAAAAAAAAAULL,
22311730Sar4jc@virginia.edu                    0x5555555555555555ULL);},
22411730Sar4jc@virginia.edu            "or (1)");
22511730Sar4jc@virginia.edu    expect<uint64_t>(0xAAAAAAAAAAAAAAAAULL,
22611730Sar4jc@virginia.edu            []{return I::or_inst(0xAAAAAAAAAAAAAAAAULL,
22711730Sar4jc@virginia.edu                    0xAAAAAAAAAAAAAAAAULL);},
22811730Sar4jc@virginia.edu            "or (A)");
22911730Sar4jc@virginia.edu
23011730Sar4jc@virginia.edu    // AND
23111730Sar4jc@virginia.edu    expect<uint64_t>(0, []{return I::and_inst(-1, 0);}, "and (0)");
23211730Sar4jc@virginia.edu    expect<uint64_t>(0x1234567812345678ULL,
23311730Sar4jc@virginia.edu            []{return I::and_inst(0x1234567812345678ULL, -1);}, "and (-1)");
23411730Sar4jc@virginia.edu
23511730Sar4jc@virginia.edu    // FENCE/FENCE.I
23611730Sar4jc@virginia.edu    asm volatile("fence" : : );
23711730Sar4jc@virginia.edu    asm volatile("fence.i" : : );
23811730Sar4jc@virginia.edu
23911730Sar4jc@virginia.edu    // ECALL
24011730Sar4jc@virginia.edu    char fname[] = "test.txt";
24111730Sar4jc@virginia.edu    char teststr[] = "this is a test";
24211730Sar4jc@virginia.edu    expect<bool>(true, [=]{
24311730Sar4jc@virginia.edu            int fd = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0644);
24411730Sar4jc@virginia.edu            if (fd < 0) {
24511730Sar4jc@virginia.edu                return false;
24611730Sar4jc@virginia.edu            }
24711730Sar4jc@virginia.edu            size_t n = write(fd, teststr, sizeof(teststr));
24811730Sar4jc@virginia.edu            cout << "Bytes written: " << n << endl;
24911730Sar4jc@virginia.edu            return close(fd) >= 0 && n > 0;
25011730Sar4jc@virginia.edu        }, "open, write");
25111730Sar4jc@virginia.edu    expect<int>(0, [=]{return access(fname, F_OK);}, "access F_OK");
25211730Sar4jc@virginia.edu    expect<int>(0, [=]{return access(fname, R_OK);}, "access R_OK");
25311730Sar4jc@virginia.edu    expect<int>(0, [=]{return access(fname, W_OK);}, "access W_OK");
25411730Sar4jc@virginia.edu    // gem5's implementation of access is incorrect; it should return
25511730Sar4jc@virginia.edu    // -1 on failure, not -errno.  Account for this using an inequality.
25611730Sar4jc@virginia.edu    expect<bool>(true, [=]{return access(fname, X_OK) != 0;}, "access X_OK");
25711730Sar4jc@virginia.edu    expect<bool>(true, [=]{
25811730Sar4jc@virginia.edu            struct stat stat_buf, fstat_buf;
25911730Sar4jc@virginia.edu            int s = stat(fname, &stat_buf);
26011730Sar4jc@virginia.edu            if (s < 0) {
26111730Sar4jc@virginia.edu                return false;
26211730Sar4jc@virginia.edu            } else {
26311730Sar4jc@virginia.edu                cout << "stat:" << endl;
26411730Sar4jc@virginia.edu                cout << "\tst_dev =\t" << stat_buf.st_dev << endl;
26511730Sar4jc@virginia.edu                cout << "\tst_ino =\t" << stat_buf.st_ino << endl;
26611730Sar4jc@virginia.edu                cout << "\tst_mode =\t" << stat_buf.st_mode << endl;
26711730Sar4jc@virginia.edu                cout << "\tst_nlink =\t" << stat_buf.st_nlink << endl;
26811730Sar4jc@virginia.edu                cout << "\tst_uid =\t" << stat_buf.st_uid << endl;
26911730Sar4jc@virginia.edu                cout << "\tst_gid =\t" << stat_buf.st_gid << endl;
27011730Sar4jc@virginia.edu                cout << "\tst_rdev =\t" << stat_buf.st_rdev << endl;
27111730Sar4jc@virginia.edu                cout << "\tst_size =\t" << stat_buf.st_size << endl;
27211730Sar4jc@virginia.edu                cout << "\tst_blksize =\t" << stat_buf.st_blksize << endl;
27311730Sar4jc@virginia.edu                cout << "\tst_blocks =\t" << stat_buf.st_blocks << endl;
27411730Sar4jc@virginia.edu            }
27511730Sar4jc@virginia.edu            int fd = open(fname, O_RDONLY);
27611730Sar4jc@virginia.edu            if (fd < 0) {
27711730Sar4jc@virginia.edu                return false;
27811730Sar4jc@virginia.edu            }
27911730Sar4jc@virginia.edu            int f = fstat(fd, &fstat_buf);
28011730Sar4jc@virginia.edu            if (f >= 0) {
28111730Sar4jc@virginia.edu                cout << "fstat:" << endl;
28211730Sar4jc@virginia.edu                cout << "\tst_dev =\t" << fstat_buf.st_dev << endl;
28311730Sar4jc@virginia.edu                cout << "\tst_ino =\t" << fstat_buf.st_ino << endl;
28411730Sar4jc@virginia.edu                cout << "\tst_mode =\t" << fstat_buf.st_mode << endl;
28511730Sar4jc@virginia.edu                cout << "\tst_nlink =\t" << fstat_buf.st_nlink << endl;
28611730Sar4jc@virginia.edu                cout << "\tst_uid =\t" << fstat_buf.st_uid << endl;
28711730Sar4jc@virginia.edu                cout << "\tst_gid =\t" << fstat_buf.st_gid << endl;
28811730Sar4jc@virginia.edu                cout << "\tst_rdev =\t" << fstat_buf.st_rdev << endl;
28911730Sar4jc@virginia.edu                cout << "\tst_size =\t" << fstat_buf.st_size << endl;
29011730Sar4jc@virginia.edu                cout << "\tst_blksize =\t" << fstat_buf.st_blksize << endl;
29111730Sar4jc@virginia.edu                cout << "\tst_blocks =\t" << fstat_buf.st_blocks << endl;
29211730Sar4jc@virginia.edu            }
29311730Sar4jc@virginia.edu            return close(fd) >= 0 && f >= 0;
29411730Sar4jc@virginia.edu        }, "open, stat");
29511730Sar4jc@virginia.edu    expect<bool>(true, [=]{
29611730Sar4jc@virginia.edu            int fd = open(fname, O_RDONLY);
29711730Sar4jc@virginia.edu            if (fd < 0) {
29811730Sar4jc@virginia.edu                return false;
29911730Sar4jc@virginia.edu            }
30011730Sar4jc@virginia.edu            char in[128];
30111730Sar4jc@virginia.edu            size_t n = read(fd, in, sizeof(in));
30211730Sar4jc@virginia.edu            cout << "Bytes read: " << n << endl;
30311730Sar4jc@virginia.edu            cout << "String read: " << in << endl;
30411730Sar4jc@virginia.edu            int cl = close(fd);
30511730Sar4jc@virginia.edu            int un = unlink(fname);
30611730Sar4jc@virginia.edu            return n > 0 && cl >= 0 && un >= 0 && strcmp(teststr, in) == 0;
30711730Sar4jc@virginia.edu        }, "open, read, unlink");
30811730Sar4jc@virginia.edu    expect<bool>(true, []{
30911730Sar4jc@virginia.edu            struct tms buf;
31011730Sar4jc@virginia.edu            clock_t t = times(&buf);
31111730Sar4jc@virginia.edu            cout << "times:" << endl;
31211730Sar4jc@virginia.edu            cout << "\ttms_utime =\t" << buf.tms_utime << endl;
31311730Sar4jc@virginia.edu            cout << "\ttms_stime =\t" << buf.tms_stime << endl;
31411730Sar4jc@virginia.edu            cout << "\ttms_cutime =\t" << buf.tms_cutime << endl;
31511730Sar4jc@virginia.edu            cout << "\ttms_cstime =\t" << buf.tms_cstime << endl;
31611730Sar4jc@virginia.edu            return t > 0;
31711730Sar4jc@virginia.edu        }, "times");
31811730Sar4jc@virginia.edu    expect<int>(0, []{
31911730Sar4jc@virginia.edu            struct timeval time;
32011730Sar4jc@virginia.edu            int res = gettimeofday(&time, nullptr);
32111730Sar4jc@virginia.edu            cout << "timeval:" << endl;
32211730Sar4jc@virginia.edu            cout << "\ttv_sec =\t" << time.tv_sec << endl;
32311730Sar4jc@virginia.edu            cout << "\ttv_usec =\t" << time.tv_usec << endl;
32411730Sar4jc@virginia.edu            return res;
32511730Sar4jc@virginia.edu        }, "gettimeofday");
32611730Sar4jc@virginia.edu
32711730Sar4jc@virginia.edu    // EBREAK not tested because it only makes sense in FS mode or when
32811730Sar4jc@virginia.edu    // using gdb
32911730Sar4jc@virginia.edu
33011730Sar4jc@virginia.edu    // ERET not tested because it only makes sense in FS mode and will cause
33111730Sar4jc@virginia.edu    // a panic when used in SE mode
33211730Sar4jc@virginia.edu
33311730Sar4jc@virginia.edu    // CSRs (RDCYCLE, RDTIME, RDINSTRET)
33411730Sar4jc@virginia.edu    expect<bool>(true, []{
33511730Sar4jc@virginia.edu                uint64_t cycles = 0;
33611730Sar4jc@virginia.edu                asm("rdcycle %0" : "=r" (cycles));
33711730Sar4jc@virginia.edu                cout << "Cycles: " << cycles << endl;
33811730Sar4jc@virginia.edu                return cycles > 0;
33911730Sar4jc@virginia.edu            }, "rdcycle");
34011730Sar4jc@virginia.edu    expect<bool>(true, []{
34111730Sar4jc@virginia.edu                uint64_t time = 0;
34211730Sar4jc@virginia.edu                asm("rdtime %0" : "=r" (time));
34311730Sar4jc@virginia.edu                cout << "Time: " << time << endl;
34411730Sar4jc@virginia.edu                return time > 0;
34511730Sar4jc@virginia.edu            }, "rdtime");
34611730Sar4jc@virginia.edu    expect<bool>(true, []{
34711730Sar4jc@virginia.edu                uint64_t instret = 0;
34811730Sar4jc@virginia.edu                asm("rdinstret %0" : "=r" (instret));
34911730Sar4jc@virginia.edu                cout << "Instructions Retired: " << instret << endl;
35011730Sar4jc@virginia.edu                return instret > 0;
35111730Sar4jc@virginia.edu            }, "rdinstret");
35211730Sar4jc@virginia.edu
35311730Sar4jc@virginia.edu    // 64-bit memory (LWU, LD, SD)
35411730Sar4jc@virginia.edu    expect<int64_t>(0xFFFFFFFF, []{return I::load<uint32_t, uint64_t>(-1);},
35511730Sar4jc@virginia.edu            "lwu");
35611730Sar4jc@virginia.edu    expect<int64_t>(30064771072,
35711730Sar4jc@virginia.edu            []{return I::load<int64_t, int64_t>(30064771072);}, "ld");
35811730Sar4jc@virginia.edu    expect<uint64_t>(-1, []{return I::store<int64_t>(-1);}, "sd");
35911730Sar4jc@virginia.edu
36011730Sar4jc@virginia.edu    // ADDIW
36111730Sar4jc@virginia.edu    expect<int64_t>(268435710, []{return I::addiw(0x0FFFFFFF, 255);}, "addiw");
36211730Sar4jc@virginia.edu    expect<int64_t>(-2147481602, []{return I::addiw(0x7FFFFFFF, 0x7FF);},
36311730Sar4jc@virginia.edu            "addiw, overflow");
36411730Sar4jc@virginia.edu    expect<int64_t>(0, []{return I::addiw(0x7FFFFFFFFFFFFFFFLL, 1);},
36511730Sar4jc@virginia.edu            "addiw, truncate");
36611730Sar4jc@virginia.edu
36711730Sar4jc@virginia.edu    // SLLIW
36811730Sar4jc@virginia.edu    expect<int64_t>(65280, []{return I::slliw(255, 8);}, "slliw, general");
36911730Sar4jc@virginia.edu    expect<int64_t>(numeric_limits<int32_t>::min(),
37011730Sar4jc@virginia.edu            []{return I::slliw(255, 31);}, "slliw, erase");
37111730Sar4jc@virginia.edu    expect<int64_t>(numeric_limits<int32_t>::min(),
37211730Sar4jc@virginia.edu            []{return I::slliw(0xFFFFFFFF00800000LL, 8);}, "slliw, truncate");
37311730Sar4jc@virginia.edu
37411730Sar4jc@virginia.edu    // SRLIW
37511730Sar4jc@virginia.edu    expect<int64_t>(255, []{return I::srliw(65280, 8);}, "srliw, general");
37611730Sar4jc@virginia.edu    expect<int64_t>(0, []{return I::srliw(255, 8);}, "srliw, erase");
37711730Sar4jc@virginia.edu    expect<int64_t>(1,
37811730Sar4jc@virginia.edu            []{return I::srliw(numeric_limits<int32_t>::min(), 31);},
37911730Sar4jc@virginia.edu            "srliw, negative");
38011730Sar4jc@virginia.edu    expect<int64_t>(1, []{return I::srliw(0xFFFFFFFF80000000LL, 31);},
38111730Sar4jc@virginia.edu            "srliw, truncate");
38211730Sar4jc@virginia.edu
38311730Sar4jc@virginia.edu    // SRAIW
38411730Sar4jc@virginia.edu    expect<int64_t>(255, []{return I::sraiw(65280, 8);}, "sraiw, general");
38511730Sar4jc@virginia.edu    expect<int64_t>(0, []{return I::sraiw(255, 8);}, "sraiw, erase");
38611730Sar4jc@virginia.edu    expect<int64_t>(-1,
38711730Sar4jc@virginia.edu            []{return I::sraiw(numeric_limits<int32_t>::min(), 31);},
38811730Sar4jc@virginia.edu            "sraiw, negative");
38911730Sar4jc@virginia.edu    expect<int64_t>(-1, []{return I::sraiw(0x0000000180000000LL, 31);},
39011730Sar4jc@virginia.edu            "sraiw, truncate");
39111730Sar4jc@virginia.edu
39211730Sar4jc@virginia.edu    // ADDW
39311730Sar4jc@virginia.edu    expect<int64_t>(1073742078, []{return I::addw(0x3FFFFFFF, 255);}, "addw");
39411730Sar4jc@virginia.edu    expect<int64_t>(-1, []{return I::addw(0x7FFFFFFF, 0x80000000);},
39511730Sar4jc@virginia.edu            "addw, overflow");
39611730Sar4jc@virginia.edu    expect<int64_t>(65536, []{return I::addw(0xFFFFFFFF0000FFFFLL, 1);},
39711730Sar4jc@virginia.edu            "addw, truncate");
39811730Sar4jc@virginia.edu
39911730Sar4jc@virginia.edu    // SUBW
40011730Sar4jc@virginia.edu    expect<int64_t>(65535, []{return I::subw(65536, 1);}, "subw");
40111730Sar4jc@virginia.edu    expect<int64_t>(-1, []{return I::subw(0x7FFFFFFF, 0x80000000);},
40211730Sar4jc@virginia.edu            "subw, \"overflow\"");
40311730Sar4jc@virginia.edu    expect<int64_t>(0,
40411730Sar4jc@virginia.edu            []{return I::subw(0xAAAAAAAAFFFFFFFFULL, 0x55555555FFFFFFFFULL);},
40511730Sar4jc@virginia.edu            "subw, truncate");
40611730Sar4jc@virginia.edu
40711730Sar4jc@virginia.edu    // SLLW
40811730Sar4jc@virginia.edu    expect<int64_t>(65280, []{return I::sllw(255, 8);}, "sllw, general");
40911730Sar4jc@virginia.edu    expect<int64_t>(numeric_limits<int32_t>::min(),
41011730Sar4jc@virginia.edu            []{return I::sllw(255, 31);}, "sllw, erase");
41111730Sar4jc@virginia.edu    expect<int64_t>(numeric_limits<int32_t>::min(),
41211730Sar4jc@virginia.edu            []{return I::sllw(0xFFFFFFFF00008000LL, 16);}, "sllw, truncate");
41311730Sar4jc@virginia.edu
41411730Sar4jc@virginia.edu    // SRLW
41511730Sar4jc@virginia.edu    expect<uint64_t>(255, []{return I::srlw(65280, 8);}, "srlw, general");
41611730Sar4jc@virginia.edu    expect<uint64_t>(0, []{return I::srlw(255, 8);}, "srlw, erase");
41711730Sar4jc@virginia.edu    expect<uint64_t>(1,
41811730Sar4jc@virginia.edu            []{return I::srlw(numeric_limits<int32_t>::min(), 31);},
41911730Sar4jc@virginia.edu            "srlw, negative");
42011730Sar4jc@virginia.edu    expect<uint64_t>(1, []{return I::srlw(0x0000000180000000LL, 31);},
42111730Sar4jc@virginia.edu            "srlw, truncate");
42211730Sar4jc@virginia.edu
42311730Sar4jc@virginia.edu    // SRAW
42411730Sar4jc@virginia.edu    expect<int64_t>(255, []{return I::sraw(65280, 8);}, "sraw, general");
42511730Sar4jc@virginia.edu    expect<int64_t>(0, []{return I::sraw(255, 8);}, "sraw, erase");
42611730Sar4jc@virginia.edu    expect<int64_t>(-1,
42711730Sar4jc@virginia.edu            []{return I::sraw(numeric_limits<int32_t>::min(), 31);},
42811730Sar4jc@virginia.edu            "sraw, negative");
42911730Sar4jc@virginia.edu    expect<int64_t>(1, []{return I::sraw(0xFFFFFFFF40000000LL, 30);},
43011730Sar4jc@virginia.edu            "sraw, truncate");
43111730Sar4jc@virginia.edu
43211730Sar4jc@virginia.edu    return 0;
43311730Sar4jc@virginia.edu}
434