From patchwork Fri Jul 24 10:14:49 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 139886 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E43AD4BA2E3F for ; Fri, 24 Jul 2026 10:15:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E43AD4BA2E3F Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=suse.com header.i=@suse.com header.a=rsa-sha256 header.s=google header.b=Krm2MFtH X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [IPv6:2a00:1450:4864:20::331]) by sourceware.org (Postfix) with ESMTPS id 630B64BA900A for ; Fri, 24 Jul 2026 10:14:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 630B64BA900A Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 630B64BA900A Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::331 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1784888092; cv=none; b=AtSYgU+Jx7NfGI7BcVBHFYUEeV4odzvdMHuUixuUN9AsoN7QG3hhKIr1Dg7OWXnsAVK56mO1jjdAG+huOTCKPLY3qLB+8sulloWeHsEQ9GzoYAhOE46i/wVeZLBvuuTnC0MRhze4aASSUCGhoXoR2V2EqnQzyE50uYTVIRxEvj4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1784888092; c=relaxed/simple; bh=OmgFOTSjYbsgMufsZ5xAoA9jx9gJvV0TxciMDMnOcDs=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:From:To; b=G4JCqemXgLR5GuTWfEtpWw+G2nfRzU2Bpib2WVeibfYJGrJRiWph/gnpCf/S6QngBMOkrkHGaH0wIKa8F7HJVPH4qW9kLCu5xYZGEm3uBeiRLXE87XIyUKMa/oPyKX3mCdYL6205pTGUeUcLwso/uwbYlKvmpz70crUGo72etow= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=suse.com header.i=@suse.com header.a=rsa-sha256 header.s=google header.b=Krm2MFtH DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 630B64BA900A Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-49550ec592cso8743395e9.0 for ; Fri, 24 Jul 2026 03:14:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1784888091; x=1785492891; darn=sourceware.org; h=content-transfer-encoding:content-type:in-reply-to:autocrypt :content-language:references:cc:to:from:subject:user-agent :mime-version:date:message-id:from:to:cc:subject:date:message-id :reply-to:content-type; bh=2ceo6A+kJOkHzwiD/JCqraAYqlR0tLSouKb0OtmCkG0=; b=Krm2MFtH8LG0TzY/OqvJSNMq1qnpFWS7vVTsoJ/W+wI3KbQeQ2T9t3h1X71eapq2CI f301BGteLCUAnd22+VjGnK8/DMSEsCoskeK3W7a76Q9uHpZcTXmvHOthwDcLBF8hq5ts 8NRiL9GKLNENig65Eatz54YNtZwqmL3yCBX+Zug1S6cTG/3rc3KqZophvMJuUsT5n412 sIBRuFWHqTh8gVor4LnxrtN952YnCWu8+RpMdaF3/N7CWCv9pruYzD2pNDbekfYfveGS xGKMxlc6aC9kwHR5Z+SKiu0g0dKHAf76iW116Svks62ZoGsr+GxrqdDAT8C59cB9gfYR F5jQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784888091; x=1785492891; h=content-transfer-encoding:content-type:in-reply-to:autocrypt :content-language:references:cc:to:from:subject:user-agent :mime-version:date:message-id:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to:content-type; bh=2ceo6A+kJOkHzwiD/JCqraAYqlR0tLSouKb0OtmCkG0=; b=ZfpYXP7FigYlphMnuQMz0VY8PAhb4dt2WWi3Wy8W7/nnMa9V1t7D+zfY3HawqFB0T+ Q8oQhMg8dz5e2iBMFu8BaUSqvNp2zYV2jWN//GHQW9CDVNEyFbwKWdOjN+AisEwq3zmx Vjv1nDN9N31cB+uVRg+pKIYoWqk1pX6U40lmwLqBMbQ4wH6fmmpU0CsmVet6ui/MBngA ZqFZaFarU0IeS/tM92ru07MrKudl6CdxJA0hvq23YZYhM9BAKujeXw8qfIja7/LmRvel D7VfdLMnHNqO3mIIvPNG/hT7/mA/LKmscakSWnQpGhcH0xAtF9sQAiy+SVU1gQGzW05W 2s0Q== X-Gm-Message-State: AOJu0YwcxqeZP7XDLboIo3nz5LrNZQuLdrCxC0Ix9XZf/GHOKaVocyTv lU56dcelmSnD8DeqRRTL/VVaaAZaGStyvjBGEQuVT/RKeubHYlun4SHsvWyWgHEf16fRXj42ilX WYDMhKA== X-Gm-Gg: AR+sD12fPIrrl9fBik8bLf1yoWnz0HcSQ4gskex8k53OzzBqOdbZZ7wlbceDC4J0m1X 3RoB3cPG6JxwmIB6lM8vBkQmmdFA8Lt79My5gMEcnf9JJpyYsQi31rs0Fu60ivk2pzTIWrrRy/w FLwZowUpXUtdiNeb5+LjrfJWTEyCvOCe/M6bC797omJtx3MM9gLhGElMGVrpf4q0rWCo8g2jjaA 0yffT8BQ7dx00EpR4wGDoC9MZvnt54vpmWm061xGYw62EFSIIYPUec735n8cMWv+Vx2WPFbG5dg pB8K0WFS2smP4d4/MIw4ivij5tkVXIK3RDGhcUEwNL4b16eoVOUP84euk6850wSclXtXb+lmR6K NAqXghf7+jPO2h7uq3NNfoHJeZoJ0t8FGeFhKDkgR36l+p/aS0bq+QvahYMZT1XXBmB0RdcNR+X gpHBl8UREjJaYnc340Wp8qho+f6rAXVxIVhqbONf1T0xArG08gmE8b4Db0vnD566butg== X-Received: by 2002:a05:600c:4fc2:b0:495:6193:c6c0 with SMTP id 5b1f17b1804b1-495745b238amr72591355e9.18.1784888091184; Fri, 24 Jul 2026 03:14:51 -0700 (PDT) Received: from [10.156.60.236] (ip-037-024-206-209.um08.pools.vodafone-ip.de. [37.24.206.209]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4957af89be2sm70359075e9.12.2026.07.24.03.14.50 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 24 Jul 2026 03:14:50 -0700 (PDT) Message-ID: <54396697-ca30-4b9e-b1a8-b80284dec395@suse.com> Date: Fri, 24 Jul 2026 12:14:49 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 3/4] x86: helper function + variables for templates' ->operand_types[] accesses From: Jan Beulich To: Binutils Cc: "H.J. Lu" References: <4bce97ee-c8d1-44f8-8c61-4ec3a5b91b4f@suse.com> Content-Language: en-US Autocrypt: addr=jbeulich@suse.com; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL In-Reply-To: <4bce97ee-c8d1-44f8-8c61-4ec3a5b91b4f@suse.com> X-Spam-Status: No, score=-3015.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces~patchwork=sourceware.org@sourceware.org This again is to reduce the churn by a subsequent change, where .operand_types[] is to no longer be directly embedded in the templates. A few instances cannot sensibly changed following the pattern used. In match_template() one use to be replaced is covered by slightly re-ordering code there, to then use an existing local variable. --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -2548,6 +2548,12 @@ operand_type_check (i386_operand_type t, return 0; } +static INLINE const i386_operand_type * +get_operand_types (const insn_template *t) +{ + return t->operand_types; +} + /* Return 1 if there is no conflict in 8bit/16bit/32bit/64bit size between operand GIVEN and operand WANTED for instruction template T. */ @@ -2555,20 +2561,22 @@ static INLINE int match_operand_size (const insn_template *t, unsigned int wanted, unsigned int given) { + const i386_operand_type *t_types = get_operand_types (t); + return !((i.types[given].bitfield.byte - && !t->operand_types[wanted].bitfield.byte) + && !t_types[wanted].bitfield.byte) || (i.types[given].bitfield.word - && !t->operand_types[wanted].bitfield.word) + && !t_types[wanted].bitfield.word) || (i.types[given].bitfield.dword - && !t->operand_types[wanted].bitfield.dword) + && !t_types[wanted].bitfield.dword) || (i.types[given].bitfield.qword - && (!t->operand_types[wanted].bitfield.qword + && (!t_types[wanted].bitfield.qword /* Don't allow 64-bit (memory) operands outside of 64-bit mode, when they're used where a 64-bit GPR could also be used. Checking is needed for Intel Syntax only. */ || (intel_syntax && flag_code != CODE_64BIT - && (t->operand_types[wanted].bitfield.class == Reg + && (t_types[wanted].bitfield.class == Reg || t->opcode_modifier.isstring))))); } @@ -2576,28 +2584,28 @@ match_operand_size (const insn_template between operand GIVEN and operand WANTED for instruction template T. */ static INLINE int -match_fp_size (const insn_template *t, unsigned int wanted, +match_fp_size (const i386_operand_type *t_types, unsigned int wanted, unsigned int given) { return !i.types[given].bitfield.tbyte - || t->operand_types[wanted].bitfield.tbyte; + || t_types[wanted].bitfield.tbyte; } /* Return 1 if there is no conflict in SIMD register between operand GIVEN and operand WANTED for instruction template T. */ static INLINE int -match_simd_size (const insn_template *t, unsigned int wanted, +match_simd_size (const i386_operand_type *t_types, unsigned int wanted, unsigned int given) { return !((i.types[given].bitfield.xmmword - && !t->operand_types[wanted].bitfield.xmmword) + && !t_types[wanted].bitfield.xmmword) || (i.types[given].bitfield.ymmword - && !t->operand_types[wanted].bitfield.ymmword) + && !t_types[wanted].bitfield.ymmword) || (i.types[given].bitfield.zmmword - && !t->operand_types[wanted].bitfield.zmmword) + && !t_types[wanted].bitfield.zmmword) || (i.types[given].bitfield.tmmword - && !t->operand_types[wanted].bitfield.tmmword)); + && !t_types[wanted].bitfield.tmmword)); } /* Return 1 if there is no conflict in any size between operand GIVEN @@ -2607,29 +2615,31 @@ static INLINE int match_mem_size (const insn_template *t, unsigned int wanted, unsigned int given) { + const i386_operand_type *t_types = get_operand_types (t); + return (match_operand_size (t, wanted, given) && (!i.types[given].bitfield.tbyte - || t->operand_types[wanted].bitfield.tbyte) + || t_types[wanted].bitfield.tbyte) && !((i.types[given].bitfield.unspecified && !i.broadcast.type && !i.broadcast.bytes - && !t->operand_types[wanted].bitfield.unspecified) + && !t_types[wanted].bitfield.unspecified) || (i.types[given].bitfield.fword - && !t->operand_types[wanted].bitfield.fword) + && !t_types[wanted].bitfield.fword) /* For scalar opcode templates to allow register and memory operands at the same time, some special casing is needed here. Also for v{,p}broadcast*, {,v}pmov{s,z}*, and down-conversion vpmov*. */ - || ((t->operand_types[wanted].bitfield.class == RegSIMD - && t->operand_types[wanted].bitfield.byte - + t->operand_types[wanted].bitfield.word - + t->operand_types[wanted].bitfield.dword - + t->operand_types[wanted].bitfield.qword + || ((t_types[wanted].bitfield.class == RegSIMD + && t_types[wanted].bitfield.byte + + t_types[wanted].bitfield.word + + t_types[wanted].bitfield.dword + + t_types[wanted].bitfield.qword > !!t->opcode_modifier.broadcast) ? (i.types[given].bitfield.xmmword || i.types[given].bitfield.ymmword || i.types[given].bitfield.zmmword) - : !match_simd_size(t, wanted, given)))); + : !match_simd_size(t_types, wanted, given)))); } /* Return value has MATCH_STRAIGHT set if there is no size conflict on any @@ -2643,6 +2653,7 @@ match_mem_size (const insn_template *t, static INLINE unsigned int operand_size_match (const insn_template *t) { + const i386_operand_type *t_types = get_operand_types (t); unsigned int j, match = MATCH_STRAIGHT; /* Don't check non-absolute jump instructions. */ @@ -2657,8 +2668,8 @@ operand_size_match (const insn_template first template if sign-extended 8-bit immediate operand should be excluded. */ if (pp.no_imm8s - && !t->operand_types[j].bitfield.imm8 - && t->operand_types[j].bitfield.imm8s) + && !t_types[j].bitfield.imm8 + && t_types[j].bitfield.imm8s) { gas_assert (!t->opcode_modifier.d); return 0; @@ -2668,12 +2679,12 @@ operand_size_match (const insn_template for (; j < i.operands; j++) { if (i.types[j].bitfield.class == Reg - && (t->operand_types[j].bitfield.class == Reg - || (t->operand_types[j].bitfield.instance == Accum - && (t->operand_types[j].bitfield.byte - || t->operand_types[j].bitfield.word - || t->operand_types[j].bitfield.dword - || t->operand_types[j].bitfield.qword))) + && (t_types[j].bitfield.class == Reg + || (t_types[j].bitfield.instance == Accum + && (t_types[j].bitfield.byte + || t_types[j].bitfield.word + || t_types[j].bitfield.dword + || t_types[j].bitfield.qword))) && !match_operand_size (t, j, j)) { match = 0; @@ -2681,28 +2692,28 @@ operand_size_match (const insn_template } if (i.types[j].bitfield.class == RegFP - && (t->operand_types[j].bitfield.class == RegFP - || (t->operand_types[j].bitfield.instance == Accum - && t->operand_types[j].bitfield.tbyte)) - && !match_fp_size (t, j, j)) + && (t_types[j].bitfield.class == RegFP + || (t_types[j].bitfield.instance == Accum + && t_types[j].bitfield.tbyte)) + && !match_fp_size (t_types, j, j)) { match = 0; break; } if (i.types[j].bitfield.class == RegSIMD - && (t->operand_types[j].bitfield.class == RegSIMD - || (t->operand_types[j].bitfield.instance == Accum + && (t_types[j].bitfield.class == RegSIMD + || (t_types[j].bitfield.instance == Accum /* Note: %ymm0, %zmm0, and %tmm0 aren't marked Accum. */ - && t->operand_types[j].bitfield.xmmword)) - && !match_simd_size (t, j, j)) + && t_types[j].bitfield.xmmword)) + && !match_simd_size (t_types, j, j)) { match = 0; break; } if ((i.flags[j] & Operand_Mem) - && operand_type_check (t->operand_types[j], anymem) + && operand_type_check (t_types[j], anymem) && t->opcode_modifier.operandconstraint != ANY_SIZE && !match_mem_size (t, j, j)) { @@ -2729,32 +2740,32 @@ operand_size_match (const insn_template given = j < 2 ? 1 - j : j; if (i.types[given].bitfield.class == Reg - && (t->operand_types[j].bitfield.class == Reg - || (t->operand_types[j].bitfield.instance == Accum - && (t->operand_types[j].bitfield.byte - || t->operand_types[j].bitfield.word - || t->operand_types[j].bitfield.dword - || t->operand_types[j].bitfield.qword - || t->operand_types[j].bitfield.tbyte))) + && (t_types[j].bitfield.class == Reg + || (t_types[j].bitfield.instance == Accum + && (t_types[j].bitfield.byte + || t_types[j].bitfield.word + || t_types[j].bitfield.dword + || t_types[j].bitfield.qword + || t_types[j].bitfield.tbyte))) && !match_operand_size (t, j, given)) return match; if (i.types[given].bitfield.class == RegFP - && (t->operand_types[j].bitfield.class == RegFP - || (t->operand_types[j].bitfield.instance == Accum - && t->operand_types[j].bitfield.tbyte)) - && !match_fp_size (t, j, given)) + && (t_types[j].bitfield.class == RegFP + || (t_types[j].bitfield.instance == Accum + && t_types[j].bitfield.tbyte)) + && !match_fp_size (t_types, j, given)) return match; /* No need to check for Accum here: There are no such templates with D set. */ if (i.types[given].bitfield.class == RegSIMD - && t->operand_types[j].bitfield.class == RegSIMD - && !match_simd_size (t, j, given)) + && t_types[j].bitfield.class == RegSIMD + && !match_simd_size (t_types, j, given)) return match; if ((i.flags[given] & Operand_Mem) - && operand_type_check (t->operand_types[j], anymem) + && operand_type_check (t_types[j], anymem) && !match_mem_size (t, j, given)) return match; } @@ -3866,10 +3877,11 @@ pte (insn_template *t) if (t->opcode_modifier.w) fprintf (stdout, "W"); fprintf (stdout, "\n"); + const i386_operand_type *t_types = get_operand_types (t); for (j = 0; j < t->operands; j++) { fprintf (stdout, " #%d type ", j + 1); - pt (t->operand_types[j]); + pt (t_types[j]); fprintf (stdout, "\n"); } } @@ -4239,8 +4251,9 @@ install_template (const insn_template *t i.tm = *t; + const i386_operand_type *t_types = get_operand_types (t); for (l = 0; l < t->operands; ++l) - i.tm_types[l] = t->operand_types[l]; + i.tm_types[l] = t_types[l]; /* Dual VEX/EVEX templates need stripping one of the possible variants. */ if (t->opcode_modifier.vex && t->opcode_modifier.evex) @@ -4500,6 +4513,7 @@ static unsigned int get_broadcast_bytes (const insn_template *t, bool diag) { unsigned int op, bytes; + const i386_operand_type *t_types = get_operand_types (t); const i386_operand_type *types; if (i.broadcast.type) @@ -4508,7 +4522,7 @@ get_broadcast_bytes (const insn_template gas_assert (intel_syntax); for (op = 0; op < t->operands; ++op) - if (t->operand_types[op].bitfield.baseindex) + if (t_types[op].bitfield.baseindex) break; gas_assert (op < t->operands); @@ -4517,23 +4531,23 @@ get_broadcast_bytes (const insn_template switch (i.broadcast.bytes) { case 1: - if (t->operand_types[op].bitfield.word) + if (t_types[op].bitfield.word) return 2; /* Fall through. */ case 2: - if (t->operand_types[op].bitfield.dword) + if (t_types[op].bitfield.dword) return 4; /* Fall through. */ case 4: - if (t->operand_types[op].bitfield.qword) + if (t_types[op].bitfield.qword) return 8; /* Fall through. */ case 8: - if (t->operand_types[op].bitfield.xmmword) + if (t_types[op].bitfield.xmmword) return 16; - if (t->operand_types[op].bitfield.ymmword) + if (t_types[op].bitfield.ymmword) return 32; - if (t->operand_types[op].bitfield.zmmword) + if (t_types[op].bitfield.zmmword) return 64; /* Fall through. */ default: @@ -4542,15 +4556,15 @@ get_broadcast_bytes (const insn_template gas_assert (op + 1 < t->operands); - if (t->operand_types[op + 1].bitfield.xmmword - + t->operand_types[op + 1].bitfield.ymmword - + t->operand_types[op + 1].bitfield.zmmword > 1) + if (t_types[op + 1].bitfield.xmmword + + t_types[op + 1].bitfield.ymmword + + t_types[op + 1].bitfield.zmmword > 1) { types = &i.types[op + 1]; diag = false; } else /* Ambiguous - guess with a preference to non-AVX512VL forms. */ - types = &t->operand_types[op]; + types = &t_types[op]; if (types->bitfield.zmmword) bytes = 64; @@ -6877,7 +6891,7 @@ static INLINE bool may_need_pass2 (const { return t->opcode_modifier.sse2avx /* Note that all SSE2AVX templates have at least one operand. */ - ? t->operand_types[t->operands - 1].bitfield.class == RegSIMD + ? get_operand_types (t)[t->operands - 1].bitfield.class == RegSIMD : (t->opcode_space == SPACE_0F && (t->base_opcode | 1) == 0xbf) || (t->opcode_space == SPACE_BASE @@ -7525,6 +7539,8 @@ i386_assemble (char *line) free (xstrdup_copy); + const i386_operand_type *t_types = get_operand_types (t); + if (sse_check != check_none /* The opcode space check isn't strictly needed; it's there only to bypass the logic below when easily possible. */ @@ -7538,9 +7554,9 @@ i386_assemble (char *line) for (j = 0; j < t->operands; ++j) { - if (t->operand_types[j].bitfield.class == RegMMX) + if (t_types[j].bitfield.class == RegMMX) break; - if (t->operand_types[j].bitfield.class == RegSIMD) + if (t_types[j].bitfield.class == RegSIMD) simd = true; } @@ -8654,10 +8670,10 @@ optimize_imm (void) break; } - allowed = operand_type_and (t->operand_types[op], mask); + allowed = operand_type_and (get_operand_types (t)[op], mask); while (++t < current_templates.end) { - allowed = operand_type_or (allowed, t->operand_types[op]); + allowed = operand_type_or (allowed, get_operand_types (t)[op]); allowed = operand_type_and (allowed, mask); } @@ -8803,6 +8819,7 @@ check_VecOperands (const insn_template * { unsigned int op; i386_cpu_flags cpu; + const i386_operand_type *t_types = get_operand_types (t); /* Templates allowing for ZMMword as well as YMMword and/or XMMword for any one operand are implicity requiring AVX512VL support if the actual @@ -8822,7 +8839,7 @@ check_VecOperands (const insn_template * { for (op = 0; op < t->operands; ++op) { - if (t->operand_types[op].bitfield.zmmword + if (t_types[op].bitfield.zmmword && (i.types[op].bitfield.ymmword || i.types[op].bitfield.xmmword)) { @@ -8839,7 +8856,7 @@ check_VecOperands (const insn_template * { for (op = 0; op < t->operands; ++op) { - if (t->operand_types[op].bitfield.xmmword + if (t_types[op].bitfield.xmmword && i.types[op].bitfield.ymmword) { i.error = operand_size_mismatch; @@ -8931,7 +8948,7 @@ check_VecOperands (const insn_template * /* For AMX instructions with 3 TMM register operands, all operands must be distinct. */ if (i.reg_operands == 3 - && t->operand_types[0].bitfield.tmmword + && t_types[0].bitfield.tmmword && (i.op[0].regs == i.op[1].regs || i.op[0].regs == i.op[2].regs || i.op[1].regs == i.op[2].regs)) @@ -9006,12 +9023,12 @@ check_VecOperands (const insn_template * goto bad_broadcast; } - overlap = operand_type_and (type, t->operand_types[op]); - if (t->operand_types[op].bitfield.class == RegSIMD - && t->operand_types[op].bitfield.byte - + t->operand_types[op].bitfield.word - + t->operand_types[op].bitfield.dword - + t->operand_types[op].bitfield.qword > 1) + overlap = operand_type_and (type, t_types[op]); + if (t_types[op].bitfield.class == RegSIMD + && t_types[op].bitfield.byte + + t_types[op].bitfield.word + + t_types[op].bitfield.dword + + t_types[op].bitfield.qword > 1) { overlap.bitfield.xmmword = 0; overlap.bitfield.ymmword = 0; @@ -9029,9 +9046,9 @@ check_VecOperands (const insn_template * { if (j != op && !operand_type_register_match(i.types[j], - t->operand_types[j], + t_types[j], type, - t->operand_types[op])) + t_types[op])) goto bad_broadcast; } } @@ -9071,7 +9088,7 @@ check_VecOperands (const insn_template * - scatter/gather insns (i.e. ones using vSIB) only allow merging- masking. */ if (i.mask.zeroing - && (t->operand_types[t->operands - 1].bitfield.class == RegMask + && (t_types[t->operands - 1].bitfield.class == RegMask || (i.flags[t->operands - 1] & Operand_Mem) || t->opcode_modifier.sib)) { @@ -9155,14 +9172,14 @@ check_VecOperands (const insn_template * { if (t->opcode_modifier.evex == EVEXLIG) i.memshift = 2 + (i.suffix == QWORD_MNEM_SUFFIX); - else if (t->operand_types[op].bitfield.xmmword - + t->operand_types[op].bitfield.ymmword - + t->operand_types[op].bitfield.zmmword <= 1) - type = &t->operand_types[op]; + else if (t_types[op].bitfield.xmmword + + t_types[op].bitfield.ymmword + + t_types[op].bitfield.zmmword <= 1) + type = &t_types[op]; else if (!i.types[op].bitfield.unspecified) type = &i.types[op]; else /* Ambiguities get resolved elsewhere. */ - fallback = &t->operand_types[op]; + fallback = &t_types[op]; } else if (i.types[op].bitfield.class == RegSIMD && t->opcode_modifier.evex != EVEXLIG) @@ -9510,18 +9527,21 @@ match_template (char mnem_suffix) if (i.jumpabsolute && t->opcode_modifier.jump != JUMP_ABSOLUTE) continue; + const i386_operand_type *t_types = get_operand_types (t); + for (j = 0; j < t->operands; ++j) + operand_types[j] = t_types[j]; + for (; j < MAX_OPERANDS; ++j) + operand_types[j] = (i386_operand_type){ .array[0] = 0 }; + /* In Intel syntax, normally we can check for memory operand size when there is no mnemonic suffix. But jmp and call have 2 different encodings with Dword memory operand size. Skip the "near" one (permitting a register operand) when "far" was requested. */ if (i.far_branch && t->opcode_modifier.jump == JUMP_ABSOLUTE - && t->operand_types[0].bitfield.class == Reg) + && operand_types[0].bitfield.class == Reg) continue; - for (j = 0; j < MAX_OPERANDS; j++) - operand_types[j] = t->operand_types[j]; - /* In general, don't allow 32-bit operands on pre-386. */ specific_error = progress (mnem_suffix ? invalid_instruction_suffix : operand_size_mismatch); @@ -9983,13 +10003,12 @@ match_template (char mnem_suffix) size_match = true; /* We ensure that the next template has the same input operands as the original matching template by the first - opernd (ATT). To avoid someone support new NDD insns and + operand (ATT). To avoid someone support new NDD insns and put it in the wrong position. */ - overlap0 = operand_type_and (i.types[0], - t[1].operand_types[0]); + const i386_operand_type *t1_types = get_operand_types (&t[1]); + overlap0 = operand_type_and (i.types[0], t1_types[0]); if (t->opcode_modifier.d) - overlap1 = operand_type_and (i.types[0], - t[1].operand_types[1]); + overlap1 = operand_type_and (i.types[0], t1_types[1]); if (!operand_type_match (overlap0, i.types[0]) && (!t->opcode_modifier.d || !operand_type_match (overlap1, i.types[0]))) @@ -15294,6 +15313,7 @@ i386_index_check (const char *operand_st if (t->opcode_modifier.isstring) { + const i386_operand_type *t_types = get_operand_types (t); /* Memory operands of string insns are special in that they only allow a single register (rDI or rSI) as their memory address. */ const reg_entry *expected_reg; @@ -15319,22 +15339,22 @@ i386_index_check (const char *operand_st int es_op = t->opcode_modifier.isstring - IS_STRING_ES_OP0; int op = 0; - if (!t->operand_types[0].bitfield.baseindex + if (!t_types[0].bitfield.baseindex || ((!i.mem_operands != !intel_syntax) - && t->operand_types[1].bitfield.baseindex)) + && t_types[1].bitfield.baseindex)) op = 1; expected_reg = str_hash_find (reg_hash, di_si[addr_mode][op == es_op]); } else { - unsigned int op = t->operand_types[0].bitfield.baseindex ? 0 : 1; + unsigned int op = t_types[0].bitfield.baseindex ? 0 : 1; - if (!t->operand_types[op].bitfield.instance) + if (!t_types[op].bitfield.instance) return 1; /* Operand mismatch will be detected elsewhere. */ expected_reg = str_hash_find (reg_hash, - loregs[addr_mode][t->operand_types[op] + loregs[addr_mode][t_types[op] .bitfield.instance - 1]); } --- a/gas/config/tc-i386-intel.c +++ b/gas/config/tc-i386-intel.c @@ -923,9 +923,11 @@ i386_intel_operand (char *operand_string i.types[this_operand].bitfield.tbyte = 1; if (got_a_float) break; + const i386_operand_type *t_types + = get_operand_types (current_templates.start); if (flag_code == CODE_64BIT - && (current_templates.start->operand_types[0].bitfield.fword - || current_templates.start->operand_types[0].bitfield.tbyte + && (t_types[0].bitfield.fword + || t_types[0].bitfield.tbyte || current_templates.start->opcode_modifier.jump == JUMP_DWORD || current_templates.start->opcode_modifier.jump == JUMP)) suffix = QWORD_MNEM_SUFFIX; /* l[fgs]s, [ls][gi]dt, call, jmp */ @@ -1031,10 +1033,11 @@ i386_intel_operand (char *operand_string if (!t->opcode_modifier.modrm) break; - if (!t->operand_types[op].bitfield.baseindex) + const i386_operand_type *t_types = get_operand_types (t); + if (!t_types[op].bitfield.baseindex) continue; - switch (t->operand_types[op].bitfield.class) + switch (t_types[op].bitfield.class) { case RegMMX: case RegSIMD: