OSDN Git Service

[mips] Support the "o" inline asm constraint
authorSimon Atanasyan <simon@atanasyan.com>
Wed, 17 Jul 2019 08:11:15 +0000 (08:11 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Wed, 17 Jul 2019 08:11:15 +0000 (08:11 +0000)
As well as other LLVM targets we do not handle "offsettable"
memory addresses in any special way. In other words, the "o" constraint
is an exact equivalent of the "m" one. But some existing code require
the "o" constraint support.

This fixes PR42589.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366299 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsISelLowering.h
lib/Target/Mips/MipsSEISelDAGToDAG.cpp
test/CodeGen/Mips/inlineasm_constraint_o.ll [new file with mode: 0644]

index 27bf18c..2db60e9 100644 (file)
@@ -653,6 +653,8 @@ class TargetRegisterClass;
 
     unsigned
     getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
+      if (ConstraintCode == "o")
+        return InlineAsm::Constraint_o;
       if (ConstraintCode == "R")
         return InlineAsm::Constraint_R;
       if (ConstraintCode == "ZC")
index c50e4c2..703f99f 100644 (file)
@@ -1237,6 +1237,7 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
     OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
     return false;
   case InlineAsm::Constraint_m:
+  case InlineAsm::Constraint_o:
     if (selectAddrRegImm16(Op, Base, Offset)) {
       OutOps.push_back(Base);
       OutOps.push_back(Offset);
diff --git a/test/CodeGen/Mips/inlineasm_constraint_o.ll b/test/CodeGen/Mips/inlineasm_constraint_o.ll
new file mode 100644 (file)
index 0000000..de677cb
--- /dev/null
@@ -0,0 +1,61 @@
+; RUN: llc -march=mipsel -relocation-model=pic < %s | FileCheck %s
+
+@data = global [8193 x i32] zeroinitializer
+
+define void @o(i32 *%p) nounwind {
+entry:
+  ; CHECK-LABEL: o:
+
+  call void asm sideeffect "lw $$1, $0", "*o,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 0))
+
+  ; CHECK: lw $[[BASEPTR:[0-9]+]], %got(data)(
+  ; CHECK: #APP
+  ; CHECK: lw $1, 0($[[BASEPTR]])
+  ; CHECK: #NO_APP
+
+  ret void
+}
+
+define void @o_offset_4(i32 *%p) nounwind {
+entry:
+  ; CHECK-LABEL: o_offset_4:
+
+  call void asm sideeffect "lw $$1, $0", "*o,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 1))
+
+  ; CHECK: lw $[[BASEPTR:[0-9]+]], %got(data)(
+  ; CHECK: #APP
+  ; CHECK: lw $1, 4($[[BASEPTR]])
+  ; CHECK: #NO_APP
+
+  ret void
+}
+
+define void @o_offset_32764(i32 *%p) nounwind {
+entry:
+  ; CHECK-LABEL: o_offset_32764:
+
+  call void asm sideeffect "lw $$1, $0", "*o,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 8191))
+
+  ; CHECK-DAG: lw $[[BASEPTR:[0-9]+]], %got(data)(
+  ; CHECK: #APP
+  ; CHECK: lw $1, 32764($[[BASEPTR]])
+  ; CHECK: #NO_APP
+
+  ret void
+}
+
+define void @o_offset_32768(i32 *%p) nounwind {
+entry:
+  ; CHECK-LABEL: o_offset_32768:
+
+  call void asm sideeffect "lw $$1, $0", "*o,~{$1}"(i32* getelementptr inbounds ([8193 x i32], [8193 x i32]* @data, i32 0, i32 8192))
+
+  ; CHECK-DAG: lw $[[BASEPTR:[0-9]+]], %got(data)(
+  ; CHECK-DAG: ori $[[T0:[0-9]+]], $zero, 32768
+  ; CHECK: addu $[[BASEPTR2:[0-9]+]], $[[BASEPTR]], $[[T0]]
+  ; CHECK: #APP
+  ; CHECK: lw $1, 0($[[BASEPTR2]])
+  ; CHECK: #NO_APP
+
+  ret void
+}