diff options
author | Daniel Cederman <cederman@gaisler.com> | 2018-04-20 06:57:49 +0000 |
---|---|---|
committer | Daniel Cederman <cederman@gaisler.com> | 2018-04-20 06:57:49 +0000 |
commit | 793af3b9f0a765912a1a27c473b6514c8108ddca (patch) | |
tree | 9e575416d9f5b3e628c824384fdfbf8d411fe1b6 /llvm/lib/Target/Sparc | |
parent | b7a3bc99c9dad554ed08765aead890e799938cbb (diff) | |
download | bcm5719-llvm-793af3b9f0a765912a1a27c473b6514c8108ddca.tar.gz bcm5719-llvm-793af3b9f0a765912a1a27c473b6514c8108ddca.zip |
[Sparc] Fix addressing mode when using 64-bit values in inline assembly
Summary:
If a 64-bit register is used as an operand in inline assembly together
with a memory reference, the memory addressing will be wrong. The
addressing will be a single reg, instead of reg+reg or reg+imm. This
will generate a bad offset value or an exception in printMemOperand().
For example:
```
long long int val = 5;
long long int mem;
__asm__ volatile ("std %1, %0":"=m"(mem):"r"(val));
```
becomes:
```
std %i0, [%i2+589833]
```
The problem is that SelectInlineAsmMemoryOperand() is never called for
the memory references if one of the operands is a 64-bit register.
By calling SelectInlineAsmMemoryOperands() in tryInlineAsm() the Sparc
version of SelectInlineAsmMemoryOperand() gets called for each memory
reference.
Reviewers: jyknight, venkatra
Reviewed By: jyknight
Subscribers: eraman, fedor.sergeev, jrtc27, llvm-commits
Differential Revision: https://reviews.llvm.org/D45761
llvm-svn: 330392
Diffstat (limited to 'llvm/lib/Target/Sparc')
-rw-r--r-- | llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp index c36e75d1b07..0932cd543f8 100644 --- a/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -311,6 +311,8 @@ bool SparcDAGToDAGISel::tryInlineAsm(SDNode *N){ if (!Changed) return false; + SelectInlineAsmMemoryOperands(AsmNodeOperands, SDLoc(N)); + SDValue New = CurDAG->getNode(ISD::INLINEASM, SDLoc(N), CurDAG->getVTList(MVT::Other, MVT::Glue), AsmNodeOperands); New->setNodeId(-1); |