diff options
author | Lauro Ramos Venancio <lauro.venancio@gmail.com> | 2008-02-01 21:25:59 +0000 |
---|---|---|
committer | Lauro Ramos Venancio <lauro.venancio@gmail.com> | 2008-02-01 21:25:59 +0000 |
commit | 11048c1346af7d2392e2c145e2eee1a9a5d718ff (patch) | |
tree | 222e58b243494f9c7dcbd7fe1cfe3b9ec5ea8ce8 /lib/Target/CBackend | |
parent | 23071519ddfe464b70edfdd0c38ca34632d0ad23 (diff) | |
download | external_llvm-11048c1346af7d2392e2c145e2eee1a9a5d718ff.zip external_llvm-11048c1346af7d2392e2c145e2eee1a9a5d718ff.tar.gz external_llvm-11048c1346af7d2392e2c145e2eee1a9a5d718ff.tar.bz2 |
CBackend: Implement unaligned load/store.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46646 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/CBackend')
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 2de6089..d434eb9 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -147,6 +147,9 @@ namespace { void writeOperandWithCast(Value* Operand, const ICmpInst &I); bool writeInstructionCast(const Instruction &I); + void writeMemoryAccess(Value *Operand, const Type *OperandType, + bool IsVolatile, unsigned Alignment); + private : std::string InterpretASMConstraint(InlineAsm::ConstraintInfo& c); @@ -2935,29 +2938,47 @@ void CWriter::printIndexingExpression(Value *Ptr, gep_type_iterator I, } } -void CWriter::visitLoadInst(LoadInst &I) { - Out << '*'; - if (I.isVolatile()) { +void CWriter::writeMemoryAccess(Value *Operand, const Type *OperandType, + bool IsVolatile, unsigned Alignment) { + + bool IsUnaligned = Alignment && + Alignment < TD->getABITypeAlignment(OperandType); + + if (!IsUnaligned) + Out << '*'; + if (IsVolatile || IsUnaligned) { Out << "(("; - printType(Out, I.getType(), false, "volatile*"); + if (IsUnaligned) + Out << "struct __attribute__ ((packed, aligned(" << Alignment << "))) {"; + printType(Out, OperandType, false, IsUnaligned ? "data" : "volatile*"); + if (IsUnaligned) { + Out << "; } "; + if (IsVolatile) Out << "volatile "; + Out << "*"; + } Out << ")"; } - writeOperand(I.getOperand(0)); + writeOperand(Operand); - if (I.isVolatile()) + if (IsVolatile || IsUnaligned) { Out << ')'; + if (IsUnaligned) + Out << "->data"; + } +} + +void CWriter::visitLoadInst(LoadInst &I) { + + writeMemoryAccess(I.getOperand(0), I.getType(), I.isVolatile(), + I.getAlignment()); + } void CWriter::visitStoreInst(StoreInst &I) { - Out << '*'; - if (I.isVolatile()) { - Out << "(("; - printType(Out, I.getOperand(0)->getType(), false, " volatile*"); - Out << ")"; - } - writeOperand(I.getPointerOperand()); - if (I.isVolatile()) Out << ')'; + + writeMemoryAccess(I.getPointerOperand(), I.getOperand(0)->getType(), + I.isVolatile(), I.getAlignment()); Out << " = "; Value *Operand = I.getOperand(0); Constant *BitMask = 0; |