From 06426f54cb8aac39c0fff5f17d61c680069d3a89 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Tue, 24 Mar 2015 15:19:14 +0000 Subject: [PATCH] [mips] Support 16-bit offsets for 'm' inline assembly memory constraint. Reviewers: vkalintiris Reviewed By: vkalintiris Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8435 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233086 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsSEISelDAGToDAG.cpp | 10 +++- test/CodeGen/Mips/inlineasm_constraint_m.ll | 61 +++++++++++++++++++++ test/CodeGen/Mips/inlineasmmemop.ll | 15 +++-- 3 files changed, 77 insertions(+), 9 deletions(-) create mode 100644 test/CodeGen/Mips/inlineasm_constraint_m.ll diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 252f9b68c1d..a598c3f1db5 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -948,11 +948,19 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, llvm_unreachable("Unexpected asm memory constraint"); // All memory constraints can at least accept raw pointers. case InlineAsm::Constraint_i: - case InlineAsm::Constraint_m: case InlineAsm::Constraint_R: OutOps.push_back(Op); OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32)); return false; + case InlineAsm::Constraint_m: + if (selectAddrRegImm16(Op, Base, Offset)) { + OutOps.push_back(Base); + OutOps.push_back(Offset); + return false; + } + OutOps.push_back(Op); + OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32)); + return false; case InlineAsm::Constraint_ZC: // ZC matches whatever the pref, ll, and sc instructions can handle for the // given subtarget. diff --git a/test/CodeGen/Mips/inlineasm_constraint_m.ll b/test/CodeGen/Mips/inlineasm_constraint_m.ll new file mode 100644 index 00000000000..00053ad3c10 --- /dev/null +++ b/test/CodeGen/Mips/inlineasm_constraint_m.ll @@ -0,0 +1,61 @@ +; RUN: llc -march=mipsel < %s | FileCheck %s + +@data = global [8193 x i32] zeroinitializer + +define void @m(i32 *%p) nounwind { +entry: + ; CHECK-LABEL: m: + + call void asm sideeffect "lw $$1, $0", "*m,~{$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 @m_offset_4(i32 *%p) nounwind { +entry: + ; CHECK-LABEL: m_offset_4: + + call void asm sideeffect "lw $$1, $0", "*m,~{$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 @m_offset_32764(i32 *%p) nounwind { +entry: + ; CHECK-LABEL: m_offset_32764: + + call void asm sideeffect "lw $$1, $0", "*m,~{$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 @m_offset_32768(i32 *%p) nounwind { +entry: + ; CHECK-LABEL: m_offset_32768: + + call void asm sideeffect "lw $$1, $0", "*m,~{$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 +} diff --git a/test/CodeGen/Mips/inlineasmmemop.ll b/test/CodeGen/Mips/inlineasmmemop.ll index 99f35f5c4f6..9e9b6cd089e 100644 --- a/test/CodeGen/Mips/inlineasmmemop.ll +++ b/test/CodeGen/Mips/inlineasmmemop.ll @@ -6,14 +6,13 @@ define i32 @f1(i32 %x) nounwind { entry: ; CHECK-LABEL: f1: -; CHECK: addiu $[[T0:[0-9]+]], $sp ; CHECK: #APP -; CHECK: sw $4, 0($[[T0]]) +; CHECK: sw $4, [[OFFSET:[0-9]+]]($sp) ; CHECK: #NO_APP +; CHECK: lw $[[T1:[0-9]+]], %got(g1) ; CHECK: #APP -; CHECK: lw $[[T3:[0-9]+]], 0($[[T0]]) +; CHECK: lw $[[T3:[0-9]+]], [[OFFSET]]($sp) ; CHECK: #NO_APP -; CHECK: lw $[[T1:[0-9]+]], %got(g1) ; CHECK: sw $[[T3]], 0($[[T1]]) %l1 = alloca i32, align 4 @@ -27,13 +26,13 @@ entry: ; "D": Second word of a double word. This works for any memory element ; double or single. ; CHECK: #APP -; CHECK: lw ${{[0-9]+}},4(${{[0-9]+}}); +; CHECK: lw ${{[0-9]+}}, 16(${{[0-9]+}}); ; CHECK: #NO_APP ; No "D": First word of a double word. This works for any memory element ; double or single. ; CHECK: #APP -; CHECK: lw ${{[0-9]+}},0(${{[0-9]+}}); +; CHECK: lw ${{[0-9]+}}, 12(${{[0-9]+}}); ; CHECK: #NO_APP @b = common global [20 x i32] zeroinitializer, align 4 @@ -41,8 +40,8 @@ entry: define void @main() { entry: ; Second word: - tail call void asm sideeffect " lw $0,${1:D};", "r,*m,~{$11}"(i32 undef, i32* getelementptr inbounds ([20 x i32], [20 x i32]* @b, i32 0, i32 3)) + tail call void asm sideeffect " lw $0, ${1:D};", "r,*m,~{$11}"(i32 undef, i32* getelementptr inbounds ([20 x i32], [20 x i32]* @b, i32 0, i32 3)) ; First word. Notice, no 'D': - tail call void asm sideeffect " lw $0,${1};", "r,*m,~{$11}"(i32 undef, i32* getelementptr inbounds ([20 x i32], [20 x i32]* @b, i32 0, i32 3)) + tail call void asm sideeffect " lw $0, ${1};", "r,*m,~{$11}"(i32 undef, i32* getelementptr inbounds ([20 x i32], [20 x i32]* @b, i32 0, i32 3)) ret void } -- 2.34.1