Fix FMDRR encoding.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59088 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2008-11-11 22:46:12 +00:00
parent cb5201f3b2
commit 0a0ab1387a
4 changed files with 51 additions and 26 deletions

View File

@ -342,6 +342,7 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
break;
case ARMII::VFPConv1Frm:
case ARMII::VFPConv2Frm:
case ARMII::VFPConv3Frm:
emitVFPConversionInstruction(MI);
break;
case ARMII::VFPLdStFrm:
@ -1080,27 +1081,41 @@ void ARMCodeEmitter::emitVFPConversionInstruction(const MachineInstr &MI) {
// Set the conditional execution predicate
Binary |= II->getPredicate(&MI) << ARMII::CondShift;
unsigned OpIdx = 0;
// FMDRR encodes registers in reverse order.
unsigned Form = TID.TSFlags & ARMII::FormMask;
unsigned OpIdx = (Form == ARMII::VFPConv2Frm) ? 2 : 0;
// Encode Dd / Sd.
unsigned RegD = getMachineOpValue(MI, OpIdx++);
unsigned RegD = getMachineOpValue(MI, OpIdx);
Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
Binary |= (RegD & 0x10) << ARMII::D_BitShift;
if (Form == ARMII::VFPConv2Frm)
--OpIdx;
else
++OpIdx;
// Encode Dn / Sn.
if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPConv1Frm) {
unsigned RegN = getMachineOpValue(MI, OpIdx++);
if (Form == ARMII::VFPConv1Frm || Form == ARMII::VFPConv2Frm) {
unsigned RegN = getMachineOpValue(MI, OpIdx);
Binary |= (RegN & 0x0f) << ARMII::RegRnShift;
Binary |= (RegN & 0x10) << ARMII::N_BitShift;
if (Form == ARMII::VFPConv2Frm)
--OpIdx;
else
++OpIdx;
// FMRS / FMSR do not have Rm.
if (!TID.OpInfo[2].isPredicate()) {
unsigned RegM = getMachineOpValue(MI, OpIdx++);
if (TID.getNumOperands() > OpIdx && MI.getOperand(OpIdx).isReg()) {
unsigned RegM = getMachineOpValue(MI, OpIdx);
Binary |= (RegM & 0x0f);
Binary |= (RegM & 0x10) << ARMII::M_BitShift;
} else if (Form == ARMII::VFPConv2Frm) {
// FMDRR encodes definition register in Dm field.
Binary |= getMachineOpValue(MI, 0);
}
} else {
unsigned RegM = getMachineOpValue(MI, OpIdx++);
assert(Form == ARMII::VFPConv3Frm && "Unsupported format!");
unsigned RegM = getMachineOpValue(MI, OpIdx);
Binary |= (RegM & 0x0f);
Binary |= (RegM & 0x10) << ARMII::M_BitShift;
}

View File

@ -41,11 +41,12 @@ def VFPUnaryFrm : Format<15>;
def VFPBinaryFrm : Format<16>;
def VFPConv1Frm : Format<17>;
def VFPConv2Frm : Format<18>;
def VFPLdStFrm : Format<19>;
def VFPLdStMulFrm : Format<20>;
def VFPMiscFrm : Format<21>;
def VFPConv3Frm : Format<19>;
def VFPLdStFrm : Format<20>;
def VFPLdStMulFrm : Format<21>;
def VFPMiscFrm : Format<22>;
def ThumbFrm : Format<22>;
def ThumbFrm : Format<23>;
// Misc flag for data processing instructions that indicates whether
// the instruction has a Rn register operand.
@ -827,9 +828,17 @@ class AVConv1I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
let Inst{4} = 1;
}
class AVConv2I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
class AVConv2I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, string opc,
string asm, list<dag> pattern>
: AI<oops, iops, VFPConv2Frm, opc, asm, pattern> {
let Inst{27-20} = opcod1;
let Inst{11-8} = opcod2;
let Inst{4} = 1;
}
class AVConv3I<bits<8> opcod1, bits<4> opcod2, bits<4> opcod3,
dag oops, dag iops, string opc, string asm, list<dag> pattern>
: AI<oops, iops, VFPConv1Frm, opc, asm, pattern> {
: AI<oops, iops, VFPConv3Frm, opc, asm, pattern> {
let Inst{27-20} = opcod1;
let Inst{19-16} = opcod2;
let Inst{11-8} = opcod3;

View File

@ -105,12 +105,13 @@ namespace ARMII {
VFPBinaryFrm = 16 << FormShift,
VFPConv1Frm = 17 << FormShift,
VFPConv2Frm = 18 << FormShift,
VFPLdStFrm = 19 << FormShift,
VFPLdStMulFrm = 20 << FormShift,
VFPMiscFrm = 21 << FormShift,
VFPConv3Frm = 19 << FormShift,
VFPLdStFrm = 20 << FormShift,
VFPLdStMulFrm = 21 << FormShift,
VFPMiscFrm = 22 << FormShift,
// Thumb format
ThumbFrm = 22 << FormShift,
ThumbFrm = 23 << FormShift,
//===------------------------------------------------------------------===//
// Field shifts - such shifts are used to set field while generating

View File

@ -235,7 +235,7 @@ def FMRRD : AVConv1I<0b11000101, 0b1011,
// FMDHR: GPR -> SPR
// FMDLR: GPR -> SPR
def FMDRR : AVConv1I<0b11000100, 0b1011, (outs DPR:$dst), (ins GPR:$src1, GPR:$src2),
def FMDRR : AVConv2I<0b11000100, 0b1011, (outs DPR:$dst), (ins GPR:$src1, GPR:$src2),
"fmdrr", " $dst, $src1, $src2",
[(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]>;
@ -251,25 +251,25 @@ def FMDRR : AVConv1I<0b11000100, 0b1011, (outs DPR:$dst), (ins GPR:$src1, GPR:$s
// Int to FP:
def FSITOD : AVConv2I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
def FSITOD : AVConv3I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
"fsitod", " $dst, $a",
[(set DPR:$dst, (arm_sitof SPR:$a))]> {
let Inst{7} = 1; // Z bit
}
def FSITOS : AVConv2I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
def FSITOS : AVConv3I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
"fsitos", " $dst, $a",
[(set SPR:$dst, (arm_sitof SPR:$a))]> {
let Inst{7} = 1; // Z bit
}
def FUITOD : AVConv2I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
def FUITOD : AVConv3I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
"fuitod", " $dst, $a",
[(set DPR:$dst, (arm_uitof SPR:$a))]> {
let Inst{7} = 0; // Z bit
}
def FUITOS : AVConv2I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
def FUITOS : AVConv3I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
"fuitos", " $dst, $a",
[(set SPR:$dst, (arm_uitof SPR:$a))]> {
let Inst{7} = 1; // Z bit
@ -278,28 +278,28 @@ def FUITOS : AVConv2I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
// FP to Int:
// Always set Z bit in the instruction, i.e. "round towards zero" variants.
def FTOSIZD : AVConv2I<0b11101011, 0b1101, 0b1011,
def FTOSIZD : AVConv3I<0b11101011, 0b1101, 0b1011,
(outs SPR:$dst), (ins DPR:$a),
"ftosizd", " $dst, $a",
[(set SPR:$dst, (arm_ftosi DPR:$a))]> {
let Inst{7} = 1; // Z bit
}
def FTOSIZS : AVConv2I<0b11101011, 0b1101, 0b1010,
def FTOSIZS : AVConv3I<0b11101011, 0b1101, 0b1010,
(outs SPR:$dst), (ins SPR:$a),
"ftosizs", " $dst, $a",
[(set SPR:$dst, (arm_ftosi SPR:$a))]> {
let Inst{7} = 1; // Z bit
}
def FTOUIZD : AVConv2I<0b11101011, 0b1100, 0b1011,
def FTOUIZD : AVConv3I<0b11101011, 0b1100, 0b1011,
(outs SPR:$dst), (ins DPR:$a),
"ftouizd", " $dst, $a",
[(set SPR:$dst, (arm_ftoui DPR:$a))]> {
let Inst{7} = 1; // Z bit
}
def FTOUIZS : AVConv2I<0b11101011, 0b1100, 0b1010,
def FTOUIZS : AVConv3I<0b11101011, 0b1100, 0b1010,
(outs SPR:$dst), (ins SPR:$a),
"ftouizs", " $dst, $a",
[(set SPR:$dst, (arm_ftoui SPR:$a))]> {