aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog24
-rw-r--r--gas/config/tc-msp430.c146
-rw-r--r--gas/doc/as.texi17
-rw-r--r--gas/doc/c-msp430.texi12
-rw-r--r--gas/testsuite/gas/msp430/attr-430-small-bad.d4
-rw-r--r--gas/testsuite/gas/msp430/attr-430-small-bad.l4
-rw-r--r--gas/testsuite/gas/msp430/attr-430-small-good.d6
-rw-r--r--gas/testsuite/gas/msp430/attr-430-small.s3
-rw-r--r--gas/testsuite/gas/msp430/attr-430x-large-any-bad.d4
-rw-r--r--gas/testsuite/gas/msp430/attr-430x-large-any-bad.l3
-rw-r--r--gas/testsuite/gas/msp430/attr-430x-large-any-good.d6
-rw-r--r--gas/testsuite/gas/msp430/attr-430x-large-any.s4
-rw-r--r--gas/testsuite/gas/msp430/attr-430x-large-lower-bad.d4
-rw-r--r--gas/testsuite/gas/msp430/attr-430x-large-lower-bad.l3
-rw-r--r--gas/testsuite/gas/msp430/attr-430x-large-lower-good.d6
-rw-r--r--gas/testsuite/gas/msp430/attr-430x-large-lower.s4
-rw-r--r--gas/testsuite/gas/msp430/msp430.exp6
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"
}