mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-03 14:21:30 +00:00 
			
		
		
		
	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:
		@@ -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,
 | 
				
			||||||
 | 
					                                bool IsVolatile, unsigned Alignment) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool IsUnaligned = Alignment &&
 | 
				
			||||||
 | 
					    Alignment < TD->getABITypeAlignment(OperandType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!IsUnaligned)
 | 
				
			||||||
    Out << '*';
 | 
					    Out << '*';
 | 
				
			||||||
  if (I.isVolatile()) {
 | 
					  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;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								test/CodeGen/CBackend/2008-02-01-UnalignedLoadStore.ll
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/CodeGen/CBackend/2008-02-01-UnalignedLoadStore.ll
									
									
									
									
									
										Normal 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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Reference in New Issue
	
	Block a user