This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH][mips] Introduce '.set noase' to the mips assembler.
- From: Egeyar Bagcioglu <egeyar dot bagcioglu at oracle dot com>
- To: Binutils <binutils at sourceware dot org>
- Date: Thu, 26 Sep 2019 19:51:58 +0200
- Subject: [PATCH][mips] Introduce '.set noase' to the mips assembler.
Hello,
I would like to propose the attached tiny patch, together with the
lengthy explanation of its use case. Please review.
Currently, the mips assembler keeps, as a part of its runtime state,
information regarding the accepted ISA and ASEs (Application Specific
Extensions). It is possible to change the ISA or allowed extensions on
the fly. It is also possible to use ".set push" to save the state
regarding the accepted instructions, change them, and pop the previously
pushed state afterwards.
Linux kernel takes advantage of this situation in its mips inline
assembly functions. The assembler is asked to push into the stack the
information of the target platform. The ISA is then set to mips3, which
is the strictest, to make sure that the assembler generates an error if
the inline assembler is not accepted by all mips platforms. At the end
of the inline assembly, the previous state of the assembler is restored
with a ".set pop":
.set push
.set mips3 #the base ISA
<assembly>
.set pop
The above usage works mostly, when no ASEs are enabled or when the
enabled ASEs are accepted in mips3 due other settings (such as micromips
being enabled, etc.). If, however, a conflicting ASE is enabled, the
switch to mips3 causes the assembler to generate a warning per file
because mips3 does not support that given ASE. While building a big
project such as the kernel, one warning per file with inline assembly
means several hundreds of warnings in total.
I have considered different ways to solve this issue. If we implicitly
disable the unsupported ASEs upon switching to a new ISA, we lose
backwards compatibility. Any project which is -for whatever reason-
generating some extension instructions that are not supported by the
given ISA would start getting errors from the assembler. If we decide to
turn off the warnings under whatever condition, the assembler would
start accepting unsupported extension instructions without even a
warning. This would, for example, undermine the kernel's use-case. A
more-user-friendly option could be delaying the warning. We would not
warn when a conflicting ISA is set. Instead, we would store this
information, check the following instructions and only warn if/when we
see the first instruction using a conflicting ASE. However, I believe
the overhead of this approach could not be justified by the need.
The change I propose is to add a new ".set noase" directive to disable
all the ASEs. This pseudo-op would be beneficial primarily within .set
push/pop pairs of inline assembly functions as used by the kernel, by
explicitly disabling all 19 extensions of mips architecture and avoiding
the related warnings. An example usage of it would transform the inline
assembly functions into the following format:
.set push
.set noase
.set mips3 #the base ISA
<assembly>
.set pop
As .set push/pop pairs also saves and restores the state of enabled
ASEs, this would indeed serve the purpose of limiting the generation of
extension instructions within that pair, without permanently changing
which instructions are allowed. Having said that, the execution of this
directive does not depend on the .set push/pop pairs. Therefore, it can
also be used separately.
I do not know how likely it is for the kernel or other projects to use
this new directive as it would depend on a very new binutils patch.
Although, it might be applied together with a macro controlling its
usage. Either way, I still see value in assembler supporting such a usage.
As it is new, this directive does not interfere with the existing
regression tests. Therefore, you'll see a new test case in the patch as
well.
The suggested gas/ChangeLog is
2019-09-26 Egeyar Bagcioglu <egeyar.bagcioglu@oracle.com>
* config/tc-mips.c (parse_code_option): Introduce ".set/.module
noase" pseudo-op to disable all Application Specific Extensions.
* gas/testsuite/gas/mips/ase-errors-5.l: New test.
* gas/testsuite/gas/mips/ase-errors-5.s: New test source.
* gas/testsuite/gas/mips/mips.exp: Run the new test.
Please review and let me know what you think.
Thanks,
Egeyar
commit d8c1a1be8f1919198cdbc1d63d3f0a4efdb9886f
Author: Egeyar Bagcioglu <egeyar.bagcioglu@oracle.com>
Date: Tue Sep 24 15:52:47 2019 +0000
Introduce '.set noase' to the mips assembler.
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index b2e4973..69c3fb1 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -205,8 +205,8 @@ struct mips_set_options
-mipsN command line option, and the default CPU. */
int isa;
/* Enabled Application Specific Extensions (ASEs). Changed by `.set
- <asename>', by command line options, and based on the default
- architecture. */
+ <asename>', by `.set noase', by command line options, and based on
+ the default architecture. */
int ase;
/* Whether we are assembling for the mips16 processor. 0 if we are
not, 1 if we are, and -1 if the value has not been initialized.
@@ -16716,6 +16716,8 @@ parse_code_option (char * name)
mips_opts.sym32 = TRUE;
else if (strcmp (name, "nosym32") == 0)
mips_opts.sym32 = FALSE;
+ else if (strcmp (name, "noase") == 0)
+ mips_opts.ase = 0;
else
return OPTION_TYPE_BAD;
diff --git a/gas/testsuite/gas/mips/ase-errors-5.l b/gas/testsuite/gas/mips/ase-errors-5.l
new file mode 100644
index 0000000..06c60ff
--- /dev/null
+++ b/gas/testsuite/gas/mips/ase-errors-5.l
@@ -0,0 +1,14 @@
+.*Assembler messages:
+.*:6: Error: opcode not supported.* `aclr 4,100\(\$4\)'
+# ----------------------------------------------------------------------------
+.*:11: Error: opcode not supported.* `aclr 4,100\(\$4\)'
+# ----------------------------------------------------------------------------
+.*:13: Error: opcode not supported.* `lbux \$4,\$5\(\$6\)'
+.*:14: Error: opcode not supported.* `ldx \$4,\$5\(\$6\)'
+.*:15: Error: opcode not supported.* `aclr 4,100\(\$4\)'
+# ----------------------------------------------------------------------------
+.*:17: Error: opcode not supported.* `lbux \$4,\$5\(\$6\)'
+.*:18: Error: opcode not supported.* `ldx \$4,\$5\(\$6\)'
+# ----------------------------------------------------------------------------
+.*:24: Error: opcode not supported.* `aclr 4,100\(\$4\)'
+# ----------------------------------------------------------------------------
diff --git a/gas/testsuite/gas/mips/ase-errors-5.s b/gas/testsuite/gas/mips/ase-errors-5.s
new file mode 100644
index 0000000..f419c16
--- /dev/null
+++ b/gas/testsuite/gas/mips/ase-errors-5.s
@@ -0,0 +1,24 @@
+ .set nomicromips
+ .set mips64r2
+ .set dsp # OK
+ lbux $4,$5($6) # OK
+ ldx $4,$5($6) # OK
+ aclr 4,100($4) # ERROR: mcu not enabled
+
+ .set push
+ lbux $4,$5($6) # OK
+ ldx $4,$5($6) # OK
+ aclr 4,100($4) # ERROR: mcu not enabled
+ .set noase
+ lbux $4,$5($6) # ERROR: dsp not enabled
+ ldx $4,$5($6) # ERROR: dsp not enabled
+ aclr 4,100($4) # ERROR: mcu not enabled
+ .set mcu
+ lbux $4,$5($6) # ERROR: dsp not enabled
+ ldx $4,$5($6) # ERROR: dsp not enabled
+ aclr 4,100($4) # OK
+ .set pop
+
+ lbux $4,$5($6) # OK
+ ldx $4,$5($6) # OK
+ aclr 4,100($4) # ERROR: mcu not enabled
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 2084ee0..9bb8886 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -1581,6 +1581,7 @@ if { [istarget mips*-*-vxworks*] } {
run_list_test "ase-errors-2" "-mabi=o64 -march=mips3" "ASE errors (2)"
run_list_test "ase-errors-3" "-mabi=32 -march=mips1" "ASE errors (3)"
run_list_test "ase-errors-4" "-mabi=o64 -march=mips3" "ASE errors (4)"
+ run_list_test "ase-errors-5" "-mabi=o64 -march=mips3" "ASE errors (5)"
run_dump_test_arches "la-reloc" [mips_arch_list_matching mips1]
run_list_test "dla-warn" "-mabi=32 -march=mips3" \