From: Simon Tatham Date: Tue, 18 Jun 2019 15:51:46 +0000 (+0000) Subject: [ARM] Add MVE integer vector min/max instructions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=636a9042976fb6564cfbd9eab1c30d82fe473718;p=llvm [ARM] Add MVE integer vector min/max instructions. Summary: These form a small family of their own, to go with the floating-point VMINNM/VMAXNM instructions added in a previous commit. They introduce the first of many special cases in the mnemonic recognition code, because VMIN with the E suffix used by the VPT predication system needs to avoid being interpreted as the nonexistent instruction 'VMI' with an ordinary 'NE' condition suffix. Reviewers: dmgreen, samparker, SjoerdMeijer, t.p.northover Subscribers: javed.absar, kristof.beyls, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D62671 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363695 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMInstrMVE.td b/lib/Target/ARM/ARMInstrMVE.td index 50b86818642..5964e645224 100644 --- a/lib/Target/ARM/ARMInstrMVE.td +++ b/lib/Target/ARM/ARMInstrMVE.td @@ -642,6 +642,32 @@ def MVE_VMAXNMf16 : MVE_VMINMAXNM<"vmaxnm", "f16", 0b1, 0b0>; def MVE_VMINNMf32 : MVE_VMINMAXNM<"vminnm", "f32", 0b0, 0b1>; def MVE_VMINNMf16 : MVE_VMINMAXNM<"vminnm", "f16", 0b1, 0b1>; +class MVE_VMINMAX size, + bit bit_4, list pattern=[]> + : MVE_comp { + + let Inst{28} = U; + let Inst{25-24} = 0b11; + let Inst{23} = 0b0; + let Inst{21-20} = size{1-0}; + let Inst{11} = 0b0; + let Inst{8} = 0b0; + let Inst{6} = 0b1; + let Inst{4} = bit_4; +} + +multiclass MVE_VMINMAX_all_sizes { + def s8 : MVE_VMINMAX; + def s16 : MVE_VMINMAX; + def s32 : MVE_VMINMAX; + def u8 : MVE_VMINMAX; + def u16 : MVE_VMINMAX; + def u32 : MVE_VMINMAX; +} + +defm MVE_VMAX : MVE_VMINMAX_all_sizes<"vmax", 0b0>; +defm MVE_VMIN : MVE_VMINMAX_all_sizes<"vmin", 0b1>; + // end of mve_comp instructions class MVE_VPT size, dag iops, string asm, list pattern=[]> diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index b76924003aa..91a48b04038 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5933,7 +5933,8 @@ StringRef ARMAsmParser::splitMnemonic(StringRef Mnemonic, if (Mnemonic != "adcs" && Mnemonic != "bics" && Mnemonic != "movs" && Mnemonic != "muls" && Mnemonic != "smlals" && Mnemonic != "smulls" && Mnemonic != "umlals" && Mnemonic != "umulls" && Mnemonic != "lsls" && - Mnemonic != "sbcs" && Mnemonic != "rscs") { + Mnemonic != "sbcs" && Mnemonic != "rscs" && + !(hasMVE() && Mnemonic == "vmine")) { unsigned CC = ARMCondCodeFromString(Mnemonic.substr(Mnemonic.size()-2)); if (CC != ~0U) { Mnemonic = Mnemonic.slice(0, Mnemonic.size() - 2); diff --git a/test/MC/ARM/mve-minmax.s b/test/MC/ARM/mve-minmax.s index 4de21043428..1c52cbc7163 100644 --- a/test/MC/ARM/mve-minmax.s +++ b/test/MC/ARM/mve-minmax.s @@ -13,3 +13,61 @@ vmaxnm.f32 q0, q1, q4 # CHECK-NOFP-NOT: vminnm.f16 q3, q0, q1 @ encoding: [0x30,0xff,0x52,0x6f] # ERROR-NOFP: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve.fp vminnm.f16 q3, q0, q1 + +# CHECK: vmin.s8 q3, q0, q7 @ encoding: [0x00,0xef,0x5e,0x66] +# CHECK-NOFP: vmin.s8 q3, q0, q7 @ encoding: [0x00,0xef,0x5e,0x66] +vmin.s8 q3, q0, q7 + +# CHECK: vmin.s16 q0, q1, q2 @ encoding: [0x12,0xef,0x54,0x06] +# CHECK-NOFP: vmin.s16 q0, q1, q2 @ encoding: [0x12,0xef,0x54,0x06] +vmin.s16 q0, q1, q2 + +# CHECK: vmin.s32 q0, q1, q2 @ encoding: [0x22,0xef,0x54,0x06] +# CHECK-NOFP: vmin.s32 q0, q1, q2 @ encoding: [0x22,0xef,0x54,0x06] +vmin.s32 q0, q1, q2 + +# CHECK: vmin.u8 q0, q1, q2 @ encoding: [0x02,0xff,0x54,0x06] +# CHECK-NOFP: vmin.u8 q0, q1, q2 @ encoding: [0x02,0xff,0x54,0x06] +vmin.u8 q0, q1, q2 + +# CHECK: vmin.u16 q0, q1, q2 @ encoding: [0x12,0xff,0x54,0x06] +# CHECK-NOFP: vmin.u16 q0, q1, q2 @ encoding: [0x12,0xff,0x54,0x06] +vmin.u16 q0, q1, q2 + +# CHECK: vmin.u32 q0, q1, q2 @ encoding: [0x22,0xff,0x54,0x06] +# CHECK-NOFP: vmin.u32 q0, q1, q2 @ encoding: [0x22,0xff,0x54,0x06] +vmin.u32 q0, q1, q2 + +# CHECK: vmax.s8 q3, q0, q7 @ encoding: [0x00,0xef,0x4e,0x66] +# CHECK-NOFP: vmax.s8 q3, q0, q7 @ encoding: [0x00,0xef,0x4e,0x66] +vmax.s8 q3, q0, q7 + +# CHECK: vmax.s16 q0, q1, q2 @ encoding: [0x12,0xef,0x44,0x06] +# CHECK-NOFP: vmax.s16 q0, q1, q2 @ encoding: [0x12,0xef,0x44,0x06] +vmax.s16 q0, q1, q2 + +# CHECK: vmax.s32 q0, q1, q2 @ encoding: [0x22,0xef,0x44,0x06] +# CHECK-NOFP: vmax.s32 q0, q1, q2 @ encoding: [0x22,0xef,0x44,0x06] +vmax.s32 q0, q1, q2 + +# CHECK: vmax.u8 q0, q1, q2 @ encoding: [0x02,0xff,0x44,0x06] +# CHECK-NOFP: vmax.u8 q0, q1, q2 @ encoding: [0x02,0xff,0x44,0x06] +vmax.u8 q0, q1, q2 + +# CHECK: vmax.u16 q0, q1, q2 @ encoding: [0x12,0xff,0x44,0x06] +# CHECK-NOFP: vmax.u16 q0, q1, q2 @ encoding: [0x12,0xff,0x44,0x06] +vmax.u16 q0, q1, q2 + +# CHECK: vmax.u32 q0, q1, q2 @ encoding: [0x22,0xff,0x44,0x06] +# CHECK-NOFP: vmax.u32 q0, q1, q2 @ encoding: [0x22,0xff,0x44,0x06] +vmax.u32 q0, q1, q2 + +vpste +vmint.s8 q0, q1, q2 +vmine.s16 q0, q1, q2 +# CHECK: vpste @ encoding: [0x71,0xfe,0x4d,0x8f] +# CHECK-NOFP: vpste @ encoding: [0x71,0xfe,0x4d,0x8f] +# CHECK: vmint.s8 q0, q1, q2 @ encoding: [0x02,0xef,0x54,0x06] +# CHECK-NOFP: vmint.s8 q0, q1, q2 @ encoding: [0x02,0xef,0x54,0x06] +# CHECK: vmine.s16 q0, q1, q2 @ encoding: [0x12,0xef,0x54,0x06] +# CHECK-NOFP: vmine.s16 q0, q1, q2 @ encoding: [0x12,0xef,0x54,0x06] diff --git a/test/MC/Disassembler/ARM/mve-minmax.txt b/test/MC/Disassembler/ARM/mve-minmax.txt index 24287573b6c..21d531583cc 100644 --- a/test/MC/Disassembler/ARM/mve-minmax.txt +++ b/test/MC/Disassembler/ARM/mve-minmax.txt @@ -9,3 +9,51 @@ # CHECK: vminnm.f16 q3, q0, q1 @ encoding: [0x30,0xff,0x52,0x6f] # CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding [0x30,0xff,0x52,0x6f] + +# CHECK: vmin.s8 q3, q0, q7 @ encoding: [0x00,0xef,0x5e,0x66] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x00,0xef,0x5e,0x66] + +# CHECK: vmin.s16 q0, q1, q2 @ encoding: [0x12,0xef,0x54,0x06] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x12,0xef,0x54,0x06] + +# CHECK: vmin.s32 q0, q1, q2 @ encoding: [0x22,0xef,0x54,0x06] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x22,0xef,0x54,0x06] + +# CHECK: vmin.u8 q0, q1, q2 @ encoding: [0x02,0xff,0x54,0x06] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x02,0xff,0x54,0x06] + +# CHECK: vmin.u16 q0, q1, q2 @ encoding: [0x12,0xff,0x54,0x06] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x12,0xff,0x54,0x06] + +# CHECK: vmin.u32 q0, q1, q2 @ encoding: [0x22,0xff,0x54,0x06] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x22,0xff,0x54,0x06] + +# CHECK: vmax.s8 q3, q0, q7 @ encoding: [0x00,0xef,0x4e,0x66] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x00,0xef,0x4e,0x66] + +# CHECK: vmax.s16 q0, q1, q2 @ encoding: [0x12,0xef,0x44,0x06] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x12,0xef,0x44,0x06] + +# CHECK: vmax.s32 q0, q1, q2 @ encoding: [0x22,0xef,0x44,0x06] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x22,0xef,0x44,0x06] + +# CHECK: vmax.u8 q0, q1, q2 @ encoding: [0x02,0xff,0x44,0x06] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x02,0xff,0x44,0x06] + +# CHECK: vmax.u16 q0, q1, q2 @ encoding: [0x12,0xff,0x44,0x06] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x12,0xff,0x44,0x06] + +# CHECK: vmax.u32 q0, q1, q2 @ encoding: [0x22,0xff,0x44,0x06] +# CHECK-NOMVE: [[@LINE+1]]:2: warning: invalid instruction encoding +[0x22,0xff,0x44,0x06]