riscv: fix Linux problems with LR and SC ops
[gem5.git] / tests / test-progs / insttest / src / riscv / rv64a.cpp
1 /*
2 * Copyright (c) 2016 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 #include <cstdint>
32 #include <limits>
33
34 #include "insttest.h"
35 #include "rv64a.h"
36
37 int main()
38 {
39 using namespace std;
40 using namespace insttest;
41
42 // Memory (LR.W, SC.W)
43 expect<pair<int64_t, int64_t>>({-1, 256}, []{
44 int32_t mem = -1;
45 int64_t rs2 = 256;
46 int64_t rd;
47 pair<int64_t, uint64_t> result;
48 do {
49 rd = A::lr_w(mem);
50 result = A::sc_w(rs2, mem);
51 } while (result.second == 1);
52 return pair<int64_t, uint64_t>(rd, result.first);
53 }, "lr.w/sc.w");
54 expect<pair<bool, int64_t>>({true, 200}, []{
55 int32_t mem = 200;
56 pair<int64_t, uint64_t> result = A::sc_w(50, mem);
57 return pair<bool, int64_t>(result.second == 1, mem);
58 }, "sc.w, no preceding lr.d");
59
60 // AMOSWAP.W
61 expect<pair<int64_t, int64_t>>({65535, 255},
62 []{return A::amoswap_w(255, 65535);}, "amoswap.w");
63 expect<pair<int64_t, int64_t>>({0xFFFFFFFF, -1},
64 []{return A::amoswap_w(0xFFFFFFFF, 0xFFFFFFFF);},
65 "amoswap.w, sign extend");
66 expect<pair<int64_t, int64_t>>({0x0000000180000000LL, -1},
67 []{return A::amoswap_w(0x00000001FFFFFFFFLL,
68 0x7FFFFFFF80000000LL);},
69 "amoswap.w, truncate");
70
71 // AMOADD.W
72 expect<pair<int64_t, int64_t>>({256, 255},
73 []{return A::amoadd_w(255, 1);}, "amoadd.w");
74 expect<pair<int64_t, int64_t>>({0, -1},
75 []{return A::amoadd_w(0xFFFFFFFF, 1);},
76 "amoadd.w, truncate/overflow");
77 expect<pair<int64_t, int64_t>>({0xFFFFFFFF, 0x7FFFFFFF},
78 []{return A::amoadd_w(0x7FFFFFFF, 0x80000000);},
79 "amoadd.w, sign extend");
80
81 // AMOXOR.W
82 expect<pair<uint64_t, uint64_t>>({0xFFFFFFFFAAAAAAAALL, -1},
83 []{return A::amoxor_w(-1, 0x5555555555555555LL);},
84 "amoxor.w, truncate");
85 expect<pair<uint64_t, uint64_t>>({0x80000000, -1},
86 []{return A::amoxor_w(0xFFFFFFFF, 0x7FFFFFFF);},
87 "amoxor.w, sign extend");
88
89 // AMOAND.W
90 expect<pair<uint64_t, uint64_t>>({0xFFFFFFFF00000000LL, -1},
91 []{return A::amoand_w(-1, 0);}, "amoand.w, truncate");
92 expect<pair<uint64_t, uint64_t>>({0x0000000080000000LL, -1},
93 []{return A::amoand_w(0xFFFFFFFF,numeric_limits<int32_t>::min());},
94 "amoand.w, sign extend");
95
96 // AMOOR.W
97 expect<pair<uint64_t, uint64_t>>({0x00000000FFFFFFFFLL, 0},
98 []{return A::amoor_w(0, -1);}, "amoor.w, truncate");
99 expect<pair<uint64_t, uint64_t>>({0x0000000080000000LL, 0},
100 []{return A::amoor_w(0, numeric_limits<int32_t>::min());},
101 "amoor.w, sign extend");
102
103 // AMOMIN.W
104 expect<pair<int64_t, int64_t>>({0x7FFFFFFF00000001LL, 1},
105 []{return A::amomin_w(0x7FFFFFFF00000001LL, 0xFFFFFFFF000000FF);},
106 "amomin.w, truncate");
107 expect<pair<int64_t, int64_t>>({0x00000000FFFFFFFELL, -1},
108 []{return A::amomin_w(0xFFFFFFFF, -2);}, "amomin.w, sign extend");
109
110 // AMOMAX.W
111 expect<pair<int64_t, int64_t>>({0x70000000000000FFLL, 1},
112 []{return A::amomax_w(0x7000000000000001LL,0x7FFFFFFF000000FFLL);},
113 "amomax.w, truncate");
114 expect<pair<int64_t, int64_t>>({-1, numeric_limits<int32_t>::min()},
115 []{return A::amomax_w(numeric_limits<int32_t>::min(), -1);},
116 "amomax.w, sign extend");
117
118 // AMOMINU.W
119 expect<pair<uint64_t, uint64_t>>({0x0FFFFFFF000000FFLL, -1},
120 []{return A::amominu_w(0x0FFFFFFFFFFFFFFFLL, 0xFFFFFFFF000000FF);},
121 "amominu.w, truncate");
122 expect<pair<uint64_t, uint64_t>>({0x0000000080000000LL, -1},
123 []{return A::amominu_w(0x00000000FFFFFFFFLL, 0x80000000);},
124 "amominu.w, sign extend");
125
126 // AMOMAXU.W
127 expect<pair<uint64_t, uint64_t>>({-1, 0},
128 []{return A::amomaxu_w(0xFFFFFFFF00000000LL,
129 0x00000000FFFFFFFFLL);},
130 "amomaxu.w, truncate");
131 expect<pair<uint64_t, uint64_t>>(
132 {0xFFFFFFFF, numeric_limits<int32_t>::min()},
133 []{return A::amomaxu_w(0x80000000, 0xFFFFFFFF);},
134 "amomaxu.w, sign extend");
135
136 // Memory (LR.D, SC.D)
137 expect<pair<int64_t, int64_t>>({-1, 256}, []{
138 int64_t mem = -1;
139 int64_t rs2 = 256;
140 int64_t rd;
141 pair<int64_t, uint64_t> result;
142 do {
143 rd = A::lr_d(mem);
144 result = A::sc_d(rs2, mem);
145 } while (result.second == 1);
146 return pair<int64_t, uint64_t>(rd, result.first);
147 }, "lr.d/sc.d");
148 expect<pair<bool, int64_t>>({true, 200}, []{
149 int64_t mem = 200;
150 pair<int64_t, uint64_t> result = A::sc_d(50, mem);
151 return pair<bool, int64_t>(result.second == 1, mem);
152 }, "sc.d, no preceding lr.d");
153
154 // AMOSWAP.D
155 expect<pair<int64_t, int64_t>>({1, -1}, []{return A::amoswap_d(-1, 1);},
156 "amoswap.d");
157
158 // AMOADD.D
159 expect<pair<int64_t, int64_t>>({0x7000000000000000LL,0x0FFFFFFFFFFFFFFFLL},
160 []{return A::amoadd_d(0x0FFFFFFFFFFFFFFFLL,0x6000000000000001LL);},
161 "amoadd.d");
162 expect<pair<int64_t, int64_t>>({0, 0x7FFFFFFFFFFFFFFFLL},
163 []{return A::amoadd_d(0x7FFFFFFFFFFFFFFFLL,0x8000000000000001LL);},
164 "amoadd.d, overflow");
165
166 // AMOXOR.D
167 expect<pair<int64_t, int64_t>>({-1, 0xAAAAAAAAAAAAAAAALL},
168 []{return A::amoxor_d(0xAAAAAAAAAAAAAAAALL,0x5555555555555555LL);},
169 "amoxor.d (1)");
170 expect<pair<int64_t, int64_t>>({0, 0xAAAAAAAAAAAAAAAALL},
171 []{return A::amoxor_d(0xAAAAAAAAAAAAAAAALL,0xAAAAAAAAAAAAAAAALL);},
172 "amoxor.d (0)");
173
174 // AMOAND.D
175 expect<pair<int64_t, int64_t>>({0xAAAAAAAAAAAAAAAALL, -1},
176 []{return A::amoand_d(-1, 0xAAAAAAAAAAAAAAAALL);}, "amoand.d");
177
178 // AMOOR.D
179 expect<pair<int64_t, int64_t>>({-1, 0xAAAAAAAAAAAAAAAALL},
180 []{return A::amoor_d(0xAAAAAAAAAAAAAAAALL, 0x5555555555555555LL);},
181 "amoor.d");
182
183 // AMOMIN.D
184 expect<pair<int64_t, int64_t>>({-1, -1},
185 []{return A::amomin_d(-1, 0);}, "amomin.d");
186
187 // AMOMAX.D
188 expect<pair<int64_t, int64_t>>({0, -1}, []{return A::amomax_d(-1, 0);},
189 "amomax.d");
190
191 // AMOMINU.D
192 expect<pair<uint64_t, uint64_t>>({0, -1},
193 []{return A::amominu_d(-1, 0);}, "amominu.d");
194
195 // AMOMAXU.D
196 expect<pair<uint64_t, uint64_t>>({-1, -1}, []{return A::amomaxu_d(-1, 0);},
197 "amomaxu.d");
198
199 return 0;
200 }