mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
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:
parent
cb5201f3b2
commit
0a0ab1387a
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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))]> {
|
||||
|
Loading…
Reference in New Issue
Block a user