diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 24 | ||||
-rw-r--r-- | gas/config/tc-msp430.c | 146 | ||||
-rw-r--r-- | gas/doc/as.texi | 17 | ||||
-rw-r--r-- | gas/doc/c-msp430.texi | 12 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430-small-bad.d | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430-small-bad.l | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430-small-good.d | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430-small.s | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430x-large-any-bad.d | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430x-large-any-bad.l | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430x-large-any-good.d | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430x-large-any.s | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430x-large-lower-bad.d | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430x-large-lower-bad.l | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430x-large-lower-good.d | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/attr-430x-large-lower.s | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/msp430.exp | 6 |
17 files changed, 252 insertions, 4 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index abb8bf0..41bcaa3 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,27 @@ +2019-10-07 Jozef Lawrynowicz <jozef.l@mittosystems.com> + + * config/tc-msp430.c (md_parse_option): Set lower_data_region_only + to FALSE if the data region is set to "upper", "either" or "none". + (msp430_object_attribute): New. + (md_pseudo_table): Handle .mspabi_attribute and .gnu_attribute. + (msp430_md_end): Replace hard-coded attribute values with enums. + Handle data region object attribute. + * doc/as.texi: Document MSP430 Data Region object attribute. + * doc/c-msp430.texi: Document the .mspabi_attribute directive. + * testsuite/gas/msp430/attr-430-small-bad.d: New test. + * testsuite/gas/msp430/attr-430-small-bad.l: New test. + * testsuite/gas/msp430/attr-430-small-good.d: New test. + * testsuite/gas/msp430/attr-430-small.s: New test. + * testsuite/gas/msp430/attr-430x-large-any-bad.d: New test. + * testsuite/gas/msp430/attr-430x-large-any-bad.l: New test. + * testsuite/gas/msp430/attr-430x-large-any-good.d: New test. + * testsuite/gas/msp430/attr-430x-large-any.s: New test. + * testsuite/gas/msp430/attr-430x-large-lower-bad.d: New test. + * testsuite/gas/msp430/attr-430x-large-lower-bad.l: New test. + * testsuite/gas/msp430/attr-430x-large-lower-good.d: New test. + * testsuite/gas/msp430/attr-430x-large-lower.s: New test. + * testsuite/gas/msp430/msp430.exp: Run new tests. + 2019-10-07 Jan Beulich <jbeulich@suse.com> * config/tc-i386.c (check_string): Make reported operand number diff --git a/gas/config/tc-msp430.c b/gas/config/tc-msp430.c index 56d2024..41413f0 100644 --- a/gas/config/tc-msp430.c +++ b/gas/config/tc-msp430.c @@ -689,6 +689,8 @@ static bfd_boolean do_unknown_interrupt_nops = TRUE; static bfd_boolean move_data = FALSE; #define OPTION_DATA_REGION 'r' static bfd_boolean upper_data_region_in_use = FALSE; +/* The default is to use the lower region only. */ +static bfd_boolean lower_data_region_only = TRUE; enum { @@ -1473,6 +1475,13 @@ md_parse_option (int c, const char * arg) if (strcmp (arg, "upper") == 0 || strcmp (arg, "either") == 0) upper_data_region_in_use = TRUE; + if (strcmp (arg, "upper") == 0 + || strcmp (arg, "either") == 0 + /* With data-region=none, the compiler has generated code assuming + data could be in the upper region, but nothing has been explicitly + placed there. */ + || strcmp (arg, "none") == 0) + lower_data_region_only = FALSE; return 1; } @@ -1598,6 +1607,120 @@ msp430_refsym (int arg ATTRIBUTE_UNUSED) (void) symbol_find_or_make (sym_name); } +/* Handle a .mspabi_attribute or .gnu_attribute directive. + attr_type is 0 for .mspabi_attribute or 1 for .gnu_attribute. + This is only used for validating the attributes in the assembly file against + the options gas has been invoked with. If the attributes and options are + compatible then we add the attributes to the assembly file in + msp430_md_end. */ +static void +msp430_object_attribute (int attr_type) +{ + char tag_name_s[32]; + char tag_value_s[32]; + int tag_name, tag_value; + /* First operand is the tag name, second is the tag value e.g. + ".mspabi_attribute 4, 2". */ + input_line_pointer = extract_operand (input_line_pointer, tag_name_s, 32); + input_line_pointer = extract_operand (input_line_pointer, tag_value_s, 32); + tag_name = atoi (tag_name_s); + tag_value = atoi (tag_value_s); + /* If the attribute directive is present, the tag_value should never be set + to 0. */ + if (tag_name == 0 || tag_value == 0) + as_bad (_("bad arguments \"%s\" and/or \"%s\" in %s directive"), + tag_name_s, tag_value_s, (attr_type ? ".gnu_attribute" + : ".mspabi_attribute")); + else if (attr_type == 0) + /* Handle .mspabi_attribute. */ + switch (tag_name) + { + case OFBA_MSPABI_Tag_ISA: + switch (tag_value) + { + case OFBA_MSPABI_Val_ISA_MSP430: + if (target_is_430x ()) + as_bad (_("file was compiled for the 430 ISA but the %s ISA is " + "selected"), (target_is_430xv2 () ? "430X" : "430Xv2")); + break; + case OFBA_MSPABI_Val_ISA_MSP430X: + if (!target_is_430x ()) + as_bad (_("file was compiled for the 430X ISA but the 430 ISA is " + "selected")); + break; + default: + as_bad (_("unknown MSPABI build attribute value '%d' for " + "OFBA_MSPABI_Tag_ISA(%d) in .mspabi_attribute directive"), + tag_value, OFBA_MSPABI_Tag_ISA); + break; + } + break; + case OFBA_MSPABI_Tag_Code_Model: + /* Fall through. */ + case OFBA_MSPABI_Tag_Data_Model: + /* FIXME: Might we want to set the memory model to large if the assembly + file has the large model attribute, but -ml has not been passed? */ + switch (tag_value) + { + case OFBA_MSPABI_Val_Code_Model_SMALL: + if (large_model) + as_bad (_("file was compiled for the small memory model, but the " + "large memory model is selected")); + break; + case OFBA_MSPABI_Val_Code_Model_LARGE: + if (!large_model) + as_bad (_("file was compiled for the large memory model, " + "but the small memory model is selected")); + break; + default: + as_bad (_("unknown MSPABI build attribute value '%d' for %s(%d) " + "in .mspabi_attribute directive"), tag_value, + (tag_name == OFBA_MSPABI_Tag_Code_Model + ? "OFBA_MSPABI_Tag_Code_Model" + : "OFBA_MSPABI_Tag_Data_Model"), + (tag_name == OFBA_MSPABI_Tag_Code_Model + ? OFBA_MSPABI_Tag_Code_Model + : OFBA_MSPABI_Tag_Data_Model)); + break; + } + break; + default: + as_bad (_("unknown MSPABI build attribute tag '%d' in " + ".mspabi_attribute directive"), tag_name); + break; + } + else if (attr_type == 1) + /* Handle .gnu_attribute. */ + switch (tag_name) + { + case Tag_GNU_MSP430_Data_Region: + /* This attribute is only applicable in the large memory model. */ + if (!large_model) + break; + switch (tag_value) + { + case Val_GNU_MSP430_Data_Region_Lower: + if (!lower_data_region_only) + as_bad (_("file was compiled assuming all data will be in the " + "lower memory region, but the upper region is in use")); + break; + case Val_GNU_MSP430_Data_Region_Any: + if (lower_data_region_only) + as_bad (_("file was compiled assuming data could be in the upper " + "memory region, but the lower data region is " + "exclusively in use")); + break; + default: + as_bad (_("unknown GNU build attribute value '%d' for " + "Tag_GNU_MSP430_Data_Region(%d) in .gnu_attribute " + "directive"), tag_value, Tag_GNU_MSP430_Data_Region); + } + } + else + as_bad (_("internal: unexpected argument '%d' to msp430_object_attribute"), + attr_type); +} + const pseudo_typeS md_pseudo_table[] = { {"arch", msp430_set_arch, OPTION_MMCU}, @@ -1611,6 +1734,8 @@ const pseudo_typeS md_pseudo_table[] = {"refsym", msp430_refsym, 0}, {"comm", msp430_comm, 0}, {"lcomm", msp430_lcomm, 0}, + {"mspabi_attribute", msp430_object_attribute, 0}, + {"gnu_attribute", msp430_object_attribute, 1}, {NULL, NULL, 0} }; @@ -4919,7 +5044,7 @@ msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED) return FALSE; } -/* Set the contents of the .MSP430.attributes section. */ +/* Set the contents of the .MSP430.attributes and .GNU.attributes sections. */ void msp430_md_end (void) @@ -4936,14 +5061,27 @@ msp430_md_end (void) as_warn (_(WARN_NOP_AT_EOF)); } + /* We have already emitted an error if any of the following attributes + disagree with the attributes in the input assembly file. See + msp430_object_attribute. */ bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_ISA, - target_is_430x () ? 2 : 1); + target_is_430x () ? OFBA_MSPABI_Val_ISA_MSP430X + : OFBA_MSPABI_Val_ISA_MSP430); bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Code_Model, - large_model ? 2 : 1); + large_model ? OFBA_MSPABI_Val_Code_Model_LARGE + : OFBA_MSPABI_Val_Code_Model_SMALL); bfd_elf_add_proc_attr_int (stdoutput, OFBA_MSPABI_Tag_Data_Model, - large_model ? 2 : 1); + large_model ? OFBA_MSPABI_Val_Code_Model_LARGE + : OFBA_MSPABI_Val_Code_Model_SMALL); + + /* The data region GNU attribute is ignored for the small memory model. */ + if (large_model) + bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_GNU, + Tag_GNU_MSP430_Data_Region, lower_data_region_only + ? Val_GNU_MSP430_Data_Region_Lower + : Val_GNU_MSP430_Data_Region_Any); } /* Returns FALSE if there is a msp430 specific reason why the diff --git a/gas/doc/as.texi b/gas/doc/as.texi index b4598e8..93e80f9 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -7585,6 +7585,23 @@ The vector ABI used by this object file. The value will be: @end itemize @end table +@subsection MSP430 Attributes + +@table @r +@item Tag_GNU_MSP430_Data_Region (4) +The data region used by this object file. The value will be: + +@itemize @bullet +@item +0 for files not using the large memory model. +@item +1 for files which have been compiled with the condition that all +data is in the lower memory region, i.e. below address 0x10000. +@item +2 for files which allow data to be placed in the full 20-bit memory range. +@end itemize +@end table + @node Defining New Object Attributes @section Defining New Object Attributes diff --git a/gas/doc/c-msp430.texi b/gas/doc/c-msp430.texi index 516c0038..3691f21 100644 --- a/gas/doc/c-msp430.texi +++ b/gas/doc/c-msp430.texi @@ -322,6 +322,18 @@ exist purely for pulling in object files from archives. Note that this reloc is not sufficient to prevent garbage collection; use a KEEP() directive in the linker file to preserve such objects. +@cindex @code{mspabi_attribute} directive, MSP430 +@item .mspabi_attribute +This directive tells the assembler what the MSPABI build attributes for this +file are. This is used for validating the command line options passed to +the assembler against the options the original source file was compiled with. +The expected format is: +@samp{.mspabi_attribute tag_name, tag_value} +For example, to set the tag @code{OFBA_MSPABI_Tag_ISA} to @code{MSP430X}: +@samp{.mspabi_attribute 4, 2} + +See the @cite{MSP430 EABI, document slaa534} for the details on tag names and +values. @end table @node MSP430 Opcodes diff --git a/gas/testsuite/gas/msp430/attr-430-small-bad.d b/gas/testsuite/gas/msp430/attr-430-small-bad.d new file mode 100644 index 0000000..302ba57 --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430-small-bad.d @@ -0,0 +1,4 @@ +#name: Error when 430 ISA and small memory model object attributes conflict with options +#source: attr-430-small.s +#as: -mdata-region=none -ml +#error_output: attr-430-small-bad.l diff --git a/gas/testsuite/gas/msp430/attr-430-small-bad.l b/gas/testsuite/gas/msp430/attr-430-small-bad.l new file mode 100644 index 0000000..c339ecf --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430-small-bad.l @@ -0,0 +1,4 @@ +[^:]*: Assembler messages: +[^:]*:1: Error: file was compiled for the 430 ISA but the 430X ISA is selected +[^:]*:2: Error: file was compiled for the small memory model, but the large memory model is selected +[^:]*:3: Error: file was compiled for the small memory model, but the large memory model is selected diff --git a/gas/testsuite/gas/msp430/attr-430-small-good.d b/gas/testsuite/gas/msp430/attr-430-small-good.d new file mode 100644 index 0000000..5f3137f --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430-small-good.d @@ -0,0 +1,6 @@ +#name: 430 ISA and small memory model object attributes +#source: attr-430-small.s +#as: -mcpu=msp430 +#objdump: -t + +#pass diff --git a/gas/testsuite/gas/msp430/attr-430-small.s b/gas/testsuite/gas/msp430/attr-430-small.s new file mode 100644 index 0000000..2bdb1db --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430-small.s @@ -0,0 +1,3 @@ +.mspabi_attribute 4, 1 ; OFBA_MSPABI_Tag_ISA == 430 +.mspabi_attribute 6, 1 ; OFBA_MSPABI_Tag_Code_Model == Small +.mspabi_attribute 8, 1 ; OFBA_MSPABI_Tag_Data_Model == Small diff --git a/gas/testsuite/gas/msp430/attr-430x-large-any-bad.d b/gas/testsuite/gas/msp430/attr-430x-large-any-bad.d new file mode 100644 index 0000000..6793f7c --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430x-large-any-bad.d @@ -0,0 +1,4 @@ +#name: Error when 430X ISA, large memory model and any data region object attributes conflict with options +#source: attr-430x-large-any.s +#as: -mcpu=msp430 -ml +#error_output: attr-430x-large-any-bad.l diff --git a/gas/testsuite/gas/msp430/attr-430x-large-any-bad.l b/gas/testsuite/gas/msp430/attr-430x-large-any-bad.l new file mode 100644 index 0000000..c7f2282 --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430x-large-any-bad.l @@ -0,0 +1,3 @@ +[^:]*: Assembler messages: +[^:]*:1: Error: file was compiled for the 430X ISA but the 430 ISA is selected +[^:]*:4: Error: file was compiled assuming data could be in the upper memory region, but the lower data region is exclusively in use diff --git a/gas/testsuite/gas/msp430/attr-430x-large-any-good.d b/gas/testsuite/gas/msp430/attr-430x-large-any-good.d new file mode 100644 index 0000000..603aab1 --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430x-large-any-good.d @@ -0,0 +1,6 @@ +#name: 430X ISA, large memory model and any data region object attributes +#source: attr-430x-large-any.s +#as: -ml -mdata-region=none +#objdump: -t + +#pass diff --git a/gas/testsuite/gas/msp430/attr-430x-large-any.s b/gas/testsuite/gas/msp430/attr-430x-large-any.s new file mode 100644 index 0000000..593c171 --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430x-large-any.s @@ -0,0 +1,4 @@ +.mspabi_attribute 4, 2 ; OFBA_MSPABI_Tag_ISA == 430x +.mspabi_attribute 6, 2 ; OFBA_MSPABI_Tag_Code_Model == Large +.mspabi_attribute 8, 2 ; OFBA_MSPABI_Tag_Data_Model == Large +.gnu_attribute 4, 2 ; Tag_GNU_MSP430_Data_Region == Any diff --git a/gas/testsuite/gas/msp430/attr-430x-large-lower-bad.d b/gas/testsuite/gas/msp430/attr-430x-large-lower-bad.d new file mode 100644 index 0000000..fb7e5ca --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430x-large-lower-bad.d @@ -0,0 +1,4 @@ +#name: Error when 430X ISA, large memory model and lower data region object attributes conflict with options +#source: attr-430x-large-lower.s +#as: -mdata-region=none -mcpu=msp430 -ml +#error_output: attr-430x-large-lower-bad.l diff --git a/gas/testsuite/gas/msp430/attr-430x-large-lower-bad.l b/gas/testsuite/gas/msp430/attr-430x-large-lower-bad.l new file mode 100644 index 0000000..a21b640 --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430x-large-lower-bad.l @@ -0,0 +1,3 @@ +[^:]*: Assembler messages: +[^:]*:1: Error: file was compiled for the 430X ISA but the 430 ISA is selected +[^:]*:4: Error: file was compiled assuming all data will be in the lower memory region, but the upper region is in use diff --git a/gas/testsuite/gas/msp430/attr-430x-large-lower-good.d b/gas/testsuite/gas/msp430/attr-430x-large-lower-good.d new file mode 100644 index 0000000..c4a395c --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430x-large-lower-good.d @@ -0,0 +1,6 @@ +#name: 430X ISA, large memory model and lower data region object attributes +#source: attr-430x-large-lower.s +#as: -ml +#objdump: -t + +#pass diff --git a/gas/testsuite/gas/msp430/attr-430x-large-lower.s b/gas/testsuite/gas/msp430/attr-430x-large-lower.s new file mode 100644 index 0000000..4ab0b5d --- /dev/null +++ b/gas/testsuite/gas/msp430/attr-430x-large-lower.s @@ -0,0 +1,4 @@ +.mspabi_attribute 4, 2 ; OFBA_MSPABI_Tag_ISA == 430x +.mspabi_attribute 6, 2 ; OFBA_MSPABI_Tag_Code_Model == Large +.mspabi_attribute 8, 2 ; OFBA_MSPABI_Tag_Data_Model == Large +.gnu_attribute 4, 1 ; Tag_GNU_MSP430_Data_Region == Lower diff --git a/gas/testsuite/gas/msp430/msp430.exp b/gas/testsuite/gas/msp430/msp430.exp index 9c7a197..ef3164d 100644 --- a/gas/testsuite/gas/msp430/msp430.exp +++ b/gas/testsuite/gas/msp430/msp430.exp @@ -46,4 +46,10 @@ if [expr [istarget "msp430-*-*"]] then { run_dump_test "preinit-array" run_dump_test "init-array" run_dump_test "fini-array" + run_dump_test "attr-430-small-bad" + run_dump_test "attr-430-small-good" + run_dump_test "attr-430x-large-lower-bad" + run_dump_test "attr-430x-large-lower-good" + run_dump_test "attr-430x-large-any-bad" + run_dump_test "attr-430x-large-any-good" } |