mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-16 00:33:10 +00:00
[arm-fast-isel] Unaligned stores of floats require special care.
rdar://10510150 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145742 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
de2e27cc52
commit
9eff1e33f6
@ -181,7 +181,7 @@ class ARMFastISel : public FastISel {
|
||||
bool ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr, bool isZExt,
|
||||
bool allocReg);
|
||||
|
||||
bool ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr);
|
||||
bool ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr, unsigned Alignment = 0);
|
||||
bool ARMComputeAddress(const Value *Obj, Address &Addr);
|
||||
void ARMSimplifyAddress(Address &Addr, EVT VT, bool useAM3);
|
||||
bool ARMIsMemCpySmall(uint64_t Len);
|
||||
@ -1053,7 +1053,7 @@ bool ARMFastISel::SelectLoad(const Instruction *I) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr) {
|
||||
bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr, unsigned Alignment) {
|
||||
unsigned StrOpc;
|
||||
bool useAM3 = false;
|
||||
switch (VT.getSimpleVT().SimpleTy) {
|
||||
@ -1102,9 +1102,23 @@ bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr) {
|
||||
case MVT::f32:
|
||||
if (!Subtarget->hasVFP2()) return false;
|
||||
StrOpc = ARM::VSTRS;
|
||||
// Unaligned stores need special handling.
|
||||
if (Alignment && Alignment < 4) {
|
||||
unsigned MoveReg = createResultReg(TLI.getRegClassFor(MVT::i32));
|
||||
AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
||||
TII.get(ARM::VMOVRS), MoveReg)
|
||||
.addReg(SrcReg));
|
||||
SrcReg = MoveReg;
|
||||
VT = MVT::i32;
|
||||
StrOpc = isThumb2 ? ARM::t2STRi12 : ARM::STRi12;
|
||||
}
|
||||
break;
|
||||
case MVT::f64:
|
||||
if (!Subtarget->hasVFP2()) return false;
|
||||
// FIXME: Unaligned stores need special handling.
|
||||
if (Alignment && Alignment < 8) {
|
||||
return false;
|
||||
}
|
||||
StrOpc = ARM::VSTRD;
|
||||
break;
|
||||
}
|
||||
@ -1141,7 +1155,8 @@ bool ARMFastISel::SelectStore(const Instruction *I) {
|
||||
if (!ARMComputeAddress(I->getOperand(1), Addr))
|
||||
return false;
|
||||
|
||||
if (!ARMEmitStore(VT, SrcReg, Addr)) return false;
|
||||
if (!ARMEmitStore(VT, SrcReg, Addr, cast<StoreInst>(I)->getAlignment()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -158,3 +158,25 @@ define void @test4() {
|
||||
; ARM: ldr r1, [r1]
|
||||
; ARM: str r0, [r1]
|
||||
}
|
||||
|
||||
; Check unaligned stores
|
||||
%struct.anon = type <{ float }>
|
||||
|
||||
@a = common global %struct.anon* null, align 4
|
||||
|
||||
define void @unaligned_store(float %x, float %y) nounwind {
|
||||
entry:
|
||||
; ARM: @unaligned_store
|
||||
; ARM: vmov r1, s0
|
||||
; ARM: str r1, [r0]
|
||||
|
||||
; THUMB: @unaligned_store
|
||||
; THUMB: vmov r1, s0
|
||||
; THUMB: str r1, [r0]
|
||||
|
||||
%add = fadd float %x, %y
|
||||
%0 = load %struct.anon** @a, align 4
|
||||
%x1 = getelementptr inbounds %struct.anon* %0, i32 0, i32 0
|
||||
store float %add, float* %x1, align 1
|
||||
ret void
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user