brig_object.hh revision 11308:7d8836fd043d
16502Snate@binkert.org/*
26502Snate@binkert.org * Copyright (c) 2012-2015 Advanced Micro Devices, Inc.
36502Snate@binkert.org * All rights reserved.
46502Snate@binkert.org *
56502Snate@binkert.org * For use for simulation and test purposes only
66502Snate@binkert.org *
76502Snate@binkert.org * Redistribution and use in source and binary forms, with or without
86502Snate@binkert.org * modification, are permitted provided that the following conditions are met:
96502Snate@binkert.org *
106502Snate@binkert.org * 1. Redistributions of source code must retain the above copyright notice,
116502Snate@binkert.org * this list of conditions and the following disclaimer.
126502Snate@binkert.org *
136502Snate@binkert.org * 2. Redistributions in binary form must reproduce the above copyright notice,
146502Snate@binkert.org * this list of conditions and the following disclaimer in the documentation
156502Snate@binkert.org * and/or other materials provided with the distribution.
166502Snate@binkert.org *
176502Snate@binkert.org * 3. Neither the name of the copyright holder nor the names of its contributors
186502Snate@binkert.org * may be used to endorse or promote products derived from this software
196502Snate@binkert.org * without specific prior written permission.
206502Snate@binkert.org *
216502Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
226502Snate@binkert.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
236502Snate@binkert.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
246502Snate@binkert.org * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
256502Snate@binkert.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
266502Snate@binkert.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
276502Snate@binkert.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
286502Snate@binkert.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
296502Snate@binkert.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
306502Snate@binkert.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
316502Snate@binkert.org * POSSIBILITY OF SUCH DAMAGE.
326502Snate@binkert.org *
336502Snate@binkert.org * Author: Steve Reinhardt, Anthony Gutierrez
346502Snate@binkert.org */
356502Snate@binkert.org
366502Snate@binkert.org#ifndef __BRIG_OBJECT_HH__
376502Snate@binkert.org#define __BRIG_OBJECT_HH__
386502Snate@binkert.org
396502Snate@binkert.org#include <cassert>
406502Snate@binkert.org#include <cstdint>
416502Snate@binkert.org#include <string>
426502Snate@binkert.org#include <vector>
436502Snate@binkert.org
446502Snate@binkert.org#include "arch/hsail/Brig.h"
456502Snate@binkert.org#include "gpu-compute/hsa_object.hh"
466502Snate@binkert.org#include "gpu-compute/hsail_code.hh"
476502Snate@binkert.org
486502Snate@binkert.orgclass LabelMap;
496502Snate@binkert.orgclass StorageMap;
506502Snate@binkert.org
516502Snate@binkert.org/* @class BrigObject
526502Snate@binkert.org * this class implements the BRIG loader object, and
536502Snate@binkert.org * is used when the simulator directly executes HSAIL.
546502Snate@binkert.org * this class is responsible for extracting all
556502Snate@binkert.org * information about kernels contained in BRIG format
566502Snate@binkert.org * and converts them to HsailCode objects that are
576502Snate@binkert.org * usable by the simulator and emulated runtime.
586502Snate@binkert.org */
596502Snate@binkert.org
606502Snate@binkert.orgclass BrigObject final : public HsaObject
616502Snate@binkert.org{
626502Snate@binkert.org  public:
636502Snate@binkert.org    enum SectionIndex
646502Snate@binkert.org    {
656502Snate@binkert.org        DataSectionIndex,
666502Snate@binkert.org        CodeSectionIndex,
676502Snate@binkert.org        OperandsSectionIndex,
686502Snate@binkert.org        NumSectionIndices
696502Snate@binkert.org    };
706502Snate@binkert.org
716502Snate@binkert.org    static const char *sectionNames[];
726502Snate@binkert.org
736502Snate@binkert.org    struct SectionInfo
746502Snate@binkert.org    {
756502Snate@binkert.org        uint8_t *ptr;
766502Snate@binkert.org        int size;
776502Snate@binkert.org    };
786502Snate@binkert.org
796502Snate@binkert.org    static HsaObject* tryFile(const std::string &fname, int len,
806502Snate@binkert.org                              uint8_t *fileData);
816502Snate@binkert.org
826502Snate@binkert.org    SectionInfo sectionInfo[NumSectionIndices];
836502Snate@binkert.org    const uint8_t *getSectionOffset(enum SectionIndex sec, int offs) const;
846502Snate@binkert.org
856502Snate@binkert.org    std::vector<HsailCode*> kernels;
866502Snate@binkert.org    std::vector<HsailCode*> functions;
876502Snate@binkert.org    std::string kern_block_name;
886502Snate@binkert.org
896502Snate@binkert.org    void processDirectives(const Brig::BrigBase *dirPtr,
906502Snate@binkert.org                           const Brig::BrigBase *endPtr,
916502Snate@binkert.org                           StorageMap *storageMap);
926502Snate@binkert.org
936502Snate@binkert.org    BrigObject(const std::string &fname, int len, uint8_t *fileData);
946502Snate@binkert.org    ~BrigObject();
956502Snate@binkert.org
966502Snate@binkert.org    // eventually these will need to be per-kernel not per-object-file
976502Snate@binkert.org    StorageMap *storageMap;
986502Snate@binkert.org    LabelMap *labelMap;
996502Snate@binkert.org
1006502Snate@binkert.org    const char* getString(int offs) const;
1016502Snate@binkert.org    const Brig::BrigData* getBrigBaseData(int offs) const;
1026502Snate@binkert.org    const uint8_t* getData(int offs) const;
1036502Snate@binkert.org    const Brig::BrigBase* getCodeSectionEntry(int offs) const;
1046502Snate@binkert.org    const Brig::BrigOperand* getOperand(int offs) const;
1056502Snate@binkert.org    unsigned getOperandPtr(int offs, int index) const;
1066502Snate@binkert.org    const Brig::BrigInstBase* getInst(int offs) const;
1076502Snate@binkert.org
1086502Snate@binkert.org    HsaCode* getKernel(const std::string &name) const override;
1096502Snate@binkert.org    HsaCode* getFunction(const std::string &name) const override;
1106502Snate@binkert.org
1116502Snate@binkert.org    int numKernels() const override { return kernels.size(); }
1126502Snate@binkert.org
1136502Snate@binkert.org    HsaCode* getKernel(int i) const override { return kernels[i]; }
1146502Snate@binkert.org
1156502Snate@binkert.org    // pointer to the current kernel/function we're processing, so elements
1166502Snate@binkert.org    // under construction can reference it.  kinda ugly, but easier
1176502Snate@binkert.org    // than passing it all over for the few places it's needed.
1186502Snate@binkert.org    mutable HsailCode *currentCode;
1196502Snate@binkert.org};
1206502Snate@binkert.org
1216502Snate@binkert.org// Utility function to bump Brig item pointer to next element given
1226502Snate@binkert.org// item size in bytes.  Really just an add but with lots of casting.
1236502Snate@binkert.orgtemplate<typename T>
1246502Snate@binkert.orgT*
1256502Snate@binkert.orgbrigNext(T *ptr)
1266502Snate@binkert.org{
1276502Snate@binkert.org    Brig::BrigBase *base_ptr = (Brig::BrigBase*)ptr;
1286502Snate@binkert.org    int size = base_ptr->byteCount;
1296502Snate@binkert.org    assert(size);
1306502Snate@binkert.org
1316502Snate@binkert.org    return (T*)((uint8_t*)ptr + size);
1326502Snate@binkert.org}
1336502Snate@binkert.org
1346502Snate@binkert.org#endif // __BRIG_OBJECT_HH__
1356502Snate@binkert.org