From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-vi1eur04on2054.outbound.protection.outlook.com [40.107.8.54]) by sourceware.org (Postfix) with ESMTPS id CF186384F021 for ; Fri, 10 Mar 2023 10:23:44 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CF186384F021 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-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Y4mOFnN4Ag+Txii0PwcVpIS069MV1c2R2QdWKSGeg3QncPwn8BRY6tZpnTUhp4GuF+EyAaUl6rPE2ZBWKT6afil6emZYPPaZ737UJQO9u8n67/+yxYOj/yONnSyD+LNsV+R/REVnmWMYwok84VRURMHa5dT6ylKW5Vb/aGfk2tpviHI58TSbCZpxQ4bUI0rO1IoDFJlpOdGQ0ORvdlexd/Yw0mnWH5Z+xejeOIKna8ezBrzFhUBfNSMu3SQYvvZkMgSjbfJkd/ZyKGK7nToQH2D+EiTZH01kkr0Frykxr4KMNkT99582Qzz+VHMByM8Oa8wTtwUhUAzjhysWTv/Zsw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=imOF/IHEj1KkJqHWluFINQYkVqWkjfjKsTOr+44/9vI=; b=aHjXm2TMn1yw8hgrcqJxMutzuRICwwpRTLgO/u6mht4RFZN0cXFFSSuhxNRi+Moc5xp9SBr2CHStPtwSWc3gBPS5NQYB7fHnPcfm5wy/ZaHEw4uvzy2sbzqB/eJI2C4vPEU+/xNT6qefPtj/aUhcxI34h2Qrw7huEp2ns0Q4MpTjImV3WyslhaYZXdcgagJ4Fjlb+sBfqXcHGbSwggPxXm79xGIcDlrEBVek/m9EcGOu6mg/mgZs+TJ7mu8sOC22ROBCoBb5pezva7pt9ltWdXlKqcAk/BhfI7io+gVvpj7cH8wBF5p5l9EYLjLOwnlWAfG/cCNHkGewCSUakneZXw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=imOF/IHEj1KkJqHWluFINQYkVqWkjfjKsTOr+44/9vI=; b=4I7XtPUuw7DBaZTWmUil0jUkgzycxPSEyT8VKHg6GnrX/M8VoObtDV511V0KEoQ4Qlo48RDGXpckZ6Oo6MRFBZHFGUWJdnf6PDTZyZuxZudv9RqFmGP18YaAzm07rsxwDK31lVRps1BYVwl78v/6q06bq96fMDRUZxNnsVKN8I5vsXeESLLE+q6fzHb6tRk1hyEHVMBuyRBcNz8xHLtHK9PzurQLEz4yc9FcgImImfcL+UZFlK4ngZ/8uhYpjwsOZ5ICDn89QwouDnKsBqN8DVxRo1qNLi+LB1435W4tDxUyijDQvBhCLCb35XdXuPkH8O/P9Ruv4YfoBRHClzc1AQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com; Received: from VE1PR04MB6560.eurprd04.prod.outlook.com (2603:10a6:803:122::25) by DB9PR04MB9819.eurprd04.prod.outlook.com (2603:10a6:10:4c0::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.19; Fri, 10 Mar 2023 10:23:42 +0000 Received: from VE1PR04MB6560.eurprd04.prod.outlook.com ([fe80::154e:166d:ec25:531b]) by VE1PR04MB6560.eurprd04.prod.outlook.com ([fe80::154e:166d:ec25:531b%5]) with mapi id 15.20.6178.019; Fri, 10 Mar 2023 10:23:42 +0000 Message-ID: <8d917f97-af55-11f3-a9f8-d5a209725336@suse.com> Date: Fri, 10 Mar 2023 11:23:40 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.8.0 Subject: [PATCH v2 08/14] x86: process instruction operands for .insn Content-Language: en-US To: Binutils Cc: "H.J. Lu" , "Jiang, Haochen" References: From: Jan Beulich In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-ClientProxiedBy: FR2P281CA0099.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:9c::9) To VE1PR04MB6560.eurprd04.prod.outlook.com (2603:10a6:803:122::25) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VE1PR04MB6560:EE_|DB9PR04MB9819:EE_ X-MS-Office365-Filtering-Correlation-Id: 2923ba69-ad92-493d-51f1-08db215185b3 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Iyd7Z5KbY/o1YI8XZxcTO0cPZFkqC4jqpmS0avk41itfM97gP0So8IpQgVESLesjovWwyHrESjcotfYDH65l+225SH+Y1qYyl/DTm+pW3buRhGgAFmGKhFtFOLTvuPx7g/3Ncd7Ze6c6fV0tbum5GnwBNsfg7cCsX/4m9WDoX92+4ToedwSQM5uLED/2Hc4X99E7F0xbB5vrofpMiX+aRlIYA8qZjCywOpdZHair1pu96fJwYqFia/44M5u+FQudiTJk0xKpdn3+jV2gYAiM1hFpGY3kiMkh15uZllf1JCPRxLm6X2ShoSawral3guK6SF+IiUwcZEzAnY8DUeKLItx+xaNS/JmfO9nUWUY3lQ0p9ie47+alR/tMNCyoJvQ6QrehaxBLiHrQ9MAibsUT4PyMStnx8RIVqvEbOZjer0Z4vs4IS5jyYTowq/BYNb+XlCLbGLTFZF3HvBG9h774fS0QTBzuGVnDZbY/GtD0sL+LL7mahMBONnsGen6AzUWT3Wv5kAFlzWLq+3zEPzHGTKoEs2YV4H5amV9UEfah7Ew6eBbyMAbPkPsy2gyHhS5tS5IKfZ5MZEn3zElS7nKrtm78Dit0f9L1TAwDCe7bnBs/CoAeDOkXaWFTM49oKzrWeeM2pyaAbURwTSl9qnyicMhIsXdjqBhtBaXzOjt9pt+AeUwICOp9+XEAcRFfPMlF7m3LsWmQxVsy+ID1J4NWALoii09mA2BHkiXp/fe6NGkOMILColf6FWF90R3uja9D X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:VE1PR04MB6560.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230025)(396003)(39860400002)(136003)(346002)(376002)(366004)(451199018)(36756003)(5660300002)(30864003)(83380400001)(26005)(186003)(6486002)(6506007)(6512007)(2616005)(66946007)(478600001)(316002)(4326008)(6916009)(8676002)(66556008)(8936002)(41300700001)(31696002)(86362001)(66476007)(54906003)(38100700002)(2906002)(66899018)(31686004)(142923001)(45980500001)(43740500002);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?RjluTElScVlPQ0RqN1RtUU1UeUZVV0RjV1FPdlVxWEJwR0JpNmdDRFdsbGc5?= =?utf-8?B?YUZrOEMrT1QrNnNiQ3hQbkg3SHJMZ3k0M2lCVmUrd1libEhyVVZ1eXBIVDVv?= =?utf-8?B?TlNwdHBTUFhjc2UrNTRKOEIyRU9EMWNrS1VlNzNwSHlJdTF0aUlKTzhSRWt6?= =?utf-8?B?WStWcHMwVm1pb0t1dUd3REg0dG9ZOG9EQmU2Q1dMWW5ZYy9ZdG03STBSNlpS?= =?utf-8?B?cnAyWm9JU3BoeEtKbkhySmV6dEN4cVRaR2FBaUFDRGV3bXJYQm5HNHVHV3VB?= =?utf-8?B?OUpXb1FyZEhwRXhrMktoS3YyK0hkckprakx4Sno0Ym1HRGNEWmZyYksvZXQ1?= =?utf-8?B?M081N1drZ0NZZUhmNkhvS29IRTJWclVtOFVzb2M1b2xnSldwOHp1U1lNMGww?= =?utf-8?B?MWRZL3NsL0xSZ2VKN0VUSFRhVm9zcTloeVJjdGY2ZzVweUV1UFV2d1owYnBt?= =?utf-8?B?WjBlQ1hoZUV1NnlkdzZCcFVnc1RSc1pFa1FCZW91OWpOZlRtdU8wZUliWWt0?= =?utf-8?B?NFVpZlY2RmFGYlpWWHRKRGYzQ0VSZ1RqRnl5L05XOEdDdFgwd3pmVTBZMHQ0?= =?utf-8?B?ejVlbUhtVXVoazhGTFZsd1JhVzNsSjlRYjhzbkxONnhkeko0NjFIaGFodnZR?= =?utf-8?B?c0NBSlVsZ0NVOFVDTkFqeGJsUThIbGh2ZkQ5VWVSQW80ZVdzcFBRbUpDVW8x?= =?utf-8?B?dDhDT2JzVmo5UUtpNUNrKzNRZWt2aVRvbHd6VlRoUnBjamU0c0pDYkgrVFNq?= =?utf-8?B?cjQvSGFpb3JmVUJXV1NWYXl6bnhpcFhuL1Mzait5Z3R2ZWVuQVk0QnZhUTZV?= =?utf-8?B?dXRzblZ5anFFWWFSRXUvMEZjZnVWcGUzS1UwMHBtQXJkVUlFUEVEeVRMMzBi?= =?utf-8?B?dW5rNVpYQlN3R0NoblMwWnRGOTY0bGxFMnJDdkhtSkNRQ2pWY3BNVzZPdVNo?= =?utf-8?B?ei82RTMwaFpndTV0c0FtK1RuYkFzNmlYREpjdW9od25wcElJNnJwS3BPdy9u?= =?utf-8?B?VkJKaGt4ZWlXOElFbXlpS2V1OGsyd0orUmcwblEveTI0SVYwRXZ1dWloQ2Ni?= =?utf-8?B?K2tXdWFXZkZiY3dUaWV4K2M3M045dnpubTBxYU85QWszd0J3WmtSRGRCZWtQ?= =?utf-8?B?TjZhVUliNUVlcmh0VUNNYUZPL3hJcEtNcFA2WGpSeHFRY0xzd2I0UlU3YUlZ?= =?utf-8?B?RGRid2NNMFdqZm9CM1NTbTVDYWJ1cE9HQ3lPSUpVUHdLa0loZ0p3MTl2TTdS?= =?utf-8?B?Q2E5ZytHMTZvK1NpYUExUHZZbm5NUVFDYTBIbitvOUlRZjFMQm5Lanl6VUFj?= =?utf-8?B?YmZwYTFBcE8vcGZaaXpLOTlGazdLTGJwcWJhNDIzRzZNNFR6dUs2cmVRNnpK?= =?utf-8?B?TTNFd2dQZDhMZ1Fxb2xKaXVNMHVHalFvT05VUmRLMnlHLzFoOXFjcC9lNTFq?= =?utf-8?B?U3c1eEp3NUtOWmY4WnRDdldkRWErRVJMU1MxelpacmRFQmJTWjNqUVZFK2R5?= =?utf-8?B?TWpHZ0hWRzhvMG4yb0dYdUx4VEthMVk0dTNpZ3oza3RLYU1FR2swL1YzdWcy?= =?utf-8?B?VERMRkttMkdBWmFnZW1FNU1qSEczZFd3WllzS2x2Y1lXSVlkME5hbW4vajJK?= =?utf-8?B?YTdYdFlmTkJVU282RW5jODNmTzlHSnF1NDNva1NKdjZ0SzBBeXVySlJLRVpK?= =?utf-8?B?MVBUc2xWZ3NENkRiZFRCVE9jRldTTndodWZUdHl2ZWNLZmo0M2FLdzZOQU82?= =?utf-8?B?SFJoTHB1QWFJeTRZblVlcnZZbjhrUjh1TU5WZE5iMDlYUmJScCsrKy9qZnFT?= =?utf-8?B?SzNsYzZoT3JRbURqN2praFoyWEh1cTRTc3Y1T09oWHlNOEQyUEoyVklMZlRU?= =?utf-8?B?ejJxREIxSitYTTF2WXhPZWczM3VNVUorVmFlVTBLRCsvOVQ1NmZGYzErdm9G?= =?utf-8?B?WElBekJFVE5rMTdGZE92M0szai94Vk0vOHB0UjE3VitaRXFGNlQxdG9ZNUZQ?= =?utf-8?B?dWZzOCtwVHVITnczQzgxaE1zUXdwWEFPNFpIeXplcm5CN012M1dGN056QVp2?= =?utf-8?B?SXk1Ry9aRldydnUwVUhLeEVhd2RJNGEvNVFEbVE1K3FZY1lpVHFzYTlKM25i?= =?utf-8?Q?ryUuOB4SPNBtNDVqDlmpTVxG1?= X-OriginatorOrg: suse.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2923ba69-ad92-493d-51f1-08db215185b3 X-MS-Exchange-CrossTenant-AuthSource: VE1PR04MB6560.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Mar 2023 10:23:42.4902 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f7a17af6-1c5c-4a36-aa8b-f5be247aa4ba X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: IFQtOAwxG6P8FHZnyfREd9DvgBW4CnodRjkeVk8Fn+/rQOBYo5Z8nDbgeFSmczWVgRugR2JAWGiAE+VYq9lrdw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR04MB9819 X-Spam-Status: No, score=-3028.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Deal with register and memory operands; immediate operands will follow later, as will the handling of EVEX embedded broadcast and EVEX Disp8 scaling. Note that because we can't really know how to encode their use, %cr8 and up cannot be used with .insn outside of 64-bit mode. Users would need to specify an explicit LOCK prefix in combination with %cr0 etc. --- I'm not convinced the assertions early in build_modrm_byte() are useful to retain. --- v2: Re-base over patch which was pulled ahead. --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -2356,7 +2356,8 @@ fits_in_disp8 (offsetT num) static INLINE int fits_in_imm4 (offsetT num) { - return (num & 0xf) == num; + /* Despite the name, check for imm3 if we're dealing with EVEX. */ + return (num & (i.vec_encoding != vex_encoding_evex ? 0xf : 7)) == num; } static i386_operand_type @@ -8228,7 +8229,7 @@ process_operands (void) } } } - else if (i.types[0].bitfield.class == SReg) + else if (i.types[0].bitfield.class == SReg && !dot_insn ()) { if (flag_code != CODE_64BIT ? i.tm.base_opcode == POP_SEG_SHORT @@ -8261,15 +8262,32 @@ process_operands (void) } else if (i.short_form) { - /* The register operand is in operand 0 or 1. */ - const reg_entry *r = i.op[0].regs; + /* The register operand is in the 1st or 2nd non-immediate operand. */ + const reg_entry *r = i.op[i.imm_operands].regs; - if (i.imm_operands - || (r->reg_type.bitfield.instance == Accum && i.op[1].regs)) - r = i.op[1].regs; + if (!dot_insn () + && r->reg_type.bitfield.instance == Accum + && i.op[i.imm_operands + 1].regs) + r = i.op[i.imm_operands + 1].regs; /* Register goes in low 3 bits of opcode. */ i.tm.base_opcode |= r->reg_num; set_rex_vrex (r, REX_B, false); + + if (dot_insn () && i.reg_operands == 2) + { + gas_assert (is_any_vex_encoding (&i.tm) + || i.vec_encoding != vex_encoding_default); + i.vex.register_specifier = i.op[i.operands - 1].regs; + } + } + else if (i.reg_operands == 1 + && !i.flags[i.operands - 1] + && i.tm.operand_types[i.operands - 1].bitfield.instance + == InstanceNone) + { + gas_assert (is_any_vex_encoding (&i.tm) + || i.vec_encoding != vex_encoding_default); + i.vex.register_specifier = i.op[i.operands - 1].regs; } if ((i.seg[0] || i.prefix[SEG_PREFIX]) @@ -8330,10 +8348,12 @@ build_modrm_byte (void) VexW0 or VexW1. The destination must be either XMM, YMM or ZMM register. 2. 4 operands: 4 register operands or 3 register operands - plus 1 memory operand, with VexXDS. */ + plus 1 memory operand, with VexXDS. + 3. Other equivalent combinations when coming from s_insn(). */ gas_assert (i.tm.opcode_modifier.vexvvvv - && i.tm.opcode_modifier.vexw - && i.tm.operand_types[dest].bitfield.class == RegSIMD); + && i.tm.opcode_modifier.vexw); + gas_assert (dot_insn () + || i.tm.operand_types[dest].bitfield.class == RegSIMD); /* Of the first two non-immediate operands the one with the template not allowing for a memory one is encoded in the immediate operand. */ @@ -8342,6 +8362,14 @@ build_modrm_byte (void) else reg_slot = source++; + if (!dot_insn ()) + { + gas_assert (i.tm.operand_types[reg_slot].bitfield.class == RegSIMD); + gas_assert (!(i.op[reg_slot].regs->reg_flags & RegVRex)); + } + else + gas_assert (i.tm.operand_types[reg_slot].bitfield.class != ClassNone); + if (i.imm_operands == 0) { /* When there is no immediate operand, generate an 8bit @@ -8351,10 +8379,7 @@ build_modrm_byte (void) i.types[i.operands].bitfield.imm8 = 1; i.operands++; - gas_assert (i.tm.operand_types[reg_slot].bitfield.class == RegSIMD); exp->X_op = O_constant; - exp->X_add_number = register_number (i.op[reg_slot].regs) << 4; - gas_assert ((i.op[reg_slot].regs->reg_flags & RegVRex) == 0); } else { @@ -8365,11 +8390,11 @@ build_modrm_byte (void) /* Turn on Imm8 again so that output_imm will generate it. */ i.types[0].bitfield.imm8 = 1; - gas_assert (i.tm.operand_types[reg_slot].bitfield.class == RegSIMD); - i.op[0].imms->X_add_number - |= register_number (i.op[reg_slot].regs) << 4; - gas_assert ((i.op[reg_slot].regs->reg_flags & RegVRex) == 0); + exp = i.op[0].imms; } + exp->X_add_number |= register_number (i.op[reg_slot].regs) + << (3 + !(is_evex_encoding (&i.tm) + || i.vec_encoding == vex_encoding_evex)); } for (v = source + 1; v < dest; ++v) @@ -10634,6 +10659,9 @@ s_insn (int dummy ATTRIBUTE_UNUSED) goto bad; } + if (line > end && i.vec_encoding == vex_encoding_default) + i.vec_encoding = evex ? vex_encoding_evex : vex_encoding_vex; + if (line > end && *line == '.') { /* Length specifier (VEX.L, XOP.L, EVEX.L'L). */ @@ -10913,7 +10941,244 @@ s_insn (int dummy ATTRIBUTE_UNUSED) goto bad; } i.opcode_length = j; - i.tm.base_opcode = val; + + /* Handle operands, if any. */ + if (*line == ',') + { + i386_operand_type combined; + bool changed; + + ptr = parse_operands (line + 1, &i386_mnemonics[MN__insn]); + this_operand = -1; + if (!ptr) + goto bad; + line = ptr; + + if (!i.operands) + { + as_bad (_("expecting operand after ','; got nothing")); + goto done; + } + + if (i.mem_operands > 1) + { + as_bad (_("too many memory references for `%s'"), + &i386_mnemonics[MN__insn]); + goto done; + } + + /* Are we to emit ModR/M encoding? */ + if (!i.short_form + && (i.mem_operands + || i.reg_operands > (i.vec_encoding != vex_encoding_default) + || i.tm.extension_opcode != None)) + i.tm.opcode_modifier.modrm = 1; + + if (!i.tm.opcode_modifier.modrm + && (i.reg_operands + > i.short_form + 0U + (i.vec_encoding != vex_encoding_default) + || i.mem_operands)) + { + as_bad (_("too many register/memory operands")); + goto done; + } + + /* Enforce certain constraints on operands. */ + switch (i.reg_operands + i.mem_operands + + (i.tm.extension_opcode != None)) + { + case 0: + if (i.short_form) + { + as_bad (_("too few register/memory operands")); + goto done; + } + /* Fall through. */ + case 1: + if (i.tm.opcode_modifier.modrm) + { + as_bad (_("too few register/memory operands")); + goto done; + } + break; + + case 2: + break; + + case 4: + if (i.imm_operands + && (i.op[0].imms->X_op != O_constant + || !fits_in_imm4 (i.op[0].imms->X_add_number))) + { + as_bad (_("constant doesn't fit in %d bits"), evex ? 3 : 4); + goto done; + } + /* Fall through. */ + case 3: + if (i.vec_encoding != vex_encoding_default) + { + i.tm.opcode_modifier.vexvvvv = 1; + break; + } + /* Fall through. */ + default: + as_bad (_("too many register/memory operands")); + goto done; + } + + /* Bring operands into canonical order (imm, mem, reg). */ + do + { + changed = false; + + for (j = 1; j < i.operands; ++j) + { + if ((!operand_type_check (i.types[j - 1], imm) + && operand_type_check (i.types[j], imm)) + || (i.types[j - 1].bitfield.class != ClassNone + && i.types[j].bitfield.class == ClassNone)) + { + swap_2_operands (j - 1, j); + changed = true; + } + } + } + while (changed); + + /* For Intel syntax swap the order of register operands. */ + if (intel_syntax) + switch (i.reg_operands) + { + case 0: + case 1: + break; + + case 4: + swap_2_operands (i.imm_operands + i.mem_operands + 1, i.operands - 2); + /* Fall through. */ + case 3: + case 2: + swap_2_operands (i.imm_operands + i.mem_operands, i.operands - 1); + break; + + default: + abort (); + } + + /* Enforce constraints when using VSIB. */ + if (i.index_reg + && (i.index_reg->reg_type.bitfield.xmmword + || i.index_reg->reg_type.bitfield.ymmword + || i.index_reg->reg_type.bitfield.zmmword)) + { + if (i.vec_encoding == vex_encoding_default) + { + as_bad (_("VSIB unavailable with legacy encoding")); + goto done; + } + + if (i.vec_encoding == vex_encoding_evex + && i.reg_operands > 1) + { + /* We could allow two register operands, encoding the 2nd one in + an 8-bit immediate like for 4-register-operand insns, but that + would require ugly fiddling with process_operands() and/or + build_modrm_byte(). */ + as_bad (_("too many register operands with VSIB")); + goto done; + } + + i.tm.opcode_modifier.sib = 1; + } + + /* Establish operand size encoding. */ + operand_type_set (&combined, 0); + for (j = i.imm_operands; j < i.operands; ++j) + { + i.types[j].bitfield.instance = InstanceNone; + + if (operand_type_check (i.types[j], disp)) + i.types[j].bitfield.baseindex = 1; + + if ((i.broadcast.type || i.broadcast.bytes) + && j == i.broadcast.operand) + continue; + + combined = operand_type_or (combined, i.types[j]); + combined.bitfield.class = ClassNone; + } + + if (i.vec_encoding == vex_encoding_default) + { + if (flag_code == CODE_64BIT && combined.bitfield.qword) + i.rex |= REX_W; + else if ((flag_code == CODE_16BIT ? combined.bitfield.dword + : combined.bitfield.word) + && !add_prefix (DATA_PREFIX_OPCODE)) + goto done; + } + else if (!i.tm.opcode_modifier.vexw) + { + if (flag_code == CODE_64BIT) + { + if (combined.bitfield.qword) + i.tm.opcode_modifier.vexw = VEXW1; + else if (combined.bitfield.dword) + i.tm.opcode_modifier.vexw = VEXW0; + } + + if (!i.tm.opcode_modifier.vexw) + i.tm.opcode_modifier.vexw = VEXWIG; + } + + if (vex || xop) + { + if (!i.tm.opcode_modifier.vex) + { + if (combined.bitfield.ymmword) + i.tm.opcode_modifier.vex = VEX256; + else if (combined.bitfield.xmmword) + i.tm.opcode_modifier.vex = VEX128; + } + } + else if (evex) + { + if (!i.tm.opcode_modifier.evex) + { + /* Do _not_ consider AVX512VL here. */ + if (i.rounding.type != rc_none || combined.bitfield.zmmword) + i.tm.opcode_modifier.evex = EVEX512; + else if (combined.bitfield.ymmword) + i.tm.opcode_modifier.evex = EVEX256; + else if (combined.bitfield.xmmword) + i.tm.opcode_modifier.evex = EVEX128; + } + } + + if (i.disp_operands && !optimize_disp (&i.tm)) + goto done; + + for (j = 0; j < i.operands; ++j) + i.tm.operand_types[j] = i.types[j]; + + process_operands (); + } + + /* Don't set opcode until after processing operands, to avoid any + potential special casing there. */ + i.tm.base_opcode |= val; + + if (i.vec_encoding == vex_encoding_error + || (i.vec_encoding != vex_encoding_evex + ? i.broadcast.type || i.broadcast.bytes + || i.rounding.type != rc_none + || i.mask.reg + : (i.broadcast.type || i.broadcast.bytes) + && i.rounding.type != rc_none)) + { + as_bad (_("conflicting .insn operands")); + goto done; + } if (vex || xop) { @@ -10931,6 +11196,8 @@ s_insn (int dummy ATTRIBUTE_UNUSED) build_evex_prefix (); i.rex &= REX_OPCODE; } + else if (i.rex != 0) + add_prefix (REX_OPCODE | i.rex); output_insn (); @@ -11899,6 +12166,15 @@ i386_att_operand (char *operand_string) as_bad (_("junk `%s' after register"), op_string); return 0; } + + /* Reject pseudo registers for .insn. */ + if (dot_insn () && r->reg_type.bitfield.class == ClassNone) + { + as_bad (_("`%s%s' cannot be used here"), + register_prefix, r->reg_name); + return 0; + } + temp = r->reg_type; temp.bitfield.baseindex = 0; i.types[this_operand] = operand_type_or (i.types[this_operand], @@ -13274,7 +13550,9 @@ static bool check_register (const reg_en } if (((r->reg_flags & (RegRex64 | RegRex)) || r->reg_type.bitfield.qword) - && (!cpu_arch_flags.bitfield.cpulm || r->reg_type.bitfield.class != RegCR) + && (!cpu_arch_flags.bitfield.cpulm + || r->reg_type.bitfield.class != RegCR + || dot_insn ()) && flag_code != CODE_64BIT) return false; --- a/gas/config/tc-i386-intel.c +++ b/gas/config/tc-i386-intel.c @@ -320,8 +320,10 @@ i386_intel_simplify_register (expression as_bad (_("invalid use of register")); return 0; } - if (i386_regtab[reg_num].reg_type.bitfield.class == SReg - && i386_regtab[reg_num].reg_num == RegFlat) + if ((i386_regtab[reg_num].reg_type.bitfield.class == SReg + && i386_regtab[reg_num].reg_num == RegFlat) + || (dot_insn () + && i386_regtab[reg_num].reg_type.bitfield.class == ClassNone)) { as_bad (_("invalid use of pseudo-register")); return 0; @@ -342,6 +344,7 @@ i386_intel_simplify_register (expression if (intel_state.in_scale || i386_regtab[reg_num].reg_type.bitfield.baseindex + || dot_insn () || t->mnem_off == MN_bndmk || t->mnem_off == MN_bndldx || t->mnem_off == MN_bndstx) --- a/gas/testsuite/gas/i386/insn-32.d +++ b/gas/testsuite/gas/i386/insn-32.d @@ -11,6 +11,24 @@ Disassembly of section .text: [ ]*[a-f0-9]+: f3 90[ ]+pause [ ]*[a-f0-9]+: d9 ee[ ]+fldz [ ]*[a-f0-9]+: f3 0f 01 e8[ ]+setssbsy +[ ]*[a-f0-9]+: 8b c1[ ]+mov %ecx,%eax +[ ]*[a-f0-9]+: 66 8b c8[ ]+mov %ax,%cx +[ ]*[a-f0-9]+: 89 48 04[ ]+mov %ecx,0x4\(%eax\) +[ ]*[a-f0-9]+: 8b 0c 05 44 44 00 00[ ]+mov 0x4444\(,%eax,1\),%ecx +[ ]*[a-f0-9]+: 66 0f b6 cc[ ]+movzbw %ah,%cx +[ ]*[a-f0-9]+: 0f b7 c8[ ]+movzwl %ax,%ecx +[ ]*[a-f0-9]+: 0f ca[ ]+bswap %edx [ ]*[a-f0-9]+: c5 fc 77[ ]+vzeroall [ ]*[a-f0-9]+: c4 e1 7c 77[ ]+vzeroall +[ ]*[a-f0-9]+: c5 f1 58 d0[ ]+vaddpd %xmm0,%xmm1,%xmm2 +[ ]*[a-f0-9]+: c5 f5 58 d0[ ]+vaddpd %ymm0,%ymm1,%ymm2 +[ ]*[a-f0-9]+: c5 f2 58 d0[ ]+vaddss %xmm0,%xmm1,%xmm2 +[ ]*[a-f0-9]+: c4 e3 69 68 19 00[ ]+vfmaddps %xmm0,\(%ecx\),%xmm2,%xmm3 +[ ]*[a-f0-9]+: c4 e3 e9 68 19 00[ ]+vfmaddps \(%ecx\),%xmm0,%xmm2,%xmm3 +[ ]*[a-f0-9]+: c4 e3 e9 68 18 10[ ]+vfmaddps \(%eax\),%xmm1,%xmm2,%xmm3 +[ ]*[a-f0-9]+: c5 f8 92 c8[ ]+kmovw %eax,%k1 +[ ]*[a-f0-9]+: c5 f8 93 c1[ ]+kmovw %k1,%eax +[ ]*[a-f0-9]+: 62 f1 74 18 58 d0[ ]+vaddps \{rn-sae\},%zmm0,%zmm1,%zmm2 +[ ]*[a-f0-9]+: c4 e2 79 92 1c 48[ ]+vgatherdps %xmm0,\(%eax,%xmm1,2\),%xmm3 +[ ]*[a-f0-9]+: 62 f2 fd 0c 93 1c 48[ ]+vgatherqpd \(%eax,%xmm1,2\),%xmm3\{%k4\} #pass --- a/gas/testsuite/gas/i386/insn-32.s +++ b/gas/testsuite/gas/i386/insn-32.s @@ -13,6 +13,42 @@ insn: # setssbsy .insn 0xf30f01e8 + # mov + .insn 0x8b, %ecx, %eax + .insn 0x8b, %ax, %cx + .insn 0x89, %ecx, 4(%eax) + .insn 0x8b, 0x4444(,%eax), %ecx + + # movzx + .insn 0x0fb6, %ah, %cx + .insn 0x0fb7, %eax, %ecx + + # bswap + .insn 0x0fc8+r, %edx + # vzeroall .insn VEX.256.0F.WIG 0x77 .insn {vex3} VEX.L1 0x0f77 + + # vaddpd + .insn VEX.66.0F 0x58, %xmm0, %xmm1, %xmm2 + .insn VEX.66 0x0f58, %ymm0, %ymm1, %ymm2 + + # vaddss + .insn VEX.LIG.F3.0F 0x58, %xmm0, %xmm1, %xmm2 + + # vfmaddps + .insn VEX.66.0F3A.W0 0x68, %xmm0, (%ecx), %xmm2, %xmm3 + .insn VEX.66.0F3A.W1 0x68, %xmm0, (%ecx), %xmm2, %xmm3 + .insn VEX.66.0F3A.W1 0x68, (%eax), %xmm1, %xmm2, %xmm3 + + # kmovw + .insn VEX.L0.0F.W0 0x92, %eax, %k1 + .insn VEX.L0.0F.W0 0x93, %k1, %eax + + # vaddps + .insn EVEX.NP.0F.W0 0x58, {rn-sae}, %zmm0, %zmm1, %zmm2 + + # vgather... + .insn VEX.66.0f38.W0 0x92, %xmm0, (%eax, %xmm1, 2), %xmm3 + .insn EVEX.66.0f38.W1 0x93, (%eax, %xmm1, 2), %xmm3{%k4} --- a/gas/testsuite/gas/i386/insn-64.d +++ b/gas/testsuite/gas/i386/insn-64.d @@ -11,6 +11,35 @@ Disassembly of section .text: [ ]*[a-f0-9]+: f3 90[ ]+pause [ ]*[a-f0-9]+: d9 ee[ ]+fldz [ ]*[a-f0-9]+: f3 0f 01 e8[ ]+setssbsy +[ ]*[a-f0-9]+: 44 8b c1[ ]+mov %ecx,%r8d +[ ]*[a-f0-9]+: 48 8b c8[ ]+mov %rax,%rcx +[ ]*[a-f0-9]+: 41 89 48 08[ ]+mov %ecx,0x8\(%r8\) +[ ]*[a-f0-9]+: 42 8b 0c 05 80 80 00 00[ ]+mov 0x8080\(,%r8,1\),%ecx +[ ]*[a-f0-9]+: 66 0f be cc[ ]+movsbw %ah,%cx +[ ]*[a-f0-9]+: 0f bf c8[ ]+movswl %ax,%ecx +[ ]*[a-f0-9]+: 48 63 c8[ ]+movslq %eax,%rcx +[ ]*[a-f0-9]+: 48 0f ca[ ]+bswap %rdx +[ ]*[a-f0-9]+: 41 0f c8[ ]+bswap %r8d [ ]*[a-f0-9]+: c5 fc 77[ ]+vzeroall [ ]*[a-f0-9]+: c4 e1 7c 77[ ]+vzeroall +[ ]*[a-f0-9]+: c4 c1 71 58 d0[ ]+vaddpd %xmm8,%xmm1,%xmm2 +[ ]*[a-f0-9]+: c5 b5 58 d0[ ]+vaddpd %ymm0,%ymm9,%ymm2 +[ ]*[a-f0-9]+: c5 72 58 d0[ ]+vaddss %xmm0,%xmm1,%xmm10 +[ ]*[a-f0-9]+: c4 e3 69 68 19 80[ ]+vfmaddps %xmm8,\(%rcx\),%xmm2,%xmm3 +[ ]*[a-f0-9]+: 67 c4 e3 e9 68 19 00[ ]+vfmaddps \(%ecx\),%xmm0,%xmm2,%xmm3 +[ ]*[a-f0-9]+: c4 c3 e9 68 18 10[ ]+vfmaddps \(%r8\),%xmm1,%xmm2,%xmm3 +[ ]*[a-f0-9]+: c4 c1 78 92 c8[ ]+kmovw %r8d,%k1 +[ ]*[a-f0-9]+: c5 78 93 c1[ ]+kmovw %k1,%r8d +[ ]*[a-f0-9]+: 62 b1 74 38 58 d0[ ]+vaddps \{rd-sae\},%zmm16,%zmm1,%zmm2 +[ ]*[a-f0-9]+: 62 f1 74 10 58 d0[ ]+vaddps \{rn-sae\},%zmm0,%zmm17,%zmm2 +[ ]*[a-f0-9]+: 62 e1 74 58 58 d0[ ]+vaddps \{ru-sae\},%zmm0,%zmm1,%zmm18 +[ ]*[a-f0-9]+: c4 e2 39 92 1c 48[ ]+vgatherdps %xmm8,\(%rax,%xmm1,2\),%xmm3 +[ ]*[a-f0-9]+: c4 c2 79 92 1c 48[ ]+vgatherdps %xmm0,\(%r8,%xmm1,2\),%xmm3 +[ ]*[a-f0-9]+: c4 a2 79 92 1c 48[ ]+vgatherdps %xmm0,\(%rax,%xmm9,2\),%xmm3 +[ ]*[a-f0-9]+: c4 62 79 92 1c 48[ ]+vgatherdps %xmm0,\(%rax,%xmm1,2\),%xmm11 +[ ]*[a-f0-9]+: 62 d2 fd 0c 93 1c 48[ ]+vgatherqpd \(%r8,%xmm1,2\),%xmm3\{%k4\} +[ ]*[a-f0-9]+: 62 b2 fd 0c 93 1c 48[ ]+vgatherqpd \(%rax,%xmm9,2\),%xmm3\{%k4\} +[ ]*[a-f0-9]+: 62 f2 fd 04 93 1c 48[ ]+vgatherqpd \(%rax,%xmm17,2\),%xmm3\{%k4\} +[ ]*[a-f0-9]+: 62 72 fd 0c 93 1c 48[ ]+vgatherqpd \(%rax,%xmm1,2\),%xmm11\{%k4\} +[ ]*[a-f0-9]+: 62 e2 fd 0c 93 1c 48[ ]+vgatherqpd \(%rax,%xmm1,2\),%xmm19\{%k4\} #pass --- a/gas/testsuite/gas/i386/insn-64.s +++ b/gas/testsuite/gas/i386/insn-64.s @@ -13,6 +13,53 @@ insn: # setssbsy .insn 0xf30f01e8 + # mov + .insn 0x8b, %ecx, %r8d + .insn 0x8b, %rax, %rcx + .insn 0x89, %ecx, 8(%r8) + .insn 0x8b, 0x8080(,%r8), %ecx + + # movsx + .insn 0x0fbe, %ah, %cx + .insn 0x0fbf, %eax, %ecx + .insn 0x63, %rax, %rcx + + # bswap + .insn 0x0fc8+r, %rdx + .insn 0x0fc8+r, %r8d + # vzeroall .insn VEX.256.0F.WIG 0x77 .insn {vex3} VEX.L1 0x0f77 + + # vaddpd + .insn VEX.66.0F 0x58, %xmm8, %xmm1, %xmm2 + .insn VEX.66 0x0f58, %ymm0, %ymm9, %ymm2 + + # vaddss + .insn VEX.LIG.F3.0F 0x58, %xmm0, %xmm1, %xmm10 + + # vfmaddps + .insn VEX.66.0F3A.W0 0x68, %xmm8, (%rcx), %xmm2, %xmm3 + .insn VEX.66.0F3A.W1 0x68, %xmm0, (%ecx), %xmm2, %xmm3 + .insn VEX.66.0F3A.W1 0x68, (%r8), %xmm1, %xmm2, %xmm3 + + # kmovw + .insn VEX.L0.0F.W0 0x92, %r8d, %k1 + .insn VEX.L0.0F.W0 0x93, %k1, %r8d + + # vaddps + .insn EVEX.NP.0F.W0 0x58, {rd-sae}, %zmm16, %zmm1, %zmm2 + .insn EVEX.NP.0F.W0 0x58, {rn-sae}, %zmm0, %zmm17, %zmm2 + .insn EVEX.NP.0F.W0 0x58, {ru-sae}, %zmm0, %zmm1, %zmm18 + + # vgather... + .insn VEX.66.0f38.W0 0x92, %xmm8, (%rax, %xmm1, 2), %xmm3 + .insn VEX.66.0f38.W0 0x92, %xmm0, (%r8, %xmm1, 2), %xmm3 + .insn VEX.66.0f38.W0 0x92, %xmm0, (%rax, %xmm9, 2), %xmm3 + .insn VEX.66.0f38.W0 0x92, %xmm0, (%rax, %xmm1, 2), %xmm11 + .insn EVEX.66.0f38.W1 0x93, (%r8, %xmm1, 2), %xmm3{%k4} + .insn EVEX.66.0f38.W1 0x93, (%rax, %xmm9, 2), %xmm3{%k4} + .insn EVEX.66.0f38.W1 0x93, (%rax, %xmm17, 2), %xmm3{%k4} + .insn EVEX.66.0f38.W1 0x93, (%rax, %xmm1, 2), %xmm11{%k4} + .insn EVEX.66.0f38.W1 0x93, (%rax, %xmm1, 2), %xmm19{%k4}