diff options
Diffstat (limited to 'tests/test-progs/insttest/src/riscv/rv64c.h')
-rw-r--r-- | tests/test-progs/insttest/src/riscv/rv64c.h | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/tests/test-progs/insttest/src/riscv/rv64c.h b/tests/test-progs/insttest/src/riscv/rv64c.h new file mode 100644 index 000000000..26d900910 --- /dev/null +++ b/tests/test-progs/insttest/src/riscv/rv64c.h @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2017 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 + */ + +#pragma once + +#include <cstdint> +#include <type_traits> + +#include "insttest.h" + +#define CIOP(op, r, imm) asm volatile(op " %0,%1" : "+r" (r) : "i" (imm)); +#define CROP(op, rd, rs) asm volatile(op " %0,%1" : "+r" (rd) : "r" (rs)) + +namespace C +{ + +inline int64_t +c_li(const int8_t imm) +{ + int64_t rd = 0; + CIOP("c.li", rd, imm); + return rd; +} + +inline int64_t +c_lui(const int8_t imm) +{ + int64_t rd = 0; + CIOP("c.lui", rd, imm); + return rd; +} + +inline int64_t +c_addi(int64_t r, const int8_t imm) +{ + CIOP("c.addi", r, imm); + return r; +} + +inline int64_t +c_addiw(int64_t r, const int8_t imm) +{ + CIOP("c.addiw", r, imm); + return r; +} + +inline uint64_t +c_addi4spn(const int16_t imm) +{ + uint64_t rd = 0; + asm volatile("c.addi4spn %0,sp,%1" : "=r" (rd) : "i" (imm)); + return rd; +} + +inline uint64_t +c_slli(uint64_t r, uint8_t shamt) +{ + CIOP("c.slli", r, shamt); + return r; +} + +inline uint64_t +c_srli(uint64_t r, uint8_t shamt) +{ + CIOP("c.srli", r, shamt); + return r; +} + +inline int64_t +c_srai(int64_t r, uint8_t shamt) +{ + CIOP("c.srai", r, shamt); + return r; +} + +inline uint64_t +c_andi(uint64_t r, uint8_t imm) +{ + CIOP("c.andi", r, imm); + return r; +} + +inline int64_t +c_mv(int64_t rs) +{ + int64_t rd = 0; + CROP("c.mv", rd, rs); + return rd; +} + +inline int64_t +c_add(int64_t rd, int64_t rs) +{ + CROP("c.add", rd, rs); + return rd; +} + +inline uint64_t +c_and(int64_t rd, int64_t rs) +{ + CROP("c.and", rd, rs); + return rd; +} + +inline uint64_t +c_or(int64_t rd, int64_t rs) +{ + CROP("c.or", rd, rs); + return rd; +} + +inline uint64_t +c_xor(int64_t rd, int64_t rs) +{ + CROP("c.xor", rd, rs); + return rd; +} + +inline int64_t +c_sub(int64_t rd, int64_t rs) +{ + CROP("c.sub", rd, rs); + return rd; +} + +inline int64_t +c_addw(int64_t rd, int64_t rs) +{ + CROP("c.addw", rd, rs); + return rd; +} + +inline int64_t +c_subw(int64_t rd, int64_t rs) +{ + CROP("c.subw", rd, rs); + return rd; +} + +template<typename M, typename R> inline R +c_load(M m) +{ + R r = 0; + switch (sizeof(M)) + { + case 4: + asm volatile("c.lw %0,0(%1)" : "=r" (r) : "r" (&m) : "memory"); + break; + case 8: + if (std::is_floating_point<M>::value) + asm volatile("c.fld %0,0(%1)" : "=f" (r) : "r" (&m) : "memory"); + else + asm volatile("c.ld %0,0(%1)" : "=r" (r) : "r" (&m) : "memory"); + break; + } + return r; +} + +template<typename M> inline M +c_store(const M& rs) +{ + M mem = 0; + switch (sizeof(M)) + { + case 4: + asm volatile("c.sw %0,0(%1)" : : "r" (rs), "r" (&mem) : "memory"); + break; + case 8: + if (std::is_floating_point<M>::value) + asm volatile("c.fsd %0,0(%1)" : : "f" (rs), "r" (&mem) : "memory"); + else + asm volatile("c.sd %0,0(%1)" : : "r" (rs), "r" (&mem) : "memory"); + break; + } + return mem; +} + +inline bool +c_j() +{ + asm volatile goto("c.j %l[jallabel]" : : : : jallabel); + return false; + jallabel: + return true; +} + +inline bool +c_jr() +{ + uint64_t a = 0; + asm volatile("auipc %0,0;" + "c.addi %0,12;" + "c.jr %0;" + "addi %0,zero,0;" + "addi %0,%0,0;" + : "+r" (a)); + return a > 0; +} + +inline bool +c_jalr() +{ + int64_t a = 0; + asm volatile("auipc %0,0;" + "c.addi %0,12;" + "c.jalr %0;" + "addi %0,zero,0;" + "sub %0,ra,%0;" + : "+r" (a) + : + : "ra"); + return a == -4; +} + +inline bool +c_beqz(int64_t a) +{ + asm volatile goto("c.beqz %0,%l[beqlabel]" + : + : "r" (a) + : + : beqlabel); + return false; + beqlabel: + return true; +} + +inline bool +c_bnez(int64_t a) +{ + asm volatile goto("c.bnez %0,%l[beqlabel]" + : + : "r" (a) + : + : beqlabel); + return false; + beqlabel: + return true; +} + +} // namespace C
\ No newline at end of file |