diff options
Diffstat (limited to 'gas')
20 files changed, 295 insertions, 2 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 5e706c1..243ccbd 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,14 @@ +2011-03-31 Bernd Schmidt <bernds@codesourcery.com> + + * config/tc-tic6x.c (sbss_section, scom_section, scom_symbol): New + static variables. + (md_begin): Initialize them. + (s_tic6x_scomm): New static function. + (md_pseudo_table): Add "scomm". + (tc_gen_reloc): Really undo all adjustments made by + bfd_install_relocation. + * doc/c-tic6x.texi: Document the .scomm directive. + 2011-03-31 Tristan Gingold <gingold@adacore.com> * dwarf2dbg.c (DWARF2_VERSION): Define. diff --git a/gas/config/tc-tic6x.c b/gas/config/tc-tic6x.c index c937ba5..6ff8006 100644 --- a/gas/config/tc-tic6x.c +++ b/gas/config/tc-tic6x.c @@ -34,6 +34,11 @@ #define TRUNC(X) ((valueT) (X) & 0xffffffffU) #define SEXT(X) ((TRUNC (X) ^ 0x80000000U) - 0x80000000U) +/* Stuff for .scomm symbols. */ +static segT sbss_section; +static asection scom_section; +static asymbol scom_symbol; + const char comment_chars[] = ";"; const char line_comment_chars[] = "#*;"; const char line_separator_chars[] = "@"; @@ -349,6 +354,138 @@ s_tic6x_nocmp (int ignored ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } +/* .scomm pseudo-op handler. + + This is a new pseudo-op to handle putting objects in .scommon. + By doing this the linker won't need to do any work, + and more importantly it removes the implicit -G arg necessary to + correctly link the object file. */ + +static void +s_tic6x_scomm (int ignore ATTRIBUTE_UNUSED) +{ + char *name; + char c; + char *p; + offsetT size; + symbolS *symbolP; + offsetT align; + int align2; + + name = input_line_pointer; + c = get_symbol_end (); + + /* Just after name is now '\0'. */ + p = input_line_pointer; + *p = c; + SKIP_WHITESPACE (); + if (*input_line_pointer != ',') + { + as_bad (_("expected comma after symbol name")); + ignore_rest_of_line (); + return; + } + + /* Skip ','. */ + input_line_pointer++; + if ((size = get_absolute_expression ()) < 0) + { + /* xgettext:c-format */ + as_warn (_("invalid length for .scomm directive")); + ignore_rest_of_line (); + return; + } + + /* The third argument to .scomm is the alignment. */ + if (*input_line_pointer != ',') + align = 8; + else + { + ++input_line_pointer; + align = get_absolute_expression (); + if (align <= 0) + { + as_warn (_("alignment is not a positive number")); + align = 8; + } + } + + /* Convert to a power of 2 alignment. */ + if (align) + { + for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2) + continue; + if (align != 1) + { + as_bad (_("alignment is not a power of 2")); + ignore_rest_of_line (); + return; + } + } + else + align2 = 0; + + *p = 0; + symbolP = symbol_find_or_make (name); + *p = c; + + if (S_IS_DEFINED (symbolP)) + { + /* xgettext:c-format */ + as_bad (_("attempt to re-define symbol `%s'"), + S_GET_NAME (symbolP)); + ignore_rest_of_line (); + return; + } + + if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size) + { + /* xgettext:c-format */ + as_bad (_("attempt to redefine `%s' with a different length"), + S_GET_NAME (symbolP)); + + ignore_rest_of_line (); + return; + } + + if (symbol_get_obj (symbolP)->local) + { + segT old_sec = now_seg; + int old_subsec = now_subseg; + char *pfrag; + + record_alignment (sbss_section, align2); + subseg_set (sbss_section, 0); + + if (align2) + frag_align (align2, 0, 0); + + if (S_GET_SEGMENT (symbolP) == sbss_section) + symbol_get_frag (symbolP)->fr_symbol = 0; + + symbol_set_frag (symbolP, frag_now); + + pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size, + (char *) 0); + *pfrag = 0; + S_SET_SIZE (symbolP, size); + S_SET_SEGMENT (symbolP, sbss_section); + S_CLEAR_EXTERNAL (symbolP); + subseg_set (old_sec, old_subsec); + } + else + { + S_SET_VALUE (symbolP, (valueT) size); + S_SET_ALIGN (symbolP, 1 << align2); + S_SET_EXTERNAL (symbolP); + S_SET_SEGMENT (symbolP, &scom_section); + } + + symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; + + demand_empty_rest_of_line (); +} + /* Track for each attribute whether it has been set explicitly (and so should not have a default value set by the assembler). */ static bfd_boolean tic6x_attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES]; @@ -396,6 +533,7 @@ const pseudo_typeS md_pseudo_table[] = { "arch", s_tic6x_arch, 0 }, { "c6xabi_attribute", s_tic6x_c6xabi_attribute, 0 }, { "nocmp", s_tic6x_nocmp, 0 }, + { "scomm", s_tic6x_scomm, 0 }, { "word", cons, 4 }, { 0, 0, 0 } }; @@ -411,6 +549,9 @@ void md_begin (void) { tic6x_opcode_id id; + flagword applicable; + segT seg; + subsegT subseg; bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0); @@ -427,6 +568,32 @@ md_begin (void) != NULL) as_fatal ("%s", _(errmsg)); } + + /* Save the current subseg so we can restore it [it's the default one and + we don't want the initial section to be .sbss]. */ + seg = now_seg; + subseg = now_subseg; + + /* The sbss section is for local .scomm symbols. */ + sbss_section = subseg_new (".bss", 0); + seg_info (sbss_section)->bss = 1; + + /* This is copied from perform_an_assembly_pass. */ + applicable = bfd_applicable_section_flags (stdoutput); + bfd_set_section_flags (stdoutput, sbss_section, applicable & SEC_ALLOC); + + subseg_set (seg, subseg); + + /* We must construct a fake section similar to bfd_com_section + but with the name .scommon. */ + scom_section = bfd_com_section; + scom_section.name = ".scommon"; + scom_section.output_section = & scom_section; + scom_section.symbol = & scom_symbol; + scom_section.symbol_ptr_ptr = & scom_section.symbol; + scom_symbol = * bfd_com_section.symbol; + scom_symbol.name = ".scommon"; + scom_symbol.section = & scom_section; } /* Whether the current line being parsed had the "||" parallel bars. */ @@ -4029,11 +4196,13 @@ arelent * tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) { arelent *reloc; + asymbol *symbol; bfd_reloc_code_real_type r_type; reloc = xmalloc (sizeof (arelent)); reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); - *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + symbol = symbol_get_bfdsym (fixp->fx_addsy); + *reloc->sym_ptr_ptr = symbol; reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; reloc->addend = (tic6x_generate_rela ? fixp->fx_offset : 0); r_type = fixp->fx_r_type; @@ -4049,7 +4218,11 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) /* Correct for adjustments bfd_install_relocation will make. */ if (reloc->howto->pcrel_offset && reloc->howto->partial_inplace) - reloc->addend += reloc->address; + { + reloc->addend += reloc->address; + if (!bfd_is_com_section (symbol)) + reloc->addend -= symbol->value; + } return reloc; } diff --git a/gas/doc/c-tic6x.texi b/gas/doc/c-tic6x.texi index ba0148c..1116275 100644 --- a/gas/doc/c-tic6x.texi +++ b/gas/doc/c-tic6x.texi @@ -151,4 +151,10 @@ The @var{tag} is either an attribute number or one of Disallow use of C64x+ compact instructions in the current text section. +@cindex @code{.scomm} directive, TIC6X +@item .scomm @var{symbol}, @var{size}, @var{align} +Like @code{.comm}, creating a common symbol @var{symbol} with size @var{size} +and alignment @var{align}, but unlike when using @code{.comm}, this symbol +will be placed into the small BSS section by the linker. + @end table diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 51502ee..62fa86d 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,22 @@ +2011-03-31 Bernd Schmidt <bernds@codesourcery.com> + + * gas/tic6x/scomm-directive-1.s: New test. + * gas/tic6x/scomm-directive-1.d: New test. + * gas/tic6x/scomm-directive-2.s: New test. + * gas/tic6x/scomm-directive-2.d: New test. + * gas/tic6x/scomm-directive-3.s: New test. + * gas/tic6x/scomm-directive-3.d: New test. + * gas/tic6x/scomm-directive-4.s: New test. + * gas/tic6x/scomm-directive-4.d: New test. + * gas/tic6x/scomm-directive-5.s: New test. + * gas/tic6x/scomm-directive-5.d: New test. + * gas/tic6x/scomm-directive-6.s: New test. + * gas/tic6x/scomm-directive-6.d: New test. + * gas/tic6x/scomm-directive-7.s: New test. + * gas/tic6x/scomm-directive-7.d: New test. + * gas/tic6x/scomm-directive-8.s: New test. + * gas/tic6x/scomm-directive-8.d: New test. + 2011-03-29 H.J. Lu <hongjiu.lu@intel.com> * gas/i386/ilp32/quad.d: Add tests for multiple operands. diff --git a/gas/testsuite/gas/tic6x/scomm-directive-1.d b/gas/testsuite/gas/tic6x/scomm-directive-1.d new file mode 100644 index 0000000..afa4496 --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-1.d @@ -0,0 +1,4 @@ +#name: C6X .scomm directive 1 +#as: +#source: scomm-directive-1.s +#error: alignment is not a power of 2 diff --git a/gas/testsuite/gas/tic6x/scomm-directive-1.s b/gas/testsuite/gas/tic6x/scomm-directive-1.s new file mode 100644 index 0000000..91f438a --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-1.s @@ -0,0 +1,2 @@ + .comm x,4,4 + .scomm y,4,5 diff --git a/gas/testsuite/gas/tic6x/scomm-directive-2.d b/gas/testsuite/gas/tic6x/scomm-directive-2.d new file mode 100644 index 0000000..f8c62fb --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-2.d @@ -0,0 +1,5 @@ +#name: C6X .scomm directive 2 +#as: +#source: scomm-directive-2.s +#error: attempt to re-define symbol + diff --git a/gas/testsuite/gas/tic6x/scomm-directive-2.s b/gas/testsuite/gas/tic6x/scomm-directive-2.s new file mode 100644 index 0000000..c53e787 --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-2.s @@ -0,0 +1,2 @@ + .scomm x,4,4 + .scomm x,8,4 diff --git a/gas/testsuite/gas/tic6x/scomm-directive-3.d b/gas/testsuite/gas/tic6x/scomm-directive-3.d new file mode 100644 index 0000000..ae3304c --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-3.d @@ -0,0 +1,4 @@ +#name: C6X .scomm directive 3 +#as: +#source: scomm-directive-3.s +#error: attempt to re-define symbol diff --git a/gas/testsuite/gas/tic6x/scomm-directive-3.s b/gas/testsuite/gas/tic6x/scomm-directive-3.s new file mode 100644 index 0000000..c17f0b5 --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-3.s @@ -0,0 +1,2 @@ + .comm x,8,4 + .scomm x,8,4 diff --git a/gas/testsuite/gas/tic6x/scomm-directive-4.d b/gas/testsuite/gas/tic6x/scomm-directive-4.d new file mode 100644 index 0000000..9eba4fd --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-4.d @@ -0,0 +1,37 @@ +#name: C6X .scomm directive 4 +#as: +#source: scomm-directive-4.s +#readelf: -Ss + +There are 8 section headers, starting at offset 0x88: + +Section Headers: + \[Nr\] Name Type Addr Off Size ES Flg Lk Inf Al + \[ 0\] NULL 00000000 000000 000000 00 0 0 0 + \[ 1\] \.text PROGBITS 00000000 000034 000000 00 AX 0 0 1 + \[ 2\] \.data PROGBITS 00000000 000034 000000 00 WA 0 0 1 + \[ 3\] \.bss NOBITS 00000000 000034 000000 00 WA 0 0 1 + \[ 4\] \.c6xabi\.attribute C6000_ATTRIBUTE 00000000 000034 000013 00 0 0 1 + \[ 5\] \.shstrtab STRTAB 00000000 000047 00003f 00 0 0 1 + \[ 6\] \.symtab SYMTAB 00000000 0001c8 0000d0 10 7 5 4 + \[ 7\] \.strtab STRTAB 00000000 000298 00001d 00 0 0 1 +Key to Flags: + W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\) + I \(info\), L \(link order\), G \(group\), T \(TLS\), E \(exclude\), x \(unknown\) + O \(extra OS processing required\) o \(OS specific\), p \(processor specific\) + +Symbol table '\.symtab' contains 13 entries: + Num: Value Size Type Bind Vis Ndx Name + 0: 00000000 0 NOTYPE LOCAL DEFAULT UND + 1: 00000000 0 SECTION LOCAL DEFAULT 1 + 2: 00000000 0 SECTION LOCAL DEFAULT 2 + 3: 00000000 0 SECTION LOCAL DEFAULT 3 + 4: 00000000 0 SECTION LOCAL DEFAULT 4 + 5: 00000004 4 OBJECT GLOBAL DEFAULT COM x4a + 6: 00000004 4 OBJECT GLOBAL DEFAULT SCOM y4a + 7: 00000002 4 OBJECT GLOBAL DEFAULT COM x4b + 8: 00000002 4 OBJECT GLOBAL DEFAULT SCOM y4b + 9: 00000004 2 OBJECT GLOBAL DEFAULT COM x2 + 10: 00000004 2 OBJECT GLOBAL DEFAULT SCOM y2 + 11: 00000004 1 OBJECT GLOBAL DEFAULT COM x1 + 12: 00000004 1 OBJECT GLOBAL DEFAULT SCOM y1 diff --git a/gas/testsuite/gas/tic6x/scomm-directive-4.s b/gas/testsuite/gas/tic6x/scomm-directive-4.s new file mode 100644 index 0000000..1d2d018 --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-4.s @@ -0,0 +1,8 @@ + .comm x4a,4,4 + .scomm y4a,4,4 + .comm x4b,4,2 + .scomm y4b,4,2 + .comm x2,2,4 + .scomm y2,2,4 + .comm x1,1,4 + .scomm y1,1,4 diff --git a/gas/testsuite/gas/tic6x/scomm-directive-5.d b/gas/testsuite/gas/tic6x/scomm-directive-5.d new file mode 100644 index 0000000..0731e12 --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-5.d @@ -0,0 +1,4 @@ +#name: C6X .scomm directive 5 +#as: +#source: scomm-directive-5.s +#error: expected comma after symbol name diff --git a/gas/testsuite/gas/tic6x/scomm-directive-5.s b/gas/testsuite/gas/tic6x/scomm-directive-5.s new file mode 100644 index 0000000..2de60ba --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-5.s @@ -0,0 +1 @@ + .scomm x diff --git a/gas/testsuite/gas/tic6x/scomm-directive-6.d b/gas/testsuite/gas/tic6x/scomm-directive-6.d new file mode 100644 index 0000000..d083039 --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-6.d @@ -0,0 +1,4 @@ +#name: C6X .scomm directive 6 +#as: +#source: scomm-directive-6.s +#error: bad or irreducible absolute expression diff --git a/gas/testsuite/gas/tic6x/scomm-directive-6.s b/gas/testsuite/gas/tic6x/scomm-directive-6.s new file mode 100644 index 0000000..9171f20 --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-6.s @@ -0,0 +1 @@ + .scomm x,fish diff --git a/gas/testsuite/gas/tic6x/scomm-directive-7.d b/gas/testsuite/gas/tic6x/scomm-directive-7.d new file mode 100644 index 0000000..3cf2803 --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-7.d @@ -0,0 +1,4 @@ +#name: C6X .scomm directive 7 +#as: +#source: scomm-directive-7.s +#warning: alignment is not a positive number diff --git a/gas/testsuite/gas/tic6x/scomm-directive-7.s b/gas/testsuite/gas/tic6x/scomm-directive-7.s new file mode 100644 index 0000000..711ddd6 --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-7.s @@ -0,0 +1 @@ + .scomm x,8,-4 diff --git a/gas/testsuite/gas/tic6x/scomm-directive-8.d b/gas/testsuite/gas/tic6x/scomm-directive-8.d new file mode 100644 index 0000000..c4a6598 --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-8.d @@ -0,0 +1,4 @@ +#name: C6X .scomm directive 8 +#as: +#source: scomm-directive-8.s +#warning: invalid length for .scomm directive diff --git a/gas/testsuite/gas/tic6x/scomm-directive-8.s b/gas/testsuite/gas/tic6x/scomm-directive-8.s new file mode 100644 index 0000000..5c33e32 --- /dev/null +++ b/gas/testsuite/gas/tic6x/scomm-directive-8.s @@ -0,0 +1 @@ + .scomm x,-8,4 |