208 lines
6.1 KiB
Diff
208 lines
6.1 KiB
Diff
|
|
From fdb688f870f5d9078de4fe77a7d3fbed57df5b07 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Lulu Cai <cailulu@loongson.cn>
|
||
|
|
Date: Tue, 21 May 2024 10:14:27 +0800
|
||
|
|
Subject: [PATCH 091/123] LoongArch: add .option directive
|
||
|
|
|
||
|
|
In some cases we may want to use different options only for certain
|
||
|
|
assembly, so the .option directive is added to control the assembler
|
||
|
|
options.
|
||
|
|
|
||
|
|
.option can accept 4 parameters:
|
||
|
|
|
||
|
|
push
|
||
|
|
pop
|
||
|
|
Pushes or pops the current option stack. They limit the scope of
|
||
|
|
option changes so that they do not affect other parts of the assembly
|
||
|
|
file.
|
||
|
|
|
||
|
|
relax
|
||
|
|
norelax
|
||
|
|
Enables or disables relaxation.
|
||
|
|
---
|
||
|
|
gas/config/tc-loongarch.c | 59 +++++++++++++++++++
|
||
|
|
gas/testsuite/gas/loongarch/loongarch.exp | 1 +
|
||
|
|
.../gas/loongarch/pseudo_op_option.d | 36 +++++++++++
|
||
|
|
.../gas/loongarch/pseudo_op_option.s | 19 ++++++
|
||
|
|
.../gas/loongarch/pseudo_op_option_fail.l | 2 +
|
||
|
|
.../gas/loongarch/pseudo_op_option_fail.s | 2 +
|
||
|
|
6 files changed, 119 insertions(+)
|
||
|
|
create mode 100644 gas/testsuite/gas/loongarch/pseudo_op_option.d
|
||
|
|
create mode 100644 gas/testsuite/gas/loongarch/pseudo_op_option.s
|
||
|
|
create mode 100644 gas/testsuite/gas/loongarch/pseudo_op_option_fail.l
|
||
|
|
create mode 100644 gas/testsuite/gas/loongarch/pseudo_op_option_fail.s
|
||
|
|
|
||
|
|
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
|
||
|
|
index f039d027..72815233 100644
|
||
|
|
--- a/gas/config/tc-loongarch.c
|
||
|
|
+++ b/gas/config/tc-loongarch.c
|
||
|
|
@@ -541,6 +541,64 @@ s_dtprel (int bytes)
|
||
|
|
demand_empty_rest_of_line ();
|
||
|
|
}
|
||
|
|
|
||
|
|
+struct LARCH_option_stack
|
||
|
|
+{
|
||
|
|
+ struct LARCH_option_stack *next;
|
||
|
|
+ struct loongarch_ASEs_option options;
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static struct LARCH_option_stack *LARCH_opts_stack = NULL;
|
||
|
|
+
|
||
|
|
+/* Handle the .option pseudo-op.
|
||
|
|
+ The alignment of .align is done by R_LARCH_ALIGN at link time.
|
||
|
|
+ If the .align directive is within the range controlled by
|
||
|
|
+ .option norelax, that is, relax is turned off, R_LARCH_ALIGN
|
||
|
|
+ cannot be generated, which may cause ld to be unable to handle
|
||
|
|
+ the alignment. */
|
||
|
|
+static void
|
||
|
|
+s_loongarch_option (int x ATTRIBUTE_UNUSED)
|
||
|
|
+{
|
||
|
|
+ char *name = input_line_pointer, ch;
|
||
|
|
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
|
||
|
|
+ ++input_line_pointer;
|
||
|
|
+ ch = *input_line_pointer;
|
||
|
|
+ *input_line_pointer = '\0';
|
||
|
|
+
|
||
|
|
+ if (strcmp (name, "relax") == 0)
|
||
|
|
+ LARCH_opts.relax = 1;
|
||
|
|
+ else if (strcmp (name, "norelax") == 0)
|
||
|
|
+ LARCH_opts.relax = 0;
|
||
|
|
+ else if (strcmp (name, "push") == 0)
|
||
|
|
+ {
|
||
|
|
+ struct LARCH_option_stack *s;
|
||
|
|
+
|
||
|
|
+ s = XNEW (struct LARCH_option_stack);
|
||
|
|
+ s->next = LARCH_opts_stack;
|
||
|
|
+ s->options = LARCH_opts;
|
||
|
|
+ LARCH_opts_stack = s;
|
||
|
|
+ }
|
||
|
|
+ else if (strcmp (name, "pop") == 0)
|
||
|
|
+ {
|
||
|
|
+ struct LARCH_option_stack *s;
|
||
|
|
+
|
||
|
|
+ s = LARCH_opts_stack;
|
||
|
|
+ if (s == NULL)
|
||
|
|
+ as_bad (_(".option pop with no .option push"));
|
||
|
|
+ else
|
||
|
|
+ {
|
||
|
|
+ LARCH_opts_stack = s->next;
|
||
|
|
+ LARCH_opts = s->options;
|
||
|
|
+ free (s);
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+ else
|
||
|
|
+ {
|
||
|
|
+ as_warn (_("unrecognized .option directive: %s"), name);
|
||
|
|
+ }
|
||
|
|
+ *input_line_pointer = ch;
|
||
|
|
+ demand_empty_rest_of_line ();
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static const pseudo_typeS loongarch_pseudo_table[] =
|
||
|
|
{
|
||
|
|
{ "dword", cons, 8 },
|
||
|
|
@@ -548,6 +606,7 @@ static const pseudo_typeS loongarch_pseudo_table[] =
|
||
|
|
{ "half", cons, 2 },
|
||
|
|
{ "dtprelword", s_dtprel, 4 },
|
||
|
|
{ "dtpreldword", s_dtprel, 8 },
|
||
|
|
+ { "option", s_loongarch_option, 0},
|
||
|
|
{ NULL, NULL, 0 },
|
||
|
|
};
|
||
|
|
|
||
|
|
diff --git a/gas/testsuite/gas/loongarch/loongarch.exp b/gas/testsuite/gas/loongarch/loongarch.exp
|
||
|
|
index a2ccfb13..157797c5 100644
|
||
|
|
--- a/gas/testsuite/gas/loongarch/loongarch.exp
|
||
|
|
+++ b/gas/testsuite/gas/loongarch/loongarch.exp
|
||
|
|
@@ -35,5 +35,6 @@ if [istarget loongarch*-*-*] {
|
||
|
|
|
||
|
|
if [istarget loongarch64-*-*] {
|
||
|
|
run_list_test "illegal-operand"
|
||
|
|
+ run_list_test "pseudo_op_option_fail"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
diff --git a/gas/testsuite/gas/loongarch/pseudo_op_option.d b/gas/testsuite/gas/loongarch/pseudo_op_option.d
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000..53921a1e
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gas/testsuite/gas/loongarch/pseudo_op_option.d
|
||
|
|
@@ -0,0 +1,36 @@
|
||
|
|
+#as: -mrelax
|
||
|
|
+#objdump: -dr
|
||
|
|
+#skip: loongarch32-*-*
|
||
|
|
+
|
||
|
|
+.*: file format .*
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+Disassembly of section .text:
|
||
|
|
+
|
||
|
|
+0.* <.text>:
|
||
|
|
+ 0: 1a000004 pcalau12i \$a0, 0
|
||
|
|
+ 0: R_LARCH_PCALA_HI20 x
|
||
|
|
+ 0: R_LARCH_RELAX \*ABS\*
|
||
|
|
+ 4: 02c00084 addi.d \$a0, \$a0, 0
|
||
|
|
+ 4: R_LARCH_PCALA_LO12 x
|
||
|
|
+ 4: R_LARCH_RELAX \*ABS\*
|
||
|
|
+ 8: 1a000004 pcalau12i \$a0, 0
|
||
|
|
+ 8: R_LARCH_PCALA_HI20 x
|
||
|
|
+ c: 02c00084 addi.d \$a0, \$a0, 0
|
||
|
|
+ c: R_LARCH_PCALA_LO12 x
|
||
|
|
+ 10: 1a000004 pcalau12i \$a0, 0
|
||
|
|
+ 10: R_LARCH_PCALA_HI20 x
|
||
|
|
+ 10: R_LARCH_RELAX \*ABS\*
|
||
|
|
+ 14: 02c00084 addi.d \$a0, \$a0, 0
|
||
|
|
+ 14: R_LARCH_PCALA_LO12 x
|
||
|
|
+ 14: R_LARCH_RELAX \*ABS\*
|
||
|
|
+ 18: 1a000004 pcalau12i \$a0, 0
|
||
|
|
+ 18: R_LARCH_PCALA_HI20 x
|
||
|
|
+ 1c: 02c00084 addi.d \$a0, \$a0, 0
|
||
|
|
+ 1c: R_LARCH_PCALA_LO12 x
|
||
|
|
+ 20: 1a000004 pcalau12i \$a0, 0
|
||
|
|
+ 20: R_LARCH_PCALA_HI20 x
|
||
|
|
+ 20: R_LARCH_RELAX \*ABS\*
|
||
|
|
+ 24: 02c00084 addi.d \$a0, \$a0, 0
|
||
|
|
+ 24: R_LARCH_PCALA_LO12 x
|
||
|
|
+ 24: R_LARCH_RELAX \*ABS\*
|
||
|
|
diff --git a/gas/testsuite/gas/loongarch/pseudo_op_option.s b/gas/testsuite/gas/loongarch/pseudo_op_option.s
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000..f21b7263
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gas/testsuite/gas/loongarch/pseudo_op_option.s
|
||
|
|
@@ -0,0 +1,19 @@
|
||
|
|
+# Gas enables relax by default.
|
||
|
|
+# Push and pop can be nested, and each pop restores the options before
|
||
|
|
+# the most recent push.
|
||
|
|
+ .text
|
||
|
|
+.L1:
|
||
|
|
+ la.pcrel $a0,x
|
||
|
|
+
|
||
|
|
+ .option push
|
||
|
|
+ .option norelax
|
||
|
|
+ la.pcrel $a0,x
|
||
|
|
+
|
||
|
|
+ .option push
|
||
|
|
+ .option relax
|
||
|
|
+ la.pcrel $a0,x
|
||
|
|
+ .option pop
|
||
|
|
+
|
||
|
|
+ la.pcrel $a0,x
|
||
|
|
+ .option pop
|
||
|
|
+ la.pcrel $a0,x
|
||
|
|
diff --git a/gas/testsuite/gas/loongarch/pseudo_op_option_fail.l b/gas/testsuite/gas/loongarch/pseudo_op_option_fail.l
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000..ffb9a72e
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gas/testsuite/gas/loongarch/pseudo_op_option_fail.l
|
||
|
|
@@ -0,0 +1,2 @@
|
||
|
|
+.*: Assembler messages:
|
||
|
|
+.*: Error: \.option pop with no \.option push
|
||
|
|
diff --git a/gas/testsuite/gas/loongarch/pseudo_op_option_fail.s b/gas/testsuite/gas/loongarch/pseudo_op_option_fail.s
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000..e368cdba
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gas/testsuite/gas/loongarch/pseudo_op_option_fail.s
|
||
|
|
@@ -0,0 +1,2 @@
|
||
|
|
+ .text
|
||
|
|
+ .option pop
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|