Add MC support for the v8fp instructions: vmaxnm and vminnm.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185767 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Joey Gouly
2013-07-06 20:50:18 +00:00
parent 0bb8aa29d8
commit 2a9683289b
5 changed files with 51 additions and 8 deletions

View File

@@ -1549,7 +1549,7 @@ class ADbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
}
// FP, binary, not predicated
class ADbInp<bits<5> opcod1, bits<2> opcod2, dag oops, dag iops,
class ADbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
InstrItinClass itin, string asm, list<dag> pattern>
: VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
VFPBinaryFrm, itin, asm, "", pattern>
@@ -1573,7 +1573,7 @@ class ADbInp<bits<5> opcod1, bits<2> opcod2, dag oops, dag iops,
let Inst{21-20} = opcod2;
let Inst{11-9} = 0b101;
let Inst{8} = 1; // double precision
let Inst{6} = 0;
let Inst{6} = opcod3;
let Inst{4} = 0;
}
@@ -1637,7 +1637,7 @@ class ASbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
}
// Single precision, binary, not predicated
class ASbInp<bits<5> opcod1, bits<2> opcod2, dag oops, dag iops,
class ASbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
InstrItinClass itin, string asm, list<dag> pattern>
: VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
VFPBinaryFrm, itin, asm, "", pattern>
@@ -1661,7 +1661,7 @@ class ASbInp<bits<5> opcod1, bits<2> opcod2, dag oops, dag iops,
let Inst{21-20} = opcod2;
let Inst{11-9} = 0b101;
let Inst{8} = 0; // Single precision
let Inst{6} = 0;
let Inst{6} = opcod3;
let Inst{4} = 0;
}

View File

@@ -335,12 +335,12 @@ def VNMULS : ASbI<0b11100, 0b10, 1, 0,
multiclass vsel_inst<string op, bits<2> opc> {
let DecoderNamespace = "VFPV8", PostEncoderMethod = "" in {
def S : ASbInp<0b11100, opc,
def S : ASbInp<0b11100, opc, 0,
(outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
NoItinerary, !strconcat("vsel", op, ".f32\t$Sd, $Sn, $Sm"),
[]>, Requires<[HasV8FP]>;
def D : ADbInp<0b11100, opc,
def D : ADbInp<0b11100, opc, 0,
(outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
NoItinerary, !strconcat("vsel", op, ".f64\t$Dd, $Dn, $Dm"),
[]>, Requires<[HasV8FP]>;
@@ -352,6 +352,23 @@ defm VSELGE : vsel_inst<"ge", 0b10>;
defm VSELEQ : vsel_inst<"eq", 0b00>;
defm VSELVS : vsel_inst<"vs", 0b01>;
multiclass vmaxmin_inst<string op, bit opc> {
let DecoderNamespace = "VFPV8", PostEncoderMethod = "" in {
def S : ASbInp<0b11101, 0b00, opc,
(outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
NoItinerary, !strconcat(op, ".f32\t$Sd, $Sn, $Sm"),
[]>, Requires<[HasV8FP]>;
def D : ADbInp<0b11101, 0b00, opc,
(outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
NoItinerary, !strconcat(op, ".f64\t$Dd, $Dn, $Dm"),
[]>, Requires<[HasV8FP]>;
}
}
defm VMAXNM : vmaxmin_inst<"vmaxnm", 0>;
defm VMINNM : vmaxmin_inst<"vminnm", 1>;
// Match reassociated forms only if not sign dependent rounding.
def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)),
(VNMULD DPR:$a, DPR:$b)>, Requires<[NoHonorSignDependentRounding]>;

View File

@@ -4905,7 +4905,8 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic,
Mnemonic == "vcgt" || Mnemonic == "vcle" || Mnemonic == "smlal" ||
Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" ||
Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" ||
Mnemonic == "fmuls" || Mnemonic.startswith("vsel"))
Mnemonic == "fmuls" || Mnemonic == "vmaxnm" || Mnemonic == "vminnm" ||
Mnemonic.startswith("vsel"))
return Mnemonic;
// First, split out any predication code. Ignore mnemonics we know aren't
@@ -5005,7 +5006,8 @@ getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
if (Mnemonic == "bkpt" || Mnemonic == "cbnz" || Mnemonic == "setend" ||
Mnemonic == "cps" || Mnemonic == "it" || Mnemonic == "cbz" ||
Mnemonic == "trap" || Mnemonic == "setend" ||
Mnemonic.startswith("cps") || Mnemonic.startswith("vsel")) {
Mnemonic.startswith("cps") || Mnemonic == "vmaxnm" ||
Mnemonic == "vminnm" || Mnemonic.startswith("vsel")) {
// These mnemonics are never predicable
CanAcceptPredicationCode = false;
} else if (!isThumb()) {