operand.hh (11308:7d8836fd043d) | operand.hh (11534:7106f550afad) |
---|---|
1/* 2 * Copyright (c) 2012-2015 Advanced Micro Devices, Inc. 3 * All rights reserved. 4 * 5 * For use for simulation and test purposes only 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: --- 28 unchanged lines hidden (view full) --- 37#define __ARCH_HSAIL_OPERAND_HH__ 38 39/** 40 * @file operand.hh 41 * 42 * Defines classes encapsulating HSAIL instruction operands. 43 */ 44 | 1/* 2 * Copyright (c) 2012-2015 Advanced Micro Devices, Inc. 3 * All rights reserved. 4 * 5 * For use for simulation and test purposes only 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: --- 28 unchanged lines hidden (view full) --- 37#define __ARCH_HSAIL_OPERAND_HH__ 38 39/** 40 * @file operand.hh 41 * 42 * Defines classes encapsulating HSAIL instruction operands. 43 */ 44 |
45#include <limits> |
|
45#include <string> 46 47#include "arch/hsail/Brig.h" 48#include "base/trace.hh" 49#include "base/types.hh" 50#include "debug/GPUReg.hh" 51#include "enums/RegisterType.hh" 52#include "gpu-compute/brig_object.hh" --- 288 unchanged lines hidden (view full) --- 341 } 342 343 std::string disassemble(); 344}; 345 346template<typename T> 347class ImmOperand : public BaseOperand 348{ | 46#include <string> 47 48#include "arch/hsail/Brig.h" 49#include "base/trace.hh" 50#include "base/types.hh" 51#include "debug/GPUReg.hh" 52#include "enums/RegisterType.hh" 53#include "gpu-compute/brig_object.hh" --- 288 unchanged lines hidden (view full) --- 342 } 343 344 std::string disassemble(); 345}; 346 347template<typename T> 348class ImmOperand : public BaseOperand 349{ |
350 private: 351 uint16_t kind; |
|
349 public: 350 T bits; 351 352 bool init(unsigned opOffset, const BrigObject *obj); 353 bool init_from_vect(unsigned opOffset, const BrigObject *obj, int at); 354 std::string disassemble(); 355 356 template<typename OperandType> 357 OperandType | 352 public: 353 T bits; 354 355 bool init(unsigned opOffset, const BrigObject *obj); 356 bool init_from_vect(unsigned opOffset, const BrigObject *obj, int at); 357 std::string disassemble(); 358 359 template<typename OperandType> 360 OperandType |
358 get() | 361 get(Wavefront *w) |
359 { 360 assert(sizeof(OperandType) <= sizeof(T)); | 362 { 363 assert(sizeof(OperandType) <= sizeof(T)); |
364 panic_if(w == nullptr, "WF pointer needs to be set"); |
|
361 | 365 |
362 return *(OperandType*)&bits; | 366 switch (kind) { 367 // immediate operand is WF size 368 case Brig::BRIG_KIND_OPERAND_WAVESIZE: 369 return (OperandType)w->computeUnit->wfSize(); 370 break; 371 372 default: 373 return *(OperandType*)&bits; 374 break; 375 } |
363 } 364 365 // This version of get() takes a WF* and a lane id for 366 // compatibility with the register-based get() methods. 367 template<typename OperandType> 368 OperandType 369 get(Wavefront *w, int lane) 370 { | 376 } 377 378 // This version of get() takes a WF* and a lane id for 379 // compatibility with the register-based get() methods. 380 template<typename OperandType> 381 OperandType 382 get(Wavefront *w, int lane) 383 { |
371 return get | 384 return get<OperandType>(w); |
372 } 373}; 374 375template<typename T> 376bool 377ImmOperand<T>::init(unsigned opOffset, const BrigObject *obj) 378{ 379 const Brig::BrigOperand *brigOp = obj->getOperand(opOffset); 380 381 switch (brigOp->kind) { 382 // this is immediate operand 383 case Brig::BRIG_KIND_OPERAND_CONSTANT_BYTES: 384 { 385 DPRINTF(GPUReg, "sizeof(T): %lu, byteCount: %d\n", sizeof(T), 386 brigOp->byteCount); 387 388 auto cbptr = (Brig::BrigOperandConstantBytes*)brigOp; 389 390 bits = *((T*)(obj->getData(cbptr->bytes + 4))); | 385 } 386}; 387 388template<typename T> 389bool 390ImmOperand<T>::init(unsigned opOffset, const BrigObject *obj) 391{ 392 const Brig::BrigOperand *brigOp = obj->getOperand(opOffset); 393 394 switch (brigOp->kind) { 395 // this is immediate operand 396 case Brig::BRIG_KIND_OPERAND_CONSTANT_BYTES: 397 { 398 DPRINTF(GPUReg, "sizeof(T): %lu, byteCount: %d\n", sizeof(T), 399 brigOp->byteCount); 400 401 auto cbptr = (Brig::BrigOperandConstantBytes*)brigOp; 402 403 bits = *((T*)(obj->getData(cbptr->bytes + 4))); |
391 | 404 kind = brigOp->kind; |
392 return true; 393 } 394 break; 395 396 case Brig::BRIG_KIND_OPERAND_WAVESIZE: | 405 return true; 406 } 407 break; 408 409 case Brig::BRIG_KIND_OPERAND_WAVESIZE: |
397 bits = VSZ; | 410 kind = brigOp->kind; 411 bits = std::numeric_limits<unsigned long long>::digits; |
398 return true; 399 400 default: | 412 return true; 413 414 default: |
415 kind = Brig::BRIG_KIND_NONE; |
|
401 return false; 402 } 403} 404 405template <typename T> 406bool 407ImmOperand<T>::init_from_vect(unsigned opOffset, const BrigObject *obj, int at) 408{ 409 const Brig::BrigOperand *brigOp = obj->getOperand(opOffset); 410 411 if (brigOp->kind != Brig::BRIG_KIND_OPERAND_OPERAND_LIST) { | 416 return false; 417 } 418} 419 420template <typename T> 421bool 422ImmOperand<T>::init_from_vect(unsigned opOffset, const BrigObject *obj, int at) 423{ 424 const Brig::BrigOperand *brigOp = obj->getOperand(opOffset); 425 426 if (brigOp->kind != Brig::BRIG_KIND_OPERAND_OPERAND_LIST) { |
427 kind = Brig::BRIG_KIND_NONE; |
|
412 return false; 413 } 414 415 416 const Brig::BrigOperandOperandList *brigVecOp = 417 (const Brig::BrigOperandOperandList *)brigOp; 418 419 unsigned *data_offset = 420 (unsigned *)obj->getData(brigVecOp->elements + 4 * (at + 1)); 421 422 const Brig::BrigOperand *p = 423 (const Brig::BrigOperand *)obj->getOperand(*data_offset); 424 425 if (p->kind != Brig::BRIG_KIND_OPERAND_CONSTANT_BYTES) { | 428 return false; 429 } 430 431 432 const Brig::BrigOperandOperandList *brigVecOp = 433 (const Brig::BrigOperandOperandList *)brigOp; 434 435 unsigned *data_offset = 436 (unsigned *)obj->getData(brigVecOp->elements + 4 * (at + 1)); 437 438 const Brig::BrigOperand *p = 439 (const Brig::BrigOperand *)obj->getOperand(*data_offset); 440 441 if (p->kind != Brig::BRIG_KIND_OPERAND_CONSTANT_BYTES) { |
442 kind = Brig::BRIG_KIND_NONE; |
|
426 return false; 427 } 428 429 return init(*data_offset, obj); 430} 431template<typename T> 432std::string 433ImmOperand<T>::disassemble() --- 17 unchanged lines hidden (view full) --- 451 void init(unsigned opOffset, const BrigObject *obj); 452 void init_from_vect(unsigned opOffset, const BrigObject *obj, int at); 453 std::string disassemble(); 454 455 template<typename OperandType> 456 OperandType 457 get(Wavefront *w, int lane) 458 { | 443 return false; 444 } 445 446 return init(*data_offset, obj); 447} 448template<typename T> 449std::string 450ImmOperand<T>::disassemble() --- 17 unchanged lines hidden (view full) --- 468 void init(unsigned opOffset, const BrigObject *obj); 469 void init_from_vect(unsigned opOffset, const BrigObject *obj, int at); 470 std::string disassemble(); 471 472 template<typename OperandType> 473 OperandType 474 get(Wavefront *w, int lane) 475 { |
459 return is_imm ? imm_op.template get | 476 return is_imm ? imm_op.template get<OperandType>(w) : |
460 reg_op.template get<OperandType>(w, lane); 461 } 462 463 uint32_t 464 opSize() 465 { 466 if (!is_imm) { 467 return reg_op.opSize(); --- 98 unchanged lines hidden (view full) --- 566 // helper function for init() 567 void parseAddr(const Brig::BrigOperandAddress *op, const BrigObject *obj); 568 569 // helper function for disassemble() 570 std::string disassemble(std::string reg_disassembly); 571 uint64_t calcUniformBase(); 572 573 public: | 477 reg_op.template get<OperandType>(w, lane); 478 } 479 480 uint32_t 481 opSize() 482 { 483 if (!is_imm) { 484 return reg_op.opSize(); --- 98 unchanged lines hidden (view full) --- 583 // helper function for init() 584 void parseAddr(const Brig::BrigOperandAddress *op, const BrigObject *obj); 585 586 // helper function for disassemble() 587 std::string disassemble(std::string reg_disassembly); 588 uint64_t calcUniformBase(); 589 590 public: |
574 virtual void calcVector(Wavefront *w, uint64_t *addrVec) = 0; | 591 virtual void calcVector(Wavefront *w, std::vector<Addr> &addrVec) = 0; |
575 virtual uint64_t calcLane(Wavefront *w, int lane=0) = 0; 576 577 uint64_t offset; 578 const char *name = nullptr; 579 StorageElement *storageElement; 580}; 581 582template<typename RegOperandType> 583class RegAddrOperand : public AddrOperandBase 584{ 585 public: 586 RegOperandType reg; 587 void init(unsigned opOffset, const BrigObject *obj); 588 uint64_t calcUniform(); | 592 virtual uint64_t calcLane(Wavefront *w, int lane=0) = 0; 593 594 uint64_t offset; 595 const char *name = nullptr; 596 StorageElement *storageElement; 597}; 598 599template<typename RegOperandType> 600class RegAddrOperand : public AddrOperandBase 601{ 602 public: 603 RegOperandType reg; 604 void init(unsigned opOffset, const BrigObject *obj); 605 uint64_t calcUniform(); |
589 void calcVector(Wavefront *w, uint64_t *addrVec); | 606 void calcVector(Wavefront *w, std::vector<Addr> &addrVec); |
590 uint64_t calcLane(Wavefront *w, int lane=0); 591 uint32_t opSize() { return reg.opSize(); } 592 bool isVectorRegister() { return reg.registerType == Enums::RT_VECTOR; } 593 bool isCondRegister() { return reg.registerType == Enums::RT_CONDITION; } 594 bool isScalarRegister() { return reg.registerType == Enums::RT_SCALAR; } 595 unsigned int regIndex() { return reg.regIndex(); } 596 std::string disassemble(); 597}; --- 38 unchanged lines hidden (view full) --- 636{ 637 fatal("can't do calcUniform() on register-based address\n"); 638 639 return 0; 640} 641 642template<typename RegOperandType> 643void | 607 uint64_t calcLane(Wavefront *w, int lane=0); 608 uint32_t opSize() { return reg.opSize(); } 609 bool isVectorRegister() { return reg.registerType == Enums::RT_VECTOR; } 610 bool isCondRegister() { return reg.registerType == Enums::RT_CONDITION; } 611 bool isScalarRegister() { return reg.registerType == Enums::RT_SCALAR; } 612 unsigned int regIndex() { return reg.regIndex(); } 613 std::string disassemble(); 614}; --- 38 unchanged lines hidden (view full) --- 653{ 654 fatal("can't do calcUniform() on register-based address\n"); 655 656 return 0; 657} 658 659template<typename RegOperandType> 660void |
644RegAddrOperand<RegOperandType>::calcVector(Wavefront *w, uint64_t *addrVec) | 661RegAddrOperand 662 std::vector<Addr> &addrVec) |
645{ 646 Addr address = calcUniformBase(); 647 | 663{ 664 Addr address = calcUniformBase(); 665 |
648 for (int lane = 0; lane < VSZ; ++lane) { | 666 for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) { |
649 if (w->execMask(lane)) { 650 if (reg.regFileChar == 's') { 651 addrVec[lane] = address + reg.template get<uint32_t>(w, lane); 652 } else { 653 addrVec[lane] = address + reg.template get<Addr>(w, lane); 654 } 655 } 656 } --- 18 unchanged lines hidden (view full) --- 675typedef RegAddrOperand<SRegOperand> SRegAddrOperand; 676typedef RegAddrOperand<DRegOperand> DRegAddrOperand; 677 678class NoRegAddrOperand : public AddrOperandBase 679{ 680 public: 681 void init(unsigned opOffset, const BrigObject *obj); 682 uint64_t calcUniform(); | 667 if (w->execMask(lane)) { 668 if (reg.regFileChar == 's') { 669 addrVec[lane] = address + reg.template get<uint32_t>(w, lane); 670 } else { 671 addrVec[lane] = address + reg.template get<Addr>(w, lane); 672 } 673 } 674 } --- 18 unchanged lines hidden (view full) --- 693typedef RegAddrOperand<SRegOperand> SRegAddrOperand; 694typedef RegAddrOperand<DRegOperand> DRegAddrOperand; 695 696class NoRegAddrOperand : public AddrOperandBase 697{ 698 public: 699 void init(unsigned opOffset, const BrigObject *obj); 700 uint64_t calcUniform(); |
683 void calcVector(Wavefront *w, uint64_t *addrVec); | 701 void calcVector(Wavefront *w, std::vector<Addr> &addrVec); |
684 uint64_t calcLane(Wavefront *w, int lane=0); 685 std::string disassemble(); 686}; 687 688inline uint64_t 689NoRegAddrOperand::calcUniform() 690{ 691 return AddrOperandBase::calcUniformBase(); 692} 693 694inline uint64_t 695NoRegAddrOperand::calcLane(Wavefront *w, int lane) 696{ 697 return calcUniform(); 698} 699 700inline void | 702 uint64_t calcLane(Wavefront *w, int lane=0); 703 std::string disassemble(); 704}; 705 706inline uint64_t 707NoRegAddrOperand::calcUniform() 708{ 709 return AddrOperandBase::calcUniformBase(); 710} 711 712inline uint64_t 713NoRegAddrOperand::calcLane(Wavefront *w, int lane) 714{ 715 return calcUniform(); 716} 717 718inline void |
701NoRegAddrOperand::calcVector(Wavefront *w, uint64_t *addrVec) | 719NoRegAddrOperand::calcVector(Wavefront *w, std::vector<Addr> &addrVec) |
702{ 703 uint64_t address = calcUniformBase(); 704 | 720{ 721 uint64_t address = calcUniformBase(); 722 |
705 for (int lane = 0; lane < VSZ; ++lane) | 723 for (int lane = 0; lane < w->computeUnit->wfSize(); ++lane) |
706 addrVec[lane] = address; 707} 708 709class LabelOperand : public BaseOperand 710{ 711 public: 712 Label *label; 713 --- 55 unchanged lines hidden --- | 724 addrVec[lane] = address; 725} 726 727class LabelOperand : public BaseOperand 728{ 729 public: 730 Label *label; 731 --- 55 unchanged lines hidden --- |