aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/ARM/ARMInstrVFP.td46
-rw-r--r--lib/Target/ARM/ARMMCCodeEmitter.cpp8
-rw-r--r--test/MC/ARM/simple-fp-encoding.ll16
3 files changed, 56 insertions, 14 deletions
diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td
index c7f3f85eec..476620535d 100644
--- a/lib/Target/ARM/ARMInstrVFP.td
+++ b/lib/Target/ARM/ARMInstrVFP.td
@@ -921,7 +921,7 @@ def VNEGScc : ASuI<0b11101, 0b11, 0b0001, 0b01, 0,
let Defs = [CPSR], Uses = [FPSCR] in
def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs",
"\tapsr_nzcv, fpscr",
- [(arm_fmstat)]> {
+ [(arm_fmstat)]> {
let Inst{27-20} = 0b11101111;
let Inst{19-16} = 0b0001;
let Inst{15-12} = 0b1111;
@@ -932,7 +932,7 @@ def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs",
let Inst{3-0} = 0b0000;
}
-// FPSCR <-> GPR (for disassembly only)
+// FPSCR <-> GPR
let hasSideEffects = 1, Uses = [FPSCR] in
def VMRS : VFPAI<(outs GPR:$Rt), (ins), VFPMiscFrm, IIC_fpSTAT,
"vmrs", "\t$Rt, fpscr",
@@ -971,25 +971,49 @@ def VMSR : VFPAI<(outs), (ins GPR:$src), VFPMiscFrm, IIC_fpSTAT,
// Materialize FP immediates. VFP3 only.
let isReMaterializable = 1 in {
-def FCONSTD : VFPAI<(outs DPR:$dst), (ins vfp_f64imm:$imm),
+def FCONSTD : VFPAI<(outs DPR:$Dd), (ins vfp_f64imm:$imm),
VFPMiscFrm, IIC_fpUNA64,
- "vmov", ".f64\t$dst, $imm",
- [(set DPR:$dst, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> {
+ "vmov", ".f64\t$Dd, $imm",
+ [(set DPR:$Dd, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> {
+ // Instruction operands.
+ bits<5> Dd;
+ bits<32> imm;
+
+ // Encode instruction operands.
+ let Inst{15-12} = Dd{3-0};
+ let Inst{22} = Dd{4};
+ let Inst{19} = imm{31};
+ let Inst{18-16} = imm{22-20};
+ let Inst{3-0} = imm{19-16};
+
+ // Encode remaining instruction bits.
let Inst{27-23} = 0b11101;
let Inst{21-20} = 0b11;
let Inst{11-9} = 0b101;
- let Inst{8} = 1;
+ let Inst{8} = 1; // Double precision.
let Inst{7-4} = 0b0000;
}
-def FCONSTS : VFPAI<(outs SPR:$dst), (ins vfp_f32imm:$imm),
- VFPMiscFrm, IIC_fpUNA32,
- "vmov", ".f32\t$dst, $imm",
- [(set SPR:$dst, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> {
+def FCONSTS : VFPAI<(outs SPR:$Sd), (ins vfp_f32imm:$imm),
+ VFPMiscFrm, IIC_fpUNA32,
+ "vmov", ".f32\t$Sd, $imm",
+ [(set SPR:$Sd, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> {
+ // Instruction operands.
+ bits<5> Sd;
+ bits<32> imm;
+
+ // Encode instruction operands.
+ let Inst{15-12} = Sd{4-1};
+ let Inst{22} = Sd{0};
+ let Inst{19} = imm{31}; // The immediate is handled as a double.
+ let Inst{18-16} = imm{22-20};
+ let Inst{3-0} = imm{19-16};
+
+ // Encode remaining instruction bits.
let Inst{27-23} = 0b11101;
let Inst{21-20} = 0b11;
let Inst{11-9} = 0b101;
- let Inst{8} = 0;
+ let Inst{8} = 0; // Single precision.
let Inst{7-4} = 0b0000;
}
}
diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp
index 5b20676961..cafd3f235c 100644
--- a/lib/Target/ARM/ARMMCCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp
@@ -138,10 +138,13 @@ EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind,
/// operand requires relocation, record the relocation and return zero.
unsigned ARMMCCodeEmitter::getMachineOpValue(const MCInst &MI,
const MCOperand &MO) const {
- if (MO.isReg())
+ if (MO.isReg()) {
return getARMRegisterNumbering(MO.getReg());
- else if (MO.isImm()) {
+ } else if (MO.isImm()) {
return static_cast<unsigned>(MO.getImm());
+ } else if (MO.isFPImm()) {
+ return static_cast<unsigned>(APFloat(MO.getFPImm())
+ .bitcastToAPInt().getHiBits(32).getLimitedValue());
} else {
#ifndef NDEBUG
errs() << MO;
@@ -151,7 +154,6 @@ unsigned ARMMCCodeEmitter::getMachineOpValue(const MCInst &MI,
return 0;
}
-
unsigned ARMMCCodeEmitter::getSORegOpValue(const MCInst &MI,
unsigned OpIdx) const {
// Sub-operands are [reg, reg, imm]. The first register is Rm, the reg
diff --git a/test/MC/ARM/simple-fp-encoding.ll b/test/MC/ARM/simple-fp-encoding.ll
index 84ccb6d005..99b479bc77 100644
--- a/test/MC/ARM/simple-fp-encoding.ll
+++ b/test/MC/ARM/simple-fp-encoding.ll
@@ -352,3 +352,19 @@ entry:
}
declare void @llvm.arm.set.fpscr(i32) nounwind
+
+
+define double @f102() nounwind readnone {
+entry:
+; CHECK: f102
+; CHECK: vmov.f64 d16, #3.000000e+00 @ encoding: [0x08,0x0b,0xf0,0xee]
+ ret double 3.000000e+00
+}
+
+define float @f103(float %a) nounwind readnone {
+entry:
+; CHECK: f103
+; CHECK: vmov.f32 s0, #3.000000e+00 @ encoding: [0x08,0x0a,0xb0,0xee]
+ %add = fadd float %a, 3.000000e+00
+ ret float %add
+}