[clang] e415cb1 - [LoongArch] Support inline asm operand modifier 'z'

Weining Lu via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 30 18:59:14 PDT 2022


Author: Weining Lu
Date: 2022-10-31T09:56:41+08:00
New Revision: e415cb1d61e798b6d69b5960a90f00518ca5008f

URL: https://github.com/llvm/llvm-project/commit/e415cb1d61e798b6d69b5960a90f00518ca5008f
DIFF: https://github.com/llvm/llvm-project/commit/e415cb1d61e798b6d69b5960a90f00518ca5008f.diff

LOG: [LoongArch] Support inline asm operand modifier 'z'

Print $zero register if operand is zero, otherwise print it normally.

Clang is highly compatible [1] with GCC inline assembly extensions,
allowing the same set of constraints, modifiers and operands as GCC
inline assembly. This patch tries to make it compatible regarding
LoongArch specific operand modifiers.

GCC supports many modifiers [2], but it seems that only x86 and msp430
are documented [3][4]. I don't know if any other modifiers are being
used except the 'z' in Linux [5].

[1]: https://clang.llvm.org/compatibility.html#inline-asm
[2]: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/loongarch.cc#L4884-L4911
[3]: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#x86Operandmodifiers
[4]: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#msp430Operandmodifiers
[5]: https://github.com/torvalds/linux/blob/master/arch/loongarch/include/asm/cmpxchg.h#L17

Differential Revision: https://reviews.llvm.org/D136841

Added: 
    clang/test/CodeGen/LoongArch/inline-asm-operand-modifiers.c
    llvm/test/CodeGen/LoongArch/inline-asm-operand-modifiers.ll

Modified: 
    llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp

Removed: 
    


################################################################################
diff  --git a/clang/test/CodeGen/LoongArch/inline-asm-operand-modifiers.c b/clang/test/CodeGen/LoongArch/inline-asm-operand-modifiers.c
new file mode 100644
index 0000000000000..b36fe7a7b69bb
--- /dev/null
+++ b/clang/test/CodeGen/LoongArch/inline-asm-operand-modifiers.c
@@ -0,0 +1,25 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple loongarch32 -O2 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple loongarch64 -O2 -emit-llvm %s -o - | FileCheck %s
+
+/// Test LoongArch specific operand modifiers (i.e. operand codes).
+
+// CHECK-LABEL: @test_z_zero(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 asm sideeffect "add.w $0, $1, ${2:z}", "=r,r,ri"(i32 [[A:%.*]], i32 0) #[[ATTR1:[0-9]+]], !srcloc !2
+// CHECK-NEXT:    ret void
+//
+void test_z_zero(int a) {
+  int tmp;
+  asm volatile ("add.w %0, %1, %z2" : "=r" (tmp) : "r" (a), "ri" (0));
+}
+
+// CHECK-LABEL: @test_z_nonzero(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 asm sideeffect "add.w $0, $1, ${2:z}", "=r,r,ri"(i32 [[A:%.*]], i32 1) #[[ATTR1]], !srcloc !3
+// CHECK-NEXT:    ret void
+//
+void test_z_nonzero(int a) {
+  int tmp;
+  asm volatile ("add.w %0, %1, %z2" : "=r" (tmp) : "r" (a), "ri" (1));
+}

diff  --git a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
index 9d69a26e18b13..5ab6bad1e891a 100644
--- a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
@@ -47,24 +47,38 @@ bool LoongArchAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
   if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
     return false;
 
-  // TODO: handle other extra codes if we have.
-  if (!ExtraCode) {
-    const MachineOperand &MO = MI->getOperand(OpNo);
-    switch (MO.getType()) {
-    case MachineOperand::MO_Immediate:
-      OS << MO.getImm();
-      return false;
-    case MachineOperand::MO_Register:
-      OS << '$' << LoongArchInstPrinter::getRegisterName(MO.getReg());
-      return false;
-    case MachineOperand::MO_GlobalAddress:
-      PrintSymbolOperand(MO, OS);
-      return false;
+  const MachineOperand &MO = MI->getOperand(OpNo);
+  if (ExtraCode && ExtraCode[0]) {
+    if (ExtraCode[1] != 0)
+      return true; // Unknown modifier.
+
+    switch (ExtraCode[0]) {
     default:
-      llvm_unreachable("not implemented");
+      return true; // Unknown modifier.
+    case 'z':      // Print $zero register if zero, regular printing otherwise.
+      if (MO.isImm() && MO.getImm() == 0) {
+        OS << '$' << LoongArchInstPrinter::getRegisterName(LoongArch::R0);
+        return false;
+      }
+      break;
+      // TODO: handle other extra codes if any.
     }
   }
 
+  switch (MO.getType()) {
+  case MachineOperand::MO_Immediate:
+    OS << MO.getImm();
+    return false;
+  case MachineOperand::MO_Register:
+    OS << '$' << LoongArchInstPrinter::getRegisterName(MO.getReg());
+    return false;
+  case MachineOperand::MO_GlobalAddress:
+    PrintSymbolOperand(MO, OS);
+    return false;
+  default:
+    llvm_unreachable("not implemented");
+  }
+
   return true;
 }
 

diff  --git a/llvm/test/CodeGen/LoongArch/inline-asm-operand-modifiers.ll b/llvm/test/CodeGen/LoongArch/inline-asm-operand-modifiers.ll
new file mode 100644
index 0000000000000..d3cf288bfd010
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/inline-asm-operand-modifiers.ll
@@ -0,0 +1,25 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch32 --verify-machineinstrs < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch64 --verify-machineinstrs < %s | FileCheck %s
+
+define i32 @modifier_z_zero(i32 %a) nounwind {
+; CHECK-LABEL: modifier_z_zero:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    add.w $a0, $a0, $zero
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    ret
+  %1 = tail call i32 asm "add.w $0, $1, ${2:z}", "=r,r,ri"(i32 %a, i32 0)
+  ret i32 %1
+}
+
+define i32 @modifier_z_nonzero(i32 %a) nounwind {
+; CHECK-LABEL: modifier_z_nonzero:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    addi.w $a0, $a0, 1
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    ret
+  %1 = tail call i32 asm "addi.w $0, $1, ${2:z}", "=r,r,ri"(i32 %a, i32 1)
+  ret i32 %1
+}


        


More information about the cfe-commits mailing list