diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index ed73d363380..9a542b93b06 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -1522,6 +1522,32 @@ class ADuI opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, let Inst{4} = opcod5; } +// Double precision, unary, not-predicated +class ADuInp opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, + bit opcod5, dag oops, dag iops, InstrItinClass itin, + string asm, list pattern> + : VFPXI { + // Instruction operands. + bits<5> Dd; + bits<5> Dm; + + let Inst{31-28} = 0b1111; + + // Encode instruction operands. + let Inst{3-0} = Dm{3-0}; + let Inst{5} = Dm{4}; + let Inst{15-12} = Dd{3-0}; + let Inst{22} = Dd{4}; + + let Inst{27-23} = opcod1; + let Inst{21-20} = opcod2; + let Inst{19-16} = opcod3; + let Inst{11-9} = 0b101; + let Inst{8} = 1; // Double precision + let Inst{7-6} = opcod4; + let Inst{4} = opcod5; +} + // Double precision, binary class ADbI opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops, InstrItinClass itin, string opc, string asm, diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td index 4ee41e8aab2..cbfd25fc689 100644 --- a/lib/Target/ARM/ARMInstrVFP.td +++ b/lib/Target/ARM/ARMInstrVFP.td @@ -669,6 +669,33 @@ defm VRINTZ : vrint_inst_zrx<"z", 0, 1>; defm VRINTR : vrint_inst_zrx<"r", 0, 0>; defm VRINTX : vrint_inst_zrx<"x", 1, 0>; +multiclass vrint_inst_anpm rm> { + let PostEncoderMethod = "" in { + def S : ASuInp<0b11101, 0b11, 0b1000, 0b01, 0, + (outs SPR:$Sd), (ins SPR:$Sm), + NoItinerary, !strconcat("vrint", opc, ".f32\t$Sd, $Sm"), + []>, Requires<[HasV8FP]> { + let Inst{17-16} = rm; + } + def D : ADuInp<0b11101, 0b11, 0b1000, 0b01, 0, + (outs DPR:$Dd), (ins DPR:$Dm), + NoItinerary, !strconcat("vrint", opc, ".f64\t$Dd, $Dm"), + []>, Requires<[HasV8FP]> { + let Inst{17-16} = rm; + } + } + + def : InstAlias(NAME#"S") SPR:$Sd, SPR:$Sm)>; + def : InstAlias(NAME#"D") DPR:$Dd, DPR:$Dm)>; +} + +defm VRINTA : vrint_inst_anpm<"a", 0b00>; +defm VRINTN : vrint_inst_anpm<"n", 0b01>; +defm VRINTP : vrint_inst_anpm<"p", 0b10>; +defm VRINTM : vrint_inst_anpm<"m", 0b11>; + def VSQRTD : ADuI<0b11101, 0b11, 0b0001, 0b11, 0, (outs DPR:$Dd), (ins DPR:$Dm), IIC_fpSQRT64, "vsqrt", ".f64\t$Dd, $Dm", diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 56557e3736c..f114b7a26dc 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -4906,8 +4906,9 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, Mnemonic == "umaal" || Mnemonic == "umlal" || Mnemonic == "vabal" || Mnemonic == "vmlal" || Mnemonic == "vpadal" || Mnemonic == "vqdmlal" || Mnemonic == "fmuls" || Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || - Mnemonic == "vcvta" || Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || - Mnemonic == "vcvtm" || Mnemonic.startswith("vsel")) + Mnemonic == "vcvta" || Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || + Mnemonic == "vcvtm" || Mnemonic == "vrinta" || Mnemonic == "vrintn" || + Mnemonic == "vrintp" || Mnemonic == "vrintm" || Mnemonic.startswith("vsel")) return Mnemonic; // First, split out any predication code. Ignore mnemonics we know aren't @@ -5009,7 +5010,9 @@ getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet, Mnemonic == "trap" || Mnemonic == "setend" || Mnemonic.startswith("cps") || Mnemonic.startswith("vsel") || Mnemonic == "vmaxnm" || Mnemonic == "vminnm" || Mnemonic == "vcvta" || - Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm") { + Mnemonic == "vcvtn" || Mnemonic == "vcvtp" || Mnemonic == "vcvtm" || + Mnemonic == "vrinta" || Mnemonic == "vrintn" || Mnemonic == "vrintp" || + Mnemonic == "vrintm") { // 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 b82705c5ec8..b12d7e26fc2 100644 --- a/test/MC/ARM/v8fp.s +++ b/test/MC/ARM/v8fp.s @@ -103,3 +103,22 @@ @ CHECK: vrintxeq.f64 d28, d30 @ encoding: [0x6e,0xcb,0xf7,0x0e] vrintxvs.f32 s10, s14 @ CHECK: vrintxvs.f32 s10, s14 @ encoding: [0x47,0x5a,0xb7,0x6e] + +@ VRINT{A,N,P,M} + + vrinta.f64 d3, d4 +@ CHECK: vrinta.f64 d3, d4 @ encoding: [0x44,0x3b,0xb8,0xfe] + vrinta.f32 s12, s1 +@ CHECK: vrinta.f32 s12, s1 @ encoding: [0x60,0x6a,0xb8,0xfe] + vrintn.f64 d3, d4 +@ CHECK: vrintn.f64 d3, d4 @ encoding: [0x44,0x3b,0xb9,0xfe] + vrintn.f32 s12, s1 +@ CHECK: vrintn.f32 s12, s1 @ encoding: [0x60,0x6a,0xb9,0xfe] + vrintp.f64 d3, d4 +@ CHECK: vrintp.f64 d3, d4 @ encoding: [0x44,0x3b,0xba,0xfe] + vrintp.f32 s12, s1 +@ CHECK: vrintp.f32 s12, s1 @ encoding: [0x60,0x6a,0xba,0xfe] + vrintm.f64 d3, d4 +@ CHECK: vrintm.f64 d3, d4 @ encoding: [0x44,0x3b,0xbb,0xfe] + vrintm.f32 s12, s1 +@ CHECK: vrintm.f32 s12, s1 @ encoding: [0x60,0x6a,0xbb,0xfe] diff --git a/test/MC/Disassembler/ARM/v8fp.txt b/test/MC/Disassembler/ARM/v8fp.txt index 795829eb1c1..a6e88b60cb3 100644 --- a/test/MC/Disassembler/ARM/v8fp.txt +++ b/test/MC/Disassembler/ARM/v8fp.txt @@ -129,3 +129,27 @@ 0x47 0x5a 0xb7 0x6e # CHECK: vrintxvs.f32 s10, s14 + +0x44 0x3b 0xb8 0xfe +# CHECK: vrinta.f64 d3, d4 + +0x60 0x6a 0xb8 0xfe +# CHECK: vrinta.f32 s12, s1 + +0x44 0x3b 0xb9 0xfe +# CHECK: vrintn.f64 d3, d4 + +0x60 0x6a 0xb9 0xfe +# CHECK: vrintn.f32 s12, s1 + +0x44 0x3b 0xba 0xfe +# CHECK: vrintp.f64 d3, d4 + +0x60 0x6a 0xba 0xfe +# CHECK: vrintp.f32 s12, s1 + +0x44 0x3b 0xbb 0xfe +# CHECK: vrintm.f64 d3, d4 + +0x60 0x6a 0xbb 0xfe +# CHECK: vrintm.f32 s12, s1