summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/RISCV
diff options
context:
space:
mode:
authorSam Elliott <selliott@lowrisc.org>2019-08-08 14:59:16 +0000
committerSam Elliott <selliott@lowrisc.org>2019-08-08 14:59:16 +0000
commit856d5c581783a31fea3099829099b0012e86ada7 (patch)
tree0797f008bb0c22408615c49274a80d04eab2cb01 /llvm/lib/Target/RISCV
parent215360737941c4c13fcdcb87128752a19363f13d (diff)
downloadbcm5719-llvm-856d5c581783a31fea3099829099b0012e86ada7.tar.gz
bcm5719-llvm-856d5c581783a31fea3099829099b0012e86ada7.zip
[RISCV] Allow ABI Names in Inline Assembly Constraints
Summary: Clang will replace references to registers using ABI names in inline assembly constraints with references to architecture names, but other frontends do not. LLVM uses the regular assembly parser to parse inline asm, so inline assembly strings can contain references to registers using their ABI names. This patch adds support for parsing constraints using either the ABI name or the architectural register name. This means we do not need to implement the ABI name replacement code in every single frontend, especially those like Rust which are a very thin shim on top of LLVM IR's inline asm, and that constraints can more closely match the assembly strings they refer to. Reviewers: asb, simoncook Reviewed By: simoncook Subscribers: hiraditya, rbar, johnrusso, JDevlieghere, apazos, sabuasal, niosHD, kito-cheng, shiva0217, jrtc27, MaskRay, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, Jim, s.egerton, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65947 llvm-svn: 368303
Diffstat (limited to 'llvm/lib/Target/RISCV')
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp112
1 files changed, 78 insertions, 34 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 1c139a576ac..c2a0a2fbca5 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -2461,47 +2461,91 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
}
}
+ // Clang will correctly decode the usage of register name aliases into their
+ // official names. However, other frontends like `rustc` do not. This allows
+ // users of these frontends to use the ABI names for registers in LLVM-style
+ // register constraints.
+ unsigned XRegFromAlias = StringSwitch<unsigned>(Constraint.lower())
+ .Case("{zero}", RISCV::X0)
+ .Case("{ra}", RISCV::X1)
+ .Case("{sp}", RISCV::X2)
+ .Case("{gp}", RISCV::X3)
+ .Case("{tp}", RISCV::X4)
+ .Case("{t0}", RISCV::X5)
+ .Case("{t1}", RISCV::X6)
+ .Case("{t2}", RISCV::X7)
+ .Cases("{s0}", "{fp}", RISCV::X8)
+ .Case("{s1}", RISCV::X9)
+ .Case("{a0}", RISCV::X10)
+ .Case("{a1}", RISCV::X11)
+ .Case("{a2}", RISCV::X12)
+ .Case("{a3}", RISCV::X13)
+ .Case("{a4}", RISCV::X14)
+ .Case("{a5}", RISCV::X15)
+ .Case("{a6}", RISCV::X16)
+ .Case("{a7}", RISCV::X17)
+ .Case("{s2}", RISCV::X18)
+ .Case("{s3}", RISCV::X19)
+ .Case("{s4}", RISCV::X20)
+ .Case("{s5}", RISCV::X21)
+ .Case("{s6}", RISCV::X22)
+ .Case("{s7}", RISCV::X23)
+ .Case("{s8}", RISCV::X24)
+ .Case("{s9}", RISCV::X25)
+ .Case("{s10}", RISCV::X26)
+ .Case("{s11}", RISCV::X27)
+ .Case("{t3}", RISCV::X28)
+ .Case("{t4}", RISCV::X29)
+ .Case("{t5}", RISCV::X30)
+ .Case("{t6}", RISCV::X31)
+ .Default(RISCV::NoRegister);
+ if (XRegFromAlias != RISCV::NoRegister)
+ return std::make_pair(XRegFromAlias, &RISCV::GPRRegClass);
+
// Since TargetLowering::getRegForInlineAsmConstraint uses the name of the
// TableGen record rather than the AsmName to choose registers for InlineAsm
// constraints, plus we want to match those names to the widest floating point
// register type available, manually select floating point registers here.
+ //
+ // The second case is the ABI name of the register, so that frontends can also
+ // use the ABI names in register constraint lists.
if (Subtarget.hasStdExtF() || Subtarget.hasStdExtD()) {
std::pair<unsigned, unsigned> FReg =
StringSwitch<std::pair<unsigned, unsigned>>(Constraint.lower())
- .Case("{f0}", {RISCV::F0_32, RISCV::F0_64})
- .Case("{f1}", {RISCV::F1_32, RISCV::F1_64})
- .Case("{f2}", {RISCV::F2_32, RISCV::F2_64})
- .Case("{f3}", {RISCV::F3_32, RISCV::F3_64})
- .Case("{f4}", {RISCV::F4_32, RISCV::F4_64})
- .Case("{f5}", {RISCV::F5_32, RISCV::F5_64})
- .Case("{f6}", {RISCV::F6_32, RISCV::F6_64})
- .Case("{f7}", {RISCV::F7_32, RISCV::F7_64})
- .Case("{f8}", {RISCV::F8_32, RISCV::F8_64})
- .Case("{f9}", {RISCV::F9_32, RISCV::F9_64})
- .Case("{f10}", {RISCV::F10_32, RISCV::F10_64})
- .Case("{f11}", {RISCV::F11_32, RISCV::F11_64})
- .Case("{f12}", {RISCV::F12_32, RISCV::F12_64})
- .Case("{f13}", {RISCV::F13_32, RISCV::F13_64})
- .Case("{f14}", {RISCV::F14_32, RISCV::F14_64})
- .Case("{f15}", {RISCV::F15_32, RISCV::F15_64})
- .Case("{f16}", {RISCV::F16_32, RISCV::F16_64})
- .Case("{f17}", {RISCV::F17_32, RISCV::F17_64})
- .Case("{f18}", {RISCV::F18_32, RISCV::F18_64})
- .Case("{f19}", {RISCV::F19_32, RISCV::F19_64})
- .Case("{f20}", {RISCV::F20_32, RISCV::F20_64})
- .Case("{f21}", {RISCV::F21_32, RISCV::F21_64})
- .Case("{f22}", {RISCV::F22_32, RISCV::F22_64})
- .Case("{f23}", {RISCV::F23_32, RISCV::F23_64})
- .Case("{f24}", {RISCV::F24_32, RISCV::F24_64})
- .Case("{f25}", {RISCV::F25_32, RISCV::F25_64})
- .Case("{f26}", {RISCV::F26_32, RISCV::F26_64})
- .Case("{f27}", {RISCV::F27_32, RISCV::F27_64})
- .Case("{f28}", {RISCV::F28_32, RISCV::F28_64})
- .Case("{f29}", {RISCV::F29_32, RISCV::F29_64})
- .Case("{f30}", {RISCV::F30_32, RISCV::F30_64})
- .Case("{f31}", {RISCV::F31_32, RISCV::F31_64})
- .Default({-1U, -1U});
- if (FReg.first != -1U)
+ .Cases("{f0}", "{ft0}", {RISCV::F0_32, RISCV::F0_64})
+ .Cases("{f1}", "{ft1}", {RISCV::F1_32, RISCV::F1_64})
+ .Cases("{f2}", "{ft2}", {RISCV::F2_32, RISCV::F2_64})
+ .Cases("{f3}", "{ft3}", {RISCV::F3_32, RISCV::F3_64})
+ .Cases("{f4}", "{ft4}", {RISCV::F4_32, RISCV::F4_64})
+ .Cases("{f5}", "{ft5}", {RISCV::F5_32, RISCV::F5_64})
+ .Cases("{f6}", "{ft6}", {RISCV::F6_32, RISCV::F6_64})
+ .Cases("{f7}", "{ft7}", {RISCV::F7_32, RISCV::F7_64})
+ .Cases("{f8}", "{fs0}", {RISCV::F8_32, RISCV::F8_64})
+ .Cases("{f9}", "{fs1}", {RISCV::F9_32, RISCV::F9_64})
+ .Cases("{f10}", "{fa0}", {RISCV::F10_32, RISCV::F10_64})
+ .Cases("{f11}", "{fa1}", {RISCV::F11_32, RISCV::F11_64})
+ .Cases("{f12}", "{fa2}", {RISCV::F12_32, RISCV::F12_64})
+ .Cases("{f13}", "{fa3}", {RISCV::F13_32, RISCV::F13_64})
+ .Cases("{f14}", "{fa4}", {RISCV::F14_32, RISCV::F14_64})
+ .Cases("{f15}", "{fa5}", {RISCV::F15_32, RISCV::F15_64})
+ .Cases("{f16}", "{fa6}", {RISCV::F16_32, RISCV::F16_64})
+ .Cases("{f17}", "{fa7}", {RISCV::F17_32, RISCV::F17_64})
+ .Cases("{f18}", "{fs2}", {RISCV::F18_32, RISCV::F18_64})
+ .Cases("{f19}", "{fs3}", {RISCV::F19_32, RISCV::F19_64})
+ .Cases("{f20}", "{fs4}", {RISCV::F20_32, RISCV::F20_64})
+ .Cases("{f21}", "{fs5}", {RISCV::F21_32, RISCV::F21_64})
+ .Cases("{f22}", "{fs6}", {RISCV::F22_32, RISCV::F22_64})
+ .Cases("{f23}", "{fs7}", {RISCV::F23_32, RISCV::F23_64})
+ .Cases("{f24}", "{fs8}", {RISCV::F24_32, RISCV::F24_64})
+ .Cases("{f25}", "{fs9}", {RISCV::F25_32, RISCV::F25_64})
+ .Cases("{f26}", "{fs10}", {RISCV::F26_32, RISCV::F26_64})
+ .Cases("{f27}", "{fs11}", {RISCV::F27_32, RISCV::F27_64})
+ .Cases("{f28}", "{ft8}", {RISCV::F28_32, RISCV::F28_64})
+ .Cases("{f29}", "{ft9}", {RISCV::F29_32, RISCV::F29_64})
+ .Cases("{f30}", "{ft10}", {RISCV::F30_32, RISCV::F30_64})
+ .Cases("{f31}", "{ft11}", {RISCV::F31_32, RISCV::F31_64})
+ .Default({RISCV::NoRegister, RISCV::NoRegister});
+ if (FReg.first != RISCV::NoRegister)
return Subtarget.hasStdExtD()
? std::make_pair(FReg.second, &RISCV::FPR64RegClass)
: std::make_pair(FReg.first, &RISCV::FPR32RegClass);
OpenPOWER on IntegriCloud