Difference between revisions of "NaplesPU Tools"

From NaplesPU Documentation
Jump to: navigation, search
 
(18 intermediate revisions by 2 users not shown)
Line 1: Line 1:
A new backend for llvm needs to be added and registered. After registration, llvm tools are able to lookup and use the new target at runtime.
+
NaplesPU is provided with a set of additional tools in order to fully support the compilation process of an application.  
In the following, we will show which files are involved in the registration phase and which changes are required.  
 
  
==== CMakeLists.txt ====
+
== elf2hex ==
<syntaxhighlight lang="cpp" line='line'>
+
elf2hex is the tool required for elf code transformation. It works on an input ELF code to produce a hex output file as the memory image to be written on device memory. NaplesPU relies on its own implementation of the elf2hex tool, located in elf2hex.cpp. In our purposes, the tool produces two different outputs:
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+
* MANGO compliant memory image, a 512-bit little-endian aligned image ready to be flashed on the MANGO platform;
set(CMAKE_INSTALL_PREFIX "/usr/local/llvm-nuplus/" CACHE PATH "NuPlusLLVM install prefix" FORCE)
+
* Standalone compliant memory image, a 512-bit little-endian aligned image to be used in a standalone environment.
endif()
 
</syntaxhighlight>
 
This specifies the installation path that, in our case, is: "/usr/local/llvm-nuplus/".
 
 
 
<syntaxhighlight lang="cpp" line='line'>
 
set(LLVM_ALL_TARGETS
 
  AArch64
 
  AMDGPU
 
  ARM
 
  BPF
 
  Hexagon
 
  Mips
 
  MSP430
 
  NVPTX
 
  PowerPC
 
  Sparc
 
  SystemZ
 
  X86
 
  XCore
 
  NuPlus
 
  )
 
</syntaxhighlight>
 
The target name should be added to the LLVM_ALL_TARGETS list.
 
 
 
<syntaxhighlight lang="cpp" line='line'>
 
set(LLVM_TARGETS_TO_BUILD "NuPlus" CACHE STRING "Semicolon-separated list of targets to build, or \"all\".")
 
</syntaxhighlight>
 
In a standard version of llvm, the LLVM_TARGETS_TO_BUILD variable is set to "all" in order to compile llvm with all the provided target backends. In out custom compiler, we set this variable to "NuPlus". In this way the compiler is built just targeting the NuPlus architecture.
 
  
<syntaxhighlight lang="cpp" line='line'>
+
== Disassembler ==
set(LLVM_DEFAULT_TARGET_TRIPLE "nuplus-none-none" CACHE STRING "Default target for which LLVM will generate code." )
+
A disassembler attempts to revert back the assembly code from the binary one. In order to be able to support NaplesPU code disassembly, LLVM requires to implement a Disassembler class. The implementation is provided in [[NaplesPUDisassembler.cpp]]. Disassembly methods rely on auto-generated ''decoder tables'' from TableGen files. TableGen also offers a way to force a specific decoder method to be called, specifying the ''DecoderMethod'' field on instructions.
</syntaxhighlight>
 
Finally, we remove the possibility of targeting a different architecture then NuPlus.
 
  
==== cmake/config-ix.cmake ====
+
<syntaxhighlight>
<syntaxhighlight lang="cpp" line='line'>
+
def V16MEMri : Operand<v16i32> {
if (LLVM_NATIVE_ARCH MATCHES "i[2-6]86")
+
  let EncoderMethod = "encodeMemoryOpValue";
  set(LLVM_NATIVE_ARCH X86)
+
  let DecoderMethod = "decodeVectorWMemoryOpValue";
 
...
 
...
elseif (LLVM_NATIVE_ARCH MATCHES "nuplus")
+
}
  set(LLVM_NATIVE_ARCH NuPlus)
 
</syntaxhighlight>
 
  
==== include/llvm/ADT/Triple.h ====
+
static DecodeStatus decodeVectorWMemoryOpValue(...)
<syntaxhighlight lang="cpp" line='line'>
+
{
enum ArchType {
+
  return decodeMemoryOpValue(Inst, Insn, Address, Decoder,
    UnknownArch,
+
        NaplesPU::VR512WRegClassID);
    arm,           // ARM (little endian): arm, armv.*, xscale
+
}
    ...
 
    nuplus,        // NuPlus
 
 
</syntaxhighlight>
 
</syntaxhighlight>
We add NuPlus to the ArchType list.
 
  
==== include/llvm/IR/Intrinsics.td ====
+
== Object File Dumper ==
<syntaxhighlight lang="cpp" line='line'>
+
LLVM provides a custom tool to work as an object file dumper, that is a utility that prints the contents of object files and of the final linked image. For this reason, it is primarily used to debug the generated machine code. In the LLVM implementation, the ''llvm-objdump'' binary relies on the Disassembler classes, in order to revert the binary code into the assembly back.
include "llvm/IR/IntrinsicsNuPlus.td"
 
</syntaxhighlight>
 
In order to use target-specific intrinsics, we include the path to IntrinsicsNuPlus.td, i.e. the file containing the NuPlus intrinsics.
 

Latest revision as of 17:22, 21 June 2019

NaplesPU is provided with a set of additional tools in order to fully support the compilation process of an application.

elf2hex

elf2hex is the tool required for elf code transformation. It works on an input ELF code to produce a hex output file as the memory image to be written on device memory. NaplesPU relies on its own implementation of the elf2hex tool, located in elf2hex.cpp. In our purposes, the tool produces two different outputs:

  • MANGO compliant memory image, a 512-bit little-endian aligned image ready to be flashed on the MANGO platform;
  • Standalone compliant memory image, a 512-bit little-endian aligned image to be used in a standalone environment.

Disassembler

A disassembler attempts to revert back the assembly code from the binary one. In order to be able to support NaplesPU code disassembly, LLVM requires to implement a Disassembler class. The implementation is provided in NaplesPUDisassembler.cpp. Disassembly methods rely on auto-generated decoder tables from TableGen files. TableGen also offers a way to force a specific decoder method to be called, specifying the DecoderMethod field on instructions.

def V16MEMri : Operand<v16i32> {
  let EncoderMethod = "encodeMemoryOpValue";
  let DecoderMethod = "decodeVectorWMemoryOpValue";
...
}

static DecodeStatus decodeVectorWMemoryOpValue(...) 
{
  return decodeMemoryOpValue(Inst, Insn, Address, Decoder,
         NaplesPU::VR512WRegClassID);
}

Object File Dumper

LLVM provides a custom tool to work as an object file dumper, that is a utility that prints the contents of object files and of the final linked image. For this reason, it is primarily used to debug the generated machine code. In the LLVM implementation, the llvm-objdump binary relies on the Disassembler classes, in order to revert the binary code into the assembly back.