]> granicus.if.org Git - llvm/commitdiff
[SystemZ] Enable index register memory constraints for inline ASM
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Mon, 13 Jun 2016 14:24:05 +0000 (14:24 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Mon, 13 Jun 2016 14:24:05 +0000 (14:24 +0000)
This enables use of the 'R' and 'T' memory constraints for inline ASM
operands on SystemZ, which allow an index register as well as an
immediate displacement. This patch includes corresponding documentation
and test case updates.

As with the last patch of this kind, I moved the 'm' constraint to the
most general case, which is now 'T' (base + 20-bit signed displacement +
index register).

Author: colpell
Differential Revision: http://reviews.llvm.org/D21239

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

docs/LangRef.rst
lib/Target/SystemZ/README.txt
lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
test/CodeGen/SystemZ/asm-02.ll
test/CodeGen/SystemZ/asm-04.ll
test/CodeGen/SystemZ/asm-05.ll

index 78c3e4cd24c6b7744f463560569a9da0c298b4d8..1645371787e4d14cbbf5f6fd9d868fe9d35a768f 100644 (file)
@@ -3590,10 +3590,14 @@ SystemZ:
 - ``K``: An immediate signed 16-bit integer.
 - ``L``: An immediate signed 20-bit integer.
 - ``M``: An immediate integer 0x7fffffff.
-- ``Q``, ``R``: A memory address operand with a base address and a 12-bit
-  immediate unsigned displacement.
-- ``S``, ``T``: A memory address operand with a base address and a 20-bit
-  immediate signed displacement.
+- ``Q``: A memory address operand with a base address and a 12-bit immediate
+  unsigned displacement.
+- ``R``: A memory address operand with a base address, a 12-bit immediate
+  unsigned displacement, and an index register.
+- ``S``: A memory address operand with a base address and a 20-bit immediate
+  signed displacement.
+- ``T``: A memory address operand with a base address, a 20-bit immediate
+  signed displacement, and an index register.
 - ``r`` or ``d``: A 32, 64, or 128-bit integer register.
 - ``a``: A 32, 64, or 128-bit integer address register (excludes R0, which in an
   address context evaluates as zero).
index 957a91e7379fe797eebff6a6abc98dd462610a9f..f002e3959eb200138d5aa4df930768b76263e94d 100644 (file)
@@ -7,12 +7,6 @@ for later architectures at some point.
 
 --
 
-SystemZDAGToDAGISel::SelectInlineAsmMemoryOperand() treats the Q and R
-constraints the same, and the S and T constraints the same, because the optional
-index is not used.
-
---
-
 If an inline asm ties an i32 "r" result to an i64 input, the input
 will be treated as an i32, leaving the upper bits uninitialised.
 For example:
index 52841f791b4fa4605f8e5101f6ec1122c6b87caa..726bc28b6db299d3e202c8e69d18b8b182a7a169 100644 (file)
@@ -1323,6 +1323,8 @@ bool SystemZDAGToDAGISel::
 SelectInlineAsmMemoryOperand(const SDValue &Op,
                              unsigned ConstraintID,
                              std::vector<SDValue> &OutOps) {
+  SystemZAddressingMode::AddrForm Form;
+  SystemZAddressingMode::DispRange DispRange;
   SDValue Base, Disp, Index;
 
   switch(ConstraintID) {
@@ -1330,33 +1332,35 @@ SelectInlineAsmMemoryOperand(const SDValue &Op,
     llvm_unreachable("Unexpected asm memory constraint");
   case InlineAsm::Constraint_i:
   case InlineAsm::Constraint_Q:
+    // Accept an address with a short displacement, but no index.
+    Form = SystemZAddressingMode::FormBD;
+    DispRange = SystemZAddressingMode::Disp12Only;
+    break;
   case InlineAsm::Constraint_R:
-    // Accept addresses with short displacements, which are compatible
-    // with Q and R. But keep the index operand for future expansion (e.g. the
-    // index for R).
-    if (selectBDXAddr(SystemZAddressingMode::FormBD,
-                      SystemZAddressingMode::Disp12Only,
-                      Op, Base, Disp, Index)) {
-      OutOps.push_back(Base);
-      OutOps.push_back(Disp);
-      OutOps.push_back(Index);
-      return false;
-    }
+    // Accept an address with a short displacement and an index.
+    Form = SystemZAddressingMode::FormBDXNormal;
+    DispRange = SystemZAddressingMode::Disp12Only;
     break;
   case InlineAsm::Constraint_S:
+    // Accept an address with a long displacement, but no index.
+    Form = SystemZAddressingMode::FormBD;
+    DispRange = SystemZAddressingMode::Disp20Only;
+    break;
   case InlineAsm::Constraint_T:
   case InlineAsm::Constraint_m:
-    // Accept addresses with long displacements. As above, keep the index for
-    // future implementation of index for the T constraint.
-    if (selectBDXAddr(SystemZAddressingMode::FormBD,
-                      SystemZAddressingMode::Disp20Only,
-                      Op, Base, Disp, Index)) {
-      OutOps.push_back(Base);
-      OutOps.push_back(Disp);
-      OutOps.push_back(Index);
-      return false;
-    }
+    // Accept an address with a long displacement and an index.
+    // m works the same as T, as this is the most general case.
+    Form = SystemZAddressingMode::FormBDXNormal;
+    DispRange = SystemZAddressingMode::Disp20Only;
     break;
   }
+
+  if (selectBDXAddr(Form, DispRange, Op, Base, Disp, Index)) {
+    OutOps.push_back(Base);
+    OutOps.push_back(Disp);
+    OutOps.push_back(Index);
+    return false;
+  }
+
   return true;
 }
index 458bfeb4975339cee753f234d0ebea23bf06b0f1..426d84882900aacbd0ac4eff1fd9c4e26b539137 100644 (file)
@@ -48,5 +48,38 @@ define void @f4(i64 %base) {
   ret void
 }
 
-; FIXME: at the moment the precise constraint is not passed down to
-; target code, so we must conservatively treat "R" as "Q".
+; Check that indices are allowed
+define void @f5(i64 %base, i64 %index) {
+; CHECK-LABEL: f5:
+; CHECK: blah 0(%r3,%r2)
+; CHECK: br %r14
+  %add = add i64 %base, %index
+  %addr = inttoptr i64 %add to i64 *
+  call void asm "blah $0", "=*R" (i64 *%addr)
+  ret void
+}
+
+; Check that indices and displacements are allowed simultaneously
+define void @f6(i64 %base, i64 %index) {
+; CHECK-LABEL: f6:
+; CHECK: blah 4095(%r3,%r2)
+; CHECK: br %r14
+  %add = add i64 %base, 4095
+  %addi = add i64 %add, %index
+  %addr = inttoptr i64 %addi to i64 *
+  call void asm "blah $0", "=*R" (i64 *%addr)
+  ret void
+}
+
+; Check that LAY is used if there is an index but the displacement is too large
+define void @f7(i64 %base, i64 %index) {
+; CHECK-LABEL: f7:
+; CHECK: lay %r0, 4096(%r3,%r2)
+; CHECK: blah 0(%r0)
+; CHECK: br %r14
+  %add = add i64 %base, 4096
+  %addi = add i64 %add, %index
+  %addr = inttoptr i64 %addi to i64 *
+  call void asm "blah $0", "=*R" (i64 *%addr)
+  ret void
+}
index a41a0a630d94f96af00d9839c2a8e108820a11a1..eb91bef83769a6da1179d82cf358880b365454be 100644 (file)
@@ -3,14 +3,71 @@
 ;
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -no-integrated-as | FileCheck %s
 
+; Check the lowest range.
 define void @f1(i64 %base) {
 ; CHECK-LABEL: f1:
+; CHECK: blah -524288(%r2)
+; CHECK: br %r14
+  %add = add i64 %base, -524288
+  %addr = inttoptr i64 %add to i64 *
+  call void asm "blah $0", "=*T" (i64 *%addr)
+  ret void
+}
+
+; Check the next lowest byte.
+define void @f2(i64 %base) {
+; CHECK-LABEL: f2:
+; CHECK: agfi %r2, -524289
 ; CHECK: blah 0(%r2)
 ; CHECK: br %r14
-  %addr = inttoptr i64 %base to i64 *
+  %add = add i64 %base, -524289
+  %addr = inttoptr i64 %add to i64 *
   call void asm "blah $0", "=*T" (i64 *%addr)
   ret void
 }
 
-; FIXME: at the moment the precise constraint is not passed down to
-; target code, so we must conservatively treat "T" as "S".
+; Check the highest range.
+define void @f3(i64 %base) {
+; CHECK-LABEL: f3:
+; CHECK: blah 524287(%r2)
+; CHECK: br %r14
+  %add = add i64 %base, 524287
+  %addr = inttoptr i64 %add to i64 *
+  call void asm "blah $0", "=*T" (i64 *%addr)
+  ret void
+}
+
+; Check the next highest byte.
+define void @f4(i64 %base) {
+; CHECK-LABEL: f4:
+; CHECK: agfi %r2, 524288
+; CHECK: blah 0(%r2)
+; CHECK: br %r14
+  %add = add i64 %base, 524288
+  %addr = inttoptr i64 %add to i64 *
+  call void asm "blah $0", "=*T" (i64 *%addr)
+  ret void
+}
+
+; Check that indices are allowed
+define void @f5(i64 %base, i64 %index) {
+; CHECK-LABEL: f5:
+; CHECK: blah 0(%r3,%r2)
+; CHECK: br %r14
+  %add = add i64 %base, %index
+  %addr = inttoptr i64 %add to i64 *
+  call void asm "blah $0", "=*T" (i64 *%addr)
+  ret void
+}
+
+; Check that indices and displacements are allowed simultaneously
+define void @f6(i64 %base, i64 %index) {
+; CHECK-LABEL: f6:
+; CHECK: blah 524287(%r3,%r2)
+; CHECK: br %r14
+  %add = add i64 %base, 524287
+  %addi = add i64 %add, %index
+  %addr = inttoptr i64 %addi to i64 *
+  call void asm "blah $0", "=*T" (i64 *%addr)
+  ret void
+}
index 780b61ac3a32b85ae649202f4e2d91303caa0b9a..9b23ac7817502e0ccd01fdb680769e3a1d140f52 100644 (file)
@@ -10,6 +10,3 @@ define void @f1(i64 %base) {
   call void asm "blah $0", "=*m" (i64 *%addr)
   ret void
 }
-
-; FIXME: at the moment the precise constraint is not passed down to
-; target code, so we must conservatively treat "m" as "S".