From: Evan Cheng Date: Tue, 11 Nov 2008 19:40:26 +0000 (+0000) Subject: Encode VFP conversion instructions. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=78be83d7c2a5b94e635b0227924a489b8d8937e8;p=oota-llvm.git Encode VFP conversion instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59074 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index b39ab7f833d..29a8f31a514 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -122,6 +122,8 @@ namespace { void emitVFPArithInstruction(const MachineInstr &MI); + void emitVFPConversionInstruction(const MachineInstr &MI); + /// getBinaryCodeForInstr - This function, generated by the /// CodeEmitterGenerator using TableGen, produces the binary encoding for /// machine instructions. @@ -320,6 +322,10 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) { case ARMII::VFPBinaryFrm: emitVFPArithInstruction(MI); break; + case ARMII::VFPConv1Frm: + case ARMII::VFPConv2Frm: + emitVFPConversionInstruction(MI); + break; } } @@ -999,7 +1005,7 @@ void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) { // Encode Dd / Sd. unsigned RegD = getMachineOpValue(MI, OpIdx++); - Binary |= (RegD & 0x0f) << ARMII::RegFdShift; + Binary |= (RegD & 0x0f) << ARMII::RegRdShift; Binary |= (RegD & 0x10) << ARMII::D_BitShift; // If this is a two-address operand, skip it, e.g. FMACD. @@ -1009,7 +1015,7 @@ void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) { // Encode Dn / Sn. if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPBinaryFrm) { unsigned RegN = getMachineOpValue(MI, OpIdx++); - Binary |= (RegN & 0x0f); + Binary |= (RegN & 0x0f) << ARMII::RegRnShift; Binary |= (RegN & 0x10) << ARMII::N_BitShift; } @@ -1021,4 +1027,41 @@ void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) { emitWordLE(Binary); } +void ARMCodeEmitter::emitVFPConversionInstruction(const MachineInstr &MI) { + const TargetInstrDesc &TID = MI.getDesc(); + + // Part of binary is determined by TableGn. + unsigned Binary = getBinaryCodeForInstr(MI); + + // Set the conditional execution predicate + Binary |= II->getPredicate(&MI) << ARMII::CondShift; + + unsigned OpIdx = 0; + + // Encode Dd / Sd. + unsigned RegD = getMachineOpValue(MI, OpIdx++); + Binary |= (RegD & 0x0f) << ARMII::RegRdShift; + Binary |= (RegD & 0x10) << ARMII::D_BitShift; + + // Encode Dn / Sn. + if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPConv1Frm) { + unsigned RegN = getMachineOpValue(MI, OpIdx++); + Binary |= (RegN & 0x0f) << ARMII::RegRnShift; + Binary |= (RegN & 0x10) << ARMII::N_BitShift; + + // FMRS / FMSR do not have Rm. + if (!TID.OpInfo[2].isPredicate()) { + unsigned RegM = getMachineOpValue(MI, OpIdx++); + Binary |= (RegM & 0x0f); + Binary |= (RegM & 0x10) << ARMII::M_BitShift; + } + } else { + unsigned RegM = getMachineOpValue(MI, OpIdx++); + Binary |= (RegM & 0x0f); + Binary |= (RegM & 0x10) << ARMII::M_BitShift; + } + + emitWordLE(Binary); +} + #include "ARMGenCodeEmitter.inc" diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index c898acae041..5efa76db8e1 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -39,7 +39,9 @@ def ExtFrm : Format<14>; def VFPFrm : Format<15>; def VFPUnaryFrm : Format<16>; def VFPBinaryFrm: Format<17>; -def ThumbFrm : Format<18>; +def VFPConv1Frm : Format<18>; +def VFPConv2Frm : Format<19>; +def ThumbFrm : Format<20>; // Misc flag for data processing instructions that indicates whether // the instruction has a Rn register operand. @@ -798,6 +800,23 @@ class ASbI opcod, dag oops, dag iops, string opc, let Inst{11-8} = 0b1010; } +class AVConv1I opcod1, bits<4> opcod2, dag oops, dag iops, string opc, + string asm, list pattern> + : AI { + let Inst{27-20} = opcod1; + let Inst{11-8} = opcod2; + let Inst{4} = 1; +} + +class AVConv2I opcod1, bits<4> opcod2, bits<4> opcod3, + dag oops, dag iops, string opc, string asm, list pattern> + : AI { + let Inst{27-20} = opcod1; + let Inst{19-16} = opcod2; + let Inst{11-8} = opcod3; + let Inst{6} = 1; +} + // Special cases. class AXSI pattern> : XI GPR Copies. Int <-> FP Conversions. // -def FMRS : ASI<(outs GPR:$dst), (ins SPR:$src), +def FMRS : AVConv1I<0b11100001, 0b1010, (outs GPR:$dst), (ins SPR:$src), "fmrs", " $dst, $src", [(set GPR:$dst, (bitconvert SPR:$src))]>; -def FMSR : ASI<(outs SPR:$dst), (ins GPR:$src), +def FMSR : AVConv1I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src), "fmsr", " $dst, $src", [(set SPR:$dst, (bitconvert GPR:$src))]>; - -def FMRRD : ADI<(outs GPR:$dst1, GPR:$dst2), (ins DPR:$src), +def FMRRD : AVConv1I<0b11000101, 0b1011, + (outs GPR:$dst1, GPR:$dst2), (ins DPR:$src), "fmrrd", " $dst1, $dst2, $src", [/* FIXME: Can't write pattern for multiple result instr*/]>; // FMDHR: GPR -> SPR // FMDLR: GPR -> SPR -def FMDRR : ADI<(outs DPR:$dst), (ins GPR:$src1, GPR:$src2), +def FMDRR : AVConv1I<0b11000100, 0b1011, (outs DPR:$dst), (ins GPR:$src1, GPR:$src2), "fmdrr", " $dst, $src1, $src2", [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]>; @@ -238,48 +238,65 @@ def FMDRR : ADI<(outs DPR:$dst), (ins GPR:$src1, GPR:$src2), // FMSRR: GPR -> SPR -let Defs = [CPSR] in -def FMSTAT : ASI<(outs), (ins), "fmstat", "", [(arm_fmstat)]>; - // FMXR: GPR -> VFP Sstem reg // Int to FP: -def FSITOD : ADI<(outs DPR:$dst), (ins SPR:$a), +def FSITOD : AVConv2I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a), "fsitod", " $dst, $a", - [(set DPR:$dst, (arm_sitof SPR:$a))]>; + [(set DPR:$dst, (arm_sitof SPR:$a))]> { + let Inst{7} = 1; // Z bit +} -def FSITOS : ASI<(outs SPR:$dst), (ins SPR:$a), +def FSITOS : AVConv2I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a), "fsitos", " $dst, $a", - [(set SPR:$dst, (arm_sitof SPR:$a))]>; + [(set SPR:$dst, (arm_sitof SPR:$a))]> { + let Inst{7} = 1; // Z bit +} -def FUITOD : ADI<(outs DPR:$dst), (ins SPR:$a), +def FUITOD : AVConv2I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a), "fuitod", " $dst, $a", - [(set DPR:$dst, (arm_uitof SPR:$a))]>; + [(set DPR:$dst, (arm_uitof SPR:$a))]> { + let Inst{7} = 0; // Z bit +} -def FUITOS : ASI<(outs SPR:$dst), (ins SPR:$a), +def FUITOS : AVConv2I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a), "fuitos", " $dst, $a", - [(set SPR:$dst, (arm_uitof SPR:$a))]>; + [(set SPR:$dst, (arm_uitof SPR:$a))]> { + let Inst{7} = 1; // Z bit +} // FP to Int: // Always set Z bit in the instruction, i.e. "round towards zero" variants. -def FTOSIZD : ADI<(outs SPR:$dst), (ins DPR:$a), +def FTOSIZD : AVConv2I<0b11101011, 0b1101, 0b1011, + (outs SPR:$dst), (ins DPR:$a), "ftosizd", " $dst, $a", - [(set SPR:$dst, (arm_ftosi DPR:$a))]>; + [(set SPR:$dst, (arm_ftosi DPR:$a))]> { + let Inst{7} = 1; // Z bit +} -def FTOSIZS : ASI<(outs SPR:$dst), (ins SPR:$a), +def FTOSIZS : AVConv2I<0b11101011, 0b1101, 0b1010, + (outs SPR:$dst), (ins SPR:$a), "ftosizs", " $dst, $a", - [(set SPR:$dst, (arm_ftosi SPR:$a))]>; + [(set SPR:$dst, (arm_ftosi SPR:$a))]> { + let Inst{7} = 1; // Z bit +} -def FTOUIZD : ADI<(outs SPR:$dst), (ins DPR:$a), +def FTOUIZD : AVConv2I<0b11101011, 0b1100, 0b1011, + (outs SPR:$dst), (ins DPR:$a), "ftouizd", " $dst, $a", - [(set SPR:$dst, (arm_ftoui DPR:$a))]>; + [(set SPR:$dst, (arm_ftoui DPR:$a))]> { + let Inst{7} = 1; // Z bit +} -def FTOUIZS : ASI<(outs SPR:$dst), (ins SPR:$a), +def FTOUIZS : AVConv2I<0b11101011, 0b1100, 0b1010, + (outs SPR:$dst), (ins SPR:$a), "ftouizs", " $dst, $a", - [(set SPR:$dst, (arm_ftoui SPR:$a))]>; + [(set SPR:$dst, (arm_ftoui SPR:$a))]> { + let Inst{7} = 1; // Z bit +} //===----------------------------------------------------------------------===// // FP FMA Operations. @@ -337,22 +354,34 @@ def FNMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b), // FP Conditional moves. // -def FCPYDcc : ADI<(outs DPR:$dst), (ins DPR:$false, DPR:$true), +def FCPYDcc : ADuI<0b11101011, 0b0000, 0b0100, + (outs DPR:$dst), (ins DPR:$false, DPR:$true), "fcpyd", " $dst, $true", [/*(set DPR:$dst, (ARMcmov DPR:$false, DPR:$true, imm:$cc))*/]>, RegConstraint<"$false = $dst">; -def FCPYScc : ASI<(outs SPR:$dst), (ins SPR:$false, SPR:$true), +def FCPYScc : ASuI<0b11101011, 0b0000, 0b0100, + (outs SPR:$dst), (ins SPR:$false, SPR:$true), "fcpys", " $dst, $true", [/*(set SPR:$dst, (ARMcmov SPR:$false, SPR:$true, imm:$cc))*/]>, RegConstraint<"$false = $dst">; -def FNEGDcc : ADI<(outs DPR:$dst), (ins DPR:$false, DPR:$true), +def FNEGDcc : ADuI<0b11101011, 0b0001, 0b0100, + (outs DPR:$dst), (ins DPR:$false, DPR:$true), "fnegd", " $dst, $true", [/*(set DPR:$dst, (ARMcneg DPR:$false, DPR:$true, imm:$cc))*/]>, RegConstraint<"$false = $dst">; -def FNEGScc : ASI<(outs SPR:$dst), (ins SPR:$false, SPR:$true), +def FNEGScc : ASuI<0b11101011, 0b0001, 0b0100, + (outs SPR:$dst), (ins SPR:$false, SPR:$true), "fnegs", " $dst, $true", [/*(set SPR:$dst, (ARMcneg SPR:$false, SPR:$true, imm:$cc))*/]>, RegConstraint<"$false = $dst">; + + +//===----------------------------------------------------------------------===// +// Misc. +// + +let Defs = [CPSR] in +def FMSTAT : ASI<(outs), (ins), "fmstat", "", [(arm_fmstat)]>;