CBackend: Implement unaligned load/store.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46646 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Lauro Ramos Venancio 2008-02-01 21:25:59 +00:00
parent 532d022794
commit 859efca7f9
2 changed files with 50 additions and 14 deletions

View File

@ -147,6 +147,9 @@ namespace {
void writeOperandWithCast(Value* Operand, const ICmpInst &I); void writeOperandWithCast(Value* Operand, const ICmpInst &I);
bool writeInstructionCast(const Instruction &I); bool writeInstructionCast(const Instruction &I);
void writeMemoryAccess(Value *Operand, const Type *OperandType,
bool IsVolatile, unsigned Alignment);
private : private :
std::string InterpretASMConstraint(InlineAsm::ConstraintInfo& c); std::string InterpretASMConstraint(InlineAsm::ConstraintInfo& c);
@ -2935,29 +2938,47 @@ void CWriter::printIndexingExpression(Value *Ptr, gep_type_iterator I,
} }
} }
void CWriter::visitLoadInst(LoadInst &I) { void CWriter::writeMemoryAccess(Value *Operand, const Type *OperandType,
Out << '*'; bool IsVolatile, unsigned Alignment) {
if (I.isVolatile()) {
bool IsUnaligned = Alignment &&
Alignment < TD->getABITypeAlignment(OperandType);
if (!IsUnaligned)
Out << '*';
if (IsVolatile || IsUnaligned) {
Out << "(("; 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 << ")"; Out << ")";
} }
writeOperand(I.getOperand(0)); writeOperand(Operand);
if (I.isVolatile()) if (IsVolatile || IsUnaligned) {
Out << ')'; 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) { void CWriter::visitStoreInst(StoreInst &I) {
Out << '*';
if (I.isVolatile()) { writeMemoryAccess(I.getPointerOperand(), I.getOperand(0)->getType(),
Out << "(("; I.isVolatile(), I.getAlignment());
printType(Out, I.getOperand(0)->getType(), false, " volatile*");
Out << ")";
}
writeOperand(I.getPointerOperand());
if (I.isVolatile()) Out << ')';
Out << " = "; Out << " = ";
Value *Operand = I.getOperand(0); Value *Operand = I.getOperand(0);
Constant *BitMask = 0; Constant *BitMask = 0;

View File

@ -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
}