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::calcVector(Wavefront *w,
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 ---