kfdtest: Add LLVM AMDGPU assembler components
Initial commit for transition from IsaGenerator/SP3 assembler model to
the LLVM AMDGPU (AMDGCN) assembler backend:
- Add Assembler class, may be instantiated for assembly similar to
IsaGenerator.
- Add Assembler and LLVM archive dependencies to build process.
- CXX bumped to gnu++14 as required for LLVM compilation.
- Compatible with LLVM 7.0 and greater (latest Lightning/llvm-git
version should be used for up-to-date gfx support). Note that this is
just a build dependency and *not* a runtime dependency. LLVM does not
need to be installed on the host machine to run kfdtest.
- CMake will first look for a Lightning build. Lightning itself does not
need to be installed system-wide, just built. If this fails, it will
attempt to find a system-wide LLVM install.
General Assembler usage and notes:
- Similar to IsaGenerator, applicable test classes will contain an
Assembler object pointer which may be instantiated in the test
constructor.
- Instantiation requires the GFXIP version in order to find the
appropriate LLVM AMDGPU Target ID.
- The RunAssemble() member func takes in a standard const char* shader and
fills the TextData member with the output binary; TextSize with the size
of TextData. These may be accessed via GetInstrStream() and
GetInstrStreamSize(), or the output binary may be copied into an
IsaBuffer via CopyInstrStream(). RunAssembleBuf() combines RunAssemble()
and CopyInstrStream() and additionally takes an optional BufSize
parameter to specify the size of the output buffer (defaults to
PAGE_SIZE).
- Assembler object deletion is to be done in the base test destructor.
Assembler-specific memory allocation is freed in the Assembler
destructor.
- For debug, one can call PrintTextHex() to print out a formatted hex
representation of the output binary, or PrintELFHex() to print out the
intermediate ELF object. Note that PrintTextHex() is public whereas
PrintELFHex() is private.
- Prints use the LLVM outs() call as that allows for use of the LLVM
format_hex() func in the aforementioned debug prints. This is subject to
change if the LOG() call would be preferred.
RunAssemble control flow:
- Ensure correct Assembler initialization and clear previous run
TextData (if necessary).
- Initialize LLVM AMDGPU target, required interfaces, and buffers.
- Set parser to specified target/subtarget and assemble into ELF code
object.
- Extract .text section from ELF, allocate space for TextData and store.
- On success, returns 0 (HSAKMT_STATUS_SUCCESS). On error, returns -1
(subject to change to be in line with HSAKMT_STATUS enum).
Signed-off-by: Graham Sider <Graham.Sider@amd.com>
Change-Id: I1d96230824db651d3ffbaa46eb68fc274e7066b5
[ROCm/ROCR-Runtime commit: 65b1e0c058]
This commit is contained in:
کامیت شده توسط
Harish Kasiviswanathan
والد
949f8fc7aa
کامیت
d916fe0129
@@ -95,6 +95,39 @@ endif()
|
||||
|
||||
message ( "Find libhsakmt at ${HSAKMT_LIBRARY_DIRS}" )
|
||||
|
||||
if ( POLICY CMP0074 )
|
||||
cmake_policy( SET CMP0074 NEW )
|
||||
endif()
|
||||
|
||||
find_path( LIGHTNING_CMAKE_DIR NAMES LLVMConfig.cmake
|
||||
PATHS $ENV{OUT_DIR}/llvm/lib/cmake/llvm NO_CACHE NO_DEFAULT_PATH)
|
||||
|
||||
if ( DEFINED LIGHTNING_CMAKE_DIR AND EXISTS ${LIGHTNING_CMAKE_DIR} )
|
||||
set ( LLVM_DIR ${LIGHTNING_CMAKE_DIR} )
|
||||
else()
|
||||
message( WARNING "Couldn't find Lightning build. "
|
||||
"Attempting to use system LLVM install..." )
|
||||
endif()
|
||||
|
||||
find_package( LLVM REQUIRED CONFIG )
|
||||
|
||||
if( ${LLVM_PACKAGE_VERSION} VERSION_LESS "7.0" )
|
||||
message( FATAL_ERROR "Requires LLVM 7.0 or greater "
|
||||
"(found ${LLVM_PACKAGE_VERSION})" )
|
||||
elseif( ${LLVM_PACKAGE_VERSION} VERSION_LESS "14.0" )
|
||||
message( WARNING "Not using latest LLVM version. "
|
||||
"Some ASIC targets may not work!" )
|
||||
endif()
|
||||
|
||||
message( STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}" )
|
||||
message( STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}" )
|
||||
|
||||
include_directories(${LLVM_INCLUDE_DIRS})
|
||||
separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
|
||||
add_definitions(${LLVM_DEFINITIONS_LIST})
|
||||
|
||||
llvm_map_components_to_libnames(llvm_libs AMDGPUAsmParser Core Support)
|
||||
|
||||
set ( SP3_DIR ${PROJECT_SOURCE_DIR}/sp3 )
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/gtest-1.6.0)
|
||||
@@ -112,6 +145,7 @@ set (SRC_FILES gtest-1.6.0/gtest-all.cpp
|
||||
src/Dispatch.cpp
|
||||
src/GoogleTestExtension.cpp
|
||||
src/IndirectBuffer.cpp
|
||||
src/Assemble.cpp
|
||||
src/IsaGenerator.cpp
|
||||
src/IsaGenerator_Aldebaran.cpp
|
||||
src/IsaGenerator_Gfx10.cpp
|
||||
@@ -163,7 +197,7 @@ message( STATUS "PROJECT_SOURCE_DIR:" ${PROJECT_SOURCE_DIR} )
|
||||
|
||||
if ( "${CMAKE_C_COMPILER_VERSION}" STRGREATER "4.8.0")
|
||||
## Add --enable-new-dtags to generate DT_RUNPATH
|
||||
set ( CMAKE_CXX_FLAGS "-std=gnu++11 -Wl,--enable-new-dtags" )
|
||||
set ( CMAKE_CXX_FLAGS "-std=gnu++14 -Wl,--enable-new-dtags" )
|
||||
endif()
|
||||
if ( "${CMAKE_BUILD_TYPE}" STREQUAL Release )
|
||||
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2" )
|
||||
@@ -185,7 +219,7 @@ link_directories(${SP3_DIR})
|
||||
|
||||
add_executable(kfdtest ${SRC_FILES})
|
||||
|
||||
target_link_libraries(kfdtest ${HSAKMT_LIBRARIES} ${DRM_LDFLAGS} ${DRM_AMDGPU_LDFLAGS} pthread m stdc++ rt amdsp3 numa)
|
||||
target_link_libraries(kfdtest ${HSAKMT_LIBRARIES} ${DRM_LDFLAGS} ${DRM_AMDGPU_LDFLAGS} ${llvm_libs} pthread m stdc++ rt amdsp3 numa)
|
||||
|
||||
configure_file ( scripts/kfdtest.exclude kfdtest.exclude COPYONLY )
|
||||
configure_file ( scripts/run_kfdtest.sh run_kfdtest.sh COPYONLY )
|
||||
|
||||
@@ -0,0 +1,379 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The University of Illinois/NCSA
|
||||
// Open Source License (NCSA)
|
||||
//
|
||||
// Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// Developed by:
|
||||
//
|
||||
// AMD Research and AMD HSA Software Development
|
||||
//
|
||||
// Advanced Micro Devices, Inc.
|
||||
//
|
||||
// www.amd.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal with the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimers.
|
||||
// - Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimers in
|
||||
// the documentation and/or other materials provided with the distribution.
|
||||
// - Neither the names of Advanced Micro Devices, Inc,
|
||||
// nor the names of its contributors may be used to endorse or promote
|
||||
// products derived from this Software without specific prior written
|
||||
// permission.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS WITH THE SOFTWARE.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Self-contained assembler that uses the LLVM MC API to assemble AMDGCN
|
||||
* instructions
|
||||
*/
|
||||
|
||||
#include <llvm/Config/llvm-config.h>
|
||||
#include <llvm/MC/MCAsmBackend.h>
|
||||
#include <llvm/MC/MCAsmInfo.h>
|
||||
#include <llvm/MC/MCCodeEmitter.h>
|
||||
#include <llvm/MC/MCContext.h>
|
||||
#include <llvm/MC/MCInstPrinter.h>
|
||||
#include <llvm/MC/MCInstrInfo.h>
|
||||
#include <llvm/MC/MCObjectFileInfo.h>
|
||||
#include <llvm/MC/MCObjectWriter.h>
|
||||
#include <llvm/MC/MCParser/AsmLexer.h>
|
||||
#include <llvm/MC/MCParser/MCTargetAsmParser.h>
|
||||
#include <llvm/MC/MCRegisterInfo.h>
|
||||
#include <llvm/MC/MCStreamer.h>
|
||||
#include <llvm/MC/MCSubtargetInfo.h>
|
||||
#include <llvm/Support/CommandLine.h>
|
||||
#include <llvm/Support/InitLLVM.h>
|
||||
#include <llvm/Support/MemoryBuffer.h>
|
||||
#include <llvm/Support/SourceMgr.h>
|
||||
#include <llvm/Support/TargetSelect.h>
|
||||
#if LLVM_VERSION_MAJOR > 13
|
||||
#include <llvm/MC/TargetRegistry.h>
|
||||
#else
|
||||
#include <llvm/Support/TargetRegistry.h>
|
||||
#endif
|
||||
|
||||
#include <linux/elf.h>
|
||||
#include "OSWrapper.hpp"
|
||||
#include "Assemble.hpp"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
Assembler::Assembler(const uint32_t Gfxv) {
|
||||
SetTargetAsic(Gfxv);
|
||||
TextData = nullptr;
|
||||
TextSize = 0;
|
||||
LLVMInit();
|
||||
}
|
||||
|
||||
Assembler::~Assembler() {
|
||||
FlushText();
|
||||
llvm_shutdown();
|
||||
}
|
||||
|
||||
const char* Assembler::GetInstrStream() {
|
||||
return TextData;
|
||||
}
|
||||
|
||||
const size_t Assembler::GetInstrStreamSize() {
|
||||
return TextSize;
|
||||
}
|
||||
|
||||
int Assembler::CopyInstrStream(char* OutBuf, const size_t BufSize) {
|
||||
if (TextSize > BufSize)
|
||||
return -2;
|
||||
|
||||
std::copy(TextData, TextData + TextSize, OutBuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* Assembler::GetTargetAsic() {
|
||||
return MCPU;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set MCPU via GFX Version from Thunk
|
||||
* LLVM Target IDs use decimal for Maj/Min, hex for Step
|
||||
*/
|
||||
void Assembler::SetTargetAsic(const uint32_t Gfxv) {
|
||||
const uint8_t Major = (Gfxv >> 16) & 0xff;
|
||||
const uint8_t Minor = (Gfxv >> 8) & 0xff;
|
||||
const uint8_t Step = Gfxv & 0xff;
|
||||
|
||||
snprintf(MCPU, ASM_MCPU_LEN, "gfx%d%d%x", Major, Minor, Step);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize LLVM targets and assembly printers/parsers
|
||||
*/
|
||||
void Assembler::LLVMInit() {
|
||||
LLVMInitializeAMDGPUTargetInfo();
|
||||
LLVMInitializeAMDGPUTargetMC();
|
||||
LLVMInitializeAMDGPUAsmParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush/reset TextData and TextSize to initial state
|
||||
*/
|
||||
void Assembler::FlushText() {
|
||||
if (TextData)
|
||||
delete[] TextData;
|
||||
TextData = nullptr;
|
||||
TextSize = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print hex of ELF object to stdout (debug)
|
||||
*/
|
||||
void Assembler::PrintELFHex(const std::string Data) {
|
||||
outs() << "ASM Info: assembled ELF hex data (length " << Data.length() << "):\n";
|
||||
outs() << "0x00:\t";
|
||||
for (size_t i = 0; i < Data.length(); ++i) {
|
||||
char c = Data[i];
|
||||
outs() << format_hex(static_cast<uint8_t>(c), 4);
|
||||
if ((i+1) % 16 == 0)
|
||||
outs() << "\n" << format_hex(i+1, 4) << ":\t";
|
||||
else
|
||||
outs() << " ";
|
||||
}
|
||||
outs() << "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Print hex of raw instruction stream to stdout (debug)
|
||||
*/
|
||||
void Assembler::PrintTextHex() {
|
||||
outs() << "ASM Info: assembled .text hex data (length " << TextSize << "):\n";
|
||||
outs() << "0x00:\t";
|
||||
for (size_t i = 0; i < TextSize; i++) {
|
||||
outs() << format_hex(static_cast<uint8_t>(TextData[i]), 4);
|
||||
if ((i+1) % 16 == 0)
|
||||
outs() << "\n" << format_hex(i+1, 4) << ":\t";
|
||||
else
|
||||
outs() << " ";
|
||||
}
|
||||
outs() << "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract raw instruction stream from .text section in ELF object
|
||||
*
|
||||
* @param RawData Raw C string of ELF object
|
||||
* @return 0 on success
|
||||
*/
|
||||
int Assembler::ExtractELFText(const char* RawData) {
|
||||
const Elf64_Ehdr* ElfHeader;
|
||||
const Elf64_Shdr* SectHeader;
|
||||
const Elf64_Shdr* SectStrTable;
|
||||
const char* SectStrAddr;
|
||||
unsigned NumSects, SectIdx;
|
||||
|
||||
if (!(ElfHeader = reinterpret_cast<const Elf64_Ehdr*>(RawData))) {
|
||||
outs() << "ASM Error: elf data is invalid or corrupted\n";
|
||||
return -1;
|
||||
}
|
||||
if (ElfHeader->e_ident[EI_CLASS] != ELFCLASS64) {
|
||||
outs() << "ASM Error: elf object must be of 64-bit type\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
SectHeader = reinterpret_cast<const Elf64_Shdr*>(RawData + ElfHeader->e_shoff);
|
||||
SectStrTable = &SectHeader[ElfHeader->e_shstrndx];
|
||||
SectStrAddr = static_cast<const char*>(RawData + SectStrTable->sh_offset);
|
||||
|
||||
// Loop through sections, break on .text
|
||||
NumSects = ElfHeader->e_shnum;
|
||||
for (SectIdx = 0; SectIdx < NumSects; SectIdx++) {
|
||||
std::string SectName = std::string(SectStrAddr + SectHeader[SectIdx].sh_name);
|
||||
if (SectName == std::string(".text")) {
|
||||
TextSize = SectHeader[SectIdx].sh_size;
|
||||
TextData = new char[TextSize];
|
||||
memcpy(TextData, RawData + SectHeader[SectIdx].sh_offset, TextSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (SectIdx >= NumSects) {
|
||||
outs() << "ASM Error: couldn't locate .text section\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assemble shader, fill member vars, and copy to output buffer
|
||||
*
|
||||
* @param AssemblySource Shader source represented as a raw C string
|
||||
* @param OutBuf Raw instruction stream output buffer
|
||||
* @param BufSize Size of OutBuf (defaults to PAGE_SIZE)
|
||||
* @return Value of RunAssemble() (0 on success)
|
||||
*/
|
||||
int Assembler::RunAssembleBuf(const char* const AssemblySource, char* OutBuf,
|
||||
const size_t BufSize) {
|
||||
int ret = RunAssemble(AssemblySource);
|
||||
return ret ? ret : CopyInstrStream(OutBuf, BufSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assemble shader and fill member vars
|
||||
*
|
||||
* @param AssemblySource Shader source represented as a raw C string
|
||||
* @return 0 on success
|
||||
*/
|
||||
int Assembler::RunAssemble(const char* const AssemblySource) {
|
||||
// Ensure target ASIC has been set
|
||||
if (!MCPU) {
|
||||
outs() << "ASM Error: target asic is uninitialized\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Delete TextData for any previous runs
|
||||
FlushText();
|
||||
|
||||
#if 0
|
||||
outs() << "ASM Info: running assembly for target: " << MCPU << "\n";
|
||||
outs() << "ASM Info: source:\n";
|
||||
outs() << AssemblySource << "\n";
|
||||
#endif
|
||||
|
||||
// Initialize MCOptions and target triple
|
||||
const MCTargetOptions MCOptions;
|
||||
Triple TheTriple;
|
||||
|
||||
const Target* TheTarget =
|
||||
TargetRegistry::lookupTarget(ArchName, TheTriple, Error);
|
||||
if (!TheTarget) {
|
||||
outs() << Error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
TheTriple.setArchName(ArchName);
|
||||
TheTriple.setVendorName(VendorName);
|
||||
TheTriple.setOSName(OSName);
|
||||
|
||||
TripleName = TheTriple.getTriple();
|
||||
TheTriple.setTriple(Triple::normalize(TripleName));
|
||||
|
||||
// Create MemoryBuffer for assembly source
|
||||
StringRef AssemblyRef(AssemblySource);
|
||||
std::unique_ptr<MemoryBuffer> BufferPtr =
|
||||
MemoryBuffer::getMemBuffer(AssemblyRef, "", false);
|
||||
if (!BufferPtr->getBufferSize()) {
|
||||
outs() << "ASM Error: assembly source is empty\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Instantiate SrcMgr and transfer BufferPtr ownership
|
||||
SourceMgr SrcMgr;
|
||||
SrcMgr.AddNewSourceBuffer(std::move(BufferPtr), SMLoc());
|
||||
|
||||
// Initialize MC interfaces and base class objects
|
||||
std::unique_ptr<const MCRegisterInfo> MRI(
|
||||
TheTarget->createMCRegInfo(TripleName));
|
||||
if (!MRI) {
|
||||
outs() << "ASM Error: no register info for target " << MCPU << "\n";
|
||||
return -1;
|
||||
}
|
||||
#if LLVM_VERSION_MAJOR > 9
|
||||
std::unique_ptr<const MCAsmInfo> MAI(
|
||||
TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
|
||||
#else
|
||||
std::unique_ptr<const MCAsmInfo> MAI(
|
||||
TheTarget->createMCAsmInfo(*MRI, TripleName));
|
||||
#endif
|
||||
if (!MAI) {
|
||||
outs() << "ASM Error: no assembly info for target " << MCPU << "\n";
|
||||
return -1;
|
||||
}
|
||||
std::unique_ptr<MCInstrInfo> MCII(
|
||||
TheTarget->createMCInstrInfo());
|
||||
if (!MCII) {
|
||||
outs() << "ASM Error: no instruction info for target " << MCPU << "\n";
|
||||
return -1;
|
||||
}
|
||||
std::unique_ptr<MCSubtargetInfo> STI(
|
||||
TheTarget->createMCSubtargetInfo(TripleName, MCPU, std::string()));
|
||||
if (!STI || !STI->isCPUStringValid(MCPU)) {
|
||||
outs() << "ASM Error: no subtarget info for target " << MCPU << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set up the MCContext for creating symbols and MCExpr's
|
||||
#if LLVM_VERSION_MAJOR > 12
|
||||
MCContext Ctx(TheTriple, MAI.get(), MRI.get(), STI.get(), &SrcMgr, &MCOptions);
|
||||
#else
|
||||
MCObjectFileInfo MOFI;
|
||||
MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr, &MCOptions);
|
||||
MOFI.InitMCObjectFileInfo(TheTriple, true, Ctx);
|
||||
#endif
|
||||
|
||||
// Finalize setup for output object code stream
|
||||
std::string Data;
|
||||
std::unique_ptr<raw_string_ostream> DataStream(std::make_unique<raw_string_ostream>(Data));
|
||||
std::unique_ptr<buffer_ostream> BOS(std::make_unique<buffer_ostream>(*DataStream));
|
||||
raw_pwrite_stream* OS = BOS.get();
|
||||
|
||||
#if LLVM_VERSION_MAJOR > 14
|
||||
MCCodeEmitter* CE = TheTarget->createMCCodeEmitter(*MCII, Ctx);
|
||||
#else
|
||||
MCCodeEmitter* CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx);
|
||||
#endif
|
||||
MCAsmBackend* MAB = TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions);
|
||||
|
||||
std::unique_ptr<MCStreamer> Streamer(TheTarget->createMCObjectStreamer(
|
||||
TheTriple, Ctx,
|
||||
std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(*OS),
|
||||
std::unique_ptr<MCCodeEmitter>(CE), *STI, MCOptions.MCRelaxAll,
|
||||
MCOptions.MCIncrementalLinkerCompatible, /*DWARFMustBeAtTheEnd*/ false));
|
||||
|
||||
std::unique_ptr<MCAsmParser> Parser(
|
||||
createMCAsmParser(SrcMgr, Ctx, *Streamer, *MAI));
|
||||
|
||||
// Set parser to target parser and run
|
||||
std::unique_ptr<MCTargetAsmParser> TAP(
|
||||
TheTarget->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
|
||||
if (!TAP) {
|
||||
outs() << "ASM Error: no assembly parsing support for target " << MCPU << "\n";
|
||||
return -1;
|
||||
}
|
||||
Parser->setTargetParser(*TAP);
|
||||
|
||||
if (Parser->Run(true)) {
|
||||
outs() << "ASM Error: assembly parser failed\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOS.reset();
|
||||
DataStream->flush();
|
||||
|
||||
int ret = ExtractELFText(Data.data());
|
||||
if (ret < 0 || !TextData) {
|
||||
outs() << "ASM Error: .text extraction failed\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
PrintELFHex(Data);
|
||||
PrintTextHex();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The University of Illinois/NCSA
|
||||
// Open Source License (NCSA)
|
||||
//
|
||||
// Copyright (c) 2022, Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// Developed by:
|
||||
//
|
||||
// AMD Research and AMD HSA Software Development
|
||||
//
|
||||
// Advanced Micro Devices, Inc.
|
||||
//
|
||||
// www.amd.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal with the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimers.
|
||||
// - Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimers in
|
||||
// the documentation and/or other materials provided with the distribution.
|
||||
// - Neither the names of Advanced Micro Devices, Inc,
|
||||
// nor the names of its contributors may be used to endorse or promote
|
||||
// products derived from this Software without specific prior written
|
||||
// permission.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS WITH THE SOFTWARE.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _ASSEMBLE_H_
|
||||
#define _ASSEMBLE_H_
|
||||
|
||||
#define ASM_MCPU_LEN 16
|
||||
|
||||
class Assembler {
|
||||
private:
|
||||
const char* ArchName = "amdgcn";
|
||||
const char* VendorName = "amd";
|
||||
const char* OSName = "amdhsa";
|
||||
char MCPU[ASM_MCPU_LEN];
|
||||
|
||||
std::string TripleName;
|
||||
std::string Error;
|
||||
|
||||
char* TextData;
|
||||
size_t TextSize;
|
||||
|
||||
void SetTargetAsic(const uint32_t Gfxv);
|
||||
|
||||
void LLVMInit();
|
||||
void FlushText();
|
||||
void PrintELFHex(const std::string Data);
|
||||
int ExtractELFText(const char* RawData);
|
||||
|
||||
public:
|
||||
Assembler(const uint32_t Gfxv);
|
||||
~Assembler();
|
||||
|
||||
void PrintTextHex();
|
||||
const char* GetTargetAsic();
|
||||
|
||||
const char* GetInstrStream();
|
||||
const size_t GetInstrStreamSize();
|
||||
int CopyInstrStream(char* OutBuf, const size_t BufSize = PAGE_SIZE);
|
||||
|
||||
int RunAssemble(const char* const AssemblySource);
|
||||
int RunAssembleBuf(const char* const AssemblySource, char* OutBuf,
|
||||
const size_t BufSize = PAGE_SIZE);
|
||||
};
|
||||
|
||||
#endif // _ASSEMBLE_H_
|
||||
مرجع در شماره جدید
Block a user