Difference between revisions of "NaplesPU Clang Documentation"
(→tools/clang/lib/Driver/ToolChains.cpp) |
(→tools/clang/lib/Driver/ToolChains.h) |
||
Line 255: | Line 255: | ||
<syntaxhighlight lang="cpp" line='line'> | <syntaxhighlight lang="cpp" line='line'> | ||
+ | class LLVM_LIBRARY_VISIBILITY NuPlusToolChain : public ToolChain { | ||
+ | public: | ||
+ | NuPlusToolChain(const Driver &D, const llvm::Triple &Triple, | ||
+ | const llvm::opt::ArgList &Args); | ||
+ | ~NuPlusToolChain(); | ||
+ | bool IsIntegratedAssemblerDefault() const override; | ||
+ | bool isPICDefault() const override; | ||
+ | bool isPIEDefault() const override; | ||
+ | bool isPICDefaultForced() const override; | ||
+ | void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, | ||
+ | tools::ArgStringList &CC1Args) const override; | ||
+ | bool IsUnwindTablesDefault() const override; | ||
+ | protected: | ||
+ | virtual Tool *buildLinker() const; | ||
+ | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Revision as of 15:52, 13 September 2017
In the following, we will show which files should be modified and how.
Contents
- 1 tools/clang/include/clang/Basic/BuiltinsNuPlus.def
- 2 tools/clang/include/clang/Basic/TargetBuiltins.h
- 3 tools/clang/lib/Basic/Targets.cpp
- 4 tools/clang/lib/CodeGen/CGBuiltin.cpp
- 5 tools/clang/lib/CodeGen/CodeGenFunction.h
- 6 tools/clang/lib/Driver/Driver.cpp
- 7 tools/clang/lib/Driver/ToolChains.cpp
- 8 tools/clang/lib/Driver/ToolChains.h
- 9 tools/clang/lib/Driver/Tools.cpp
- 10 tools/clang/lib/Driver/Tools.h
tools/clang/include/clang/Basic/BuiltinsNuPlus.def
This file defines the NuPlus-specific builtin function database. The format of this database matches clang/Basic/Builtins.def.
tools/clang/include/clang/Basic/TargetBuiltins.h
namespace NuPlus {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsNuPlus.def"
LastTSBuiltin
};
}
tools/clang/lib/Basic/Targets.cpp
class NuPlusTargetInfo : public TargetInfo {
static const char *const GCCRegNames[];
static const Builtin::Info BuiltinInfo[];
public:
NuPlusTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
BigEndian = false;
TLSSupported = false; //thread-local storage
IntWidth = IntAlign = 32;
PointerWidth = PointerAlign = 32;
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
resetDataLayout("e-m:e-p:32:32");
}
bool setCPU(const std::string &Name) override {
return Name == "nuplus";
}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
Builder.defineMacro("__NUPLUS__");
}
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
return llvm::makeArrayRef(BuiltinInfo,
clang::NuPlus::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
virtual ArrayRef<const char*> getGCCRegNames() const override;
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
return None;
}
virtual bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const override;
virtual const char *getClobbers() const override {
return "";
}
virtual BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
}
};
This is required to implement the construction of a TargetInfo object. The NuPlusTargetInfo object is inherited from the TargetInfo object and the majority of its attributes are set by default in the TargetInfo constructor. Check the constructor in tools/clang/lib/Basic/TargetInfo.cpp. As regards NuPlus, the information that must be provided to the frontend includes:
- endianess
- thread-local storage (TLS)
- allignment and width of several types
- a DataLayout string used to describe the target. The string related to NuPlus is "e-m:e-p:32:32". The lower-case 'e' indicates little-endian. "m:e" indicates the ELF mangling mode. p:32:32 indicates size and alignment of pointers. For more information, check the DataLayout class implementation in lib/IR/DataLayout.cpp.
const char *const NuPlusTargetInfo::GCCRegNames[] = {
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
"s32", "s33", "s34", "s35", "s36", "s37", "s38", "s39",
"s40", "s41", "s42", "s43", "s44", "s45", "s46", "s47",
"s48", "s49", "s50", "s51", "s52", "s53", "s54", "s55",
"s56", "s57", "TR", "RM", "FP", "SP", "RA", "PC",
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
"v32", "v33", "v34", "v35", "v36", "v37", "v38", "v39",
"v40", "v41", "v42", "v43", "v44", "v45", "v46", "v47",
"v48", "v49", "v50", "v51", "v52", "v53", "v54", "v55",
"v56", "v57", "v58", "v59", "v60", "v61", "v62", "v63"
};
This is the list of all registers in the NuPlus register file.
ArrayRef<const char *> NuPlusTargetInfo::getGCCRegNames() const {
return llvm::makeArrayRef(GCCRegNames);
}
bool NuPlusTargetInfo::
validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const {
switch (*Name) {
default:
return false;
case 's':
case 'v':
Info.setAllowsRegister();
return true;
case 'I': // Unsigned 8-bit constant
case 'J': // Unsigned 12-bit constant
case 'K': // Signed 16-bit constant
case 'L': // Signed 20-bit displacement (on all targets we support)
case 'M': // 0x7fffffff
return true;
case 'Q': // Memory with base and unsigned 12-bit displacement
case 'R': // Likewise, plus an index
case 'S': // Memory with base and signed 20-bit displacement
case 'T': // Likewise, plus an index
Info.setAllowsMemory();
return true;
}
}
const Builtin::Info NuPlusTargetInfo::BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
ALL_LANGUAGES },
#include "clang/Basic/BuiltinsNuPlus.def"
};
static TargetInfo *AllocateTarget(const llvm::Triple &Triple, const TargetOptions &Opts) {
switch (Triple.getArch()) {
...
case llvm::Triple::nuplus:
return new NuPlusTargetInfo(Triple);
tools/clang/lib/CodeGen/CGBuiltin.cpp
static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF, unsigned BuiltinID, const CallExpr *E, llvm::Triple::ArchType Arch) {
switch (Arch) {
...
case llvm::Triple::nuplus:
return CGF->EmitNuPlusBuiltinExpr(BuiltinID, E);
...
Value *CodeGenFunction::EmitNuPlusBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
...
}
The EmitNuPlusBuiltinExpr function maps each Builtin call to the corresponding LLVM intrinsic. This is a target dependent function and hence it should be filled with all the NuPlus Builtin calls.
tools/clang/lib/CodeGen/CodeGenFunction.h
llvm::Value *EmitNuPlusBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
We add the function prototype.
tools/clang/lib/Driver/Driver.cpp
const ToolChain &Driver::getToolChain(const ArgList &Args, const llvm::Triple &Target) const {
...
switch (Target.getArch()) {
case llvm::Triple::nuplus:
TC = new toolchains::NuPlusToolChain(*this, Target, Args);
break;
This is required to retrieve the ToolChain for the NuPlus triple.
tools/clang/lib/Driver/ToolChains.cpp
NuPlusToolChain::NuPlusToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args) : ToolChain(D, Triple, Args){
// We expect 'as', 'ld', etc. to be adjacent to our install dir.
getProgramPaths().push_back(getDriver().getInstalledDir());
if (getDriver().getInstalledDir() != getDriver().Dir)
getProgramPaths().push_back(getDriver().Dir);
}
NuPlusToolChain::~NuPlusToolChain()
{
}
bool NuPlusToolChain::IsIntegratedAssemblerDefault() const
{
return true;
}
We use the default integrated assembler.
bool NuPlusToolChain::isPICDefault() const
{
return false;
}
bool NuPlusToolChain::isPIEDefault() const
{
return false;
}
bool NuPlusToolChain::isPICDefaultForced() const
{
return false;
}
By default, we don't use the Position Independent Code (PIC) and the Position Independent Executable (PIE).
void NuPlusToolChain::addClangTargetOptions(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
CC1Args.push_back("-nostdsysteminc");
if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
options::OPT_fno_use_init_array,
true))
{
CC1Args.push_back("-fuse-init-array");
}
}
This is used to add some options to Clang. In particular,
- -nostdsysteminc Disable standard system #include directories
- -fuse-init-array Use .init_array instead of .ctors
bool NuPlusToolChain::IsUnwindTablesDefault() const {
return true;
}
This enables the generation of unwind tables (DWARF-based stack unwinding, .eh_frame section).
Tool *NuPlusToolChain::buildLinker() const {
return new tools::NuPlus::Link(*this);
}
It builds the linker.
tools/clang/lib/Driver/ToolChains.h
class LLVM_LIBRARY_VISIBILITY NuPlusToolChain : public ToolChain {
public:
NuPlusToolChain(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
~NuPlusToolChain();
bool IsIntegratedAssemblerDefault() const override;
bool isPICDefault() const override;
bool isPIEDefault() const override;
bool isPICDefaultForced() const override;
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
tools::ArgStringList &CC1Args) const override;
bool IsUnwindTablesDefault() const override;
protected:
virtual Tool *buildLinker() const;
};