neon64.isa revision 10196:be0e1724eb39
1// -*- mode: c++ -*- 2 3// Copyright (c) 2012-2013 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: Mbou Eyole 39// Giacomo Gabrielli 40 41let {{ 42 simd64EnabledCheckCode = vfp64EnabledCheckCode 43}}; 44 45def template NeonX2RegOpDeclare {{ 46template <class _Element> 47class %(class_name)s : public %(base_class)s 48{ 49 protected: 50 typedef _Element Element; 51 public: 52 // Constructor 53 %(class_name)s(ExtMachInst machInst, 54 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2) 55 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 56 _dest, _op1, _op2) 57 { 58 %(constructor)s; 59 } 60 61 %(BasicExecDeclare)s 62}; 63}}; 64 65def template NeonX2RegImmOpDeclare {{ 66template <class _Element> 67class %(class_name)s : public %(base_class)s 68{ 69 protected: 70 typedef _Element Element; 71 public: 72 // Constructor 73 %(class_name)s(ExtMachInst machInst, 74 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, 75 uint64_t _imm) 76 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 77 _dest, _op1, _op2, _imm) 78 { 79 %(constructor)s; 80 } 81 82 %(BasicExecDeclare)s 83}; 84}}; 85 86def template NeonX1RegOpDeclare {{ 87template <class _Element> 88class %(class_name)s : public %(base_class)s 89{ 90 protected: 91 typedef _Element Element; 92 public: 93 // Constructor 94 %(class_name)s(ExtMachInst machInst, 95 IntRegIndex _dest, IntRegIndex _op1) 96 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 97 _dest, _op1) 98 { 99 %(constructor)s; 100 } 101 102 %(BasicExecDeclare)s 103}; 104}}; 105 106def template NeonX1RegImmOpDeclare {{ 107template <class _Element> 108class %(class_name)s : public %(base_class)s 109{ 110 protected: 111 typedef _Element Element; 112 public: 113 // Constructor 114 %(class_name)s(ExtMachInst machInst, 115 IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm) 116 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 117 _dest, _op1, _imm) 118 { 119 %(constructor)s; 120 } 121 122 %(BasicExecDeclare)s 123}; 124}}; 125 126def template NeonX1Reg2ImmOpDeclare {{ 127template <class _Element> 128class %(class_name)s : public %(base_class)s 129{ 130 protected: 131 typedef _Element Element; 132 public: 133 // Constructor 134 %(class_name)s(ExtMachInst machInst, 135 IntRegIndex _dest, IntRegIndex _op1, uint64_t _imm1, 136 uint64_t _imm2) 137 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 138 _dest, _op1, _imm1, _imm2) 139 { 140 %(constructor)s; 141 } 142 143 %(BasicExecDeclare)s 144}; 145}}; 146 147def template NeonX1RegImmOnlyOpDeclare {{ 148template <class _Element> 149class %(class_name)s : public %(base_class)s 150{ 151 protected: 152 typedef _Element Element; 153 public: 154 // Constructor 155 %(class_name)s(ExtMachInst machInst, 156 IntRegIndex _dest, uint64_t _imm) 157 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 158 _dest, _imm) 159 { 160 %(constructor)s; 161 } 162 163 %(BasicExecDeclare)s 164}; 165}}; 166 167def template NeonXExecDeclare {{ 168 template 169 Fault %(class_name)s<%(targs)s>::execute( 170 CPU_EXEC_CONTEXT *, Trace::InstRecord *) const; 171}}; 172 173def template NeonXEqualRegOpExecute {{ 174 template <class Element> 175 Fault %(class_name)s<Element>::execute(CPU_EXEC_CONTEXT *xc, 176 Trace::InstRecord *traceData) const 177 { 178 Fault fault = NoFault; 179 %(op_decl)s; 180 %(op_rd)s; 181 182 const unsigned rCount = %(r_count)d; 183 const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element); 184 const unsigned eCountFull = 4 * sizeof(FloatRegBits) / sizeof(Element); 185 186 union RegVect { 187 FloatRegBits regs[rCount]; 188 Element elements[eCount]; 189 }; 190 191 union FullRegVect { 192 FloatRegBits regs[4]; 193 Element elements[eCountFull]; 194 }; 195 196 %(code)s; 197 if (fault == NoFault) 198 { 199 %(op_wb)s; 200 } 201 202 return fault; 203 } 204}}; 205 206def template NeonXUnequalRegOpExecute {{ 207 template <class Element> 208 Fault %(class_name)s<Element>::execute(CPU_EXEC_CONTEXT *xc, 209 Trace::InstRecord *traceData) const 210 { 211 typedef typename bigger_type_t<Element>::type BigElement; 212 Fault fault = NoFault; 213 %(op_decl)s; 214 %(op_rd)s; 215 216 const unsigned rCount = %(r_count)d; 217 const unsigned eCount = rCount * sizeof(FloatRegBits) / sizeof(Element); 218 const unsigned eCountFull = 4 * sizeof(FloatRegBits) / sizeof(Element); 219 220 union RegVect { 221 FloatRegBits regs[rCount]; 222 Element elements[eCount]; 223 BigElement bigElements[eCount / 2]; 224 }; 225 226 union BigRegVect { 227 FloatRegBits regs[2 * rCount]; 228 BigElement elements[eCount]; 229 }; 230 231 union FullRegVect { 232 FloatRegBits regs[4]; 233 Element elements[eCountFull]; 234 }; 235 236 %(code)s; 237 if (fault == NoFault) 238 { 239 %(op_wb)s; 240 } 241 242 return fault; 243 } 244}}; 245 246def template MicroNeonMemDeclare64 {{ 247 class %(class_name)s : public %(base_class)s 248 { 249 protected: 250 // True if the base register is SP (used for SP alignment checking) 251 bool baseIsSP; 252 // Access size in bytes 253 uint8_t accSize; 254 // Vector element size (0 -> 8-bit, 1 -> 16-bit, 2 -> 32-bit, 255 // 3 -> 64-bit) 256 uint8_t eSize; 257 258 public: 259 %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _ura, 260 uint32_t _imm, unsigned extraMemFlags, bool _baseIsSP, 261 uint8_t _accSize, uint8_t _eSize) 262 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _dest, 263 _ura, _imm), 264 baseIsSP(_baseIsSP), accSize(_accSize), eSize(_eSize) 265 { 266 memAccessFlags |= extraMemFlags; 267 %(constructor)s; 268 } 269 270 %(BasicExecDeclare)s 271 %(InitiateAccDeclare)s 272 %(CompleteAccDeclare)s 273 }; 274}}; 275 276def template NeonLoadExecute64 {{ 277 Fault %(class_name)s::execute( 278 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const 279 { 280 Addr EA; 281 Fault fault = NoFault; 282 283 %(op_decl)s; 284 %(mem_decl)s; 285 %(op_rd)s; 286 %(ea_code)s; 287 288 MemUnion memUnion; 289 uint8_t *dataPtr = memUnion.bytes; 290 291 if (fault == NoFault) { 292 fault = xc->readMem(EA, dataPtr, accSize, memAccessFlags); 293 %(memacc_code)s; 294 } 295 296 if (fault == NoFault) { 297 %(op_wb)s; 298 } 299 300 return fault; 301 } 302}}; 303 304def template NeonLoadInitiateAcc64 {{ 305 Fault %(class_name)s::initiateAcc( 306 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const 307 { 308 Addr EA; 309 Fault fault = NoFault; 310 311 %(op_decl)s; 312 %(mem_decl)s; 313 %(op_rd)s; 314 %(ea_code)s; 315 316 MemUnion memUnion; 317 uint8_t *dataPtr = memUnion.bytes; 318 319 if (fault == NoFault) { 320 fault = xc->readMem(EA, dataPtr, accSize, memAccessFlags); 321 } 322 323 return fault; 324 } 325}}; 326 327def template NeonLoadCompleteAcc64 {{ 328 Fault %(class_name)s::completeAcc( 329 PacketPtr pkt, CPU_EXEC_CONTEXT *xc, 330 Trace::InstRecord *traceData) const 331 { 332 Fault fault = NoFault; 333 334 %(mem_decl)s; 335 %(op_decl)s; 336 %(op_rd)s; 337 338 MemUnion &memUnion = *(MemUnion *)pkt->getPtr<uint8_t>(); 339 340 if (fault == NoFault) { 341 %(memacc_code)s; 342 } 343 344 if (fault == NoFault) { 345 %(op_wb)s; 346 } 347 348 return fault; 349 } 350}}; 351 352def template NeonStoreExecute64 {{ 353 Fault %(class_name)s::execute( 354 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const 355 { 356 Addr EA; 357 Fault fault = NoFault; 358 359 %(op_decl)s; 360 %(mem_decl)s; 361 %(op_rd)s; 362 %(ea_code)s; 363 364 MemUnion memUnion; 365 uint8_t *dataPtr = memUnion.bytes; 366 367 if (fault == NoFault) { 368 %(memacc_code)s; 369 } 370 371 if (fault == NoFault) { 372 fault = xc->writeMem(dataPtr, accSize, EA, memAccessFlags, 373 NULL); 374 } 375 376 if (fault == NoFault) { 377 %(op_wb)s; 378 } 379 380 return fault; 381 } 382}}; 383 384def template NeonStoreInitiateAcc64 {{ 385 Fault %(class_name)s::initiateAcc( 386 CPU_EXEC_CONTEXT *xc, Trace::InstRecord *traceData) const 387 { 388 Addr EA; 389 Fault fault = NoFault; 390 391 %(op_decl)s; 392 %(mem_decl)s; 393 %(op_rd)s; 394 %(ea_code)s; 395 396 MemUnion memUnion; 397 if (fault == NoFault) { 398 %(memacc_code)s; 399 } 400 401 if (fault == NoFault) { 402 fault = xc->writeMem(memUnion.bytes, accSize, EA, memAccessFlags, 403 NULL); 404 } 405 406 return fault; 407 } 408}}; 409 410def template NeonStoreCompleteAcc64 {{ 411 Fault %(class_name)s::completeAcc( 412 PacketPtr pkt, CPU_EXEC_CONTEXT *xc, 413 Trace::InstRecord *traceData) const 414 { 415 return NoFault; 416 } 417}}; 418 419def template VMemMultDeclare64 {{ 420 class %(class_name)s : public %(base_class)s 421 { 422 public: 423 // Constructor 424 %(class_name)s(ExtMachInst machInst, RegIndex rn, RegIndex vd, 425 RegIndex rm, uint8_t eSize, uint8_t dataSize, 426 uint8_t numStructElems, uint8_t numRegs, bool wb); 427 %(BasicExecPanic)s 428 }; 429}}; 430 431def template VMemSingleDeclare64 {{ 432 class %(class_name)s : public %(base_class)s 433 { 434 public: 435 // Constructor 436 %(class_name)s(ExtMachInst machInst, RegIndex rn, RegIndex vd, 437 RegIndex rm, uint8_t eSize, uint8_t dataSize, 438 uint8_t numStructElems, uint8_t index, bool wb, 439 bool replicate = false); 440 %(BasicExecPanic)s 441 }; 442}}; 443 444def template VMemMultConstructor64 {{ 445 %(class_name)s::%(class_name)s( 446 ExtMachInst machInst, RegIndex rn, RegIndex vd, RegIndex rm, 447 uint8_t _eSize, uint8_t _dataSize, uint8_t _numStructElems, 448 uint8_t _numRegs, bool _wb) : 449 %(base_class)s( 450 "%(mnemonic)s", machInst, %(op_class)s, rn, vd, rm, 451 _eSize, _dataSize, _numStructElems, _numRegs, _wb) 452 { 453 %(constructor)s; 454 } 455}}; 456 457def template VMemSingleConstructor64 {{ 458 %(class_name)s::%(class_name)s( 459 ExtMachInst machInst, RegIndex rn, RegIndex vd, RegIndex rm, 460 uint8_t _eSize, uint8_t _dataSize, uint8_t _numStructElems, 461 uint8_t _index, bool _wb, bool _replicate) : 462 %(base_class)s( 463 "%(mnemonic)s", machInst, %(op_class)s, rn, vd, rm, 464 _eSize, _dataSize, _numStructElems, _index, _wb, 465 _replicate) 466 { 467 %(constructor)s; 468 } 469}}; 470 471def template MicroNeonMixDeclare64 {{ 472 class %(class_name)s : public %(base_class)s 473 { 474 public: 475 %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1, 476 uint8_t _eSize, uint8_t _dataSize, 477 uint8_t _numStructElems, uint8_t _numRegs, 478 uint8_t _step) : 479 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 480 _dest, _op1, _eSize, _dataSize, _numStructElems, 481 _numRegs, _step) 482 { 483 %(constructor)s; 484 } 485 486 %(BasicExecDeclare)s 487 }; 488}}; 489 490def template MicroNeonMixLaneDeclare64 {{ 491 class %(class_name)s : public %(base_class)s 492 { 493 public: 494 %(class_name)s(ExtMachInst machInst, RegIndex _dest, RegIndex _op1, 495 uint8_t _eSize, uint8_t _dataSize, 496 uint8_t _numStructElems, uint8_t _lane, uint8_t _step, 497 bool _replicate = false) : 498 %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 499 _dest, _op1, _eSize, _dataSize, _numStructElems, 500 _lane, _step, _replicate) 501 { 502 %(constructor)s; 503 } 504 505 %(BasicExecDeclare)s 506 }; 507}}; 508 509def template MicroNeonMixExecute64 {{ 510 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 511 Trace::InstRecord *traceData) const 512 { 513 Fault fault = NoFault; 514 uint64_t resTemp = 0; 515 resTemp = resTemp; 516 %(op_decl)s; 517 %(op_rd)s; 518 519 %(code)s; 520 if (fault == NoFault) 521 { 522 %(op_wb)s; 523 } 524 525 return fault; 526 } 527}}; 528