From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id B2B0E3860C32 for ; Fri, 26 Mar 2021 13:48:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B2B0E3860C32 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id CDC80AB8A; Fri, 26 Mar 2021 13:48:12 +0000 (UTC) Subject: [PATCH 3/7] x86: integrate broadcast_op into struct _i386_insn To: Binutils References: <139e8ac5-fda2-caaf-39e0-35a56b1c0e0f@suse.com> From: Jan Beulich Message-ID: Date: Fri, 26 Mar 2021 14:48:11 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.9.0 MIME-Version: 1.0 In-Reply-To: <139e8ac5-fda2-caaf-39e0-35a56b1c0e0f@suse.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-3033.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Mar 2021 13:48:15 -0000 There's no need for the extra level of indirection and the extra storage needed for the pointer, pointing from one piece of static data to another. Key checking of broadcast being in effect off of the type field of the structure instead. gas/ 2021-03-XX Jan Beulich * config/tc-i386.c (broadcast_op): Delete. (struct Broadcast_Operation): Move ... (struct _i386_insn): ... here. Change field "broadcast". (match_mem_size): Adjust check for broadcast. (optimize_encoding): Likewise. (process_suffix): Likewise. (build_evex_prefix): Adjust broadcast processing. (swap_2_operands): Likewise. (check_VecOperations): Likewise. (match_template): Likewise. (check_VecOperands): Likewise. --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -232,22 +232,6 @@ struct RC_Operation static struct RC_Operation rc_op; -/* The struct describes broadcasting, applied to OPERAND. FACTOR is - broadcast factor. */ -struct Broadcast_Operation -{ - /* Type of broadcast: {1to2}, {1to4}, {1to8}, or {1to16}. */ - int type; - - /* Index of broadcasted operand. */ - unsigned int operand; - - /* Number of bytes to broadcast. */ - int bytes; -}; - -static struct Broadcast_Operation broadcast_op; - /* VEX prefix. */ typedef struct { @@ -398,8 +382,21 @@ struct _i386_insn /* Rounding control and SAE attributes. */ struct RC_Operation *rounding; - /* Broadcasting attributes. */ - struct Broadcast_Operation *broadcast; + /* Broadcasting attributes. + + The struct describes broadcasting, applied to OPERAND. TYPE is + expresses the broadcast factor. */ + struct Broadcast_Operation + { + /* Type of broadcast: {1to2}, {1to4}, {1to8}, or {1to16}. */ + unsigned int type; + + /* Index of broadcasted operand. */ + unsigned int operand; + + /* Number of bytes to broadcast. */ + unsigned int bytes; + } broadcast; /* Compressed disp8*N attribute. */ unsigned int memshift; @@ -2211,7 +2208,7 @@ match_mem_size (const insn_template *t, { return (match_operand_size (t, wanted, given) && !((i.types[given].bitfield.unspecified - && !i.broadcast + && !i.broadcast.type && !t->operand_types[wanted].bitfield.unspecified) || (i.types[given].bitfield.fword && !t->operand_types[wanted].bitfield.fword) @@ -3911,9 +3908,9 @@ build_evex_prefix (void) i.tm.opcode_modifier.evex = EVEX128; break; } - else if (i.broadcast && op == i.broadcast->operand) + else if (i.broadcast.type && op == i.broadcast.operand) { - switch (i.broadcast->bytes) + switch (i.broadcast.bytes) { case 64: i.tm.opcode_modifier.evex = EVEX512; @@ -3955,7 +3952,7 @@ build_evex_prefix (void) } i.vex.bytes[3] |= vec_length; /* Encode the broadcast bit. */ - if (i.broadcast) + if (i.broadcast.type) i.vex.bytes[3] |= 0x10; } else @@ -4255,7 +4252,7 @@ optimize_encoding (void) && !i.types[0].bitfield.zmmword && !i.types[1].bitfield.zmmword && !i.mask.reg - && !i.broadcast + && !i.broadcast.type && is_evex_encoding (&i.tm) && ((i.tm.base_opcode & ~Opcode_SIMD_IntD) == 0x6f || (i.tm.base_opcode & ~4) == 0xdb @@ -5472,12 +5469,12 @@ swap_2_operands (unsigned int xchg1, uns else if (i.mask.operand == xchg2) i.mask.operand = xchg1; } - if (i.broadcast) + if (i.broadcast.type) { - if (i.broadcast->operand == xchg1) - i.broadcast->operand = xchg2; - else if (i.broadcast->operand == xchg2) - i.broadcast->operand = xchg1; + if (i.broadcast.operand == xchg1) + i.broadcast.operand = xchg2; + else if (i.broadcast.operand == xchg2) + i.broadcast.operand = xchg1; } if (i.rounding) { @@ -5892,13 +5889,13 @@ check_VecOperands (const insn_template * /* Check if broadcast is supported by the instruction and is applied to the memory operand. */ - if (i.broadcast) + if (i.broadcast.type) { i386_operand_type type, overlap; /* Check if specified broadcast is supported in this instruction, and its broadcast bytes match the memory operand. */ - op = i.broadcast->operand; + op = i.broadcast.operand; if (!t->opcode_modifier.broadcast || !(i.flags[op] & Operand_Mem) || (!i.types[op].bitfield.unspecified @@ -5909,10 +5906,10 @@ check_VecOperands (const insn_template * return 1; } - i.broadcast->bytes = ((1 << (t->opcode_modifier.broadcast - 1)) - * i.broadcast->type); + i.broadcast.bytes = ((1 << (t->opcode_modifier.broadcast - 1)) + * i.broadcast.type); operand_type_set (&type, 0); - switch (i.broadcast->bytes) + switch (i.broadcast.bytes) { case 2: type.bitfield.word = 1; @@ -6066,7 +6063,7 @@ check_VecOperands (const insn_template * if (t->opcode_modifier.disp8memshift && i.disp_encoding != disp_encoding_32bit) { - if (i.broadcast) + if (i.broadcast.type) i.memshift = t->opcode_modifier.broadcast - 1; else if (t->opcode_modifier.disp8memshift != DISP8_SHIFT_VL) i.memshift = t->opcode_modifier.disp8memshift; @@ -6394,8 +6391,8 @@ match_template (char mnem_suffix) if (t->opcode_modifier.checkregsize) { check_register = (1 << t->operands) - 1; - if (i.broadcast) - check_register &= ~(1 << i.broadcast->operand); + if (i.broadcast.type) + check_register &= ~(1 << i.broadcast.operand); } else check_register = 0; @@ -6961,7 +6958,7 @@ process_suffix (void) /* For [XYZ]MMWORD operands inspect operand sizes. While generally also suitable for AT&T syntax mode, it was requested that this be restricted to just Intel syntax. */ - if (intel_syntax && is_any_vex_encoding (&i.tm) && !i.broadcast) + if (intel_syntax && is_any_vex_encoding (&i.tm) && !i.broadcast.type) { unsigned int op; @@ -10391,9 +10388,9 @@ check_VecOperations (char *op_string, ch /* Check broadcasts. */ if (strncmp (op_string, "1to", 3) == 0) { - int bcst_type; + unsigned int bcst_type; - if (i.broadcast) + if (i.broadcast.type) goto duplicated_vec_op; op_string += 3; @@ -10416,10 +10413,8 @@ check_VecOperations (char *op_string, ch } op_string++; - broadcast_op.type = bcst_type; - broadcast_op.operand = this_operand; - broadcast_op.bytes = 0; - i.broadcast = &broadcast_op; + i.broadcast.type = bcst_type; + i.broadcast.operand = this_operand; } /* Check masking operation. */ else if ((mask = parse_register (op_string, &end_op)) != NULL)