[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