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#pragma once
3212121Sar4jc@virginia.edu
3312121Sar4jc@virginia.edu#include <cstdint>
3412121Sar4jc@virginia.edu#include <type_traits>
3512121Sar4jc@virginia.edu
3612121Sar4jc@virginia.edu#include "insttest.h"
3712121Sar4jc@virginia.edu
3812121Sar4jc@virginia.edu#define CIOP(op, r, imm) asm volatile(op " %0,%1" : "+r" (r) : "i" (imm));
3912121Sar4jc@virginia.edu#define CROP(op, rd, rs) asm volatile(op " %0,%1" : "+r" (rd) : "r" (rs))
4012121Sar4jc@virginia.edu
4112121Sar4jc@virginia.edunamespace C
4212121Sar4jc@virginia.edu{
4312121Sar4jc@virginia.edu
4412121Sar4jc@virginia.eduinline int64_t
4512121Sar4jc@virginia.educ_li(const int8_t imm)
4612121Sar4jc@virginia.edu{
4712121Sar4jc@virginia.edu    int64_t rd = 0;
4812121Sar4jc@virginia.edu    CIOP("c.li", rd, imm);
4912121Sar4jc@virginia.edu    return rd;
5012121Sar4jc@virginia.edu}
5112121Sar4jc@virginia.edu
5212121Sar4jc@virginia.eduinline int64_t
5312121Sar4jc@virginia.educ_lui(const int8_t imm)
5412121Sar4jc@virginia.edu{
5512121Sar4jc@virginia.edu    int64_t rd = 0;
5612121Sar4jc@virginia.edu    CIOP("c.lui", rd, imm);
5712121Sar4jc@virginia.edu    return rd;
5812121Sar4jc@virginia.edu}
5912121Sar4jc@virginia.edu
6012121Sar4jc@virginia.eduinline int64_t
6112121Sar4jc@virginia.educ_addi(int64_t r, const int8_t imm)
6212121Sar4jc@virginia.edu{
6312121Sar4jc@virginia.edu    CIOP("c.addi", r, imm);
6412121Sar4jc@virginia.edu    return r;
6512121Sar4jc@virginia.edu}
6612121Sar4jc@virginia.edu
6712121Sar4jc@virginia.eduinline int64_t
6812121Sar4jc@virginia.educ_addiw(int64_t r, const int8_t imm)
6912121Sar4jc@virginia.edu{
7012121Sar4jc@virginia.edu    CIOP("c.addiw", r, imm);
7112121Sar4jc@virginia.edu    return r;
7212121Sar4jc@virginia.edu}
7312121Sar4jc@virginia.edu
7412121Sar4jc@virginia.eduinline uint64_t
7512121Sar4jc@virginia.educ_addi4spn(const int16_t imm)
7612121Sar4jc@virginia.edu{
7712121Sar4jc@virginia.edu    uint64_t rd = 0;
7812121Sar4jc@virginia.edu    asm volatile("c.addi4spn %0,sp,%1" : "=r" (rd) : "i" (imm));
7912121Sar4jc@virginia.edu    return rd;
8012121Sar4jc@virginia.edu}
8112121Sar4jc@virginia.edu
8212121Sar4jc@virginia.eduinline uint64_t
8312121Sar4jc@virginia.educ_slli(uint64_t r, uint8_t shamt)
8412121Sar4jc@virginia.edu{
8512121Sar4jc@virginia.edu    CIOP("c.slli", r, shamt);
8612121Sar4jc@virginia.edu    return r;
8712121Sar4jc@virginia.edu}
8812121Sar4jc@virginia.edu
8912121Sar4jc@virginia.eduinline uint64_t
9012121Sar4jc@virginia.educ_srli(uint64_t r, uint8_t shamt)
9112121Sar4jc@virginia.edu{
9212121Sar4jc@virginia.edu    CIOP("c.srli", r, shamt);
9312121Sar4jc@virginia.edu    return r;
9412121Sar4jc@virginia.edu}
9512121Sar4jc@virginia.edu
9612121Sar4jc@virginia.eduinline int64_t
9712121Sar4jc@virginia.educ_srai(int64_t r, uint8_t shamt)
9812121Sar4jc@virginia.edu{
9912121Sar4jc@virginia.edu    CIOP("c.srai", r, shamt);
10012121Sar4jc@virginia.edu    return r;
10112121Sar4jc@virginia.edu}
10212121Sar4jc@virginia.edu
10312121Sar4jc@virginia.eduinline uint64_t
10412121Sar4jc@virginia.educ_andi(uint64_t r, uint8_t imm)
10512121Sar4jc@virginia.edu{
10612121Sar4jc@virginia.edu    CIOP("c.andi", r, imm);
10712121Sar4jc@virginia.edu    return r;
10812121Sar4jc@virginia.edu}
10912121Sar4jc@virginia.edu
11012121Sar4jc@virginia.eduinline int64_t
11112121Sar4jc@virginia.educ_mv(int64_t rs)
11212121Sar4jc@virginia.edu{
11312121Sar4jc@virginia.edu    int64_t rd = 0;
11412121Sar4jc@virginia.edu    CROP("c.mv", rd, rs);
11512121Sar4jc@virginia.edu    return rd;
11612121Sar4jc@virginia.edu}
11712121Sar4jc@virginia.edu
11812121Sar4jc@virginia.eduinline int64_t
11912121Sar4jc@virginia.educ_add(int64_t rd, int64_t rs)
12012121Sar4jc@virginia.edu{
12112121Sar4jc@virginia.edu    CROP("c.add", rd, rs);
12212121Sar4jc@virginia.edu    return rd;
12312121Sar4jc@virginia.edu}
12412121Sar4jc@virginia.edu
12512121Sar4jc@virginia.eduinline uint64_t
12612121Sar4jc@virginia.educ_and(int64_t rd, int64_t rs)
12712121Sar4jc@virginia.edu{
12812121Sar4jc@virginia.edu    CROP("c.and", rd, rs);
12912121Sar4jc@virginia.edu    return rd;
13012121Sar4jc@virginia.edu}
13112121Sar4jc@virginia.edu
13212121Sar4jc@virginia.eduinline uint64_t
13312121Sar4jc@virginia.educ_or(int64_t rd, int64_t rs)
13412121Sar4jc@virginia.edu{
13512121Sar4jc@virginia.edu    CROP("c.or", rd, rs);
13612121Sar4jc@virginia.edu    return rd;
13712121Sar4jc@virginia.edu}
13812121Sar4jc@virginia.edu
13912121Sar4jc@virginia.eduinline uint64_t
14012121Sar4jc@virginia.educ_xor(int64_t rd, int64_t rs)
14112121Sar4jc@virginia.edu{
14212121Sar4jc@virginia.edu    CROP("c.xor", rd, rs);
14312121Sar4jc@virginia.edu    return rd;
14412121Sar4jc@virginia.edu}
14512121Sar4jc@virginia.edu
14612121Sar4jc@virginia.eduinline int64_t
14712121Sar4jc@virginia.educ_sub(int64_t rd, int64_t rs)
14812121Sar4jc@virginia.edu{
14912121Sar4jc@virginia.edu    CROP("c.sub", rd, rs);
15012121Sar4jc@virginia.edu    return rd;
15112121Sar4jc@virginia.edu}
15212121Sar4jc@virginia.edu
15312121Sar4jc@virginia.eduinline int64_t
15412121Sar4jc@virginia.educ_addw(int64_t rd, int64_t rs)
15512121Sar4jc@virginia.edu{
15612121Sar4jc@virginia.edu    CROP("c.addw", rd, rs);
15712121Sar4jc@virginia.edu    return rd;
15812121Sar4jc@virginia.edu}
15912121Sar4jc@virginia.edu
16012121Sar4jc@virginia.eduinline int64_t
16112121Sar4jc@virginia.educ_subw(int64_t rd, int64_t rs)
16212121Sar4jc@virginia.edu{
16312121Sar4jc@virginia.edu    CROP("c.subw", rd, rs);
16412121Sar4jc@virginia.edu    return rd;
16512121Sar4jc@virginia.edu}
16612121Sar4jc@virginia.edu
16712121Sar4jc@virginia.edutemplate<typename M, typename R> inline R
16812121Sar4jc@virginia.educ_load(M m)
16912121Sar4jc@virginia.edu{
17012121Sar4jc@virginia.edu    R r = 0;
17112121Sar4jc@virginia.edu    switch (sizeof(M))
17212121Sar4jc@virginia.edu    {
17312121Sar4jc@virginia.edu      case 4:
17412121Sar4jc@virginia.edu        asm volatile("c.lw %0,0(%1)" : "=r" (r) : "r" (&m) : "memory");
17512121Sar4jc@virginia.edu        break;
17612121Sar4jc@virginia.edu      case 8:
17712121Sar4jc@virginia.edu        if (std::is_floating_point<M>::value)
17812121Sar4jc@virginia.edu            asm volatile("c.fld %0,0(%1)" : "=f" (r) : "r" (&m) : "memory");
17912121Sar4jc@virginia.edu        else
18012121Sar4jc@virginia.edu            asm volatile("c.ld %0,0(%1)" : "=r" (r) : "r" (&m) : "memory");
18112121Sar4jc@virginia.edu        break;
18212121Sar4jc@virginia.edu    }
18312121Sar4jc@virginia.edu    return r;
18412121Sar4jc@virginia.edu}
18512121Sar4jc@virginia.edu
18612121Sar4jc@virginia.edutemplate<typename M> inline M
18712121Sar4jc@virginia.educ_store(const M& rs)
18812121Sar4jc@virginia.edu{
18912121Sar4jc@virginia.edu    M mem = 0;
19012121Sar4jc@virginia.edu    switch (sizeof(M))
19112121Sar4jc@virginia.edu    {
19212121Sar4jc@virginia.edu      case 4:
19312121Sar4jc@virginia.edu        asm volatile("c.sw %0,0(%1)" : : "r" (rs), "r" (&mem) : "memory");
19412121Sar4jc@virginia.edu        break;
19512121Sar4jc@virginia.edu      case 8:
19612121Sar4jc@virginia.edu        if (std::is_floating_point<M>::value)
19712121Sar4jc@virginia.edu            asm volatile("c.fsd %0,0(%1)" : : "f" (rs), "r" (&mem) : "memory");
19812121Sar4jc@virginia.edu        else
19912121Sar4jc@virginia.edu            asm volatile("c.sd %0,0(%1)" : : "r" (rs), "r" (&mem) : "memory");
20012121Sar4jc@virginia.edu        break;
20112121Sar4jc@virginia.edu    }
20212121Sar4jc@virginia.edu    return mem;
20312121Sar4jc@virginia.edu}
20412121Sar4jc@virginia.edu
20512121Sar4jc@virginia.eduinline bool
20612121Sar4jc@virginia.educ_j()
20712121Sar4jc@virginia.edu{
20812121Sar4jc@virginia.edu    asm volatile goto("c.j %l[jallabel]" : : : : jallabel);
20912121Sar4jc@virginia.edu    return false;
21012121Sar4jc@virginia.edu  jallabel:
21112121Sar4jc@virginia.edu    return true;
21212121Sar4jc@virginia.edu}
21312121Sar4jc@virginia.edu
21412121Sar4jc@virginia.eduinline bool
21512121Sar4jc@virginia.educ_jr()
21612121Sar4jc@virginia.edu{
21712121Sar4jc@virginia.edu    uint64_t a = 0;
21812121Sar4jc@virginia.edu    asm volatile("auipc %0,0;"
21912121Sar4jc@virginia.edu                 "c.addi %0,12;"
22012121Sar4jc@virginia.edu                 "c.jr %0;"
22112121Sar4jc@virginia.edu                 "addi %0,zero,0;"
22212121Sar4jc@virginia.edu                 "addi %0,%0,0;"
22312121Sar4jc@virginia.edu                 : "+r" (a));
22412121Sar4jc@virginia.edu    return a > 0;
22512121Sar4jc@virginia.edu}
22612121Sar4jc@virginia.edu
22712121Sar4jc@virginia.eduinline bool
22812121Sar4jc@virginia.educ_jalr()
22912121Sar4jc@virginia.edu{
23012121Sar4jc@virginia.edu    int64_t a = 0;
23112121Sar4jc@virginia.edu    asm volatile("auipc %0,0;"
23212121Sar4jc@virginia.edu                 "c.addi %0,12;"
23312121Sar4jc@virginia.edu                 "c.jalr %0;"
23412121Sar4jc@virginia.edu                 "addi %0,zero,0;"
23512121Sar4jc@virginia.edu                 "sub %0,ra,%0;"
23612121Sar4jc@virginia.edu                 : "+r" (a)
23712121Sar4jc@virginia.edu                 :
23812121Sar4jc@virginia.edu                 : "ra");
23912121Sar4jc@virginia.edu    return a == -4;
24012121Sar4jc@virginia.edu}
24112121Sar4jc@virginia.edu
24212121Sar4jc@virginia.eduinline bool
24312121Sar4jc@virginia.educ_beqz(int64_t a)
24412121Sar4jc@virginia.edu{
24512121Sar4jc@virginia.edu    asm volatile goto("c.beqz %0,%l[beqlabel]"
24612121Sar4jc@virginia.edu            :
24712121Sar4jc@virginia.edu            : "r" (a)
24812121Sar4jc@virginia.edu            :
24912121Sar4jc@virginia.edu            : beqlabel);
25012121Sar4jc@virginia.edu    return false;
25112121Sar4jc@virginia.edu  beqlabel:
25212121Sar4jc@virginia.edu    return true;
25312121Sar4jc@virginia.edu}
25412121Sar4jc@virginia.edu
25512121Sar4jc@virginia.eduinline bool
25612121Sar4jc@virginia.educ_bnez(int64_t a)
25712121Sar4jc@virginia.edu{
25812121Sar4jc@virginia.edu    asm volatile goto("c.bnez %0,%l[beqlabel]"
25912121Sar4jc@virginia.edu            :
26012121Sar4jc@virginia.edu            : "r" (a)
26112121Sar4jc@virginia.edu            :
26212121Sar4jc@virginia.edu            : beqlabel);
26312121Sar4jc@virginia.edu    return false;
26412121Sar4jc@virginia.edu  beqlabel:
26512121Sar4jc@virginia.edu    return true;
26612121Sar4jc@virginia.edu}
26712121Sar4jc@virginia.edu
26812121Sar4jc@virginia.edu} // namespace C