[llvm] [SPARC] Implement L and H inline asm argument modifiers (PR #87259)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 1 09:48:03 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-sparc
Author: Koakuma (koachan)
<details>
<summary>Changes</summary>
This adds support for using the L and H argument modifiers for twinword operands in inline asm code, which is used by the Linux kernel.
---
Full diff: https://github.com/llvm/llvm-project/pull/87259.diff
3 Files Affected:
- (modified) llvm/docs/LangRef.rst (+2)
- (modified) llvm/lib/Target/Sparc/SparcAsmPrinter.cpp (+42)
- (modified) llvm/test/CodeGen/SPARC/inlineasm.ll (+9)
``````````diff
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 8bc1cab01bf0a6..3f8f4c01201a6c 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -5557,6 +5557,8 @@ RISC-V:
Sparc:
+- ``L``: Print the low-order register of a two-register operand.
+- ``H``: Print the high-order register of a two-register operand.
- ``r``: No effect.
SystemZ:
diff --git a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp
index 215a8ea8319046..35daf84a351239 100644
--- a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp
+++ b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp
@@ -434,6 +434,48 @@ bool SparcAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
default:
// See if this is a generic print operand
return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
+ case 'L': // Low order register of a twin word register operand
+ case 'H': // High order register of a twin word register operand
+ {
+ if (OpNo == 0)
+ return true;
+
+ const SparcSubtarget &Subtarget = MF->getSubtarget<SparcSubtarget>();
+ const MachineOperand &MO = MI->getOperand(OpNo);
+ const Register MOReg = MO.getReg();
+
+ Register HiReg, LoReg;
+ if (SP::IntPairRegClass.contains(MOReg)) {
+ // If we're given a register pair, decompose it
+ // to its constituents and use them as-is.
+ const SparcRegisterInfo *RegisterInfo = Subtarget.getRegisterInfo();
+ HiReg = RegisterInfo->getSubReg(MOReg, SP::sub_even);
+ LoReg = RegisterInfo->getSubReg(MOReg, SP::sub_odd);
+ } else {
+ // Otherwise we should be given an even-numbered register,
+ // which will become the Hi part of the pair.
+ HiReg = MOReg;
+ LoReg = MOReg + 1;
+
+ // FIXME this really should not be an assert check, but
+ // I have no good idea on how to raise an error with explainations.
+ assert(((HiReg - SP::G0) % 2 == 0) &&
+ "Hi part of pair should point to an even-numbered register!");
+ }
+
+ Register Reg;
+ switch (ExtraCode[0]) {
+ case 'L':
+ Reg = LoReg;
+ break;
+ case 'H':
+ Reg = HiReg;
+ break;
+ }
+
+ O << '%' << SparcInstPrinter::getRegisterName(Reg);
+ return false;
+ }
case 'f':
case 'r':
break;
diff --git a/llvm/test/CodeGen/SPARC/inlineasm.ll b/llvm/test/CodeGen/SPARC/inlineasm.ll
index ec27598e5e83b7..cfb44817fb54a8 100644
--- a/llvm/test/CodeGen/SPARC/inlineasm.ll
+++ b/llvm/test/CodeGen/SPARC/inlineasm.ll
@@ -143,3 +143,12 @@ entry:
%1 = call double asm sideeffect "faddd $1, $2, $0", "=f,f,e"(i64 0, i64 0)
ret void
}
+
+; CHECK-label:test_twinword
+; CHECK: rd %asr5, %i1
+; CHECK: srlx %i1, 32, %i0
+
+define i64 @test_twinword(){
+ %1 = tail call i64 asm sideeffect "rd %asr5, ${0:L} \0A\09 srlx ${0:L}, 32, ${0:H}", "=r"()
+ ret i64 %1
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/87259
More information about the llvm-commits
mailing list