Skip to content

Commit

Permalink
[SystemZ] Enable long displacement constraints for inline ASM operands
Browse files Browse the repository at this point in the history
This enables use of the 'S' constraint for inline ASM operands on
SystemZ, which allows for a memory reference with a signed 20-bit
immediate displacement. This patch includes corresponding documentation
and test case updates.

I've changed the 'T' constraint to match the new behavior for 'S', as
'T' also uses a long displacement (though index constraints are still
not implemented). I also changed 'm' to match the behavior for 'S' as
this will allow for a wider range of displacements for 'm', though
correct me if that's not the right decision.

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



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272266 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
uweigand committed Jun 9, 2016
1 parent cbf7512 commit 09f4ea2
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 16 deletions.
6 changes: 4 additions & 2 deletions docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3590,8 +3590,10 @@ SystemZ:
- ``K``: An immediate signed 16-bit integer.
- ``L``: An immediate signed 20-bit integer.
- ``M``: An immediate integer 0x7fffffff.
- ``Q``, ``R``, ``S``, ``T``: A memory address operand, treated the same as
``m``, at the moment.
- ``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.
- ``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).
Expand Down
7 changes: 3 additions & 4 deletions lib/Target/SystemZ/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ for later architectures at some point.

--

SystemZDAGToDAGISel::SelectInlineAsmMemoryOperand() is passed "m" for all
inline asm memory constraints; it doesn't get to see the original constraint.
This means that it must conservatively treat all inline asm constraints
as the most restricted type, "R".
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.

--

Expand Down
23 changes: 18 additions & 5 deletions lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1322,18 +1322,17 @@ bool SystemZDAGToDAGISel::
SelectInlineAsmMemoryOperand(const SDValue &Op,
unsigned ConstraintID,
std::vector<SDValue> &OutOps) {
SDValue Base, Disp, Index;

switch(ConstraintID) {
default:
llvm_unreachable("Unexpected asm memory constraint");
case InlineAsm::Constraint_i:
case InlineAsm::Constraint_m:
case InlineAsm::Constraint_Q:
case InlineAsm::Constraint_R:
case InlineAsm::Constraint_S:
case InlineAsm::Constraint_T:
// Accept addresses with short displacements, which are compatible
// with Q, R, S and T. But keep the index operand for future expansion.
SDValue Base, Disp, Index;
// 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)) {
Expand All @@ -1343,6 +1342,20 @@ SelectInlineAsmMemoryOperand(const SDValue &Op,
return false;
}
break;
case InlineAsm::Constraint_S:
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;
}
break;
}
return true;
}
40 changes: 37 additions & 3 deletions test/CodeGen/SystemZ/asm-03.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,48 @@
;
; 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", "=*S" (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", "=*S" (i64 *%addr)
ret void
}

; FIXME: at the moment the precise constraint is not passed down to
; target code, so we must conservatively treat "S" as "Q".
; 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", "=*S" (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", "=*S" (i64 *%addr)
ret void
}
2 changes: 1 addition & 1 deletion test/CodeGen/SystemZ/asm-04.ll
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ define void @f1(i64 %base) {
}

; FIXME: at the moment the precise constraint is not passed down to
; target code, so we must conservatively treat "T" as "Q".
; target code, so we must conservatively treat "T" as "S".
2 changes: 1 addition & 1 deletion test/CodeGen/SystemZ/asm-05.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ define void @f1(i64 %base) {
}

; FIXME: at the moment the precise constraint is not passed down to
; target code, so we must conservatively treat "m" as "Q".
; target code, so we must conservatively treat "m" as "S".

0 comments on commit 09f4ea2

Please sign in to comment.