From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lj1-x231.google.com (mail-lj1-x231.google.com [IPv6:2a00:1450:4864:20::231]) by sourceware.org (Postfix) with ESMTPS id 422E33857C5B for ; Tue, 12 Jul 2022 13:51:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 422E33857C5B Received: by mail-lj1-x231.google.com with SMTP id a39so9936140ljq.11 for ; Tue, 12 Jul 2022 06:51:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=SYWnq9kZr8UcIkCucNzhYLeTrE5HAfJ9fO7Zk8F/2Sk=; b=14gInQaPvo2z8bOGIROpcSLEFDPxVoClHycLm+1I8ZIf69ktMrgtQQlnv9gs+HKHEB SG6Bdp9ROVK+wViUM57zK5aUQWO6NKtonJyAEjDCkdpD5V1gnvlibVw7dU40l8F/ADZn nmpQQ8ZsbGMgNaf5qmZJ6qlf08Lblv8Ux3egCJqrQlx3pvGRGLCpdGwZoYFuej1VL4Ac R/a2puD/fCjAX5usQvQGXkAuGb36rS5IH662mblKMg+OT1eswOUilFKap2q1eavokKyD WNHjh0/6s3NXnMaL+R0zg1ufmOfUODhilarVnXVtqQb4VRuAUO82ZQDA/2JV0LqJ14vx Zl+Q== X-Gm-Message-State: AJIora/f1CMPjTVvjIxraL5uKiCD1MKELm91if6I2PvNNILcXGQL9qMU 73N6r/H8zbUOcTWo5SZB4q5s9lkZ8KY= X-Google-Smtp-Source: AGRyM1t8CXlssWef6vUhAl+iQ+0EvOMrqcWQNv38N/DI84I2nIf3T53b3E0M4L6SgF52WtIZ2WLbjw== X-Received: by 2002:a2e:944a:0:b0:24f:10bd:b7e8 with SMTP id o10-20020a2e944a000000b0024f10bdb7e8mr13816548ljh.238.1657633888523; Tue, 12 Jul 2022 06:51:28 -0700 (PDT) Received: from localhost.localdomain (broadband-188-32-220-156.ip.moscow.rt.ru. [188.32.220.156]) by smtp.gmail.com with ESMTPSA id o28-20020a198c1c000000b00482bb812713sm2194642lfd.94.2022.07.12.06.51.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Jul 2022 06:51:27 -0700 (PDT) Sender: Dmitry Selyutin From: Dmitry Selyutin To: binutils@sourceware.org Cc: Alan Modra , Luke Leighton , Jan Beulich , Dmitry Selyutin Subject: [PATCH 1/1] ppc: support register names in macros Date: Tue, 12 Jul 2022 16:50:57 +0300 Message-Id: <20220712135057.170969-2-ghostmansd@gmail.com> X-Mailer: git-send-email 2.37.0 In-Reply-To: <20220712135057.170969-1-ghostmansd@gmail.com> References: <20220712135057.170969-1-ghostmansd@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Tue, 12 Jul 2022 13:51:32 -0000 This patch is a follow-up of discussion: https://sourceware.org/pipermail/binutils/2022-July/121719.html Form now on, PPC assembly becomes capable of compiling such code: .set VREG, %r0 .set REG, VREG extsw REG, 2 extsw %r1, 1 The custom register_name() code path, as well as checks for CRs, are deprecated; from now on, we use md_operand() routine everywhere. Whilst we're here, let's also reuse register lookup for CFI. --- gas/config/tc-ppc.c | 206 +++++++++++++++++--------------------------- gas/config/tc-ppc.h | 9 +- 2 files changed, 86 insertions(+), 129 deletions(-) diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index ac61cd8f12..0b814c4873 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -317,7 +317,7 @@ struct pd_reg The table is sorted. Suitable for searching by a binary search. */ -static const struct pd_reg pre_defined_registers[] = +static const struct pd_reg reg_names[] = { /* VSX accumulators. */ { "a0", 0, PPC_OPERAND_ACC }, @@ -784,8 +784,25 @@ static const struct pd_reg pre_defined_registers[] = { "xer", 1, PPC_OPERAND_SPR } }; +#define REG_NAME_CNT (sizeof (reg_names) / sizeof (struct pd_reg)) -#define REG_NAME_CNT (sizeof (pre_defined_registers) / sizeof (struct pd_reg)) +static const struct pd_reg cr_names[] = +{ + { "cr0", 0, PPC_OPERAND_CR_REG }, + { "cr1", 1, PPC_OPERAND_CR_REG }, + { "cr2", 2, PPC_OPERAND_CR_REG }, + { "cr3", 3, PPC_OPERAND_CR_REG }, + { "cr4", 4, PPC_OPERAND_CR_REG }, + { "cr5", 5, PPC_OPERAND_CR_REG }, + { "cr6", 6, PPC_OPERAND_CR_REG }, + { "cr7", 7, PPC_OPERAND_CR_REG }, + { "eq", 2, PPC_OPERAND_CR_BIT }, + { "gt", 1, PPC_OPERAND_CR_BIT }, + { "lt", 0, PPC_OPERAND_CR_BIT }, + { "so", 3, PPC_OPERAND_CR_BIT }, + { "un", 3, PPC_OPERAND_CR_BIT } +}; +#define CR_NAME_CNT (sizeof (cr_names) / sizeof (struct pd_reg)) /* Given NAME, find the register number associated with that name, return the integer value associated with the given name or -1 on failure. */ @@ -815,106 +832,68 @@ reg_name_search (const struct pd_reg *regs, int regcount, const char *name) return NULL; } -/* - * Summary of register_name. - * - * in: Input_line_pointer points to 1st char of operand. - * - * out: A expressionS. - * The operand may have been a register: in this case, X_op == O_register, - * X_add_number is set to the register number, and truth is returned. - * Input_line_pointer->(next non-blank) char after operand, or is in its - * original state. - */ + +static bool cr_operand; -static bool -register_name (expressionS *expressionP) +int +ppc_parse_name (const char *name, expressionS *exp) { + symbolS *symbol; const struct pd_reg *reg; - char *name; - char *start; - char c; /* Find the spelling of the operand. */ - start = name = input_line_pointer; if (name[0] == '%' && ISALPHA (name[1])) - name = ++input_line_pointer; - - else if (!reg_names_p || !ISALPHA (name[0])) - return false; - - c = get_symbol_name (&name); - reg = reg_name_search (pre_defined_registers, REG_NAME_CNT, name); - - /* Put back the delimiting char. */ - *input_line_pointer = c; + ++name; + else if (!cr_operand && (!reg_names_p || !ISALPHA (name[0]))) + return 0; /* Look to see if it's in the register table. */ + if (cr_operand) + reg = reg_name_search (cr_names, CR_NAME_CNT, name); + else + reg = reg_name_search (reg_names, REG_NAME_CNT, name); if (reg != NULL) { - expressionP->X_op = O_register; - expressionP->X_add_number = reg->value; - expressionP->X_md = reg->flags; + exp->X_op = O_register; + exp->X_add_number = reg->value; + exp->X_md = reg->flags; - /* Make the rest nice. */ - expressionP->X_add_symbol = NULL; - expressionP->X_op_symbol = NULL; - return true; - } + if (! cr_operand) + { + /* Make the rest nice. */ + exp->X_add_symbol = NULL; + exp->X_op_symbol = NULL; + } - /* Reset the line as if we had not done anything. */ - input_line_pointer = start; - return false; -} - -/* This function is called for each symbol seen in an expression. It - handles the special parsing which PowerPC assemblers are supposed - to use for condition codes. */ + return 1; + } -/* Whether to do the special parsing. */ -static bool cr_operand; + /* Look to see if it's a macro. */ + symbol = symbol_find_or_make (name); + if (symbol != NULL) + { + expressionS symbol_exp = *symbol_get_value_expression (symbol); -/* Names to recognize in a condition code. This table is sorted. */ -static const struct pd_reg cr_names[] = -{ - { "cr0", 0, PPC_OPERAND_CR_REG }, - { "cr1", 1, PPC_OPERAND_CR_REG }, - { "cr2", 2, PPC_OPERAND_CR_REG }, - { "cr3", 3, PPC_OPERAND_CR_REG }, - { "cr4", 4, PPC_OPERAND_CR_REG }, - { "cr5", 5, PPC_OPERAND_CR_REG }, - { "cr6", 6, PPC_OPERAND_CR_REG }, - { "cr7", 7, PPC_OPERAND_CR_REG }, - { "eq", 2, PPC_OPERAND_CR_BIT }, - { "gt", 1, PPC_OPERAND_CR_BIT }, - { "lt", 0, PPC_OPERAND_CR_BIT }, - { "so", 3, PPC_OPERAND_CR_BIT }, - { "un", 3, PPC_OPERAND_CR_BIT } -}; + if ((symbol_exp.X_op == O_register) + || (symbol_exp.X_op == O_constant)) + { + *exp = symbol_exp; + return 1; + } + } -/* Parsing function. This returns non-zero if it recognized an - expression. */ + return 0; +} -int -ppc_parse_name (const char *name, expressionS *exp) +void +ppc_operand (expressionS *exp) { - const struct pd_reg *reg; - - if (! cr_operand) - return 0; - - if (*name == '%') - ++name; - reg = reg_name_search (cr_names, sizeof cr_names / sizeof cr_names[0], - name); - if (reg == NULL) - return 0; - - exp->X_op = O_register; - exp->X_add_number = reg->value; - exp->X_md = reg->flags; + char endc; + char *name = input_line_pointer; - return 1; + endc = get_symbol_name (&name); + if (!ppc_parse_name (name, exp)) + restore_line_pointer (endc); } /* Propagate X_md and check register expressions. This is to support @@ -3276,7 +3255,6 @@ parse_tls_arg (char **str, const expressionS *exp, struct ppc_fixup *tls_fix) #endif /* This routine is called for each instruction to be assembled. */ - void md_assemble (char *str) { @@ -3439,25 +3417,11 @@ md_assemble (char *str) /* Gather the operand. */ hold = input_line_pointer; input_line_pointer = str; - - if ((reg_names_p - && (((operand->flags & PPC_OPERAND_CR_BIT) != 0) - || ((operand->flags & PPC_OPERAND_CR_REG) != 0))) - || !register_name (&ex)) - { - char save_lex = lex_type['%']; - - if (((operand->flags & PPC_OPERAND_CR_REG) != 0) - || (operand->flags & PPC_OPERAND_CR_BIT) != 0) - { - cr_operand = true; - lex_type['%'] |= LEX_BEGIN_NAME; - } - expression (&ex); - cr_operand = false; - lex_type['%'] = save_lex; - } - + memset (&ex, 0, sizeof (expressionS)); + if (operand->flags & (PPC_OPERAND_CR_BIT | PPC_OPERAND_CR_REG)) + cr_operand = true; + expression (&ex); + cr_operand = false; str = input_line_pointer; input_line_pointer = hold; @@ -7736,10 +7700,8 @@ ppc_cfi_frame_initial_instructions (void) int tc_ppc_regname_to_dw2regnum (char *regname) { - unsigned int regnum = -1; unsigned int i; - const char *p; - char *q; + const struct pd_reg *reg; static struct { const char *name; int dw2regnum; } regnames[] = { { "sp", 1 }, { "r.sp", 1 }, { "rtoc", 2 }, { "r.toc", 2 }, @@ -7752,23 +7714,15 @@ tc_ppc_regname_to_dw2regnum (char *regname) if (strcmp (regnames[i].name, regname) == 0) return regnames[i].dw2regnum; - if (regname[0] == 'r' || regname[0] == 'f' || regname[0] == 'v') - { - p = regname + 1 + (regname[1] == '.'); - regnum = strtoul (p, &q, 10); - if (p == q || *q || regnum >= 32) - return -1; - if (regname[0] == 'f') - regnum += 32; - else if (regname[0] == 'v') - regnum += 77; - } - else if (regname[0] == 'c' && regname[1] == 'r') - { - p = regname + 2 + (regname[2] == '.'); - if (p[0] < '0' || p[0] > '7' || p[1]) - return -1; - regnum = p[0] - '0' + 68; - } - return regnum; + if (regname[0] == '%' && ISALPHA (regname[1])) + ++regname; + + reg = reg_name_search (reg_names, REG_NAME_CNT, regname); + if (reg == NULL) + reg = reg_name_search (cr_names, CR_NAME_CNT, regname); + + if (reg != NULL) + return reg->value; + + return -1; } diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index ed06a29638..da3c427c4a 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -322,14 +322,17 @@ extern void ppc_frob_label (symbolS *); /* call md_pcrel_from_section, not md_pcrel_from */ #define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section(FIX, SEC) +#define LEX_PCT (LEX_BEGIN_NAME) + +extern int ppc_parse_name (const char *name, struct expressionS *exp); #define md_parse_name(name, exp, mode, c) ppc_parse_name (name, exp) -extern int ppc_parse_name (const char *, struct expressionS *); + +extern void ppc_operand (expressionS *exp); +#define md_operand ppc_operand #define md_optimize_expr(left, op, right) ppc_optimize_expr (left, op, right) extern int ppc_optimize_expr (expressionS *, operatorT, expressionS *); -#define md_operand(x) - #define md_cleanup() ppc_cleanup () extern void ppc_cleanup (void); -- 2.37.0