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#pragma once 32 33#include <cstdint> 34#include <tuple> 35 36#include "insttest.h" 37 38namespace A 39{ 40 41inline int64_t 42lr_w(int32_t& mem) 43{ 44 int64_t r = 0; 45 uint64_t addr = (uint64_t)&mem; 46 asm volatile("lr.w %0,(%1)" : "=r" (r) : "r" (addr) : "memory"); 47 return r; 48} 49 50inline std::pair<int64_t, uint64_t> 51sc_w(int64_t rs2, int32_t& mem) 52{ 53 uint64_t addr = (uint64_t)&mem; 54 uint64_t rd = -1; 55 asm volatile("sc.w %0,%2,(%1)" 56 : "=r" (rd) 57 : "r" (addr), "r" (rs2) 58 : "memory"); 59 return {mem, rd}; 60} 61 62inline std::pair<int64_t, int64_t> 63amoswap_w(int64_t mem, int64_t rs2) 64{ 65 int64_t rd = 0; 66 uint64_t addr = (uint64_t)&mem; 67 asm volatile("amoswap.w %0,%2,(%1)" 68 : "=r" (rd) 69 : "r" (addr), "r" (rs2) 70 : "memory"); 71 return {mem, rd}; 72} 73 74inline std::pair<int64_t, int64_t> 75amoadd_w(int64_t mem, int64_t rs2) 76{ 77 int64_t rd = 0; 78 uint64_t addr = (uint64_t)&mem; 79 asm volatile("amoadd.w %0,%2,(%1)" 80 : "=r" (rd) 81 : "r" (addr), "r" (rs2) 82 : "memory"); 83 return {mem, rd}; 84} 85 86inline std::pair<uint64_t, uint64_t> 87amoxor_w(uint64_t mem, uint64_t rs2) 88{ 89 uint64_t rd = 0; 90 uint64_t addr = (uint64_t)&mem; 91 asm volatile("amoxor.w %0,%2,(%1)" 92 : "=r" (rd) 93 : "r" (addr), "r" (rs2) 94 : "memory"); 95 return {mem, rd}; 96} 97 98inline std::pair<uint64_t, uint64_t> 99amoand_w(uint64_t mem, uint64_t rs2) 100{ 101 uint64_t rd = 0; 102 uint64_t addr = (uint64_t)&mem; 103 asm volatile("amoand.w %0,%2,(%1)" 104 : "=r" (rd) 105 : "r" (addr), "r" (rs2) 106 : "memory"); 107 return {mem, rd}; 108} 109 110inline std::pair<uint64_t, uint64_t> 111amoor_w(uint64_t mem, uint64_t rs2) 112{ 113 uint64_t rd = 0; 114 uint64_t addr = (uint64_t)&mem; 115 asm volatile("amoor.w %0,%2,(%1)" 116 : "=r" (rd) 117 : "r" (addr), "r" (rs2) 118 : "memory"); 119 return {mem, rd}; 120} 121 122inline std::pair<int64_t, int64_t> 123amomin_w(int64_t mem, int64_t rs2) 124{ 125 int64_t rd = 0; 126 uint64_t addr = (uint64_t)&mem; 127 asm volatile("amomin.w %0,%2,(%1)" 128 : "=r" (rd) 129 : "r" (addr), "r" (rs2) 130 : "memory"); 131 return {mem, rd}; 132} 133 134inline std::pair<int64_t, int64_t> 135amomax_w(int64_t mem, int64_t rs2) 136{ 137 int64_t rd = 0; 138 uint64_t addr = (uint64_t)&mem; 139 asm volatile("amomax.w %0,%2,(%1)" 140 : "=r" (rd) 141 : "r" (addr), "r" (rs2) 142 : "memory"); 143 return {mem, rd}; 144} 145 146inline std::pair<uint64_t, uint64_t> 147amominu_w(uint64_t mem, uint64_t rs2) 148{ 149 uint64_t rd = 0; 150 uint64_t addr = (uint64_t)&mem; 151 asm volatile("amominu.w %0,%2,(%1)" 152 : "=r" (rd) 153 : "r" (addr), "r" (rs2) 154 : "memory"); 155 return {mem, rd}; 156} 157 158inline std::pair<uint64_t, uint64_t> 159amomaxu_w(uint64_t mem, uint64_t rs2) 160{ 161 uint64_t rd = 0; 162 uint64_t addr = (uint64_t)&mem; 163 asm volatile("amomaxu.w %0,%2,(%1)" 164 : "=r" (rd) 165 : "r" (addr), "r" (rs2) 166 : "memory"); 167 return {mem, rd}; 168} 169 170inline int64_t 171lr_d(int64_t& mem) 172{ 173 int64_t r = 0; 174 uint64_t addr = (uint64_t)&mem; 175 asm volatile("lr.d %0,(%1)" : "=r" (r) : "r" (addr) : "memory"); 176 return r; 177} 178 179inline std::pair<int64_t, uint64_t> 180sc_d(int64_t rs2, int64_t& mem) 181{ 182 uint64_t addr = (uint64_t)&mem; 183 uint64_t rd = -1; 184 asm volatile("sc.d %0,%2,(%1)" 185 : "=r" (rd) 186 : "r" (addr), "r" (rs2) 187 : "memory"); 188 return {mem, rd}; 189} 190 191inline std::pair<int64_t, int64_t> 192amoswap_d(int64_t mem, int64_t rs2) 193{ 194 int64_t rd = 0; 195 uint64_t addr = (uint64_t)&mem; 196 asm volatile("amoswap.d %0,%2,(%1)" 197 : "=r" (rd) 198 : "r" (addr), "r" (rs2) 199 : "memory"); 200 return {mem, rd}; 201} 202 203inline std::pair<int64_t, int64_t> 204amoadd_d(int64_t mem, int64_t rs2) 205{ 206 int64_t rd = 0; 207 uint64_t addr = (uint64_t)&mem; 208 asm volatile("amoadd.d %0,%2,(%1)" 209 : "=r" (rd) 210 : "r" (addr), "r" (rs2) 211 : "memory"); 212 return {mem, rd}; 213} 214 215inline std::pair<uint64_t, uint64_t> 216amoxor_d(uint64_t mem, uint64_t rs2) 217{ 218 uint64_t rd = 0; 219 uint64_t addr = (uint64_t)&mem; 220 asm volatile("amoxor.d %0,%2,(%1)" 221 : "=r" (rd) 222 : "r" (addr), "r" (rs2) 223 : "memory"); 224 return {mem, rd}; 225} 226 227inline std::pair<uint64_t, uint64_t> 228amoand_d(uint64_t mem, uint64_t rs2) 229{ 230 uint64_t rd = 0; 231 uint64_t addr = (uint64_t)&mem; 232 asm volatile("amoand.d %0,%2,(%1)" 233 : "=r" (rd) 234 : "r" (addr), "r" (rs2) 235 : "memory"); 236 return {mem, rd}; 237} 238 239inline std::pair<uint64_t, uint64_t> 240amoor_d(uint64_t mem, uint64_t rs2) 241{ 242 uint64_t rd = 0; 243 uint64_t addr = (uint64_t)&mem; 244 asm volatile("amoor.d %0,%2,(%1)" 245 : "=r" (rd) 246 : "r" (addr), "r" (rs2) 247 : "memory"); 248 return {mem, rd}; 249} 250 251inline std::pair<int64_t, int64_t> 252amomin_d(int64_t mem, int64_t rs2) 253{ 254 int64_t rd = 0; 255 uint64_t addr = (uint64_t)&mem; 256 asm volatile("amomin.d %0,%2,(%1)" 257 : "=r" (rd) 258 : "r" (addr), "r" (rs2) 259 : "memory"); 260 return {mem, rd}; 261} 262 263inline std::pair<int64_t, int64_t> 264amomax_d(int64_t mem, int64_t rs2) 265{ 266 int64_t rd = 0; 267 uint64_t addr = (uint64_t)&mem; 268 asm volatile("amomax.d %0,%2,(%1)" 269 : "=r" (rd) 270 : "r" (addr), "r" (rs2) 271 : "memory"); 272 return {mem, rd}; 273} 274 275inline std::pair<uint64_t, uint64_t> 276amominu_d(uint64_t mem, uint64_t rs2) 277{ 278 uint64_t rd = 0; 279 uint64_t addr = (uint64_t)&mem; 280 asm volatile("amominu.d %0,%2,(%1)" 281 : "=r" (rd) 282 : "r" (addr), "r" (rs2) 283 : "memory"); 284 return {mem, rd}; 285} 286 287inline std::pair<uint64_t, uint64_t> 288amomaxu_d(uint64_t mem, uint64_t rs2) 289{ 290 uint64_t rd = 0; 291 uint64_t addr = (uint64_t)&mem; 292 asm volatile("amomaxu.d %0,%2,(%1)" 293 : "=r" (rd) 294 : "r" (addr), "r" (rs2) 295 : "memory"); 296 return {mem, rd}; 297} 298 299} // namespace A 300