From 2a9683289b78a2533b261e1b341f9ea9724465a0 Mon Sep 17 00:00:00 2001 From: Joey Gouly Date: Sat, 6 Jul 2013 20:50:18 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMInstrFormats.td | 8 ++++---- lib/Target/ARM/ARMInstrVFP.td | 21 +++++++++++++++++++-- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 6 ++++-- test/MC/ARM/v8fp.s | 11 +++++++++++ test/MC/Disassembler/ARM/v8fp.txt | 13 +++++++++++++ 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 91564da8e62..16b7bc5e404 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -1549,7 +1549,7 @@ class ADbI opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, } // FP, binary, not predicated -class ADbInp opcod1, bits<2> opcod2, dag oops, dag iops, +class ADbInp opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, InstrItinClass itin, string asm, list pattern> : VFPXI @@ -1573,7 +1573,7 @@ class ADbInp 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 opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, } // Single precision, binary, not predicated -class ASbInp opcod1, bits<2> opcod2, dag oops, dag iops, +class ASbInp opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, InstrItinClass itin, string asm, list pattern> : VFPXI @@ -1661,7 +1661,7 @@ class ASbInp 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; } diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td index dcac7544373..27e2df4bfd4 100644 --- a/lib/Target/ARM/ARMInstrVFP.td +++ b/lib/Target/ARM/ARMInstrVFP.td @@ -335,12 +335,12 @@ def VNMULS : ASbI<0b11100, 0b10, 1, 0, multiclass vsel_inst 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 { + 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]>; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 687ea3f9410..f7f19014895 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -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()) { diff --git a/test/MC/ARM/v8fp.s b/test/MC/ARM/v8fp.s index 440a94ca1ad..05a7f1badde 100644 --- a/test/MC/ARM/v8fp.s +++ b/test/MC/ARM/v8fp.s @@ -39,3 +39,14 @@ @ CHECK: vselvs.f32 s21, s16, s14 @ encoding: [0x07,0xaa,0x58,0xfe] vselvs.f64 d0, d1, d31 @ CHECK: vselvs.f64 d0, d1, d31 @ encoding: [0x2f,0x0b,0x11,0xfe] + + +@ VMAXNM / VMINNM + vmaxnm.f32 s5, s12, s0 +@ CHECK: vmaxnm.f32 s5, s12, s0 @ encoding: [0x00,0x2a,0xc6,0xfe] + vmaxnm.f64 d5, d22, d30 +@ CHECK: vmaxnm.f64 d5, d22, d30 @ encoding: [0xae,0x5b,0x86,0xfe] + vminnm.f32 s0, s0, s12 +@ CHECK: vminnm.f32 s0, s0, s12 @ encoding: [0x46,0x0a,0x80,0xfe] + vminnm.f64 d4, d6, d9 +@ CHECK: vminnm.f64 d4, d6, d9 @ encoding: [0x49,0x4b,0x86,0xfe] diff --git a/test/MC/Disassembler/ARM/v8fp.txt b/test/MC/Disassembler/ARM/v8fp.txt index a4a91c14959..a805f817681 100644 --- a/test/MC/Disassembler/ARM/v8fp.txt +++ b/test/MC/Disassembler/ARM/v8fp.txt @@ -48,3 +48,16 @@ 0x2f 0x0b 0x11 0xfe # CHECK: vselvs.f64 d0, d1, d31 + + +0x00 0x2a 0xc6 0xfe +# CHECK: vmaxnm.f32 s5, s12, s0 + +0xae 0x5b 0x86 0xfe +# CHECK: vmaxnm.f64 d5, d22, d30 + +0x46 0x0a 0x80 0xfe +# CHECK: vminnm.f32 s0, s0, s12 + +0x49 0x4b 0x86 0xfe +# CHECK: vminnm.f64 d4, d6, d9 -- 2.34.1