From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 84945 invoked by alias); 15 Dec 2017 12:50:29 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 84920 invoked by uid 89); 15 Dec 2017 12:50:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-16.2 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-ot0-f195.google.com Received: from mail-ot0-f195.google.com (HELO mail-ot0-f195.google.com) (74.125.82.195) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 15 Dec 2017 12:50:25 +0000 Received: by mail-ot0-f195.google.com with SMTP id d5so7693205oti.3 for ; Fri, 15 Dec 2017 04:50:25 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=y4vdisQ5F1ObhbvLFUNqi2myIuhzKbZNcHonX4MMj9A=; b=dx7DfWffKoeHjd+S+okdLJNZIOWkHQCDWMq2QsPhXi70O7qiWnQE3id1kbQy7fPU2b niJHmZ8KaDX4HieQ65EDobrsO26JquMkjEMauhg4ve2ZydOPXefttZqkAWMdVJp9hOTt eQFzpmL4iA84qEkKZyzScf2K47JP4henJu+rW5vWvw+SqC2nUbTnl4/9yU3AIOjuHI2O nSAUso3ANdCUrX7Qz/ZG94BsAenxUP2CZFIGnnHqOQn8UY43JKy0VBrCoUb+lGpajsmi FcYFy8mj/TS5XNGb0yhAq7bnP9o26DCbLenuXHpyjHV+Fomi+GyLpHI9BJxmxpHYO4q0 2jUA== X-Gm-Message-State: AKGB3mLwc3ng4JrVeZ+6eO8gZoiECld3MlIVTwKfynlHtcr01+BxIT5u v9b+LPsMnPuW4bSBzpLNW1thC3iGv2qjA2ZEGxo= X-Google-Smtp-Source: ACJfBosV9CnR/v5GBhifmW5zEsMlJWaU0pieVP8llykRXgLVXRumV5HoYOGtcm+Q42vqcDzmy6JggJZFqvzaEGMvVMg= X-Received: by 10.157.65.210 with SMTP id v18mr7390186oti.365.1513342223911; Fri, 15 Dec 2017 04:50:23 -0800 (PST) MIME-Version: 1.0 Received: by 10.74.151.42 with HTTP; Fri, 15 Dec 2017 04:50:23 -0800 (PST) In-Reply-To: <5A33B34602000078001979F9@prv-mh.provo.novell.com> References: <5A33A9D802000078001979BE@prv-mh.provo.novell.com> <5A33B34602000078001979F9@prv-mh.provo.novell.com> From: "H.J. Lu" Date: Fri, 15 Dec 2017 12:50:00 -0000 Message-ID: Subject: Re: [PATCH 3/4] x86: fold RegXMM/RegYMM/RegZMM into RegSIMD To: Jan Beulich Cc: Binutils Content-Type: text/plain; charset="UTF-8" X-IsSubscribed: yes X-SW-Source: 2017-12/txt/msg00138.txt.bz2 On Fri, Dec 15, 2017 at 2:34 AM, Jan Beulich wrote: > ... qualified by their respective sizes, allowing to drop FirstXmm0 at > the same time. > > gas/ > 2017-12-15 Jan Beulich > > * config/tc-i386.c (match_simd_size): New. > (match_mem_size): Use it. > (operand_size_match): Likewise. Split .reg and .acc checks. > (pi, check_VecOperands, match_template, check_byte_reg, > check_long_reg, check_qword_reg, build_modrm_byte, > parse_real_register): Replace .regxmm, .regymm, and .regzmm > checks. > (md_assemble): Qualify .acc check with .xmmword one. > (bad_implicit_operand): Delete. > (process_operands): Replace .firstxmm0 checks with .acc plus > .xmmword ones. Drop now pointless assertions. Convert .acc to > .regsimd. > * config/tc-i386-intel.c (i386_intel_simplify_register): Replace > .regxmm, .regymm, and .regzmm checks. > * testsuite/gas/i386/x86-64-specific-reg.l: Adjust expectations. > > opcodes/ > 2017-12-15 Jan Beulich > > * i386-gen.c (operand_type_shorthands): Add RegXMM, RegYMM, and > RegZMM. > (opcode_modifiers): Drop FirstXmm0. > (operand_types): Replace RegXMM, RegYMM, and RegZMM with just > RegSIMD. > * i386-opc.h (enum of opcode modifiers): Drop FirstXmm0. > (struct i386_opcode_modifier): Drop firstxmm0. > (enum of operand types): Replace RegXMM, RegYMM, and RegZMM with > just RegSIMD. Extend comment. > (union i386_operand_type): Replace regxmm, regymm, and regzmm > with just regsimd. > * i386-opc.tbl (blendvpd, blendvps, pblendvb, sha256rnds2): Use > Acc|Xmmword. > * i386-reg.tbl (xmm0): Add Acc. > * i386-init.h, i386-tbl.h: Re-generate. > > --- a/gas/config/tc-i386-intel.c > +++ b/gas/config/tc-i386-intel.c > @@ -286,9 +286,9 @@ i386_intel_simplify_register (expression > i.op[this_operand].regs = i386_regtab + reg_num; > } > else if (!intel_state.index > - && (i386_regtab[reg_num].reg_type.bitfield.regxmm > - || i386_regtab[reg_num].reg_type.bitfield.regymm > - || i386_regtab[reg_num].reg_type.bitfield.regzmm > + && (i386_regtab[reg_num].reg_type.bitfield.xmmword > + || i386_regtab[reg_num].reg_type.bitfield.ymmword > + || i386_regtab[reg_num].reg_type.bitfield.zmmword > || i386_regtab[reg_num].reg_num == RegRiz > || i386_regtab[reg_num].reg_num == RegEiz)) > intel_state.index = i386_regtab + reg_num; > --- a/gas/config/tc-i386.c > +++ b/gas/config/tc-i386.c > @@ -1825,6 +1825,20 @@ match_reg_size (const insn_template *t, > && !t->operand_types[j].bitfield.tbyte)); > } > > +/* Return 1 if there is no conflict in SIMD register on > + operand J for instruction template T. */ > + > +static INLINE int > +match_simd_size (const insn_template *t, unsigned int j) > +{ > + return !((i.types[j].bitfield.xmmword > + && !t->operand_types[j].bitfield.xmmword) > + || (i.types[j].bitfield.ymmword > + && !t->operand_types[j].bitfield.ymmword) > + || (i.types[j].bitfield.zmmword > + && !t->operand_types[j].bitfield.zmmword)); > +} > + > /* Return 1 if there is no conflict in any size on operand J for > instruction template T. */ > > @@ -1837,12 +1851,17 @@ match_mem_size (const insn_template *t, > && !t->operand_types[j].bitfield.unspecified) > || (i.types[j].bitfield.fword > && !t->operand_types[j].bitfield.fword) > - || (i.types[j].bitfield.xmmword > - && !t->operand_types[j].bitfield.xmmword) > - || (i.types[j].bitfield.ymmword > - && !t->operand_types[j].bitfield.ymmword) > - || (i.types[j].bitfield.zmmword > - && !t->operand_types[j].bitfield.zmmword))); > + /* For scalar opcode templates to allow register and memory > + operands at the same time, some special casing is needed > + here. */ > + || ((t->operand_types[j].bitfield.regsimd > + && !t->opcode_modifier.broadcast > + && (t->operand_types[j].bitfield.dword > + || t->operand_types[j].bitfield.qword)) > + ? (i.types[j].bitfield.xmmword > + || i.types[j].bitfield.ymmword > + || i.types[j].bitfield.zmmword) > + : !match_simd_size(t, j)))); > } > > /* Return 1 if there is no size conflict on any operands for > @@ -1864,17 +1883,31 @@ operand_size_match (const insn_template > /* Check memory and accumulator operand size. */ > for (j = 0; j < i.operands; j++) > { > - if (!i.types[j].bitfield.reg && t->operand_types[j].bitfield.anysize) > + if (!i.types[j].bitfield.reg && !i.types[j].bitfield.regsimd > + && t->operand_types[j].bitfield.anysize) > continue; > > - if ((t->operand_types[j].bitfield.reg > - || t->operand_types[j].bitfield.acc) > + if (t->operand_types[j].bitfield.reg > && !match_reg_size (t, j)) > { > match = 0; > break; > } > > + if (t->operand_types[j].bitfield.regsimd > + && !match_simd_size (t, j)) > + { > + match = 0; > + break; > + } > + > + if (t->operand_types[j].bitfield.acc > + && (!match_reg_size (t, j) || !match_simd_size (t, j))) > + { > + match = 0; > + break; > + } > + > if (i.types[j].bitfield.mem && !match_mem_size (t, j)) > { > match = 0; > @@ -2804,9 +2837,7 @@ pi (char *line, i386_insn *x) > fprintf (stdout, "\n"); > if (x->types[j].bitfield.reg > || x->types[j].bitfield.regmmx > - || x->types[j].bitfield.regxmm > - || x->types[j].bitfield.regymm > - || x->types[j].bitfield.regzmm > + || x->types[j].bitfield.regsimd > || x->types[j].bitfield.sreg2 > || x->types[j].bitfield.sreg3 > || x->types[j].bitfield.control > @@ -3768,7 +3799,7 @@ md_assemble (char *line) > for (j = 0; j < i.operands; j++) > if (i.types[j].bitfield.inoutportreg > || i.types[j].bitfield.shiftcount > - || i.types[j].bitfield.acc) > + || (i.types[j].bitfield.acc && !i.types[j].bitfield.xmmword)) > i.reg_operands--; > > /* ImmExt should be processed after SSE2AVX. */ > @@ -4576,9 +4607,9 @@ check_VecOperands (const insn_template * > /* Without VSIB byte, we can't have a vector register for index. */ > if (!t->opcode_modifier.vecsib > && i.index_reg > - && (i.index_reg->reg_type.bitfield.regxmm > - || i.index_reg->reg_type.bitfield.regymm > - || i.index_reg->reg_type.bitfield.regzmm)) > + && (i.index_reg->reg_type.bitfield.xmmword > + || i.index_reg->reg_type.bitfield.ymmword > + || i.index_reg->reg_type.bitfield.zmmword)) > { > i.error = unsupported_vector_index_register; > return 1; > @@ -4598,11 +4629,11 @@ check_VecOperands (const insn_template * > { > if (!i.index_reg > || !((t->opcode_modifier.vecsib == VecSIB128 > - && i.index_reg->reg_type.bitfield.regxmm) > + && i.index_reg->reg_type.bitfield.xmmword) > || (t->opcode_modifier.vecsib == VecSIB256 > - && i.index_reg->reg_type.bitfield.regymm) > + && i.index_reg->reg_type.bitfield.ymmword) > || (t->opcode_modifier.vecsib == VecSIB512 > - && i.index_reg->reg_type.bitfield.regzmm))) > + && i.index_reg->reg_type.bitfield.zmmword))) > { > i.error = invalid_vsib_address; > return 1; > @@ -4611,10 +4642,12 @@ check_VecOperands (const insn_template * > gas_assert (i.reg_operands == 2 || i.mask); > if (i.reg_operands == 2 && !i.mask) > { > - gas_assert (i.types[0].bitfield.regxmm > - || i.types[0].bitfield.regymm); > - gas_assert (i.types[2].bitfield.regxmm > - || i.types[2].bitfield.regymm); > + gas_assert (i.types[0].bitfield.regsimd); > + gas_assert (i.types[0].bitfield.xmmword > + || i.types[0].bitfield.ymmword); > + gas_assert (i.types[2].bitfield.regsimd); > + gas_assert (i.types[2].bitfield.xmmword > + || i.types[2].bitfield.ymmword); > if (operand_check == check_none) > return 0; > if (register_number (i.op[0].regs) > @@ -4633,9 +4666,10 @@ check_VecOperands (const insn_template * > } > else if (i.reg_operands == 1 && i.mask) > { > - if ((i.types[1].bitfield.regxmm > - || i.types[1].bitfield.regymm > - || i.types[1].bitfield.regzmm) > + if (i.types[1].bitfield.regsimd > + && (i.types[1].bitfield.xmmword > + || i.types[1].bitfield.ymmword > + || i.types[1].bitfield.zmmword) > && (register_number (i.op[1].regs) > == register_number (i.index_reg))) > { > @@ -4941,13 +4975,9 @@ match_template (char mnem_suffix) > && !intel_float_operand (t->name)) > : intel_float_operand (t->name) != 2) > && ((!operand_types[0].bitfield.regmmx > - && !operand_types[0].bitfield.regxmm > - && !operand_types[0].bitfield.regymm > - && !operand_types[0].bitfield.regzmm) > + && !operand_types[0].bitfield.regsimd) > || (!operand_types[t->operands > 1].bitfield.regmmx > - && !operand_types[t->operands > 1].bitfield.regxmm > - && !operand_types[t->operands > 1].bitfield.regymm > - && !operand_types[t->operands > 1].bitfield.regzmm)) > + && !operand_types[t->operands > 1].bitfield.regsimd)) > && (t->base_opcode != 0x0fc7 > || t->extension_opcode != 1 /* cmpxchg8b */)) > continue; > @@ -4960,9 +4990,9 @@ match_template (char mnem_suffix) > && !intel_float_operand (t->name)) > : intel_float_operand (t->name) != 2) > && ((!operand_types[0].bitfield.regmmx > - && !operand_types[0].bitfield.regxmm) > + && !operand_types[0].bitfield.regsimd) > || (!operand_types[t->operands > 1].bitfield.regmmx > - && !operand_types[t->operands > 1].bitfield.regxmm))) > + && !operand_types[t->operands > 1].bitfield.regsimd))) > continue; > > /* Do not verify operands when there are none. */ > @@ -5653,9 +5683,7 @@ check_byte_reg (void) > /* Any other register is bad. */ > if (i.types[op].bitfield.reg > || i.types[op].bitfield.regmmx > - || i.types[op].bitfield.regxmm > - || i.types[op].bitfield.regymm > - || i.types[op].bitfield.regzmm > + || i.types[op].bitfield.regsimd > || i.types[op].bitfield.sreg2 > || i.types[op].bitfield.sreg3 > || i.types[op].bitfield.control > @@ -5728,7 +5756,7 @@ check_long_reg (void) > { > if (intel_syntax > && i.tm.opcode_modifier.toqword > - && !i.types[0].bitfield.regxmm) > + && !i.types[0].bitfield.regsimd) > { > /* Convert to QWORD. We want REX byte. */ > i.suffix = QWORD_MNEM_SUFFIX; > @@ -5779,7 +5807,7 @@ check_qword_reg (void) > lowering is more complicated. */ > if (intel_syntax > && i.tm.opcode_modifier.todword > - && !i.types[0].bitfield.regxmm) > + && !i.types[0].bitfield.regsimd) > { > /* Convert to DWORD. We don't want REX byte. */ > i.suffix = LONG_MNEM_SUFFIX; > @@ -5930,20 +5958,6 @@ finalize_imm (void) > } > > static int > -bad_implicit_operand (int xmm) > -{ > - const char *ireg = xmm ? "xmm0" : "ymm0"; > - > - if (intel_syntax) > - as_bad (_("the last operand of `%s' must be `%s%s'"), > - i.tm.name, register_prefix, ireg); > - else > - as_bad (_("the first operand of `%s' must be `%s%s'"), > - i.tm.name, register_prefix, ireg); > - return 0; > -} > - Will we miss the assembly operand error checking? -- H.J.