MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
break;
}
+ case G_FCONSTANT: {
+ // Load from constant pool
+ unsigned Size = MRI.getType(I.getOperand(0).getReg()).getSizeInBits() / 8;
+ unsigned Alignment = Size;
+
+ assert((Size == 4 || Size == 8) && "Unsupported FP constant type");
+ auto LoadOpcode = Size == 4 ? ARM::VLDRS : ARM::VLDRD;
+
+ auto ConstPool = MF.getConstantPool();
+ auto CPIndex =
+ ConstPool->getConstantPoolIndex(I.getOperand(1).getFPImm(), Alignment);
+ MIB->setDesc(TII.get(LoadOpcode));
+ MIB->RemoveOperand(1);
+ MIB.addConstantPoolIndex(CPIndex, /*Offset*/ 0, /*TargetFlags*/ 0)
+ .addMemOperand(
+ MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF),
+ MachineMemOperand::MOLoad, Size, Alignment))
+ .addImm(0)
+ .add(predOps(ARMCC::AL));
+ break;
+ }
case G_INTTOPTR:
case G_PTRTOINT: {
auto SrcReg = I.getOperand(1).getReg();
--- /dev/null
+# RUN: llc -O0 -mtriple arm-- -mattr=+vfp3,-neonfp -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,VFP3
+# RUN: llc -O0 -mtriple thumb-- -mattr=+v6t2,+vfp3,-neonfp -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,VFP3
+# RUN: llc -O0 -mtriple arm-- -mattr=+vfp2,-neonfp -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,VFP2
+# RUN: llc -O0 -mtriple thumb-- -mattr=+v6t2,+vfp2,-neonfp -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,VFP2
+--- |
+ define void @test_fpconst_zero_s32() { ret void }
+ define void @test_fpconst_zero_s64() { ret void }
+
+ define void @test_fpconst_8bit_s32() { ret void }
+ define void @test_fpconst_8bit_s64() { ret void }
+...
+---
+name: test_fpconst_zero_s32
+# CHECK-LABEL: name: test_fpconst_zero_s32
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: fprb }
+# CHECK: constants:
+# CHECK-NEXT: id: 0
+# CHECK-NEXT: value: 'float 0.000000e+00'
+# CHECK-NEXT: alignment: 4
+# CHECK-NEXT: isTargetSpecific: false
+body: |
+ bb.0:
+ liveins: $r0
+
+ %0(p0) = COPY $r0
+ ; CHECK: [[PTR:%[0-9]+]]:gpr = COPY $r0
+
+ %1(s32) = G_FCONSTANT float 0.0
+ ; CHECK: [[VREG:%[0-9]+]]:spr = VLDRS %const.0, 0, 14, $noreg :: (load 4 from constant-pool)
+
+ G_STORE %1(s32), %0 :: (store 4)
+ ; CHECK: VSTRS [[VREG]], [[PTR]], 0, 14, $noreg
+
+ BX_RET 14, $noreg
+ ; CHECK: BX_RET 14, $noreg
+...
+---
+name: test_fpconst_zero_s64
+# CHECK-LABEL: name: test_fpconst_zero_s64
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: fprb }
+# CHECK: constants:
+# CHECK-NEXT: id: 0
+# CHECK-NEXT: value: 'double 0.000000e+00'
+# CHECK-NEXT: alignment: 8
+# CHECK-NEXT: isTargetSpecific: false
+body: |
+ bb.0:
+ liveins: $r0
+
+ %0(p0) = COPY $r0
+ ; CHECK: [[PTR:%[0-9]+]]:gpr = COPY $r0
+
+ %1(s64) = G_FCONSTANT double 0.0
+ ; CHECK: [[VREG:%[0-9]+]]:dpr = VLDRD %const.0, 0, 14, $noreg :: (load 8 from constant-pool)
+
+ G_STORE %1(s64), %0 :: (store 8)
+ ; CHECK: VSTRD [[VREG]], [[PTR]], 0, 14, $noreg
+
+ BX_RET 14, $noreg
+ ; CHECK: BX_RET 14, $noreg
+...
+---
+name: test_fpconst_8bit_s32
+# CHECK-LABEL: name: test_fpconst_8bit_s32
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: fprb }
+# CHECK: constants:
+# CHECK-NEXT: id: 0
+# CHECK-NEXT: value: 'float -2.000000e+00'
+# CHECK-NEXT: alignment: 4
+# CHECK-NEXT: isTargetSpecific: false
+body: |
+ bb.0:
+ liveins: $r0
+
+ %0(p0) = COPY $r0
+ ; CHECK: [[PTR:%[0-9]+]]:gpr = COPY $r0
+
+ %1(s32) = G_FCONSTANT float -2.0
+ ; CHECK: [[VREG:%[0-9]+]]:spr = VLDRS %const.0, 0, 14, $noreg :: (load 4 from constant-pool)
+
+ G_STORE %1(s32), %0 :: (store 4)
+ ; CHECK: VSTRS [[VREG]], [[PTR]], 0, 14, $noreg
+
+ BX_RET 14, $noreg
+ ; CHECK: BX_RET 14, $noreg
+...
+---
+name: test_fpconst_8bit_s64
+# CHECK-LABEL: name: test_fpconst_8bit_s64
+legalized: true
+regBankSelected: true
+selected: false
+# CHECK: selected: true
+registers:
+ - { id: 0, class: gprb }
+ - { id: 1, class: fprb }
+# CHECK: constants:
+# CHECK-NEXT: id: 0
+# CHECK-NEXT: value: double 5.000000e-01
+# CHECK-NEXT: alignment: 8
+# CHECK-NEXT: isTargetSpecific: false
+body: |
+ bb.0:
+ liveins: $r0
+
+ %0(p0) = COPY $r0
+ ; CHECK: [[PTR:%[0-9]+]]:gpr = COPY $r0
+
+ %1(s64) = G_FCONSTANT double 5.0e-1
+ ; CHECK: [[VREG:%[0-9]+]]:dpr = VLDRD %const.0, 0, 14, $noreg :: (load 8 from constant-pool)
+
+ G_STORE %1(s64), %0 :: (store 8)
+ ; CHECK: VSTRD [[VREG]], [[PTR]], 0, 14, $noreg
+
+ BX_RET 14, $noreg
+ ; CHECK: BX_RET 14, $noreg
+...