1/* 2 * Copyright (c) 2011-2013,2017 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Gabe Black 38 */ 39#ifndef __ARCH_ARM_MEM64_HH__ 40#define __ARCH_ARM_MEM64_HH__ 41 42#include "arch/arm/insts/misc64.hh" 43#include "arch/arm/insts/static_inst.hh" 44 45namespace ArmISA 46{ 47 48class SysDC64 : public MiscRegOp64 49{ 50 protected: 51 IntRegIndex base; 52 MiscRegIndex dest; 53 uint64_t imm; 54 55 SysDC64(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 56 IntRegIndex _base, MiscRegIndex _dest, uint64_t _imm) 57 : MiscRegOp64(mnem, _machInst, __opClass, false), 58 base(_base), dest(_dest), imm(_imm) 59 {} 60 61 std::string generateDisassembly( 62 Addr pc, const SymbolTable *symtab) const override; 63}; 64 65class MightBeMicro64 : public ArmStaticInst 66{ 67 protected: 68 MightBeMicro64(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 69 : ArmStaticInst(mnem, _machInst, __opClass) 70 {} 71 72 void 73 advancePC(PCState &pcState) const 74 { 75 if (flags[IsLastMicroop]) { 76 pcState.uEnd(); 77 } else if (flags[IsMicroop]) { 78 pcState.uAdvance(); 79 } else { 80 pcState.advance(); 81 } 82 } 83}; 84 85class Memory64 : public MightBeMicro64 86{ 87 public: 88 enum AddrMode { 89 AddrMd_Offset, 90 AddrMd_PreIndex, 91 AddrMd_PostIndex 92 }; 93 94 protected: 95 96 IntRegIndex dest; 97 IntRegIndex base; 98 /// True if the base register is SP (used for SP alignment checking). 99 bool baseIsSP; 100 static const unsigned numMicroops = 3; 101 102 StaticInstPtr *uops; 103 104 Memory64(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 105 IntRegIndex _dest, IntRegIndex _base) 106 : MightBeMicro64(mnem, _machInst, __opClass), 107 dest(_dest), base(_base), uops(NULL), memAccessFlags(0) 108 { 109 baseIsSP = isSP(_base); 110 } 111 112 virtual 113 ~Memory64() 114 { 115 delete [] uops; 116 } 117 118 StaticInstPtr 119 fetchMicroop(MicroPC microPC) const override 120 { 121 assert(uops != NULL && microPC < numMicroops); 122 return uops[microPC]; 123 } 124 125 void startDisassembly(std::ostream &os) const; 126 127 unsigned memAccessFlags; 128 129 void setExcAcRel(bool exclusive, bool acrel); 130}; 131 132class MemoryImm64 : public Memory64 133{ 134 protected: 135 int64_t imm; 136 137 MemoryImm64(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 138 IntRegIndex _dest, IntRegIndex _base, int64_t _imm) 139 : Memory64(mnem, _machInst, __opClass, _dest, _base), imm(_imm) 140 {} 141 142 std::string generateDisassembly( 143 Addr pc, const SymbolTable *symtab) const override; 144}; 145 146class MemoryDImm64 : public MemoryImm64 147{ 148 protected: 149 IntRegIndex dest2; 150 151 MemoryDImm64(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 152 IntRegIndex _dest, IntRegIndex _dest2, IntRegIndex _base, 153 int64_t _imm) 154 : MemoryImm64(mnem, _machInst, __opClass, _dest, _base, _imm), 155 dest2(_dest2) 156 {} 157 158 std::string generateDisassembly( 159 Addr pc, const SymbolTable *symtab) const override; 160}; 161 162class MemoryDImmEx64 : public MemoryDImm64 163{ 164 protected: 165 IntRegIndex result; 166 167 MemoryDImmEx64(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 168 IntRegIndex _result, IntRegIndex _dest, IntRegIndex _dest2, 169 IntRegIndex _base, int32_t _imm) 170 : MemoryDImm64(mnem, _machInst, __opClass, _dest, _dest2, 171 _base, _imm), result(_result) 172 {} 173 174 std::string generateDisassembly( 175 Addr pc, const SymbolTable *symtab) const override; 176}; 177 178class MemoryPreIndex64 : public MemoryImm64 179{ 180 protected: 181 MemoryPreIndex64(const char *mnem, ExtMachInst _machInst, 182 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base, 183 int64_t _imm) 184 : MemoryImm64(mnem, _machInst, __opClass, _dest, _base, _imm) 185 {} 186 187 std::string generateDisassembly( 188 Addr pc, const SymbolTable *symtab) const override; 189}; 190 191class MemoryPostIndex64 : public MemoryImm64 192{ 193 protected: 194 MemoryPostIndex64(const char *mnem, ExtMachInst _machInst, 195 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base, 196 int64_t _imm) 197 : MemoryImm64(mnem, _machInst, __opClass, _dest, _base, _imm) 198 {} 199 200 std::string generateDisassembly( 201 Addr pc, const SymbolTable *symtab) const override; 202}; 203 204class MemoryReg64 : public Memory64 205{ 206 protected: 207 IntRegIndex offset; 208 ArmExtendType type; 209 uint64_t shiftAmt; 210 211 MemoryReg64(const char *mnem, ExtMachInst _machInst, 212 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base, 213 IntRegIndex _offset, ArmExtendType _type, 214 uint64_t _shiftAmt) 215 : Memory64(mnem, _machInst, __opClass, _dest, _base), 216 offset(_offset), type(_type), shiftAmt(_shiftAmt) 217 {} 218 219 std::string generateDisassembly( 220 Addr pc, const SymbolTable *symtab) const override; 221}; 222 223class MemoryRaw64 : public Memory64 224{ 225 protected: 226 MemoryRaw64(const char *mnem, ExtMachInst _machInst, 227 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base) 228 : Memory64(mnem, _machInst, __opClass, _dest, _base) 229 {} 230 231 std::string generateDisassembly( 232 Addr pc, const SymbolTable *symtab) const override; 233}; 234 235class MemoryEx64 : public Memory64 236{ 237 protected: 238 IntRegIndex result; 239 240 MemoryEx64(const char *mnem, ExtMachInst _machInst, 241 OpClass __opClass, IntRegIndex _dest, IntRegIndex _base, 242 IntRegIndex _result) 243 : Memory64(mnem, _machInst, __opClass, _dest, _base), result(_result) 244 {} 245 246 std::string generateDisassembly( 247 Addr pc, const SymbolTable *symtab) const override; 248}; 249 250class MemoryLiteral64 : public Memory64 251{ 252 protected: 253 int64_t imm; 254 255 MemoryLiteral64(const char *mnem, ExtMachInst _machInst, 256 OpClass __opClass, IntRegIndex _dest, int64_t _imm) 257 : Memory64(mnem, _machInst, __opClass, _dest, INTREG_ZERO), imm(_imm) 258 {} 259 260 std::string generateDisassembly( 261 Addr pc, const SymbolTable *symtab) const override; 262}; 263 264/** 265 * A generic atomic op class 266 */ 267 268template<typename T> 269class AtomicGeneric2Op : public TypedAtomicOpFunctor<T> 270{ 271 public: 272 AtomicGeneric2Op(T _a, std::function<void(T*,T)> _op) 273 : a(_a), op(_op) 274 {} 275 AtomicOpFunctor* clone() override 276 { 277 return new AtomicGeneric2Op<T>(*this); 278 } 279 void execute(T *b) override 280 { 281 op(b, a); 282 } 283 private: 284 T a; 285 std::function<void(T*,T)> op; 286 }; 287 288template<typename T> 289class AtomicGeneric3Op : public TypedAtomicOpFunctor<T> 290{ 291 public: 292 AtomicGeneric3Op(T _a, T _c, std::function<void(T*, T, T)> _op) 293 : a(_a), c(_c), op(_op) 294 {} 295 AtomicOpFunctor* clone() override 296 { 297 return new AtomicGeneric3Op<T>(*this); 298 } 299 void execute(T *b) override 300 { 301 op(b, a, c); 302 } 303 private: 304 T a; 305 T c; 306 std::function<void(T*, T, T)> op; 307}; 308 309template<typename T> 310class AtomicGenericPair3Op : public TypedAtomicOpFunctor<T> 311{ 312 public: 313 AtomicGenericPair3Op(std::array<T, 2>& _a, std::array<T, 2> _c, 314 std::function<void(T*, std::array<T, 2>&, std::array<T, 2>)> _op) 315 : a(_a), c(_c), op(_op) 316 {} 317 AtomicOpFunctor* clone() override 318 { 319 return new AtomicGenericPair3Op<T>(*this); 320 } 321 void execute(T* b) override 322 { 323 op(b, a, c); 324 } 325 private: 326 std::array<T, 2> a; 327 std::array<T, 2> c; 328 std::function<void(T*, std::array<T, 2>&, std::array<T, 2>)> op; 329}; 330 331} 332 333#endif //__ARCH_ARM_INSTS_MEM_HH__ 334