26d900910ab4a9ac1efce5639e255ca037383ede
[gem5.git] / tests / test-progs / insttest / src / riscv / rv64c.h
1 /*
2 * Copyright (c) 2017 The University of Virginia
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Alec Roelke
29 */
30
31 #pragma once
32
33 #include <cstdint>
34 #include <type_traits>
35
36 #include "insttest.h"
37
38 #define CIOP(op, r, imm) asm volatile(op " %0,%1" : "+r" (r) : "i" (imm));
39 #define CROP(op, rd, rs) asm volatile(op " %0,%1" : "+r" (rd) : "r" (rs))
40
41 namespace C
42 {
43
44 inline int64_t
45 c_li(const int8_t imm)
46 {
47 int64_t rd = 0;
48 CIOP("c.li", rd, imm);
49 return rd;
50 }
51
52 inline int64_t
53 c_lui(const int8_t imm)
54 {
55 int64_t rd = 0;
56 CIOP("c.lui", rd, imm);
57 return rd;
58 }
59
60 inline int64_t
61 c_addi(int64_t r, const int8_t imm)
62 {
63 CIOP("c.addi", r, imm);
64 return r;
65 }
66
67 inline int64_t
68 c_addiw(int64_t r, const int8_t imm)
69 {
70 CIOP("c.addiw", r, imm);
71 return r;
72 }
73
74 inline uint64_t
75 c_addi4spn(const int16_t imm)
76 {
77 uint64_t rd = 0;
78 asm volatile("c.addi4spn %0,sp,%1" : "=r" (rd) : "i" (imm));
79 return rd;
80 }
81
82 inline uint64_t
83 c_slli(uint64_t r, uint8_t shamt)
84 {
85 CIOP("c.slli", r, shamt);
86 return r;
87 }
88
89 inline uint64_t
90 c_srli(uint64_t r, uint8_t shamt)
91 {
92 CIOP("c.srli", r, shamt);
93 return r;
94 }
95
96 inline int64_t
97 c_srai(int64_t r, uint8_t shamt)
98 {
99 CIOP("c.srai", r, shamt);
100 return r;
101 }
102
103 inline uint64_t
104 c_andi(uint64_t r, uint8_t imm)
105 {
106 CIOP("c.andi", r, imm);
107 return r;
108 }
109
110 inline int64_t
111 c_mv(int64_t rs)
112 {
113 int64_t rd = 0;
114 CROP("c.mv", rd, rs);
115 return rd;
116 }
117
118 inline int64_t
119 c_add(int64_t rd, int64_t rs)
120 {
121 CROP("c.add", rd, rs);
122 return rd;
123 }
124
125 inline uint64_t
126 c_and(int64_t rd, int64_t rs)
127 {
128 CROP("c.and", rd, rs);
129 return rd;
130 }
131
132 inline uint64_t
133 c_or(int64_t rd, int64_t rs)
134 {
135 CROP("c.or", rd, rs);
136 return rd;
137 }
138
139 inline uint64_t
140 c_xor(int64_t rd, int64_t rs)
141 {
142 CROP("c.xor", rd, rs);
143 return rd;
144 }
145
146 inline int64_t
147 c_sub(int64_t rd, int64_t rs)
148 {
149 CROP("c.sub", rd, rs);
150 return rd;
151 }
152
153 inline int64_t
154 c_addw(int64_t rd, int64_t rs)
155 {
156 CROP("c.addw", rd, rs);
157 return rd;
158 }
159
160 inline int64_t
161 c_subw(int64_t rd, int64_t rs)
162 {
163 CROP("c.subw", rd, rs);
164 return rd;
165 }
166
167 template<typename M, typename R> inline R
168 c_load(M m)
169 {
170 R r = 0;
171 switch (sizeof(M))
172 {
173 case 4:
174 asm volatile("c.lw %0,0(%1)" : "=r" (r) : "r" (&m) : "memory");
175 break;
176 case 8:
177 if (std::is_floating_point<M>::value)
178 asm volatile("c.fld %0,0(%1)" : "=f" (r) : "r" (&m) : "memory");
179 else
180 asm volatile("c.ld %0,0(%1)" : "=r" (r) : "r" (&m) : "memory");
181 break;
182 }
183 return r;
184 }
185
186 template<typename M> inline M
187 c_store(const M& rs)
188 {
189 M mem = 0;
190 switch (sizeof(M))
191 {
192 case 4:
193 asm volatile("c.sw %0,0(%1)" : : "r" (rs), "r" (&mem) : "memory");
194 break;
195 case 8:
196 if (std::is_floating_point<M>::value)
197 asm volatile("c.fsd %0,0(%1)" : : "f" (rs), "r" (&mem) : "memory");
198 else
199 asm volatile("c.sd %0,0(%1)" : : "r" (rs), "r" (&mem) : "memory");
200 break;
201 }
202 return mem;
203 }
204
205 inline bool
206 c_j()
207 {
208 asm volatile goto("c.j %l[jallabel]" : : : : jallabel);
209 return false;
210 jallabel:
211 return true;
212 }
213
214 inline bool
215 c_jr()
216 {
217 uint64_t a = 0;
218 asm volatile("auipc %0,0;"
219 "c.addi %0,12;"
220 "c.jr %0;"
221 "addi %0,zero,0;"
222 "addi %0,%0,0;"
223 : "+r" (a));
224 return a > 0;
225 }
226
227 inline bool
228 c_jalr()
229 {
230 int64_t a = 0;
231 asm volatile("auipc %0,0;"
232 "c.addi %0,12;"
233 "c.jalr %0;"
234 "addi %0,zero,0;"
235 "sub %0,ra,%0;"
236 : "+r" (a)
237 :
238 : "ra");
239 return a == -4;
240 }
241
242 inline bool
243 c_beqz(int64_t a)
244 {
245 asm volatile goto("c.beqz %0,%l[beqlabel]"
246 :
247 : "r" (a)
248 :
249 : beqlabel);
250 return false;
251 beqlabel:
252 return true;
253 }
254
255 inline bool
256 c_bnez(int64_t a)
257 {
258 asm volatile goto("c.bnez %0,%l[beqlabel]"
259 :
260 : "r" (a)
261 :
262 : beqlabel);
263 return false;
264 beqlabel:
265 return true;
266 }
267
268 } // namespace C