2 * Copyright (c) 2017 The University of Virginia
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.
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.
37 using namespace insttest
;
41 expect
<bool>(true, []{
42 uint64_t lw
= 0, lwsp
= -1;
44 asm volatile("lw %0,%2(sp);"
46 : "=r" (lw
), "=r" (lwsp
)
52 expect
<bool>(true, []{
53 uint64_t ld
= 0, ldsp
= -1;
55 asm volatile("ld %0,%2(sp);"
57 : "=r" (ld
), "=r" (ldsp
)
63 expect
<bool>(true, []{
64 double fld
= 0.0, fldsp
= -1.0;
66 asm volatile("fld %0,%2(sp);"
68 : "=f" (fld
), "=f" (fldsp
)
70 return D::bits(fld
) == D::bits(fldsp
);
74 expect
<bool>(true, []{
75 int64_t value
= -1, result
= 0;
76 asm volatile("addi sp,sp,-8;"
83 return value
== result
;
87 expect
<bool>(true, []{
88 int64_t value
= -1, result
= 0;
89 asm volatile("addi sp,sp,-8;"
96 return value
== result
;
100 expect
<bool>(true, []{
101 double value
= 0.1, result
= numeric_limits
<double>::signaling_NaN();
102 asm volatile("addi sp,sp,-8;"
109 return value
== result
;
113 expect
<int64_t>(458752,
114 []{return C::c_load
<int32_t, int64_t>(0x00070000);},
116 expect
<int64_t>(numeric_limits
<int32_t>::min(),
117 []{return C::c_load
<int32_t, int64_t>(0x80000000);},
119 expect
<int64_t>(30064771072,
120 []{return C::c_load
<int64_t, int64_t>(30064771072);}, "c.ld");
121 expect
<double>(3.1415926, []{return C::c_load
<double, double>(3.1415926);},
125 expect
<uint32_t>(0xFFFFFFFF, []{return C::c_store
<int32_t>(-1);}, "c.sw");
126 expect
<uint64_t>(-1, []{return C::c_store
<int64_t>(-1);}, "c.sd");
127 expect
<double>(1.61803398875,
128 []{return C::c_store
<double>(1.61803398875);}, "c.fsd");
131 expect
<bool>(true, []{return C::c_j();}, "c.j");
132 expect
<bool>(true, []{return C::c_jr();}, "c.jr");
133 expect
<bool>(true, []{return C::c_jalr();}, "c.jalr");
136 expect
<bool>(true, []{return C::c_beqz(0);}, "c.beqz, zero");
137 expect
<bool>(false, []{return C::c_beqz(7);}, "c.beqz, not zero");
140 expect
<bool>(true, []{return C::c_bnez(15);}, "c.bnez, not zero");
141 expect
<bool>(false, []{return C::c_bnez(0);}, "c.bnez, zero");
144 expect
<int64_t>(1, []{return C::c_li(1);}, "c.li");
145 expect
<int64_t>(-1, []{return C::c_li(-1);}, "c.li, sign extend");
148 expect
<int64_t>(4096, []{return C::c_lui(1);}, "c.lui");
149 // Note that sign extension can't be tested here because apparently the
150 // compiler doesn't allow the 6th (sign) bit of the immediate to be 1
153 expect
<int64_t>(15, []{return C::c_addi(7, 8);}, "c.addi");
156 expect
<int64_t>(15, []{return C::c_addiw(8, 7);}, "c.addiw");
157 expect
<int64_t>(1, []{return C::c_addiw(0xFFFFFFFF, 2);},
158 "c.addiw, overflow");
159 expect
<int64_t>(1, []{return C::c_addiw(0x100000001, 0);},
160 "c.addiw, truncate");
163 expect
<bool>(true, []{
164 uint64_t sp
= 0, rd
= 0;
166 asm volatile("mv %0,sp;"
170 : "+r" (sp
), "=r" (rd
)
172 return rd
== sp
+ i
*16;
176 expect
<bool>(true, []{
177 uint64_t sp
= 0, rd
= 0;
179 asm volatile("mv %0,sp;"
180 "c.addi4spn %1,sp,%2;"
181 : "=r" (sp
), "=r" (rd
)
183 return rd
== sp
+ i
*4;
187 expect
<uint64_t>(16, []{return C::c_slli(1, 4);}, "c.slli");
188 expect
<uint64_t>(0, []{return C::c_slli(8, 61);}, "c.slli, overflow");
191 expect
<uint64_t>(4, []{return C::c_srli(128, 5);}, "c.srli");
192 expect
<uint64_t>(0, []{return C::c_srli(128, 8);}, "c.srli, overflow");
193 expect
<uint64_t>(1, []{return C::c_srli(-1, 63);}, "c.srli, -1");
196 expect
<uint64_t>(4, []{return C::c_srai(128, 5);}, "c.srai");
197 expect
<uint64_t>(0, []{return C::c_srai(128, 8);}, "c.srai, overflow");
198 expect
<uint64_t>(-1, []{return C::c_srai(-2, 63);}, "c.srai, -1");
201 expect
<uint64_t>(0, []{return C::c_andi(-1, 0);}, "c.andi (0)");
202 expect
<uint64_t>(0x1234567812345678ULL
,
203 []{return C::c_andi(0x1234567812345678ULL
, -1);}, "c.andi (1)");
206 expect
<int64_t>(1024, []{return C::c_mv(1024);}, "c.mv");
209 expect
<int64_t>(15, []{return C::c_add(10, 5);}, "c.add");
212 expect
<uint64_t>(0, []{return C::c_and(-1, 0);}, "c.and (0)");
213 expect
<uint64_t>(0x1234567812345678ULL
,
214 []{return C::c_and(0x1234567812345678ULL
, -1);}, "c.and (-1)");
218 []{return C::c_or(0xAAAAAAAAAAAAAAAAULL
,
219 0x5555555555555555ULL
);},
221 expect
<uint64_t>(0xAAAAAAAAAAAAAAAAULL
,
222 []{return C::c_or(0xAAAAAAAAAAAAAAAAULL
,
223 0xAAAAAAAAAAAAAAAAULL
);},
228 []{return C::c_xor(0xAAAAAAAAAAAAAAAAULL
,
229 0x5555555555555555ULL
);},
232 []{return C::c_xor(0xAAAAAAAAAAAAAAAAULL
,
233 0xAAAAAAAAAAAAAAAAULL
);},
237 expect
<int64_t>(65535, []{return C::c_sub(65536, 1);}, "c.sub");
240 expect
<int64_t>(1073742078, []{return C::c_addw(0x3FFFFFFF, 255);},
242 expect
<int64_t>(-1, []{return C::c_addw(0x7FFFFFFF, 0x80000000);},
244 expect
<int64_t>(65536, []{return C::c_addw(0xFFFFFFFF0000FFFFLL
, 1);},
248 expect
<int64_t>(65535, []{return C::c_subw(65536, 1);}, "c.subw");
249 expect
<int64_t>(-1, []{return C::c_subw(0x7FFFFFFF, 0x80000000);},
250 "c.subw, \"overflow\"");
252 []{return C::c_subw(0xAAAAAAAAFFFFFFFFULL
,0x55555555FFFFFFFFULL
);},