[PATCH] LoongArch: add .option directive
Lulu Cai
cailulu@loongson.cn
Fri May 31 07:26:11 GMT 2024
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.
Push and pop limit the scope of the option change, and other assembly
will not be affected.
Such as le relax:
.text
L1:
.option push
.option norelax
lu12i.w $t0,%le_hi20(s)
addi.d $t0,$t0,le_lo12(s)
.option relax
lu12i.w $t0,%le_hi20(s)
addi.d $t0,$t0,le_lo12(s)
.option pop
After assembly:
Disassembly of section .text:
0000000000000000 <L1>:
0: 1400000c lu12i.w $t0, 0
0: R_LARCH_TLS_LE_HI20 s
4: 02c0018c addi.d $t0, $t0, 0
4: R_LARCH_TLS_LE_LO12 s
8: 1400000c lu12i.w $t0, 0
8: R_LARCH_TLS_LE_HI20 s
8: R_LARCH_RELAX *ABS*
c: 02c0018c addi.d $t0, $t0, 0
c: R_LARCH_TLS_LE_LO12 s
c: R_LARCH_RELAX *ABS*
---
gas/config/tc-loongarch.c | 54 +++++++++++
.../gas/loongarch/pseudo_op_option.d | 90 +++++++++++++++++++
.../gas/loongarch/pseudo_op_option.s | 42 +++++++++
3 files changed, 186 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/pseudo_op_option.d
create mode 100644 gas/testsuite/gas/loongarch/pseudo_op_option.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 00b8c80c3de..ae228dfa572 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -482,6 +482,59 @@ 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. */
+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 },
@@ -489,6 +542,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/pseudo_op_option.d b/gas/testsuite/gas/loongarch/pseudo_op_option.d
new file mode 100644
index 00000000000..b3d7c0dddc9
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pseudo_op_option.d
@@ -0,0 +1,90 @@
+#as: -mno-relax
+#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_GOT_PC_HI20 x
+ 8: R_LARCH_RELAX \*ABS\*
+ c: 28c00084 ld.d \$a0, \$a0, 0
+ c: R_LARCH_GOT_PC_LO12 x
+ c: R_LARCH_RELAX \*ABS\*
+ 10: 14000004 lu12i.w \$a0, 0
+ 10: R_LARCH_TLS_LE_HI20 t
+ 10: R_LARCH_RELAX \*ABS\*
+ 14: 03800084 ori \$a0, \$a0, 0x0
+ 14: R_LARCH_TLS_LE_LO12 t
+ 14: R_LARCH_RELAX \*ABS\*
+ 18: 1a000004 pcalau12i \$a0, 0
+ 18: R_LARCH_TLS_IE_PC_HI20 t
+ 18: R_LARCH_RELAX \*ABS\*
+ 1c: 28c00084 ld.d \$a0, \$a0, 0
+ 1c: R_LARCH_TLS_IE_PC_LO12 t
+ 1c: R_LARCH_RELAX \*ABS\*
+ 20: 1a000004 pcalau12i \$a0, 0
+ 20: R_LARCH_TLS_LD_PC_HI20 t
+ 20: R_LARCH_RELAX \*ABS\*
+ 24: 02c00084 addi.d \$a0, \$a0, 0
+ 24: R_LARCH_GOT_PC_LO12 t
+ 24: R_LARCH_RELAX \*ABS\*
+ 28: 1a000004 pcalau12i \$a0, 0
+ 28: R_LARCH_TLS_GD_PC_HI20 t
+ 28: R_LARCH_RELAX \*ABS\*
+ 2c: 02c00084 addi.d \$a0, \$a0, 0
+ 2c: R_LARCH_GOT_PC_LO12 t
+ 2c: R_LARCH_RELAX \*ABS\*
+ 30: 1a000004 pcalau12i \$a0, 0
+ 30: R_LARCH_TLS_DESC_PC_HI20 t
+ 30: R_LARCH_RELAX \*ABS\*
+ 34: 02c00084 addi.d \$a0, \$a0, 0
+ 34: R_LARCH_TLS_DESC_PC_LO12 t
+ 34: R_LARCH_RELAX \*ABS\*
+ 38: 28c00081 ld.d \$ra, \$a0, 0
+ 38: R_LARCH_TLS_DESC_LD t
+ 38: R_LARCH_RELAX \*ABS\*
+ 3c: 4c000021 jirl \$ra, \$ra, 0
+ 3c: R_LARCH_TLS_DESC_CALL t
+ 3c: R_LARCH_RELAX \*ABS\*
+ 40: 1a000004 pcalau12i \$a0, 0
+ 40: R_LARCH_PCALA_HI20 x
+ 44: 02c00084 addi.d \$a0, \$a0, 0
+ 44: R_LARCH_PCALA_LO12 x
+ 48: 1a000004 pcalau12i \$a0, 0
+ 48: R_LARCH_GOT_PC_HI20 x
+ 4c: 28c00084 ld.d \$a0, \$a0, 0
+ 4c: R_LARCH_GOT_PC_LO12 x
+ 50: 14000004 lu12i.w \$a0, 0
+ 50: R_LARCH_TLS_LE_HI20 t
+ 54: 03800084 ori \$a0, \$a0, 0x0
+ 54: R_LARCH_TLS_LE_LO12 t
+ 58: 1a000004 pcalau12i \$a0, 0
+ 58: R_LARCH_TLS_IE_PC_HI20 t
+ 5c: 28c00084 ld.d \$a0, \$a0, 0
+ 5c: R_LARCH_TLS_IE_PC_LO12 t
+ 60: 1a000004 pcalau12i \$a0, 0
+ 60: R_LARCH_TLS_LD_PC_HI20 t
+ 64: 02c00084 addi.d \$a0, \$a0, 0
+ 64: R_LARCH_GOT_PC_LO12 t
+ 68: 1a000004 pcalau12i \$a0, 0
+ 68: R_LARCH_TLS_GD_PC_HI20 t
+ 6c: 02c00084 addi.d \$a0, \$a0, 0
+ 6c: R_LARCH_GOT_PC_LO12 t
+ 70: 1a000004 pcalau12i \$a0, 0
+ 70: R_LARCH_TLS_DESC_PC_HI20 t
+ 74: 02c00084 addi.d \$a0, \$a0, 0
+ 74: R_LARCH_TLS_DESC_PC_LO12 t
+ 78: 28c00081 ld.d \$ra, \$a0, 0
+ 78: R_LARCH_TLS_DESC_LD t
+ 7c: 4c000021 jirl \$ra, \$ra, 0
+ 7c: R_LARCH_TLS_DESC_CALL t
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 00000000000..e0ba770035d
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pseudo_op_option.s
@@ -0,0 +1,42 @@
+ .section .tdata,"awT",@progbits
+ .type t,@object
+t:
+ .word 1
+
+ .text
+.L1:
+ .option push
+
+ .option relax
+# pc relative offset
+ la.pcrel $a0,x
+# got relative offset
+ la.got $a0,x
+# tls le
+ la.tls.le $a0,t
+# tls ie
+ la.tls.ie $a0,t
+# tls ld
+ la.tls.ld $a0,t
+# tls gd
+ la.tls.gd $a0,t
+#tlsdesc
+ la.tls.desc $a0,t
+
+ .option norelax
+# pc relative offset
+ la.pcrel $a0,x
+# got relative offset
+ la.got $a0,x
+# tls le
+ la.tls.le $a0,t
+# tls ie
+ la.tls.ie $a0,t
+# tls ld
+ la.tls.ld $a0,t
+# tls gd
+ la.tls.gd $a0,t
+#tlsdesc
+ la.tls.desc $a0,t
+
+ .option pop
--
2.38.1
More information about the Binutils
mailing list