- Next up, we must implement the getM88kTargetCPU() function, in which, given the clang CPU name that we implemented earlier in clang/include/clang/Driver/Options.td, we get the corresponding LLVM name for the M88k CPU we are targeting:
StringRef m88k::getM88kTargetCPU(const ArgList &Args) {
Arg *A = Args.getLastArg(options::OPT_m88000, options::OPT_m88100, options::OPT_m88110, options::OPT_mcpu_EQ);
if (!A)
return StringRef();
switch (A->getOption().getID()) {
case options::OPT_m88000:
return “mc88000”;
case options::OPT_m88100:
return “mc88100”;
case options::OPT_m88110:
return “mc88110”;
case options::OPT_mcpu_EQ:
return normalizeCPU(A->getValue());
default:
llvm_unreachable(“Impossible option ID”);
}
}
- The getM88kTuneCPU() function is implemented after. This is the behavior of the clang -mtune= option, which changes the instruction scheduling model to use data from a given CPU for M88k. We simply tune for whatever CPU that we are currently targeting:
StringRef m88k::getM88kTuneCPU(const ArgList &Args) {
if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ))
return normalizeCPU(A->getValue());
return StringRef();
}
- We’ll also implement the getM88kFloatABI() method, which gets the floating-point ABI. Initially, we’ll set the ABI to be m88k::FloatABI::Invalid as a default value. Next, we must check if any of the -msoft-float or -mhard-float options are passed to the command line. If -msoft-float is specified, then we set the ABI to m88k::FloatABI::Soft accordingly. Likewise, we set m88k::FloatABI::Hard when -mhard-float is specified to clang. Finally, if none of these options are specified, we choose the default on the current platform, which would be a hard floating-point value for M88k:
m88k::FloatABI m88k::getM88kFloatABI(const Driver &D, const ArgList &Args) {
m88k::FloatABI ABI = m88k::FloatABI::Invalid;
if (Arg *A =
Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) {
if (A->getOption().matches(options::OPT_msoft_float))
ABI = m88k::FloatABI::Soft;
else if (A->getOption().matches(options::OPT_mhard_float))
ABI = m88k::FloatABI::Hard;
}
if (ABI == m88k::FloatABI::Invalid)
ABI = m88k::FloatABI::Hard;
return ABI;
}
- We’ll add the implementation for getM88kTargetFeatures() next. The important part of this function is the vector of Features that are passed as a parameter. As we can see, the only target features that are handled are the floating-point ABI. From the driver and arguments passed to it, we’ll get the appropriate floating-point ABI from what we implemented in the previous step. Note that we add the -hard-float target features to the Features vector for soft float ABI as well, which means that currently, M88k only supports hard float:
void m88k::getM88kTargetFeatures(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args,
std::vector &Features) {
m88k::FloatABI FloatABI = m88k::getM88kFloatABI(D, Args);
if (FloatABI == m88k::FloatABI::Soft)
Features.push_back(“-hard-float”);
}