From 20b36a95ab568a0de00130164834322706e59d1d Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 14 Feb 2005 07:47:51 +0000 Subject: [PATCH 1/1] gas/ 2005-02-13 Jan Beulich * config/tc-ia64.c (dot_rot): Add comment that name strings should be freed when wiping out previous state. Canonicalize names before use. Free name string when detecting redefinition. (dot_pred_rel): Call generic expression parser to process arguments. Handle O_register case for individual predicates and O_subtract for ranges. (ia64_parse_name): Canonicalize name before looking it up in dynamic register hash. (ia64_canonicalize_symbol_name): Strip off all trailing # characters. Warn if multiple found, issue error if resulting symbol name has zero length. (dot_alias): Canonicalize name before use. gas/testsuite/ 2005-02-13 Jan Beulich * gas/ia64/pound.[ls]: New. * gas/ia64/ia64.exp: Run new test. --- gas/ChangeLog | 15 ++++ gas/config/tc-ia64.c | 123 ++++++++++++++++++-------------- gas/testsuite/ChangeLog | 5 ++ gas/testsuite/gas/ia64/ia64.exp | 1 + gas/testsuite/gas/ia64/pound.l | 58 +++++++++++++++ gas/testsuite/gas/ia64/pound.s | 43 +++++++++++ 6 files changed, 191 insertions(+), 54 deletions(-) create mode 100644 gas/testsuite/gas/ia64/pound.l create mode 100644 gas/testsuite/gas/ia64/pound.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 2a9dd66fc4..19b4ee9861 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,18 @@ +2005-02-13 Jan Beulich + + * config/tc-ia64.c (dot_rot): Add comment that name strings should + be freed when wiping out previous state. Canonicalize names before + use. Free name string when detecting redefinition. + (dot_pred_rel): Call generic expression parser to process arguments. + Handle O_register case for individual predicates and O_subtract for + ranges. + (ia64_parse_name): Canonicalize name before looking it up in dynamic + register hash. + (ia64_canonicalize_symbol_name): Strip off all trailing # characters. + Warn if multiple found, issue error if resulting symbol name has zero + length. + (dot_alias): Canonicalize name before use. + 2005-02-11 H.J. Lu * config/tc-ia64.c (unwind_diagnostic): Return -1 for warning diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index d65218a973..7dcb67cf90 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -4560,6 +4560,7 @@ dot_rot (type) for (dr = md.dynreg[type]; dr && dr->num_regs; dr = dr->next) { hash_delete (md.dynreg_hash, dr->name); + /* FIXME: Free dr->name. */ dr->num_regs = 0; } @@ -4568,8 +4569,8 @@ dot_rot (type) { start = input_line_pointer; ch = get_symbol_end (); + len = strlen (ia64_canonicalize_symbol_name (start)); *input_line_pointer = ch; - len = (input_line_pointer - start); SKIP_WHITESPACE (); if (*input_line_pointer != '[') @@ -4618,16 +4619,16 @@ dot_rot (type) break; } - name = obstack_alloc (¬es, len + 1); - memcpy (name, start, len); - name[len] = '\0'; - if (!*drpp) { *drpp = obstack_alloc (¬es, sizeof (*dr)); memset (*drpp, 0, sizeof (*dr)); } + name = obstack_alloc (¬es, len + 1); + memcpy (name, start, len); + name[len] = '\0'; + dr = *drpp; dr->name = name; dr->num_regs = num_regs; @@ -4638,6 +4639,7 @@ dot_rot (type) if (hash_insert (md.dynreg_hash, name, dr)) { as_bad ("Attempt to redefine register set `%s'", name); + obstack_free (¬es, name); goto err; } @@ -5060,59 +5062,57 @@ dot_pred_rel (type) SKIP_WHITESPACE (); while (1) { - valueT bit = 1; + valueT bits = 1; int regno; - - if (TOUPPER (*input_line_pointer) != 'P' - || (regno = atoi (++input_line_pointer)) < 0 - || regno > 63) - { - as_bad (_("Predicate register expected")); - ignore_rest_of_line (); - return; - } - while (ISDIGIT (*input_line_pointer)) - ++input_line_pointer; - if (p1 == -1) - p1 = regno; - else if (p2 == -1) - p2 = regno; - bit <<= regno; - if (mask & bit) - as_warn (_("Duplicate predicate register ignored")); - mask |= bit; - count++; - /* See if it's a range. */ - if (*input_line_pointer == '-') - { - valueT stop = 1; - ++input_line_pointer; - - if (TOUPPER (*input_line_pointer) != 'P' - || (regno = atoi (++input_line_pointer)) < 0 - || regno > 63) - { - as_bad (_("Predicate register expected")); - ignore_rest_of_line (); - return; - } - while (ISDIGIT (*input_line_pointer)) - ++input_line_pointer; - stop <<= regno; - if (bit >= stop) + expressionS pr, *pr1, *pr2; + + expression (&pr); + if (pr.X_op == O_register + && pr.X_add_number >= REG_P + && pr.X_add_number <= REG_P + 63) + { + regno = pr.X_add_number - REG_P; + bits <<= regno; + count++; + if (p1 == -1) + p1 = regno; + else if (p2 == -1) + p2 = regno; + } + else if (type != 'i' + && pr.X_op == O_subtract + && (pr1 = symbol_get_value_expression (pr.X_add_symbol)) + && pr1->X_op == O_register + && pr1->X_add_number >= REG_P + && pr1->X_add_number <= REG_P + 63 + && (pr2 = symbol_get_value_expression (pr.X_op_symbol)) + && pr2->X_op == O_register + && pr2->X_add_number >= REG_P + && pr2->X_add_number <= REG_P + 63) + { + /* It's a range. */ + int stop; + + regno = pr1->X_add_number - REG_P; + stop = pr2->X_add_number - REG_P; + if (regno >= stop) { as_bad (_("Bad register range")); ignore_rest_of_line (); return; } - while (bit < stop) - { - bit <<= 1; - mask |= bit; - count++; - } - SKIP_WHITESPACE (); + bits = ((bits << stop) << 1) - (bits << regno); + count += stop - regno + 1; + } + else + { + as_bad (_("Predicate register expected")); + ignore_rest_of_line (); + return; } + if (mask & bits) + as_warn (_("Duplicate predicate register ignored")); + mask |= bits; if (*input_line_pointer != ',') break; ++input_line_pointer; @@ -7728,6 +7728,9 @@ ia64_parse_name (name, e, nextcharP) } } + end = alloca (strlen (name) + 1); + strcpy (end, name); + name = ia64_canonicalize_symbol_name (end); if ((dr = hash_find (md.dynreg_hash, name))) { /* We've got ourselves the name of a rotating register set. @@ -7747,9 +7750,20 @@ char * ia64_canonicalize_symbol_name (name) char *name; { - size_t len = strlen (name); - if (len > 1 && name[len - 1] == '#') - name[len - 1] = '\0'; + size_t len = strlen (name), full = len; + + while (len > 0 && name[len - 1] == '#') + --len; + if (len <= 0) + { + if (full > 0) + as_bad ("Standalone `#' is illegal"); + else + as_bad ("Zero-length symbol is illegal"); + } + else if (len < full - 1) + as_warn ("Redundant `#' suffix operators"); + name[len] = '\0'; return name; } @@ -11318,6 +11332,7 @@ dot_alias (int section) input_line_pointer++; *end_name = 0; + ia64_canonicalize_symbol_name (name); /* We call demand_copy_C_string to check if alias string is valid. There should be a closing `"' and no `\0' in the string. */ diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 7f4b209f69..823d36e057 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-02-13 Jan Beulich + + * gas/ia64/pound.[ls]: New. + * gas/ia64/ia64.exp: Run new test. + 2005-02-13 H.J. Lu * gas/ia64/ia64.exp: Add "operand-or". diff --git a/gas/testsuite/gas/ia64/ia64.exp b/gas/testsuite/gas/ia64/ia64.exp index 9d628c9e7f..0455b2e76f 100644 --- a/gas/testsuite/gas/ia64/ia64.exp +++ b/gas/testsuite/gas/ia64/ia64.exp @@ -67,6 +67,7 @@ if [istarget "ia64-*"] then { run_dump_test "bundling" run_list_test "label" "" run_list_test "last" "" + run_list_test "pound" "-al" run_list_test "proc" "-munwind-check=error" run_list_test "slot2" "" run_list_test "unwind-err" "-munwind-check=error" diff --git a/gas/testsuite/gas/ia64/pound.l b/gas/testsuite/gas/ia64/pound.l new file mode 100644 index 0000000000..71f2a4fa25 --- /dev/null +++ b/gas/testsuite/gas/ia64/pound.l @@ -0,0 +1,58 @@ +.*: Assembler messages: +.*:35: Warning: .* WAW .* +#... +.*:41: Error: symbol .esym. .* .efunction. +.*:43: Error: section .\.extra. .* .esection. +GAS LISTING .* +#... +[[:space:]]*[[:digit:]]+[[:space:]]+\.explicit +[[:space:]]*[[:digit:]]+[[:space:]]+ +[[:space:]]*[[:digit:]]+[[:space:]]+\.global esym# +[[:space:]]*[[:digit:]]+[[:space:]]+ +[[:space:]]*[[:digit:]]+[[:space:]]+\.section \.extra#, "a", @progbits +[[:space:]]*[[:digit:]]+[[:space:]]+ +[[:space:]]*[[:digit:]]+[[:space:]]+\.text +[[:space:]]*[[:digit:]]+[[:space:]]+ +[[:space:]]*[[:digit:]]+[[:space:]]+ break 0 +[[:space:]]*[[:digit:]]+[[:space:]]+ +[[:space:]]*[[:digit:]]+[[:space:]]+\?*[[:space:]]+[[:xdigit:]]+[[:space:]]+\.proc psym +#... +[[:space:]]*[[:digit:]]+[[:space:]]+psym: +[[:space:]]*[[:digit:]]+[[:space:]]+ mov\.ret\.sptk b7 = r0, tag# +[[:space:]]*[[:digit:]]+[[:space:]]+ mov r8 = 0 +[[:space:]]*[[:digit:]]+[[:space:]]+\[tag:\] br\.ret\.sptk rp +[[:space:]]*[[:digit:]]+[[:space:]]+\?*[[:space:]]+[[:xdigit:]]+[[:space:]]+\.endp psym +#... +[[:space:]]*[[:digit:]]+[[:space:]]+ +[[:space:]]*[[:digit:]]+[[:space:]]+\.proc esym# +[[:space:]]*[[:digit:]]+[[:space:]]+\.entry entry# +[[:space:]]*[[:digit:]]+[[:space:]]+esym: +[[:space:]]*[[:digit:]]+[[:space:]]+\.unwentry +[[:space:]]*[[:digit:]]+[[:space:]]+\.personality psym# +[[:space:]]*[[:digit:]]+[[:space:]]+\.regstk 0, 8, 0, 8 +[[:space:]]*[[:digit:]]+[[:space:]]+\.rotp p#\[2\], p1#\[4\] +[[:space:]]*[[:digit:]]+[[:space:]]+\.rotr r#\[2\], r1#\[4\] +[[:space:]]*[[:digit:]]+[[:space:]]+\.reg\.val r#\[1\], 0 +[[:space:]]*[[:digit:]]+[[:space:]]+\.reg\.val r1#\[3\], 0 +[[:space:]]*[[:digit:]]+[[:space:]]+\(p1#\[1\]\) cmp\.eq p\[0\] = r\[1\], r1#\[1\] +[[:space:]]*[[:digit:]]+[[:space:]]+\(p1#\[3\]\) cmp\.eq p#\[1\] = r#\[1\], r1#\[3\] +[[:space:]]*[[:digit:]]+[[:space:]]+\.pred\.rel "mutex", p#\[0\], p\[1\] +[[:space:]]*[[:digit:]]+[[:space:]]+ nop 0 +[[:space:]]*[[:digit:]]+[[:space:]]+ ;; +[[:space:]]*[[:digit:]]+[[:space:]]+entry: +[[:space:]]*[[:digit:]]+[[:space:]]+\?*[[:space:]]+61828446[[:space:]]+\(p\[0\]\) mov r8 = 1 +[[:space:]]*[[:digit:]]+[[:space:]]+00781509[[:space:]]* +[[:space:]]*[[:digit:]]+[[:space:]]+95007000[[:space:]]* +[[:space:]]*[[:digit:]]+[[:space:]]+00000400[[:space:]]* +[[:space:]]*[[:digit:]]+[[:space:]]+\(p#\[1\]\) mov r8 = 0 +[[:space:]]*[[:digit:]]+[[:space:]]+ br\.ret\.sptk rp +[[:space:]]*[[:digit:]]+[[:space:]]+\.xdata4 \.extra#, -1 +[[:space:]]*[[:digit:]]+[[:space:]]+\?*[[:space:]]+11420400+[[:space:]]+\.endp esym# +[[:space:]]*[[:digit:]]+[[:space:]]+00648400[[:space:]]* +[[:space:]]*[[:digit:]]+[[:space:]]+00004880[[:space:]]* +[[:space:]]*[[:digit:]]+[[:space:]]+00008400[[:space:]]* +#... +[[:space:]]*[[:digit:]]+[[:space:]]+\.alias esym#, "efunction" +[[:space:]]*[[:digit:]]+[[:space:]]+\.alias esym, "efunc" +[[:space:]]*[[:digit:]]+[[:space:]]+\.secalias \.extra#, "esection" +[[:space:]]*[[:digit:]]+[[:space:]]+\.secalias \.extra, "esec" diff --git a/gas/testsuite/gas/ia64/pound.s b/gas/testsuite/gas/ia64/pound.s new file mode 100644 index 0000000000..f54c072f5b --- /dev/null +++ b/gas/testsuite/gas/ia64/pound.s @@ -0,0 +1,43 @@ +.explicit + +.global esym# + +.section .extra#, "a", @progbits + +.text + + break 0 + +.proc psym +psym: + mov.ret.sptk b7 = r0, tag# + mov r8 = 0 +[tag:] br.ret.sptk rp +.endp psym + +.proc esym# +.entry entry# +esym: +.unwentry +.personality psym# +.regstk 0, 8, 0, 8 +.rotp p#[2], p1#[4] +.rotr r#[2], r1#[4] +.reg.val r#[1], 0 +.reg.val r1#[3], 0 +(p1#[1]) cmp.eq p[0] = r[1], r1#[1] +(p1#[3]) cmp.eq p#[1] = r#[1], r1#[3] +.pred.rel "mutex", p#[0], p[1] + nop 0 + ;; +entry: +(p[0]) mov r8 = 1 +(p#[1]) mov r8 = 0 + br.ret.sptk rp +.xdata4 .extra#, -1 +.endp esym# + +.alias esym#, "efunction" +.alias esym, "efunc" +.secalias .extra#, "esection" +.secalias .extra, "esec" -- 2.34.1