From 859efca7f9c412f251e2303fe1f0ae80728d2c91 Mon Sep 17 00:00:00 2001 From: Lauro Ramos Venancio Date: Fri, 1 Feb 2008 21:25:59 +0000 Subject: [PATCH] CBackend: Implement unaligned load/store. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46646 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/CBackend/CBackend.cpp | 49 +++++++++++++------ .../CBackend/2008-02-01-UnalignedLoadStore.ll | 15 ++++++ 2 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 test/CodeGen/CBackend/2008-02-01-UnalignedLoadStore.ll diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 2de608953d5..d434eb9786d 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; diff --git a/test/CodeGen/CBackend/2008-02-01-UnalignedLoadStore.ll b/test/CodeGen/CBackend/2008-02-01-UnalignedLoadStore.ll new file mode 100644 index 00000000000..269126d7598 --- /dev/null +++ b/test/CodeGen/CBackend/2008-02-01-UnalignedLoadStore.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | llc -march=c | \ +; RUN: grep {struct __attribute__ ((packed, aligned(} | count 4 + +define void @test(i32* %P) { + %X = load i32* %P, align 1 + store i32 %X, i32* %P, align 1 + ret void +} + +define void @test2(i32* %P) { + %X = volatile load i32* %P, align 2 + volatile store i32 %X, i32* %P, align 2 + ret void +} + -- 2.34.1