From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1062) id 2D8D53857BBF; Thu, 14 Jul 2022 02:32:53 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2D8D53857BBF Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Alan Modra To: bfd-cvs@sourceware.org Subject: [binutils-gdb] PowerPC: implement md_operand to parse register names X-Act-Checkin: binutils-gdb X-Git-Author: Alan Modra X-Git-Refname: refs/heads/master X-Git-Oldrev: 869fa2b36cb2db03deda55225560a2f93d98cc0b X-Git-Newrev: 00b37cc41e699faa30435fb6a302311a5ad44a3d Message-Id: <20220714023253.2D8D53857BBF@sourceware.org> Date: Thu, 14 Jul 2022 02:32:53 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jul 2022 02:32:53 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D00b37cc41e69= 9faa30435fb6a302311a5ad44a3d commit 00b37cc41e699faa30435fb6a302311a5ad44a3d Author: Alan Modra Date: Tue Jul 12 11:10:08 2022 +0930 PowerPC: implement md_operand to parse register names =20 Allows register names to appear in symbol assignments, so for example tocp =3D %r2 mr %r3,tocp now assembles. =20 * gas/config/tc-ppc.c (REG_NAME_CNT): Delete, replace uses with ARRAY_SIZE. (register_name): Rename to.. (md_operand): ..this. Only handle %reg. (cr_names): Rename to.. (cr_cond): ..this. Just keep conditions. (ppc_parse_name): Add mode param. Search both cr_cond and pre_defined_registers. Handle absolute and register symbol values here rather than in expr.c:operand(). (md_assemble): Don't special case register name matching in operands, except to set cr_operand as appropriate. * gas/config/tc-ppc.h (md_operand): Don't define. (md_parse_name, ppc_parse_name): Update. * read.c (pseudo_set): Copy over entire O_register value. * testsuite/gas/ppc/regsyms.d. * testsuite/gas/ppc/regsyms.s: New test. * testsuite/gas/ppc/ppc.exp: Run it. Diff: --- gas/config/tc-ppc.c | 147 +++++++++++++++++-------------------= ---- gas/config/tc-ppc.h | 6 +- gas/read.c | 3 +- gas/testsuite/gas/ppc/ppc.exp | 1 + gas/testsuite/gas/ppc/regsyms.d | 10 +++ gas/testsuite/gas/ppc/regsyms.s | 4 ++ 6 files changed, 82 insertions(+), 89 deletions(-) diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 5015777d600..05d8ee19be7 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -785,8 +785,6 @@ static const struct pd_reg pre_defined_registers[] =3D { "xer", 1, PPC_OPERAND_SPR } }; =20 -#define REG_NAME_CNT (sizeof (pre_defined_registers) / sizeof (struct pd_r= eg)) - /* Given NAME, find the register number associated with that name, return the integer value associated with the given name or -1 on failure. */ =20 @@ -815,76 +813,43 @@ reg_name_search (const struct pd_reg *regs, int regco= unt, const char *name) return NULL; } =20 -/* - * 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 =3D=3D 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. - */ +/* Called for a non-symbol, non-number operand. Handles %reg. */ =20 -static bool -register_name (expressionS *expressionP) +void +md_operand (expressionS *expressionP) { const struct pd_reg *reg; char *name; char *start; char c; =20 - /* Find the spelling of the operand. */ - start =3D name =3D input_line_pointer; - if (name[0] =3D=3D '%' && ISALPHA (name[1])) - name =3D ++input_line_pointer; + if (input_line_pointer[0] !=3D '%' || !ISALPHA (input_line_pointer[1])) + return; =20 - else if (!reg_names_p || !ISALPHA (name[0])) - return false; + start =3D input_line_pointer; + ++input_line_pointer; =20 c =3D get_symbol_name (&name); - reg =3D reg_name_search (pre_defined_registers, REG_NAME_CNT, name); - - /* Put back the delimiting char. */ + reg =3D reg_name_search (pre_defined_registers, + ARRAY_SIZE (pre_defined_registers), name); *input_line_pointer =3D c; =20 - /* Look to see if it's in the register table. */ if (reg !=3D NULL) { expressionP->X_op =3D O_register; expressionP->X_add_number =3D reg->value; expressionP->X_md =3D reg->flags; - - /* Make the rest nice. */ - expressionP->X_add_symbol =3D NULL; - expressionP->X_op_symbol =3D NULL; - return true; } - - /* Reset the line as if we had not done anything. */ - input_line_pointer =3D start; - return false; + else + input_line_pointer =3D start; } -=0C -/* 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. */ =20 /* Whether to do the special parsing. */ static bool cr_operand; =20 -/* Names to recognize in a condition code. This table is sorted. */ -static const struct pd_reg cr_names[] =3D +/* Extra names to recognise in a condition code. This table is sorted. */ +static const struct pd_reg cr_cond[] =3D { - { "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 }, @@ -892,29 +857,60 @@ static const struct pd_reg cr_names[] =3D { "un", 3, PPC_OPERAND_CR_BIT } }; =20 -/* Parsing function. This returns non-zero if it recognized an - expression. */ +/* 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, and recognises other registers when + -mregnames. */ =20 int -ppc_parse_name (const char *name, expressionS *exp) +ppc_parse_name (const char *name, expressionS *exp, enum expr_mode mode) { - const struct pd_reg *reg; + const struct pd_reg *reg =3D NULL; =20 - if (! cr_operand) - return 0; + if (cr_operand) + reg =3D reg_name_search (cr_cond, ARRAY_SIZE (cr_cond), name); + if (reg =3D=3D NULL && (cr_operand || reg_names_p)) + reg =3D reg_name_search (pre_defined_registers, + ARRAY_SIZE (pre_defined_registers), name); + if (reg !=3D NULL) + { + exp->X_op =3D O_register; + exp->X_add_number =3D reg->value; + exp->X_md =3D reg->flags; + return true; + } =20 - if (*name =3D=3D '%') - ++name; - reg =3D reg_name_search (cr_names, sizeof cr_names / sizeof cr_names[0], - name); - if (reg =3D=3D NULL) - return 0; + /* The following replaces code in expr.c operand() after the + md_parse_name call. There is too much difference between targets + in the way X_md is used to move this code into expr.c. If you + do, you'll get failures on x86 due to uninitialised X_md fields, + failures on alpha and other targets due to creating register + symbols as O_constant rather than O_register, and failures on arc + and others due to expecting expr() to leave X_md alone. */ + symbolS *sym =3D symbol_find_or_make (name); =20 - exp->X_op =3D O_register; - exp->X_add_number =3D reg->value; - exp->X_md =3D reg->flags; + /* If we have an absolute symbol or a reg, then we know its value + now. Copy the symbol value expression to propagate X_md. */ + bool done =3D false; + if (mode !=3D expr_defer + && !S_FORCE_RELOC (sym, 0)) + { + segT segment =3D S_GET_SEGMENT (sym); + if (segment =3D=3D absolute_section || segment =3D=3D reg_section) + { + resolve_symbol_value (sym); + *exp =3D *symbol_get_value_expression (sym); + done =3D true; + } + } + if (!done) + { + exp->X_op =3D O_symbol; + exp->X_add_symbol =3D sym; + exp->X_add_number =3D 0; + } =20 - return 1; + return true; } =20 /* Propagate X_md and check register expressions. This is to support @@ -3437,25 +3433,10 @@ md_assemble (char *str) /* Gather the operand. */ hold =3D input_line_pointer; input_line_pointer =3D str; - - if ((reg_names_p - && (((operand->flags & PPC_OPERAND_CR_BIT) !=3D 0) - || ((operand->flags & PPC_OPERAND_CR_REG) !=3D 0))) - || !register_name (&ex)) - { - char save_lex =3D lex_type['%']; - - if (((operand->flags & PPC_OPERAND_CR_REG) !=3D 0) - || (operand->flags & PPC_OPERAND_CR_BIT) !=3D 0) - { - cr_operand =3D true; - lex_type['%'] |=3D LEX_BEGIN_NAME; - } - expression (&ex); - cr_operand =3D false; - lex_type['%'] =3D save_lex; - } - + cr_operand =3D ((operand->flags & PPC_OPERAND_CR_BIT) !=3D 0 + || (operand->flags & PPC_OPERAND_CR_REG) !=3D 0); + expression (&ex); + cr_operand =3D false; str =3D input_line_pointer; input_line_pointer =3D hold; =20 diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index ed06a296382..480c952be45 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -322,14 +322,12 @@ 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) =20 -#define md_parse_name(name, exp, mode, c) ppc_parse_name (name, exp) -extern int ppc_parse_name (const char *, struct expressionS *); +#define md_parse_name(name, exp, mode, c) ppc_parse_name (name, exp, mode) +extern int ppc_parse_name (const char *, struct expressionS *, enum expr_m= ode); =20 #define md_optimize_expr(left, op, right) ppc_optimize_expr (left, op, rig= ht) extern int ppc_optimize_expr (expressionS *, operatorT, expressionS *); =20 -#define md_operand(x) - #define md_cleanup() ppc_cleanup () extern void ppc_cleanup (void); =20 diff --git a/gas/read.c b/gas/read.c index 6f3a51df761..559fd05a8db 100644 --- a/gas/read.c +++ b/gas/read.c @@ -3934,10 +3934,9 @@ pseudo_set (symbolS *symbolP) return; } #endif + symbol_set_value_expression (symbolP, &exp); S_SET_SEGMENT (symbolP, reg_section); - S_SET_VALUE (symbolP, (valueT) exp.X_add_number); set_zero_frag (symbolP); - symbol_get_value_expression (symbolP)->X_op =3D O_register; break; =20 case O_symbol: diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp index a2e23a2c6af..9844ce7e4a1 100644 --- a/gas/testsuite/gas/ppc/ppc.exp +++ b/gas/testsuite/gas/ppc/ppc.exp @@ -36,6 +36,7 @@ run_dump_test "bcy" run_dump_test "bcaterr" run_dump_test "bcat" run_dump_test "regnames" +run_dump_test "regsyms" run_dump_test "misalign" run_dump_test "misalign2" run_dump_test "machine" diff --git a/gas/testsuite/gas/ppc/regsyms.d b/gas/testsuite/gas/ppc/regsym= s.d new file mode 100644 index 00000000000..7586b0df4ca --- /dev/null +++ b/gas/testsuite/gas/ppc/regsyms.d @@ -0,0 +1,10 @@ +#as: -mregnames +#objdump: -d + +.*: file format .* + +Disassembly of section \.text: + +0+ <.text>: + 0: (7c 43 13 78|78 13 43 7c) mr r3,r2 + 4: (7f c3 f3 78|78 f3 c3 7f) mr r3,r30 diff --git a/gas/testsuite/gas/ppc/regsyms.s b/gas/testsuite/gas/ppc/regsym= s.s new file mode 100644 index 00000000000..6dc3ddc070b --- /dev/null +++ b/gas/testsuite/gas/ppc/regsyms.s @@ -0,0 +1,4 @@ + tocp =3D %r2 + mr %r3,tocp + x =3D r30 + mr 3,x