data64.isa revision 12504
1// -*- mode:c++ -*- 2 3// Copyright (c) 2011-2013, 2016-2017 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Redistribution and use in source and binary forms, with or without 16// modification, are permitted provided that the following conditions are 17// met: redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer; 19// redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution; 22// neither the name of the copyright holders nor the names of its 23// contributors may be used to endorse or promote products derived from 24// this software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37// 38// Authors: Gabe Black 39 40let {{ 41 42 header_output = "" 43 decoder_output = "" 44 exec_output = "" 45 46 def createCcCode64(carry, overflow): 47 code = "" 48 code += ''' 49 uint16_t _iz, _in; 50 _in = bits(resTemp, intWidth - 1); 51 _iz = ((resTemp & mask(intWidth)) == 0); 52 CondCodesNZ = (_in << 1) | _iz; 53 DPRINTF(Arm, "(in, iz) = (%d, %d)\\n", _in, _iz); 54 ''' 55 if overflow and overflow != "none": 56 code += ''' 57 uint16_t _iv; 58 _iv = %s & 1; 59 CondCodesV = _iv; 60 DPRINTF(Arm, "(iv) = (%%d)\\n", _iv); 61 ''' % overflow 62 if carry and carry != "none": 63 code += ''' 64 uint16_t _ic; 65 _ic = %s & 1; 66 CondCodesC = _ic; 67 DPRINTF(Arm, "(ic) = (%%d)\\n", _ic); 68 ''' % carry 69 return code 70 71 oldC = 'CondCodesC' 72 oldV = 'CondCodesV' 73 # Dicts of ways to set the carry flag. 74 carryCode64 = { 75 "none": "none", 76 "add": 'findCarry(intWidth, resTemp, Op164, secOp)', 77 "sub": 'findCarry(intWidth, resTemp, Op164, ~secOp)', 78 "logic": '0' 79 } 80 # Dict of ways to set the overflow flag. 81 overflowCode64 = { 82 "none": "none", 83 "add": 'findOverflow(intWidth, resTemp, Op164, secOp)', 84 "sub": 'findOverflow(intWidth, resTemp, Op164, ~secOp)', 85 "logic": '0' 86 } 87 88 immOp2 = "uint64_t secOp M5_VAR_USED = imm;" 89 sRegOp2 = "uint64_t secOp M5_VAR_USED = " + \ 90 "shiftReg64(Op264, shiftAmt, shiftType, intWidth);" 91 eRegOp2 = "uint64_t secOp M5_VAR_USED = " + \ 92 "extendReg64(Op264, extendType, shiftAmt, intWidth);" 93 94 def buildDataWork(mnem, code, flagType, suffix, buildCc, buildNonCc, 95 base, templateBase): 96 code = ''' 97 uint64_t resTemp M5_VAR_USED = 0; 98 ''' + code 99 ccCode = createCcCode64(carryCode64[flagType], overflowCode64[flagType]) 100 Name = mnem.capitalize() + suffix 101 iop = InstObjParams(mnem, Name, base, code) 102 iopCc = InstObjParams(mnem + "s", Name + "Cc", base, code + ccCode) 103 104 def subst(iop): 105 global header_output, decoder_output, exec_output 106 header_output += eval(templateBase + "Declare").subst(iop) 107 decoder_output += eval(templateBase + "Constructor").subst(iop) 108 exec_output += BasicExecute.subst(iop) 109 110 if buildNonCc: 111 subst(iop) 112 if buildCc: 113 subst(iopCc) 114 115 def buildXImmDataInst(mnem, code, flagType = "logic", \ 116 buildCc = True, buildNonCc = True, \ 117 suffix = "XImm"): 118 buildDataWork(mnem, immOp2 + code, flagType, suffix, 119 buildCc, buildNonCc, "DataXImmOp", "DataXImm") 120 121 def buildXSRegDataInst(mnem, code, flagType = "logic", \ 122 buildCc = True, buildNonCc = True, \ 123 suffix = "XSReg"): 124 buildDataWork(mnem, sRegOp2 + code, flagType, suffix, 125 buildCc, buildNonCc, "DataXSRegOp", "DataXSReg") 126 127 def buildXERegDataInst(mnem, code, flagType = "logic", \ 128 buildCc = True, buildNonCc = True, \ 129 suffix = "XEReg"): 130 buildDataWork(mnem, eRegOp2 + code, flagType, suffix, 131 buildCc, buildNonCc, "DataXERegOp", "DataXEReg") 132 133 def buildDataInst(mnem, code, flagType = "logic", 134 buildCc = True, buildNonCc = True): 135 buildXImmDataInst(mnem, code, flagType, buildCc, buildNonCc) 136 buildXSRegDataInst(mnem, code, flagType, buildCc, buildNonCc) 137 buildXERegDataInst(mnem, code, flagType, buildCc, buildNonCc) 138 139 buildXImmDataInst("adr", "Dest64 = RawPC + imm", buildCc = False); 140 buildXImmDataInst("adrp", "Dest64 = (RawPC & ~mask(12)) + imm", 141 buildCc = False); 142 buildDataInst("and", "Dest64 = resTemp = Op164 & secOp;") 143 buildDataInst("eor", "Dest64 = Op164 ^ secOp;", buildCc = False) 144 buildXSRegDataInst("eon", "Dest64 = Op164 ^ ~secOp;", buildCc = False) 145 buildDataInst("sub", "Dest64 = resTemp = Op164 - secOp;", "sub") 146 buildDataInst("add", "Dest64 = resTemp = Op164 + secOp;", "add") 147 buildXSRegDataInst("adc", 148 "Dest64 = resTemp = Op164 + secOp + %s;" % oldC, "add") 149 buildXSRegDataInst("sbc", 150 "Dest64 = resTemp = Op164 - secOp - !%s;" % oldC, "sub") 151 buildDataInst("orr", "Dest64 = Op164 | secOp;", buildCc = False) 152 buildXSRegDataInst("orn", "Dest64 = Op164 | ~secOp;", buildCc = False) 153 buildXSRegDataInst("bic", "Dest64 = resTemp = Op164 & ~secOp;") 154 155 def buildDataXImmInst(mnem, code, optArgs = []): 156 global header_output, decoder_output, exec_output 157 classNamePrefix = mnem[0].upper() + mnem[1:] 158 templateBase = "DataXImm" 159 iop = InstObjParams(mnem, classNamePrefix + "64", 160 templateBase + "Op", code, optArgs) 161 header_output += eval(templateBase + "Declare").subst(iop) 162 decoder_output += eval(templateBase + "Constructor").subst(iop) 163 exec_output += BasicExecute.subst(iop) 164 165 def buildDataXRegInst(mnem, regOps, code, optArgs = [], 166 overrideOpClass=None): 167 global header_output, decoder_output, exec_output 168 templateBase = "DataX%dReg" % regOps 169 classNamePrefix = mnem[0].upper() + mnem[1:] 170 if overrideOpClass: 171 iop = InstObjParams(mnem, classNamePrefix + "64", 172 templateBase + "Op", 173 { 'code': code, 'op_class': overrideOpClass}, 174 optArgs) 175 else: 176 iop = InstObjParams(mnem, classNamePrefix + "64", 177 templateBase + "Op", code, optArgs) 178 header_output += eval(templateBase + "Declare").subst(iop) 179 decoder_output += eval(templateBase + "Constructor").subst(iop) 180 exec_output += BasicExecute.subst(iop) 181 182 buildDataXRegInst("madd", 3, "Dest64 = Op164 + Op264 * Op364", 183 overrideOpClass="IntMultOp") 184 buildDataXRegInst("msub", 3, "Dest64 = Op164 - Op264 * Op364", 185 overrideOpClass="IntMultOp") 186 buildDataXRegInst("smaddl", 3, 187 "XDest = XOp1 + sext<32>(WOp2) * sext<32>(WOp3)", 188 overrideOpClass="IntMultOp") 189 buildDataXRegInst("smsubl", 3, 190 "XDest = XOp1 - sext<32>(WOp2) * sext<32>(WOp3)", 191 overrideOpClass="IntMultOp") 192 buildDataXRegInst("smulh", 2, ''' 193 uint64_t op1H = (int32_t)(XOp1 >> 32); 194 uint64_t op1L = (uint32_t)XOp1; 195 uint64_t op2H = (int32_t)(XOp2 >> 32); 196 uint64_t op2L = (uint32_t)XOp2; 197 uint64_t mid1 = ((op1L * op2L) >> 32) + op1H * op2L; 198 uint64_t mid2 = op1L * op2H; 199 uint64_t result = ((uint64_t)(uint32_t)mid1 + (uint32_t)mid2) >> 32; 200 result += shiftReg64(mid1, 32, ASR, intWidth); 201 result += shiftReg64(mid2, 32, ASR, intWidth); 202 XDest = result + op1H * op2H; 203 ''', overrideOpClass="IntMultOp") 204 buildDataXRegInst("umaddl", 3, "XDest = XOp1 + WOp2 * WOp3", 205 overrideOpClass="IntMultOp") 206 buildDataXRegInst("umsubl", 3, "XDest = XOp1 - WOp2 * WOp3", 207 overrideOpClass="IntMultOp") 208 buildDataXRegInst("umulh", 2, ''' 209 uint64_t op1H = (uint32_t)(XOp1 >> 32); 210 uint64_t op1L = (uint32_t)XOp1; 211 uint64_t op2H = (uint32_t)(XOp2 >> 32); 212 uint64_t op2L = (uint32_t)XOp2; 213 uint64_t mid1 = ((op1L * op2L) >> 32) + op1H * op2L; 214 uint64_t mid2 = op1L * op2H; 215 uint64_t result = ((uint64_t)(uint32_t)mid1 + (uint32_t)mid2) >> 32; 216 result += mid1 >> 32; 217 result += mid2 >> 32; 218 XDest = result + op1H * op2H; 219 ''', overrideOpClass="IntMultOp") 220 221 buildDataXRegInst("asrv", 2, 222 "Dest64 = shiftReg64(Op164, Op264, ASR, intWidth)") 223 buildDataXRegInst("lslv", 2, 224 "Dest64 = shiftReg64(Op164, Op264, LSL, intWidth)") 225 buildDataXRegInst("lsrv", 2, 226 "Dest64 = shiftReg64(Op164, Op264, LSR, intWidth)") 227 buildDataXRegInst("rorv", 2, 228 "Dest64 = shiftReg64(Op164, Op264, ROR, intWidth)") 229 230 crcCode = ''' 231 constexpr uint8_t size_bytes = %(sz)d; 232 constexpr uint32_t poly = %(polynom)s; 233 234 // Initial value is often a previously evaluated 235 // crc value hence is always 32bit in CRC32 236 uint32_t initial_crc = Op164 & 0xFFFFFFFF; 237 238 uint64_t data = htole(Op264); 239 auto data_buffer = reinterpret_cast<uint8_t*>(&data); 240 241 Dest = crc32<poly>( 242 data_buffer, /* Message register */ 243 initial_crc, /* Initial value of the CRC */ 244 size_bytes /* Size of the original Message */ 245 ); 246 ''' 247 buildDataXRegInst("crc32b", 2, 248 crcCode % {"sz": 1, "polynom": "0x04C11DB7"}) 249 buildDataXRegInst("crc32h", 2, 250 crcCode % {"sz": 2, "polynom": "0x04C11DB7"}) 251 buildDataXRegInst("crc32w", 2, 252 crcCode % {"sz": 4, "polynom": "0x04C11DB7"}) 253 buildDataXRegInst("crc32x", 2, 254 crcCode % {"sz": 8, "polynom": "0x04C11DB7"}) 255 256 buildDataXRegInst("crc32cb", 2, 257 crcCode % {"sz": 1, "polynom": "0x1EDC6F41"}) 258 buildDataXRegInst("crc32ch", 2, 259 crcCode % {"sz": 2, "polynom": "0x1EDC6F41"}) 260 buildDataXRegInst("crc32cw", 2, 261 crcCode % {"sz": 4, "polynom": "0x1EDC6F41"}) 262 buildDataXRegInst("crc32cx", 2, 263 crcCode % {"sz": 8, "polynom": "0x1EDC6F41"}) 264 265 buildDataXRegInst("sdiv", 2, ''' 266 int64_t op1 = Op164; 267 int64_t op2 = Op264; 268 if (intWidth == 32) { 269 op1 = sext<32>(op1); 270 op2 = sext<32>(op2); 271 } 272 Dest64 = op2 == -1 ? -op1 : op2 ? op1 / op2 : 0; 273 ''', overrideOpClass="IntDivOp") 274 buildDataXRegInst("udiv", 2, "Dest64 = Op264 ? Op164 / Op264 : 0", 275 overrideOpClass="IntDivOp") 276 277 buildDataXRegInst("cls", 1, ''' 278 uint64_t op1 = Op164; 279 if (bits(op1, intWidth - 1)) 280 op1 ^= mask(intWidth); 281 Dest64 = (op1 == 0) ? intWidth - 1 : (intWidth - 2 - findMsbSet(op1)); 282 ''') 283 buildDataXRegInst("clz", 1, ''' 284 Dest64 = (Op164 == 0) ? intWidth : (intWidth - 1 - findMsbSet(Op164)); 285 ''') 286 buildDataXRegInst("rbit", 1, ''' 287 Dest64 = reverseBits(Op164, intWidth/8); 288 ''') 289 buildDataXRegInst("rev", 1, ''' 290 if (intWidth == 32) 291 Dest64 = betole<uint32_t>(Op164); 292 else 293 Dest64 = betole<uint64_t>(Op164); 294 ''') 295 buildDataXRegInst("rev16", 1, ''' 296 int count = intWidth / 16; 297 uint64_t result = 0; 298 for (unsigned i = 0; i < count; i++) { 299 uint16_t hw = Op164 >> (i * 16); 300 result |= (uint64_t)betole<uint16_t>(hw) << (i * 16); 301 } 302 Dest64 = result; 303 ''') 304 buildDataXRegInst("rev32", 1, ''' 305 int count = intWidth / 32; 306 uint64_t result = 0; 307 for (unsigned i = 0; i < count; i++) { 308 uint32_t hw = Op164 >> (i * 32); 309 result |= (uint64_t)betole<uint32_t>(hw) << (i * 32); 310 } 311 Dest64 = result; 312 ''') 313 314 msrMrs64EnabledCheckCode = ''' 315 // Check for read/write access right 316 if (!can%sAArch64SysReg(flat_idx, Scr64, cpsr, xc->tcBase())) { 317 if (flat_idx == MISCREG_DAIF || 318 flat_idx == MISCREG_DC_ZVA_Xt || 319 flat_idx == MISCREG_DC_CVAC_Xt || 320 flat_idx == MISCREG_DC_CIVAC_Xt || 321 flat_idx == MISCREG_DC_IVAC_Xt 322 ) 323 return std::make_shared<UndefinedInstruction>( 324 machInst, 0, EC_TRAPPED_MSR_MRS_64, 325 mnemonic); 326 return std::make_shared<UndefinedInstruction>(machInst, false, 327 mnemonic); 328 } 329 330 // Check for traps to supervisor (FP/SIMD regs) 331 if (el <= EL1 && msrMrs64TrapToSup(flat_idx, el, Cpacr64)) 332 return std::make_shared<SupervisorTrap>(machInst, 0x1E00000, 333 EC_TRAPPED_SIMD_FP); 334 335 bool is_vfp_neon = false; 336 337 // Check for traps to hypervisor 338 if ((ArmSystem::haveVirtualization(xc->tcBase()) && el <= EL2) && 339 msrMrs64TrapToHyp(flat_idx, el, %s, CptrEl264, Hcr64, &is_vfp_neon)) { 340 return std::make_shared<HypervisorTrap>( 341 machInst, is_vfp_neon ? 0x1E00000 : imm, 342 is_vfp_neon ? EC_TRAPPED_SIMD_FP : EC_TRAPPED_MSR_MRS_64); 343 } 344 345 // Check for traps to secure monitor 346 if ((ArmSystem::haveSecurity(xc->tcBase()) && el <= EL3) && 347 msrMrs64TrapToMon(flat_idx, CptrEl364, el, &is_vfp_neon)) { 348 return std::make_shared<SecureMonitorTrap>( 349 machInst, 350 is_vfp_neon ? 0x1E00000 : imm, 351 is_vfp_neon ? EC_TRAPPED_SIMD_FP : EC_TRAPPED_MSR_MRS_64); 352 } 353 ''' 354 355 mrsCode = ''' 356 MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()-> 357 flattenRegId(RegId(MiscRegClass, op1)).index(); 358 CPSR cpsr = Cpsr; 359 ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; 360 %s 361 XDest = MiscOp1_ud; 362 ''' % (msrMrs64EnabledCheckCode % ('Read', 'true'),) 363 364 mrsIop = InstObjParams("mrs", "Mrs64", "RegMiscRegImmOp64", 365 mrsCode, 366 ["IsSerializeBefore"]) 367 header_output += RegMiscRegOp64Declare.subst(mrsIop) 368 decoder_output += RegMiscRegOp64Constructor.subst(mrsIop) 369 exec_output += BasicExecute.subst(mrsIop) 370 371 buildDataXRegInst("mrsNZCV", 1, ''' 372 CPSR cpsr = 0; 373 cpsr.nz = CondCodesNZ; 374 cpsr.c = CondCodesC; 375 cpsr.v = CondCodesV; 376 XDest = cpsr; 377 ''') 378 379 msrCode = ''' 380 MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()-> 381 flattenRegId(RegId(MiscRegClass, dest)).index(); 382 CPSR cpsr = Cpsr; 383 ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; 384 %s 385 MiscDest_ud = XOp1; 386 ''' % (msrMrs64EnabledCheckCode % ('Write', 'false'),) 387 388 msrIop = InstObjParams("msr", "Msr64", "MiscRegRegImmOp64", 389 msrCode, 390 ["IsSerializeAfter", "IsNonSpeculative"]) 391 header_output += MiscRegRegOp64Declare.subst(msrIop) 392 decoder_output += MiscRegRegOp64Constructor.subst(msrIop) 393 exec_output += BasicExecute.subst(msrIop) 394 395 396 buildDataXRegInst("msrNZCV", 1, ''' 397 CPSR cpsr = XOp1; 398 CondCodesNZ = cpsr.nz; 399 CondCodesC = cpsr.c; 400 CondCodesV = cpsr.v; 401 ''') 402 403 msrdczva_ea_code = ''' 404 MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId( 405 RegId(MiscRegClass, dest)).index(); 406 CPSR cpsr = Cpsr; 407 ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; 408 ''' 409 410 msrdczva_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false') 411 msrdczva_ea_code += ''' 412 Request::Flags memAccessFlags = Request::CACHE_BLOCK_ZERO|ArmISA::TLB::MustBeOne; 413 EA = XBase; 414 assert(!(Dczid & 0x10)); 415 uint64_t op_size = power(2, Dczid + 2); 416 EA &= ~(op_size - 1); 417 418 ''' 419 420 msrDCZVAIop = InstObjParams("dc zva", "Dczva", "SysDC64", 421 { "ea_code" : msrdczva_ea_code, 422 "memacc_code" : ";", "use_uops" : 0, 423 "op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']); 424 header_output += DCStore64Declare.subst(msrDCZVAIop); 425 decoder_output += DCStore64Constructor.subst(msrDCZVAIop); 426 exec_output += DCStore64Execute.subst(msrDCZVAIop); 427 exec_output += DCStore64InitiateAcc.subst(msrDCZVAIop); 428 exec_output += Store64CompleteAcc.subst(msrDCZVAIop); 429 430 431 msrdccvau_ea_code = ''' 432 MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId( 433 RegId(MiscRegClass, dest)).index(); 434 CPSR cpsr = Cpsr; 435 ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; 436 ''' 437 438 msrdccvau_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false') 439 msrdccvau_ea_code += ''' 440 Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POU | 441 ArmISA::TLB::MustBeOne; 442 EA = XBase; 443 System *sys = xc->tcBase()->getSystemPtr(); 444 Addr op_size = sys->cacheLineSize(); 445 EA &= ~(op_size - 1); 446 ''' 447 448 msrDCCVAUIop = InstObjParams("dc cvau", "Dccvau", "SysDC64", 449 { "ea_code" : msrdccvau_ea_code, 450 "memacc_code" : ";", "use_uops" : 0, 451 "op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']); 452 header_output += DCStore64Declare.subst(msrDCCVAUIop); 453 decoder_output += DCStore64Constructor.subst(msrDCCVAUIop); 454 exec_output += DCStore64Execute.subst(msrDCCVAUIop); 455 exec_output += DCStore64InitiateAcc.subst(msrDCCVAUIop); 456 exec_output += Store64CompleteAcc.subst(msrDCCVAUIop); 457 458 459 msrdccvac_ea_code = ''' 460 MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId( 461 RegId(MiscRegClass, dest)).index(); 462 CPSR cpsr = Cpsr; 463 ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; 464 ''' 465 466 msrdccvac_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false') 467 msrdccvac_ea_code += ''' 468 Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POC | 469 ArmISA::TLB::MustBeOne; 470 EA = XBase; 471 System *sys = xc->tcBase()->getSystemPtr(); 472 Addr op_size = sys->cacheLineSize(); 473 EA &= ~(op_size - 1); 474 ''' 475 476 msrDCCVACIop = InstObjParams("dc cvac", "Dccvac", "SysDC64", 477 { "ea_code" : msrdccvac_ea_code, 478 "memacc_code" : ";", "use_uops" : 0, 479 "op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']); 480 header_output += DCStore64Declare.subst(msrDCCVACIop); 481 decoder_output += DCStore64Constructor.subst(msrDCCVACIop); 482 exec_output += DCStore64Execute.subst(msrDCCVACIop); 483 exec_output += DCStore64InitiateAcc.subst(msrDCCVACIop); 484 exec_output += Store64CompleteAcc.subst(msrDCCVACIop); 485 486 487 msrdccivac_ea_code = ''' 488 MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId( 489 RegId(MiscRegClass, dest)).index(); 490 CPSR cpsr = Cpsr; 491 ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; 492 ''' 493 494 msrdccivac_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false') 495 msrdccivac_ea_code += ''' 496 Request::Flags memAccessFlags = Request::CLEAN | 497 Request::INVALIDATE | Request::DST_POC | ArmISA::TLB::MustBeOne; 498 EA = XBase; 499 System *sys = xc->tcBase()->getSystemPtr(); 500 Addr op_size = sys->cacheLineSize(); 501 EA &= ~(op_size - 1); 502 ''' 503 504 msrDCCIVACIop = InstObjParams("dc civac", "Dccivac", "SysDC64", 505 { "ea_code" : msrdccivac_ea_code, 506 "memacc_code" : ";", "use_uops" : 0, 507 "op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']); 508 header_output += DCStore64Declare.subst(msrDCCIVACIop); 509 decoder_output += DCStore64Constructor.subst(msrDCCIVACIop); 510 exec_output += DCStore64Execute.subst(msrDCCIVACIop); 511 exec_output += DCStore64InitiateAcc.subst(msrDCCIVACIop); 512 exec_output += Store64CompleteAcc.subst(msrDCCIVACIop); 513 514 515 msrdcivac_ea_code = ''' 516 MiscRegIndex flat_idx = (MiscRegIndex) xc->tcBase()->flattenRegId( 517 RegId(MiscRegClass, dest)).index(); 518 CPSR cpsr = Cpsr; 519 ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el; 520 ''' 521 522 msrdcivac_ea_code += msrMrs64EnabledCheckCode % ('Write', 'false') 523 msrdcivac_ea_code += ''' 524 Request::Flags memAccessFlags = Request::INVALIDATE | 525 Request::DST_POC | ArmISA::TLB::MustBeOne; 526 EA = XBase; 527 System *sys = xc->tcBase()->getSystemPtr(); 528 Addr op_size = sys->cacheLineSize(); 529 EA &= ~(op_size - 1); 530 ''' 531 532 msrDCIVACIop = InstObjParams("dc ivac", "Dcivac", "SysDC64", 533 { "ea_code" : msrdcivac_ea_code, 534 "memacc_code" : ";", "use_uops" : 0, 535 "op_wb" : ";", "fa_code" : ";"}, ['IsStore', 'IsMemRef']); 536 header_output += DCStore64Declare.subst(msrDCIVACIop); 537 decoder_output += DCStore64Constructor.subst(msrDCIVACIop); 538 exec_output += DCStore64Execute.subst(msrDCIVACIop); 539 exec_output += DCStore64InitiateAcc.subst(msrDCIVACIop); 540 exec_output += Store64CompleteAcc.subst(msrDCIVACIop); 541 542 543 buildDataXImmInst("msrSP", ''' 544 if (!canWriteAArch64SysReg( 545 (MiscRegIndex) xc->tcBase()->flattenRegId( 546 RegId(MiscRegClass, dest)).index(), 547 Scr64, Cpsr, xc->tcBase())) { 548 return std::make_shared<UndefinedInstruction>(machInst, false, 549 mnemonic); 550 } 551 MiscDest_ud = imm; 552 ''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"]) 553 554 buildDataXImmInst("msrDAIFSet", ''' 555 if (!canWriteAArch64SysReg( 556 (MiscRegIndex) xc->tcBase()->flattenRegId( 557 RegId(MiscRegClass, dest)).index(), 558 Scr64, Cpsr, xc->tcBase())) { 559 return std::make_shared<UndefinedInstruction>( 560 machInst, 0, EC_TRAPPED_MSR_MRS_64, 561 mnemonic); 562 } 563 CPSR cpsr = Cpsr; 564 cpsr.daif = cpsr.daif | imm; 565 Cpsr = cpsr; 566 ''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"]) 567 568 buildDataXImmInst("msrDAIFClr", ''' 569 if (!canWriteAArch64SysReg( 570 (MiscRegIndex) xc->tcBase()->flattenRegId( 571 RegId(MiscRegClass, dest)).index(), 572 Scr64, Cpsr, xc->tcBase())) { 573 return std::make_shared<UndefinedInstruction>( 574 machInst, 0, EC_TRAPPED_MSR_MRS_64, 575 mnemonic); 576 } 577 CPSR cpsr = Cpsr; 578 cpsr.daif = cpsr.daif & ~imm; 579 Cpsr = cpsr; 580 ''', optArgs = ["IsSerializeAfter", "IsNonSpeculative"]) 581 582 def buildDataXCompInst(mnem, instType, suffix, code): 583 global header_output, decoder_output, exec_output 584 templateBase = "DataXCond%s" % instType 585 iop = InstObjParams(mnem, mnem.capitalize() + suffix + "64", 586 templateBase + "Op", code) 587 header_output += eval(templateBase + "Declare").subst(iop) 588 decoder_output += eval(templateBase + "Constructor").subst(iop) 589 exec_output += BasicExecute.subst(iop) 590 591 def buildDataXCondImmInst(mnem, code): 592 buildDataXCompInst(mnem, "CompImm", "Imm", code) 593 def buildDataXCondRegInst(mnem, code): 594 buildDataXCompInst(mnem, "CompReg", "Reg", code) 595 def buildDataXCondSelInst(mnem, code): 596 buildDataXCompInst(mnem, "Sel", "", code) 597 598 def condCompCode(flagType, op, imm): 599 ccCode = createCcCode64(carryCode64[flagType], overflowCode64[flagType]) 600 opDecl = "uint64_t secOp M5_VAR_USED = imm;" 601 if not imm: 602 opDecl = "uint64_t secOp M5_VAR_USED = Op264;" 603 return opDecl + ''' 604 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) { 605 uint64_t resTemp = Op164 ''' + op + ''' secOp; 606 ''' + ccCode + ''' 607 } else { 608 CondCodesNZ = (defCc >> 2) & 0x3; 609 CondCodesC = (defCc >> 1) & 0x1; 610 CondCodesV = defCc & 0x1; 611 } 612 ''' 613 614 buildDataXCondImmInst("ccmn", condCompCode("add", "+", True)) 615 buildDataXCondImmInst("ccmp", condCompCode("sub", "-", True)) 616 buildDataXCondRegInst("ccmn", condCompCode("add", "+", False)) 617 buildDataXCondRegInst("ccmp", condCompCode("sub", "-", False)) 618 619 condSelCode = ''' 620 if (testPredicate(CondCodesNZ, CondCodesC, CondCodesV, condCode)) { 621 Dest64 = Op164; 622 } else { 623 Dest64 = %(altVal)s; 624 } 625 ''' 626 buildDataXCondSelInst("csel", condSelCode % {"altVal" : "Op264"}) 627 buildDataXCondSelInst("csinc", condSelCode % {"altVal" : "Op264 + 1"}) 628 buildDataXCondSelInst("csinv", condSelCode % {"altVal" : "~Op264"}) 629 buildDataXCondSelInst("csneg", condSelCode % {"altVal" : "-Op264"}) 630}}; 631