mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-02 07:32:52 +00:00
[fast-isel] Unaligned loads of floats are not supported. Therefore, convert to a regular
load and then move the result from a GPR to a FPR. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146502 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
21e1b7a13c
commit
8a9bce978f
@ -178,8 +178,8 @@ class ARMFastISel : public FastISel {
|
||||
bool isLoadTypeLegal(Type *Ty, MVT &VT);
|
||||
bool ARMEmitCmp(const Value *Src1Value, const Value *Src2Value,
|
||||
bool isZExt);
|
||||
bool ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr, bool isZExt,
|
||||
bool allocReg);
|
||||
bool ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr, unsigned Alignment = 0,
|
||||
bool isZExt = true, bool allocReg = true);
|
||||
|
||||
bool ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr,
|
||||
unsigned Alignment = 0);
|
||||
@ -965,10 +965,11 @@ void ARMFastISel::AddLoadStoreOperands(EVT VT, Address &Addr,
|
||||
}
|
||||
|
||||
bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr,
|
||||
bool isZExt = true, bool allocReg = true) {
|
||||
unsigned Alignment, bool isZExt, bool allocReg) {
|
||||
assert(VT.isSimple() && "Non-simple types are invalid here!");
|
||||
unsigned Opc;
|
||||
bool useAM3 = false;
|
||||
bool needVMOV = false;
|
||||
TargetRegisterClass *RC;
|
||||
switch (VT.getSimpleVT().SimpleTy) {
|
||||
// This is mostly going to be Neon/vector support.
|
||||
@ -1014,10 +1015,23 @@ bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr,
|
||||
RC = ARM::GPRRegisterClass;
|
||||
break;
|
||||
case MVT::f32:
|
||||
Opc = ARM::VLDRS;
|
||||
RC = TLI.getRegClassFor(VT);
|
||||
// Unaligned loads need special handling. Floats require word-alignment.
|
||||
if (Alignment && Alignment < 4) {
|
||||
needVMOV = true;
|
||||
VT = MVT::i32;
|
||||
Opc = isThumb2 ? ARM::t2LDRi12 : ARM::LDRi12;
|
||||
RC = ARM::GPRRegisterClass;
|
||||
} else {
|
||||
Opc = ARM::VLDRS;
|
||||
RC = TLI.getRegClassFor(VT);
|
||||
}
|
||||
break;
|
||||
case MVT::f64:
|
||||
if (Alignment && Alignment < 4) {
|
||||
// FIXME: Unaligned loads need special handling. Doublewords require
|
||||
// word-alignment.
|
||||
return false;
|
||||
}
|
||||
Opc = ARM::VLDRD;
|
||||
RC = TLI.getRegClassFor(VT);
|
||||
break;
|
||||
@ -1032,6 +1046,16 @@ bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr,
|
||||
MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
||||
TII.get(Opc), ResultReg);
|
||||
AddLoadStoreOperands(VT, Addr, MIB, MachineMemOperand::MOLoad, useAM3);
|
||||
|
||||
// If we had an unaligned load of a float we've converted it to an regular
|
||||
// load. Now we must move from the GRP to the FP register.
|
||||
if (needVMOV) {
|
||||
unsigned MoveReg = createResultReg(TLI.getRegClassFor(MVT::f32));
|
||||
AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
||||
TII.get(ARM::VMOVSR), MoveReg)
|
||||
.addReg(ResultReg));
|
||||
ResultReg = MoveReg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1050,7 +1074,8 @@ bool ARMFastISel::SelectLoad(const Instruction *I) {
|
||||
if (!ARMComputeAddress(I->getOperand(0), Addr)) return false;
|
||||
|
||||
unsigned ResultReg;
|
||||
if (!ARMEmitLoad(VT, ResultReg, Addr)) return false;
|
||||
if (!ARMEmitLoad(VT, ResultReg, Addr, cast<LoadInst>(I)->getAlignment()))
|
||||
return false;
|
||||
UpdateValueMap(I, ResultReg);
|
||||
return true;
|
||||
}
|
||||
@ -2477,7 +2502,7 @@ bool ARMFastISel::TryToFoldLoad(MachineInstr *MI, unsigned OpNo,
|
||||
if (!ARMComputeAddress(LI->getOperand(0), Addr)) return false;
|
||||
|
||||
unsigned ResultReg = MI->getOperand(0).getReg();
|
||||
if (!ARMEmitLoad(VT, ResultReg, Addr, isZExt, false))
|
||||
if (!ARMEmitLoad(VT, ResultReg, Addr, LI->getAlignment(), isZExt, false))
|
||||
return false;
|
||||
MI->eraseFromParent();
|
||||
return true;
|
||||
|
@ -198,3 +198,24 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; Check unaligned loads of floats
|
||||
%class.TAlignTest = type <{ i16, float }>
|
||||
|
||||
define zeroext i1 @test6(%class.TAlignTest* %this) nounwind align 2 {
|
||||
entry:
|
||||
; ARM: @test6
|
||||
; THUMB: @test6
|
||||
%0 = alloca %class.TAlignTest*, align 4
|
||||
store %class.TAlignTest* %this, %class.TAlignTest** %0, align 4
|
||||
%1 = load %class.TAlignTest** %0
|
||||
%2 = getelementptr inbounds %class.TAlignTest* %1, i32 0, i32 1
|
||||
%3 = load float* %2, align 1
|
||||
%4 = fcmp une float %3, 0.000000e+00
|
||||
; ARM: ldr r0, [r0, #2]
|
||||
; ARM: vmov s0, r0
|
||||
; ARM: vcmpe.f32 s0, #0
|
||||
; THUMB: ldr.w r0, [r0, #2]
|
||||
; THUMB: vmov s0, r0
|
||||
; THUMB: vcmpe.f32 s0, #0
|
||||
ret i1 %4
|
||||
}
|
Loading…
Reference in New Issue
Block a user