Add support for vmov.f64/.f32 encoding. There's a bit of a hack going on

here. The f32 in FCONSTS is handled as a double instead of a float in the
code. So the encoding of the immediate into the instruction isn't exactly in
line with the documentation in that regard. But given that we know it's handled
as a double, it doesn't cause any harm.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116471 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2010-10-14 02:33:26 +00:00
parent 946a2740a5
commit bbbdcd453d
3 changed files with 56 additions and 14 deletions

View File

@ -921,7 +921,7 @@ def VNEGScc : ASuI<0b11101, 0b11, 0b0001, 0b01, 0,
let Defs = [CPSR], Uses = [FPSCR] in let Defs = [CPSR], Uses = [FPSCR] in
def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs", def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs",
"\tapsr_nzcv, fpscr", "\tapsr_nzcv, fpscr",
[(arm_fmstat)]> { [(arm_fmstat)]> {
let Inst{27-20} = 0b11101111; let Inst{27-20} = 0b11101111;
let Inst{19-16} = 0b0001; let Inst{19-16} = 0b0001;
let Inst{15-12} = 0b1111; let Inst{15-12} = 0b1111;
@ -932,7 +932,7 @@ def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs",
let Inst{3-0} = 0b0000; let Inst{3-0} = 0b0000;
} }
// FPSCR <-> GPR (for disassembly only) // FPSCR <-> GPR
let hasSideEffects = 1, Uses = [FPSCR] in let hasSideEffects = 1, Uses = [FPSCR] in
def VMRS : VFPAI<(outs GPR:$Rt), (ins), VFPMiscFrm, IIC_fpSTAT, def VMRS : VFPAI<(outs GPR:$Rt), (ins), VFPMiscFrm, IIC_fpSTAT,
"vmrs", "\t$Rt, fpscr", "vmrs", "\t$Rt, fpscr",
@ -971,25 +971,49 @@ def VMSR : VFPAI<(outs), (ins GPR:$src), VFPMiscFrm, IIC_fpSTAT,
// Materialize FP immediates. VFP3 only. // Materialize FP immediates. VFP3 only.
let isReMaterializable = 1 in { 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, VFPMiscFrm, IIC_fpUNA64,
"vmov", ".f64\t$dst, $imm", "vmov", ".f64\t$Dd, $imm",
[(set DPR:$dst, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> { [(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{27-23} = 0b11101;
let Inst{21-20} = 0b11; let Inst{21-20} = 0b11;
let Inst{11-9} = 0b101; let Inst{11-9} = 0b101;
let Inst{8} = 1; let Inst{8} = 1; // Double precision.
let Inst{7-4} = 0b0000; let Inst{7-4} = 0b0000;
} }
def FCONSTS : VFPAI<(outs SPR:$dst), (ins vfp_f32imm:$imm), def FCONSTS : VFPAI<(outs SPR:$Sd), (ins vfp_f32imm:$imm),
VFPMiscFrm, IIC_fpUNA32, VFPMiscFrm, IIC_fpUNA32,
"vmov", ".f32\t$dst, $imm", "vmov", ".f32\t$Sd, $imm",
[(set SPR:$dst, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> { [(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{27-23} = 0b11101;
let Inst{21-20} = 0b11; let Inst{21-20} = 0b11;
let Inst{11-9} = 0b101; let Inst{11-9} = 0b101;
let Inst{8} = 0; let Inst{8} = 0; // Single precision.
let Inst{7-4} = 0b0000; let Inst{7-4} = 0b0000;
} }
} }

View File

@ -138,10 +138,13 @@ EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind,
/// operand requires relocation, record the relocation and return zero. /// operand requires relocation, record the relocation and return zero.
unsigned ARMMCCodeEmitter::getMachineOpValue(const MCInst &MI, unsigned ARMMCCodeEmitter::getMachineOpValue(const MCInst &MI,
const MCOperand &MO) const { const MCOperand &MO) const {
if (MO.isReg()) if (MO.isReg()) {
return getARMRegisterNumbering(MO.getReg()); return getARMRegisterNumbering(MO.getReg());
else if (MO.isImm()) { } else if (MO.isImm()) {
return static_cast<unsigned>(MO.getImm()); return static_cast<unsigned>(MO.getImm());
} else if (MO.isFPImm()) {
return static_cast<unsigned>(APFloat(MO.getFPImm())
.bitcastToAPInt().getHiBits(32).getLimitedValue());
} else { } else {
#ifndef NDEBUG #ifndef NDEBUG
errs() << MO; errs() << MO;
@ -151,7 +154,6 @@ unsigned ARMMCCodeEmitter::getMachineOpValue(const MCInst &MI,
return 0; return 0;
} }
unsigned ARMMCCodeEmitter::getSORegOpValue(const MCInst &MI, unsigned ARMMCCodeEmitter::getSORegOpValue(const MCInst &MI,
unsigned OpIdx) const { unsigned OpIdx) const {
// Sub-operands are [reg, reg, imm]. The first register is Rm, the reg // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg

View File

@ -352,3 +352,19 @@ entry:
} }
declare void @llvm.arm.set.fpscr(i32) nounwind 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
}