public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [patch] MIPS gas problems with gcc's explicit relocs
@ 2004-05-28 19:00 Maciej W. Rozycki
  2004-05-28 21:50 ` Thiemo Seufer
  2004-05-29  6:39 ` Richard Sandiford
  0 siblings, 2 replies; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-05-28 19:00 UTC (permalink / raw)
  To: binutils

Hello,

 The recent addition of explicit relocation generation to gcc triggered 
failures for inline assembly under certain conditions.  Example: given the 
following program:

$ cat dlac.c
extern void *foo;
void *bar(void)
{
	void *result;
	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
	return result;
}

I get:

$ mips64el-linux-gcc -mno-abicalls -S -o dlac.s dlac.c
$ cat dlac.s
	.file	1 "dlac.c"
	.section .mdebug.abi64
	.previous
	.text
	.align	2
	.align	2
	.globl	bar
	.ent	bar
	.type	bar, @function
bar:
	.frame	$fp,32,$31		# vars= 16, regs= 1/0, args= 0, gp= 0
	.mask	0x40000000,-16
	.fmask	0x00000000,0
	daddiu	$sp,$sp,-32
	sd	$fp,16($sp)
	move	$fp,$sp
	lui	$2,%highest(foo)
	daddiu	$2,$2,%higher(foo)
	dsll	$2,$2,16
	daddiu	$2,$2,%hi(foo)
	dsll	$2,$2,16
#APP
	dla	$2,%lo(foo)($2)
#NO_APP
	sd	$2,0($fp)
	ld	$2,0($fp)
	move	$sp,$fp
	ld	$fp,16($sp)
	daddiu	$sp,$sp,32
	j	$31
	.end	bar
	.ident	"GCC: (GNU) 3.5.0 20040522 (experimental)"

which fails to be assembled by gas due to a reloc operator used in the
second operand of "dla":

$ mips64el-linux-gcc -mno-abicalls -c -o dlac.o dlac.s
dlac.s: Assembler messages:
dlac.s:23: Error: bad expression
dlac.s:23: Error: illegal operands `dla'

 Here's a patch that adds handling of such reloc operators to "la" and 
related macros, implementing the expected behavior.  The above program 
gets assembled to:

$ mips64el-linux-objdump -Sr dlac.o

dlac.o:     file format elf64-tradlittlemips

Disassembly of section .text:

0000000000000000 <bar>:
   0:	67bdffe0 	daddiu	sp,sp,-32
   4:	ffbe0010 	sd	s8,16(sp)
   8:	03a0f02d 	move	s8,sp
   c:	3c020000 	lui	v0,0x0
			c: R_MIPS_HIGHEST	foo
			c: R_MIPS_NONE	*ABS*
			c: R_MIPS_NONE	*ABS*
  10:	64420000 	daddiu	v0,v0,0
			10: R_MIPS_HIGHER	foo
			10: R_MIPS_NONE	*ABS*
			10: R_MIPS_NONE	*ABS*
  14:	00021438 	dsll	v0,v0,0x10
  18:	64420000 	daddiu	v0,v0,0
			18: R_MIPS_HI16	foo
			18: R_MIPS_NONE	*ABS*
			18: R_MIPS_NONE	*ABS*
  1c:	00021438 	dsll	v0,v0,0x10
  20:	64420000 	daddiu	v0,v0,0
			20: R_MIPS_LO16	foo
			20: R_MIPS_NONE	*ABS*
			20: R_MIPS_NONE	*ABS*
  24:	ffc20000 	sd	v0,0(s8)
  28:	dfc20000 	ld	v0,0(s8)
  2c:	03c0e82d 	move	sp,s8
  30:	dfbe0010 	ld	s8,16(sp)
  34:	03e00008 	jr	ra
  38:	67bd0020 	daddiu	sp,sp,32
  3c:	00000000 	nop

gas/ChangeLog:
2004-05-28  Maciej W. Rozycki  <macro@ds2.pg.gda.pl>

	* config/tc-mips.c (append_insn): Handle constant expressions with 
	no associated relocation.
	(macro): Handle reloc operators in operands of load address 
	macros.
	(mips_ip): Cancel the expression after use for the Q format 
	specifier.
	(parse_relocation): Return no relocation for unsupported 
	operators.
	(my_getSmallExpression): Return no relocation if no relocation 
	operators are used.

gas/testsuite/ChangeLog:
2004-05-28  Maciej W. Rozycki  <macro@ds2.pg.gda.pl>

	* gas/mips/elf-rel20.d: New test for reloc operators with "la".
	* gas/mips/elf-rel20.s: Source for the new test.
	* gas/mips/mips.exp: Run the new test.

opcodes/ChangeLog:
2004-05-28  Maciej W. Rozycki  <macro@ds2.pg.gda.pl>

	* mips-opc.c (mips_builtin_opcodes): Handle reloc operators in 
	operands of load address macros.

 A few notes:

1. I handle "dla", "dlca", "la" and "lca" the same way for symmetry and
simplicity.  The reloc used overrides the macro name for GOT vs CALL
relocations.  I see no point in making it more complicated.  Ditto about
reloc operators of a dubious use here -- they're all handled as with
load/store instructions.

2. I feel the changes to use BFD_RELOC_UNUSED when no relocation is to be 
used are the Right Thing -- I see no point in pretending a BFD_RELOC_LO16 
relocation was used.  The change appears safe, except a small bug had to 
be corrected in MDMX support code.

3. The change was tested for the mips64el-linux target -- no regressions
in the testsuite.  A testcase is included.

 OK to apply?

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

binutils-2.15.91-20040527-mips-la-reloc.patch
diff -up --recursive --new-file binutils-2.15.91-20040527.macro/gas/config/tc-mips.c binutils-2.15.91-20040527/gas/config/tc-mips.c
--- binutils-2.15.91-20040527.macro/gas/config/tc-mips.c	2004-05-21 03:25:26.000000000 +0000
+++ binutils-2.15.91-20040527/gas/config/tc-mips.c	2004-05-28 14:38:52.000000000 +0000
@@ -2079,7 +2079,7 @@ append_insn (struct mips_cl_insn *ip, ex
     }
 
   fixp[0] = fixp[1] = fixp[2] = NULL;
-  if (address_expr != NULL && *reloc_type < BFD_RELOC_UNUSED)
+  if (address_expr != NULL)
     {
       if (address_expr->X_op == O_constant)
 	{
@@ -2112,6 +2112,7 @@ append_insn (struct mips_cl_insn *ip, ex
 	      ip->insn_opcode |= (address_expr->X_add_number >> 16) & 0xffff;
 	      break;
 
+	    case BFD_RELOC_UNUSED:
 	    case BFD_RELOC_LO16:
 	    case BFD_RELOC_MIPS_GOT_DISP:
 	      ip->insn_opcode |= address_expr->X_add_number & 0xffff;
@@ -2147,7 +2148,7 @@ append_insn (struct mips_cl_insn *ip, ex
 	      internalError ();
 	    }
 	}
-      else
+      else if (*reloc_type < BFD_RELOC_UNUSED)
 	need_reloc:
 	{
 	  reloc_howto_type *howto;
@@ -4869,6 +4870,15 @@ macro (struct mips_cl_insn *ip)
 	  return;
 	}
 
+      if (offset_expr.X_op == O_symbol
+	  && *offset_reloc != BFD_RELOC_UNUSED)
+	{
+	  macro_build (&offset_expr,
+		       (dbl || HAVE_64BIT_ADDRESSES) ? "daddiu" : "addiu",
+		       "t,r,j", treg, sreg, *offset_reloc);
+	  return;
+	}
+
       if (treg == breg)
 	{
 	  tempreg = AT;
@@ -8596,6 +8606,7 @@ do_msbd:
 			  ip->insn_opcode |= (imm_expr.X_add_number
 					      << (OP_SH_VSEL +
 						  (is_qh ? 2 : 1)));
+			  imm_expr.X_op = O_absent;
 			  if (*s != ']')
 			    as_warn(_("Expecting ']' found '%s'"), s);
 			  else
@@ -9809,7 +9820,7 @@ parse_relocation (char **str, bfd_reloc_
 	  {
 	    as_bad ("relocation %s isn't supported by the current ABI",
 		    percent_op[i].str);
-	    *reloc = BFD_RELOC_LO16;
+	    *reloc = BFD_RELOC_UNUSED;
 	  }
 	return TRUE;
       }
@@ -9821,8 +9832,7 @@ parse_relocation (char **str, bfd_reloc_
    expression in *EP and the relocations in the array starting
    at RELOC.  Return the number of relocation operators used.
 
-   On exit, EXPR_END points to the first character after the expression.
-   If no relocation operators are used, RELOC[0] is set to BFD_RELOC_LO16.  */
+   On exit, EXPR_END points to the first character after the expression.  */
 
 static size_t
 my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
@@ -9868,9 +9878,7 @@ my_getSmallExpression (expressionS *ep, 
 
   expr_end = str;
 
-  if (reloc_index == 0)
-    reloc[0] = BFD_RELOC_LO16;
-  else
+  if (reloc_index != 0)
     {
       prev_reloc_op_frag = frag_now;
       for (i = 0; i < reloc_index; i++)
diff -up --recursive --new-file binutils-2.15.91-20040527.macro/gas/testsuite/gas/mips/elf-rel20.d binutils-2.15.91-20040527/gas/testsuite/gas/mips/elf-rel20.d
--- binutils-2.15.91-20040527.macro/gas/testsuite/gas/mips/elf-rel20.d	1970-01-01 00:00:00.000000000 +0000
+++ binutils-2.15.91-20040527/gas/testsuite/gas/mips/elf-rel20.d	2004-05-28 15:48:29.000000000 +0000
@@ -0,0 +1,31 @@
+#objdump: -dr --prefix-addresses -mmips:3000
+#name: MIPS ELF reloc 20
+#as: -march=mips2 -mabi=32
+#source: elf-rel20.s
+
+# Test relocations on the la macro.
+
+.*: +file format .*mips.*
+
+Disassembly of section .text:
+[0-9a-f]+ <[^>]*> lui	a0,0x0
+[ 	]*[0-9a-f]+: R_MIPS_CALL_HI16	gfunc
+[0-9a-f]+ <[^>]*> addu	a0,a0,gp
+[0-9a-f]+ <[^>]*> addiu	t9,a0,0
+[ 	]*[0-9a-f]+: R_MIPS_CALL_LO16	gfunc
+[0-9a-f]+ <[^>]*> lui	a0,0x0
+[ 	]*[0-9a-f]+: R_MIPS_GOT_HI16	gvar
+[0-9a-f]+ <[^>]*> addu	a0,a0,gp
+[0-9a-f]+ <[^>]*> addiu	a1,a0,0
+[ 	]*[0-9a-f]+: R_MIPS_GOT_LO16	gvar
+[0-9a-f]+ <[^>]*> lw	a0,0\(gp\)
+[ 	]*[0-9a-f]+: R_MIPS_GOT16	.data
+[0-9a-f]+ <[^>]*> addiu	a1,a0,0
+[ 	]*[0-9a-f]+: R_MIPS_LO16	.data
+[0-9a-f]+ <[^>]*> addiu	t9,gp,0
+[ 	]*[0-9a-f]+: R_MIPS_CALL16	gfunc
+[0-9a-f]+ <[^>]*> addiu	a0,gp,0
+[ 	]*[0-9a-f]+: R_MIPS_GOT_DISP	gvar
+[0-9a-f]+ <[^>]*> addiu	a0,gp,0
+[ 	]*[0-9a-f]+: R_MIPS_GPREL16	gvar
+	...
diff -up --recursive --new-file binutils-2.15.91-20040527.macro/gas/testsuite/gas/mips/elf-rel20.s binutils-2.15.91-20040527/gas/testsuite/gas/mips/elf-rel20.s
--- binutils-2.15.91-20040527.macro/gas/testsuite/gas/mips/elf-rel20.s	1970-01-01 00:00:00.000000000 +0000
+++ binutils-2.15.91-20040527/gas/testsuite/gas/mips/elf-rel20.s	2004-05-28 15:35:20.000000000 +0000
@@ -0,0 +1,28 @@
+	.ent	foo
+foo:
+	# Check various forms of paired relocations.
+
+	lui	$4,%call_hi(gfunc)
+	addu	$4,$4,$gp
+	la	$25,%call_lo(gfunc)($4)
+
+	lui	$4,%got_hi(gvar)
+	addu	$4,$4,$gp
+	la	$5,%got_lo(gvar)($4)
+
+	lw	$4,%got(lvar)($28)
+	la	$5,%lo(lvar)($4)
+
+	# Check individual relocations.
+
+	la	$25,%call16(gfunc)($28)
+
+	la	$4,%got_disp(gvar)($28)
+
+	la	$4,%gp_rel(gvar)($28)
+
+	.space	64
+	.end	foo
+
+	.data
+lvar:	.word	1,2
diff -up --recursive --new-file binutils-2.15.91-20040527.macro/gas/testsuite/gas/mips/mips.exp binutils-2.15.91-20040527/gas/testsuite/gas/mips/mips.exp
--- binutils-2.15.91-20040527.macro/gas/testsuite/gas/mips/mips.exp	2004-05-12 03:25:38.000000000 +0000
+++ binutils-2.15.91-20040527/gas/testsuite/gas/mips/mips.exp	2004-05-28 15:52:39.000000000 +0000
@@ -660,6 +660,7 @@ if { [istarget mips*-*-*] } then {
 	    run_dump_test "elf-rel18"
 	}
 	run_dump_test "elf-rel19"
+	run_dump_test "elf-rel20"
 
 	if { !$no_mips16 } {
 	    run_dump_test "${tmips}mips${el}16-e"
diff -up --recursive --new-file binutils-2.15.91-20040527.macro/opcodes/mips-opc.c binutils-2.15.91-20040527/opcodes/mips-opc.c
--- binutils-2.15.91-20040527.macro/opcodes/mips-opc.c	2003-11-19 04:25:23.000000000 +0000
+++ binutils-2.15.91-20040527/opcodes/mips-opc.c	2004-05-28 10:35:19.000000000 +0000
@@ -516,7 +516,9 @@ const struct mips_opcode mips_builtin_op
 {"divu",    "z,t",      0x0000001b, 0xffe0ffff, RD_s|RD_t|WR_HILO,      I1      },
 {"divu",    "d,v,t",	0,    (int) M_DIVU_3,	INSN_MACRO,		I1	},
 {"divu",    "d,v,I",	0,    (int) M_DIVU_3I,	INSN_MACRO,		I1	},
+{"dla",     "t,o(b)",	0,    (int) M_DLA_AB,	INSN_MACRO,		I3	},
 {"dla",     "t,A(b)",	0,    (int) M_DLA_AB,	INSN_MACRO,		I3	},
+{"dlca",    "t,o(b)",	0,    (int) M_DLA_AB,	INSN_MACRO,		I3	},
 {"dlca",    "t,A(b)",	0,    (int) M_DLCA_AB,	INSN_MACRO,		I3	},
 {"dli",     "t,j",      0x24000000, 0xffe00000, WR_t,			I3	}, /* addiu */
 {"dli",	    "t,i",	0x34000000, 0xffe00000, WR_t,			I3	}, /* ori */
@@ -636,11 +638,13 @@ const struct mips_opcode mips_builtin_op
    will match first).  */
 {"jal",     "a",	0x0c000000, 0xfc000000,	UBD|WR_31,		I1	},
 {"jalx",    "a",	0x74000000, 0xfc000000, UBD|WR_31,		I16     },
+{"la",      "t,o(b)",	0,    (int) M_LA_AB,	INSN_MACRO,		I1	},
 {"la",      "t,A(b)",	0,    (int) M_LA_AB,	INSN_MACRO,		I1	},
 {"lb",      "t,o(b)",	0x80000000, 0xfc000000,	LDD|RD_b|WR_t,		I1	},
 {"lb",      "t,A(b)",	0,    (int) M_LB_AB,	INSN_MACRO,		I1	},
 {"lbu",     "t,o(b)",	0x90000000, 0xfc000000,	LDD|RD_b|WR_t,		I1	},
 {"lbu",     "t,A(b)",	0,    (int) M_LBU_AB,	INSN_MACRO,		I1	},
+{"lca",     "t,o(b)",	0,    (int) M_LA_AB,	INSN_MACRO,		I1	},
 {"lca",     "t,A(b)",	0,    (int) M_LCA_AB,	INSN_MACRO,		I1	},
 {"ld",	    "t,o(b)",   0xdc000000, 0xfc000000, WR_t|RD_b,		I3	},
 {"ld",      "t,o(b)",	0,    (int) M_LD_OB,	INSN_MACRO,		I1	},

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-28 19:00 [patch] MIPS gas problems with gcc's explicit relocs Maciej W. Rozycki
@ 2004-05-28 21:50 ` Thiemo Seufer
  2004-05-28 21:59   ` Zack Weinberg
  2004-05-28 22:20   ` Maciej W. Rozycki
  2004-05-29  6:39 ` Richard Sandiford
  1 sibling, 2 replies; 47+ messages in thread
From: Thiemo Seufer @ 2004-05-28 21:50 UTC (permalink / raw)
  To: binutils

Maciej W. Rozycki wrote:
[snip]
> 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
[snip]
> 	lui	$2,%highest(foo)
> 	daddiu	$2,$2,%higher(foo)
> 	dsll	$2,$2,16
> 	daddiu	$2,$2,%hi(foo)
> 	dsll	$2,$2,16
> #APP
> 	dla	$2,%lo(foo)($2)
> #NO_APP

IMHO this is broken in the compiler. It should either only provide the
sympol for %1, or handle the dla expansion correctly, preferably with
better optimization for superscalar processors (that is, a
lui - lui - daddiu - daddiu - dsll32 - daddu sequence).


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-28 21:50 ` Thiemo Seufer
@ 2004-05-28 21:59   ` Zack Weinberg
  2004-05-28 22:00     ` Thiemo Seufer
  2004-05-28 22:20   ` Maciej W. Rozycki
  1 sibling, 1 reply; 47+ messages in thread
From: Zack Weinberg @ 2004-05-28 21:59 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:

> Maciej W. Rozycki wrote:
> [snip]
>> 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> [snip]
>> 	lui	$2,%highest(foo)
>> 	daddiu	$2,$2,%higher(foo)
>> 	dsll	$2,$2,16
>> 	daddiu	$2,$2,%hi(foo)
>> 	dsll	$2,$2,16
>> #APP
>> 	dla	$2,%lo(foo)($2)
>> #NO_APP
>
> IMHO this is broken in the compiler. It should either only provide the
> sympol for %1, or handle the dla expansion correctly, preferably with
> better optimization for superscalar processors (that is, a
> lui - lui - daddiu - daddiu - dsll32 - daddu sequence).

Huh? This is an asm statement; the compiler has no idea that it's a
dla instruction.

zw

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-28 21:59   ` Zack Weinberg
@ 2004-05-28 22:00     ` Thiemo Seufer
  2004-05-28 22:31       ` Maciej W. Rozycki
  0 siblings, 1 reply; 47+ messages in thread
From: Thiemo Seufer @ 2004-05-28 22:00 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: binutils

Zack Weinberg wrote:
> Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:
> 
> > Maciej W. Rozycki wrote:
> > [snip]
> >> 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> > [snip]
> >> 	lui	$2,%highest(foo)
> >> 	daddiu	$2,$2,%higher(foo)
> >> 	dsll	$2,$2,16
> >> 	daddiu	$2,$2,%hi(foo)
> >> 	dsll	$2,$2,16
> >> #APP
> >> 	dla	$2,%lo(foo)($2)
> >> #NO_APP
> >
> > IMHO this is broken in the compiler. It should either only provide the
> > sympol for %1, or handle the dla expansion correctly, preferably with
> > better optimization for superscalar processors (that is, a
> > lui - lui - daddiu - daddiu - dsll32 - daddu sequence).
> 
> Huh? This is an asm statement; the compiler has no idea that it's a
> dla instruction.

AFAICS it tries to alter it.


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-28 21:50 ` Thiemo Seufer
  2004-05-28 21:59   ` Zack Weinberg
@ 2004-05-28 22:20   ` Maciej W. Rozycki
  2004-05-28 23:32     ` Thiemo Seufer
  1 sibling, 1 reply; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-05-28 22:20 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

On Fri, 28 May 2004, Thiemo Seufer wrote:

> Maciej W. Rozycki wrote:
> [snip]
> > 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> [snip]
> > 	lui	$2,%highest(foo)
> > 	daddiu	$2,$2,%higher(foo)
> > 	dsll	$2,$2,16
> > 	daddiu	$2,$2,%hi(foo)
> > 	dsll	$2,$2,16
> > #APP
> > 	dla	$2,%lo(foo)($2)
> > #NO_APP
> 
> IMHO this is broken in the compiler. It should either only provide the
> sympol for %1, [...]

 This is what gcc 2.95 did and it was inferior -- for each %1 reference, a
full address load was performed.  A better alternative (and the only one
if I'd use the "R" constraint; 2.95 got it wrong, though) would be
finishing the address load sequence before the inline asm and substituting
"($2)" for %1.  It would waste an instruction if %1 was used for loads and
stores only, though.

 I like the current behavior of gcc for being optimal.

> [...] or handle the dla expansion correctly, preferably with
> better optimization for superscalar processors (that is, a
> lui - lui - daddiu - daddiu - dsll32 - daddu sequence).

 Hmm, do you suggest gcc should interpret the inline asm anyhow?

 Anyway, I think gas should be consistent with its interpretation of 
addresses for load/store and for load address instructions, i.e. it should 
be possible to split:

<op>	<reg>,<addr>

into:

la	<tmp>,<addr>
<op>	<reg>,(<tmp>)

for any valid <addr>.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-28 22:00     ` Thiemo Seufer
@ 2004-05-28 22:31       ` Maciej W. Rozycki
  0 siblings, 0 replies; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-05-28 22:31 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Zack Weinberg, binutils

On Fri, 28 May 2004, Thiemo Seufer wrote:

> > > Maciej W. Rozycki wrote:
> > > [snip]
> > >> 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> > > [snip]
> > >> 	lui	$2,%highest(foo)
> > >> 	daddiu	$2,$2,%higher(foo)
> > >> 	dsll	$2,$2,16
> > >> 	daddiu	$2,$2,%hi(foo)
> > >> 	dsll	$2,$2,16
> > >> #APP
> > >> 	dla	$2,%lo(foo)($2)
> > >> #NO_APP
> > >
> > > IMHO this is broken in the compiler. It should either only provide the
> > > sympol for %1, or handle the dla expansion correctly, preferably with
> > > better optimization for superscalar processors (that is, a
> > > lui - lui - daddiu - daddiu - dsll32 - daddu sequence).
> > 
> > Huh? This is an asm statement; the compiler has no idea that it's a
> > dla instruction.
> 
> AFAICS it tries to alter it.

 It merely substitutes "$2" for "%0" and "%lo(foo)($2)" for "%1".

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-28 22:20   ` Maciej W. Rozycki
@ 2004-05-28 23:32     ` Thiemo Seufer
  2004-05-29  3:59       ` Maciej W. Rozycki
  0 siblings, 1 reply; 47+ messages in thread
From: Thiemo Seufer @ 2004-05-28 23:32 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: binutils

Maciej W. Rozycki wrote:
> On Fri, 28 May 2004, Thiemo Seufer wrote:
> 
> > Maciej W. Rozycki wrote:
> > [snip]
> > > 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> > [snip]
> > > 	lui	$2,%highest(foo)
> > > 	daddiu	$2,$2,%higher(foo)
> > > 	dsll	$2,$2,16
> > > 	daddiu	$2,$2,%hi(foo)
> > > 	dsll	$2,$2,16
> > > #APP
> > > 	dla	$2,%lo(foo)($2)
> > > #NO_APP
> > 
> > IMHO this is broken in the compiler. It should either only provide the
> > sympol for %1, [...]
> 
>  This is what gcc 2.95 did and it was inferior -- for each %1 reference, a
> full address load was performed.  A better alternative (and the only one
> if I'd use the "R" constraint; 2.95 got it wrong, though) would be
> finishing the address load sequence before the inline asm and substituting
> "($2)" for %1.  It would waste an instruction if %1 was used for loads and
> stores only, though.

I can't follow you here. As long as gcc is supposed to leave inline asm
alone it shouldn't attempt to do (parts of) the expansion itself. The
resulting asm should be something like

#APP
	dla	$2,foo
#NO_APP

and leave the interpretation up to the assembler.

>  I like the current behavior of gcc for being optimal.

Creating broken code can hardly be called optimal.

> > [...] or handle the dla expansion correctly, preferably with
> > better optimization for superscalar processors (that is, a
> > lui - lui - daddiu - daddiu - dsll32 - daddu sequence).
> 
>  Hmm, do you suggest gcc should interpret the inline asm anyhow?

Not really. :-) I was wondering why loading the "foo" high part resulted
in a suboptimal insn sequence.

>  Anyway, I think gas should be consistent with its interpretation of 
> addresses for load/store and for load address instructions, i.e. it should 
> be possible to split:
> 
> <op>	<reg>,<addr>
> 
> into:
> 
> la	<tmp>,<addr>
> <op>	<reg>,(<tmp>)
> 
> for any valid <addr>.

This would be broken syntax.

	<op>	<reg>,<addr>

loads an absolute address in a register, while

	<op>	<reg>,<addr>(<reg2>)

loads the _content_ pointed to by reg2, with addr as offset.

	<op>	<reg>,(<reg2>)

merely means an offset of zero, and is invalid for (d)la.


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-28 23:32     ` Thiemo Seufer
@ 2004-05-29  3:59       ` Maciej W. Rozycki
  2004-06-03 18:50         ` Thiemo Seufer
  0 siblings, 1 reply; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-05-29  3:59 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

On Sat, 29 May 2004, Thiemo Seufer wrote:

> > > > 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> > > [snip]
> > > > 	lui	$2,%highest(foo)
> > > > 	daddiu	$2,$2,%higher(foo)
> > > > 	dsll	$2,$2,16
> > > > 	daddiu	$2,$2,%hi(foo)
> > > > 	dsll	$2,$2,16
> > > > #APP
> > > > 	dla	$2,%lo(foo)($2)
> > > > #NO_APP
> > > 
> > > IMHO this is broken in the compiler. It should either only provide the
> > > sympol for %1, [...]
> > 
> >  This is what gcc 2.95 did and it was inferior -- for each %1 reference, a
> > full address load was performed.  A better alternative (and the only one
> > if I'd use the "R" constraint; 2.95 got it wrong, though) would be
> > finishing the address load sequence before the inline asm and substituting
> > "($2)" for %1.  It would waste an instruction if %1 was used for loads and
> > stores only, though.
> 
> I can't follow you here. As long as gcc is supposed to leave inline asm
> alone it shouldn't attempt to do (parts of) the expansion itself. The
> resulting asm should be something like
> 
> #APP
> 	dla	$2,foo
> #NO_APP
> 
> and leave the interpretation up to the assembler.

 Well, "%lo(foo)($2)" is a correct address of the C variable "foo" here.

> >  I like the current behavior of gcc for being optimal.
> 
> Creating broken code can hardly be called optimal.

 Please justify.  Note e.g. "dla $4,0x100($2)" is currently OK, but you 
consider "dla $4,%lo(foo)($2)" bad.  Why?

> >  Anyway, I think gas should be consistent with its interpretation of 
> > addresses for load/store and for load address instructions, i.e. it should 
> > be possible to split:
> > 
> > <op>	<reg>,<addr>
> > 
> > into:
> > 
> > la	<tmp>,<addr>
> > <op>	<reg>,(<tmp>)
> > 
> > for any valid <addr>.
> 
> This would be broken syntax.
> 
> 	<op>	<reg>,<addr>
> 
> loads an absolute address in a register, while

 Nope, it loads the content pointed to by addr, of which the register part
happens to be $zero.

> 	<op>	<reg>,<addr>(<reg2>)
> 
> loads the _content_ pointed to by reg2, with addr as offset.
> 
> 	<op>	<reg>,(<reg2>)
> 
> merely means an offset of zero, and is invalid for (d)la.

 But "la <reg>,0(<reg2>)" works.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-28 19:00 [patch] MIPS gas problems with gcc's explicit relocs Maciej W. Rozycki
  2004-05-28 21:50 ` Thiemo Seufer
@ 2004-05-29  6:39 ` Richard Sandiford
       [not found]   ` <mailpost.1085811082.16442@news-sj1-1>
                     ` (2 more replies)
  1 sibling, 3 replies; 47+ messages in thread
From: Richard Sandiford @ 2004-05-29  6:39 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: binutils

Hi Maciej,

"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes:
>  The recent addition of explicit relocation generation to gcc triggered 
> failures for inline assembly under certain conditions.

Thanks for sticking up for the new gcc behaviour ;).

I just wanted to point out that using %lo(...) in "m" constraints
isn't in itself a new thing.  And that includes "m" constraints in
inline asms, since gcc doesn't treat them any differently from "m"
constraints in its own internal patterns.  For example, if you
select non-abicalls o32 or o64 code, I think it's been possible
for "m" to use %lo(...) for some time.  (Unless of course you
disabled it via -mno-split-addresses.)

If allowing %lo(...) in dla isn't acceptable (I've no opinion either
way really), then we'll just have to call:

> 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));

ill-formed.  You should only use "m" if the instruction can handle
every valid memory reference.

Richard

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
       [not found]   ` <mailpost.1085811082.16442@news-sj1-1>
@ 2004-05-29 22:24     ` cgd
  0 siblings, 0 replies; 47+ messages in thread
From: cgd @ 2004-05-29 22:24 UTC (permalink / raw)
  To: rsandifo; +Cc: Maciej W. Rozycki, binutils

At Sat, 29 May 2004 06:11:22 +0000 (UTC), "Richard Sandiford" wrote:
> If allowing %lo(...) in dla isn't acceptable (I've no opinion either
> way really), then we'll just have to call:

my take on this is that if 16bit_offset(reg) is allowed, it should be.
after all, %lo(sym) is just a really weird way of describing a 16-bit
offset.  8-)

(not that my opinion in this much matters.  8-)

cgd

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-29  6:39 ` Richard Sandiford
       [not found]   ` <mailpost.1085811082.16442@news-sj1-1>
@ 2004-05-31 16:05   ` Maciej W. Rozycki
  2004-06-03 16:31     ` Richard Sandiford
  2004-06-03 18:28     ` Thiemo Seufer
  2004-06-03 18:20   ` Thiemo Seufer
  2 siblings, 2 replies; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-05-31 16:05 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: binutils

Hello Richard,

> I just wanted to point out that using %lo(...) in "m" constraints
> isn't in itself a new thing.  And that includes "m" constraints in
> inline asms, since gcc doesn't treat them any differently from "m"
> constraints in its own internal patterns.  For example, if you
> select non-abicalls o32 or o64 code, I think it's been possible
> for "m" to use %lo(...) for some time.  (Unless of course you
> disabled it via -mno-split-addresses.)

 Well, it certainly is not forbidden, but it's never happened to me with 
gcc 2.95.x.  I can't comment on anything between that and 3.4, though.

> If allowing %lo(...) in dla isn't acceptable (I've no opinion either
> way really), then we'll just have to call:
> 
> > 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> 
> ill-formed.  You should only use "m" if the instruction can handle
> every valid memory reference.

 Well, I think "la" and friends should accept any valid address that is
accepted by memory transfer instructions (it's "load address" after all --
why should it be selective on what "address" can be?).  I have no document
providing a grammar for "la" and friends, but it's pretty well described
in SGI's "MIPSpro Assembly Language Programmer's Guide;" for the purpose
of references, mine is document #007-2418-004.

 It lists "la" together with "lw" and other memory load instructions as
having "destination, address" operands (table 12, page 27).  So there's no
differentiation between these two kinds of instructions.  Then the format 
of "address" is specified as being one of (tables 7-8, pp 8-10):

- (base-register),

- expression,

- expression (base-register),

- index-register (base-register) (!),

- relocatable-symbol,

- relocatable-symbol +/- expression,

- relocatable-symbol +/- expression (index register).

There's no explicit reference to %reloc operators here and they're only
briefly mentioned elsewhere as a possibility to refer to relocations
explicitly (section 4.9, page 24).

 Thus I suppose the SGI assembler supports such constructs, as:

dla	$2,%lo(foo)($3)

As you seem to have an access to an Irix host, could you please verify it?
Given the above I suppose we should support:

dla	$2,$4($3)

as well. ;-)

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-31 16:05   ` Maciej W. Rozycki
@ 2004-06-03 16:31     ` Richard Sandiford
  2004-06-03 17:06       ` Maciej W. Rozycki
  2004-06-03 18:28     ` Thiemo Seufer
  1 sibling, 1 reply; 47+ messages in thread
From: Richard Sandiford @ 2004-06-03 16:31 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: binutils

Sorry for the delay...

"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes:
>  Thus I suppose the SGI assembler supports such constructs, as:
>
> dla	$2,%lo(foo)($3)
>
> As you seem to have an access to an Irix host, could you please verify it?

The SGI assembler doesn't seem to like it:

as: Error: /foo.s, line 1: cannot use % relocation in macro instruction

Not that that's necessarily a reason for gas to reject it.  (Like I say,
I don't really have any opinion on that.  I just wanted to respond to
the SGI question.)

Richard

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-03 16:31     ` Richard Sandiford
@ 2004-06-03 17:06       ` Maciej W. Rozycki
  0 siblings, 0 replies; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-06-03 17:06 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: binutils

On Thu, 3 Jun 2004, Richard Sandiford wrote:

> Sorry for the delay...

 No problem.

> >  Thus I suppose the SGI assembler supports such constructs, as:
> >
> > dla	$2,%lo(foo)($3)
> >
> > As you seem to have an access to an Irix host, could you please verify it?
> 
> The SGI assembler doesn't seem to like it:
> 
> as: Error: /foo.s, line 1: cannot use % relocation in macro instruction

 Hmm, interesting -- so they contradict their own specification.  Perhaps
it was too tough for them to handle. ;-)

> Not that that's necessarily a reason for gas to reject it.  (Like I say,
> I don't really have any opinion on that.  I just wanted to respond to
> the SGI question.)

 I find interpreting addresses universally in the same way consistent and 
it makes the life easier for inline asm programmers.

 Note I think we should get rid of the use of artificial BFD_RELOC_LO16
relocations regardless.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-29  6:39 ` Richard Sandiford
       [not found]   ` <mailpost.1085811082.16442@news-sj1-1>
  2004-05-31 16:05   ` Maciej W. Rozycki
@ 2004-06-03 18:20   ` Thiemo Seufer
  2004-06-04  8:55     ` Maciej W. Rozycki
  2 siblings, 1 reply; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-03 18:20 UTC (permalink / raw)
  To: binutils

Richard Sandiford wrote:
> Hi Maciej,
> 
> "Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes:
> >  The recent addition of explicit relocation generation to gcc triggered 
> > failures for inline assembly under certain conditions.
> 
> Thanks for sticking up for the new gcc behaviour ;).
> 
> I just wanted to point out that using %lo(...) in "m" constraints
> isn't in itself a new thing.  And that includes "m" constraints in
> inline asms, since gcc doesn't treat them any differently from "m"
> constraints in its own internal patterns.  For example, if you
> select non-abicalls o32 or o64 code, I think it's been possible
> for "m" to use %lo(...) for some time.  (Unless of course you
> disabled it via -mno-split-addresses.)

For register-indexed memory load/stores this happens to work, but
la/dla/li/dli are expanded to immediate loads. They use purely
register operations, and need the "m" reference only for its address.

> If allowing %lo(...) in dla isn't acceptable (I've no opinion either
> way really),

It's not about the %(lo) versus some constant or symbol.
I think it's a misfeature of gas to allow

	la <reg>, <const>(<reg2>)

which suggests the idea of having a memory load, but expands to

	lui <reg>, %hi(<const>)
	addiu <reg>, %lo(<const>)
	addu <reg>, <reg>

while the usual load operations like

	lw <reg>, <const>(<reg2>)

expand to some actual memory access

	lui <reg>, %hi(<const>)
	lw <reg>, %lo(<const>)(<reg2>)

and while

	li <reg>, <const>(<reg2>)

is rejected as invalid by the assembler. For gcc this problem probably
never appears, but inline assembler code should either always get the
full unprocessed argument, or we need different constraints for memory
loads and memory addresses.


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-31 16:05   ` Maciej W. Rozycki
  2004-06-03 16:31     ` Richard Sandiford
@ 2004-06-03 18:28     ` Thiemo Seufer
  1 sibling, 0 replies; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-03 18:28 UTC (permalink / raw)
  To: binutils

Maciej W. Rozycki wrote:
> Hello Richard,
> 
> > I just wanted to point out that using %lo(...) in "m" constraints
> > isn't in itself a new thing.  And that includes "m" constraints in
> > inline asms, since gcc doesn't treat them any differently from "m"
> > constraints in its own internal patterns.  For example, if you
> > select non-abicalls o32 or o64 code, I think it's been possible
> > for "m" to use %lo(...) for some time.  (Unless of course you
> > disabled it via -mno-split-addresses.)
> 
>  Well, it certainly is not forbidden, but it's never happened to me with 
> gcc 2.95.x.  I can't comment on anything between that and 3.4, though.

3.3 still leaves the argument alone.

> > If allowing %lo(...) in dla isn't acceptable (I've no opinion either
> > way really), then we'll just have to call:
> > 
> > > 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> > 
> > ill-formed.  You should only use "m" if the instruction can handle
> > every valid memory reference.
> 
>  Well, I think "la" and friends should accept any valid address that is
> accepted by memory transfer instructions (it's "load address" after all --
> why should it be selective on what "address" can be?).  I have no document
> providing a grammar for "la" and friends, but it's pretty well described
> in SGI's "MIPSpro Assembly Language Programmer's Guide;" for the purpose
> of references, mine is document #007-2418-004.

FWIW, I lost trust in SGI documentation some years ago.

>  It lists "la" together with "lw" and other memory load instructions as
> having "destination, address" operands (table 12, page 27).  So there's no
> differentiation between these two kinds of instructions.  Then the format 
> of "address" is specified as being one of (tables 7-8, pp 8-10):
> 
> - (base-register),
> 
> - expression,
> 
> - expression (base-register),
> 
> - index-register (base-register) (!),
> 
> - relocatable-symbol,
> 
> - relocatable-symbol +/- expression,
> 
> - relocatable-symbol +/- expression (index register).

This list seems to mention all possible variants, but not all always
valid ones.

> There's no explicit reference to %reloc operators here and they're only
> briefly mentioned elsewhere as a possibility to refer to relocations
> explicitly (section 4.9, page 24).

AFAIK the %reloc were hacked in the SGI toolchain later, and remained
scarcely documented.


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-05-29  3:59       ` Maciej W. Rozycki
@ 2004-06-03 18:50         ` Thiemo Seufer
  2004-06-04  9:05           ` Maciej W. Rozycki
  0 siblings, 1 reply; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-03 18:50 UTC (permalink / raw)
  To: binutils

Maciej W. Rozycki wrote:
[snip]
> > >  I like the current behavior of gcc for being optimal.
> > 
> > Creating broken code can hardly be called optimal.
> 
>  Please justify.  Note e.g. "dla $4,0x100($2)" is currently OK, but you 
> consider "dla $4,%lo(foo)($2)" bad.  Why?

We misunderstood each other. I think adding in some register value
to dla is a misfeature of gas (I've expained in more detail in another
mail just sent).

Adding some code to handle

	(d)la	<reg>, %reloc(<sym>)

isn't wrong, but probably a bit nonsensical, given that (d)la is supposed
to do the expansion required to handle %reloc itself (for %reloc in
%highest, %higher, %hi, %lo).

[snip]
> > This would be broken syntax.
> > 
> > 	<op>	<reg>,<addr>
> > 
> > loads an absolute address in a register, while
> 
>  Nope, it loads the content pointed to by addr, of which the register part
> happens to be $zero.

No, it doesn't dereference.


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-03 18:20   ` Thiemo Seufer
@ 2004-06-04  8:55     ` Maciej W. Rozycki
  2004-06-04 16:41       ` Nigel Stephens
  0 siblings, 1 reply; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-06-04  8:55 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: Dominic Sweetman, Nigel Stephens, binutils

On Thu, 3 Jun 2004, Thiemo Seufer wrote:

> > I just wanted to point out that using %lo(...) in "m" constraints
> > isn't in itself a new thing.  And that includes "m" constraints in
> > inline asms, since gcc doesn't treat them any differently from "m"
> > constraints in its own internal patterns.  For example, if you
> > select non-abicalls o32 or o64 code, I think it's been possible
> > for "m" to use %lo(...) for some time.  (Unless of course you
> > disabled it via -mno-split-addresses.)
> 
> For register-indexed memory load/stores this happens to work, but
> la/dla/li/dli are expanded to immediate loads. They use purely
> register operations, and need the "m" reference only for its address.
> 
> > If allowing %lo(...) in dla isn't acceptable (I've no opinion either
> > way really),
> 
> It's not about the %(lo) versus some constant or symbol.
> I think it's a misfeature of gas to allow
> 
> 	la <reg>, <const>(<reg2>)
> 
> which suggests the idea of having a memory load, but expands to
> 
> 	lui <reg>, %hi(<const>)
> 	addiu <reg>, %lo(<const>)
> 	addu <reg>, <reg>
> 
> while the usual load operations like
> 
> 	lw <reg>, <const>(<reg2>)
> 
> expand to some actual memory access
> 
> 	lui <reg>, %hi(<const>)
> 	lw <reg>, %lo(<const>)(<reg2>)
> 
> and while
> 
> 	li <reg>, <const>(<reg2>)
> 
> is rejected as invalid by the assembler. For gcc this problem probably
> never appears, but inline assembler code should either always get the
> full unprocessed argument, or we need different constraints for memory
> loads and memory addresses.

 Apparently others want to use it, too.  I can see it mentioned e.g. in:
"IDT R30xx Family Software Reference Manual" (revision 1.0, p. 9-6, IDT
doc #3467), where such expansions are quoted:

la	$2, 4($3)	->	addiu	$2, $3, 4

la	$2, addr	->	lui	$at, %hi_addr
				addiu   $2, $at, %lo_addr

la	$2, addr($3)	->	lui	$at, %hi_addr
				addiu	$2, $at, %lo_addr
				addu	$2, $2, $3

which I find consistent with my assumption addresses should be handled
uniformly universally.  The book was largely written by Dominic Sweetman
and Nigel Stephens, so perhaps they can express their opinions whether
using "la" for anything beyond symbol literals is broken or not.  I find
it a natural consequence of the macro being "load *address*" after all.

 The "li" macro naturally rejects any non-immediate addresses as it's
"load *immediate*".

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-03 18:50         ` Thiemo Seufer
@ 2004-06-04  9:05           ` Maciej W. Rozycki
  2004-06-04 15:10             ` Thiemo Seufer
  0 siblings, 1 reply; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-06-04  9:05 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

On Thu, 3 Jun 2004, Thiemo Seufer wrote:

> Adding some code to handle
> 
> 	(d)la	<reg>, %reloc(<sym>)
> 
> isn't wrong, but probably a bit nonsensical, given that (d)la is supposed
> to do the expansion required to handle %reloc itself (for %reloc in
> %highest, %higher, %hi, %lo).

 It's the same as with other macros using addresses.  E.g. "lw" is
expected to do the same expansions, except that the last resulting
instruction is going to be "lw" instead of "addiu"/"daddiu" (modulo
possible instruction reordering).

> > > This would be broken syntax.
> > > 
> > > 	<op>	<reg>,<addr>
> > > 
> > > loads an absolute address in a register, while
> > 
> >  Nope, it loads the content pointed to by addr, of which the register part
> > happens to be $zero.
> 
> No, it doesn't dereference.

 How can it, given I defined <op> as a memory transfer instruction for the 
purpose of this discourse?

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04  9:05           ` Maciej W. Rozycki
@ 2004-06-04 15:10             ` Thiemo Seufer
  2004-06-04 15:53               ` Eric Christopher
                                 ` (2 more replies)
  0 siblings, 3 replies; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-04 15:10 UTC (permalink / raw)
  To: binutils

Maciej W. Rozycki wrote:
> On Thu, 3 Jun 2004, Thiemo Seufer wrote:
> 
> > Adding some code to handle
> > 
> > 	(d)la	<reg>, %reloc(<sym>)
> > 
> > isn't wrong, but probably a bit nonsensical, given that (d)la is supposed
> > to do the expansion required to handle %reloc itself (for %reloc in
> > %highest, %higher, %hi, %lo).
> 
>  It's the same as with other macros using addresses.  E.g. "lw" is
> expected to do the same expansions, except that the last resulting
> instruction is going to be "lw" instead of "addiu"/"daddiu" (modulo
> possible instruction reordering).

My point is we have this expanion normally done either by the compiler,
or by the assembler. In the latter case, dla is supposed to get fed a
valid memory reference and do the expansion. If you want to do that
expansion manually, you can (and should, for clarity) simply use addiu
to add in the last part.

The case which led to this whole thing is IMHO a compiler bug/feature
which leads to invalid memory references fed to the dla macro.
Basically, I see three ways to handle this:

- Add a "memory address" constraint to the compiler in addition to
  the "memory content" aka "m" constraint.

- Try to workaround it in the assembler. This can't be done easily,
  since the 32bit relocation handling code assumes an LO16 reloc to
  reference to the same address than the preceding HI16 reloc.

- Work around the problem by not using "m" constraints for (d)la in
  the inline assembler, that is instead of

	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));

  something like

	asm("dla\t%0,foo" : "=r" (result));


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 15:10             ` Thiemo Seufer
@ 2004-06-04 15:53               ` Eric Christopher
  2004-06-04 16:06                 ` Andreas Schwab
                                   ` (2 more replies)
  2004-06-14 14:17               ` Richard Sandiford
  2004-06-16 18:08               ` Maciej W. Rozycki
  2 siblings, 3 replies; 47+ messages in thread
From: Eric Christopher @ 2004-06-04 15:53 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils


> - Work around the problem by not using "m" constraints for (d)la in
>   the inline assembler, that is instead of
> 
> 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> 
>   something like
> 
> 	asm("dla\t%0,foo" : "=r" (result));

I like this I think the most. It fits with what people are trying to do
with the la instruction, i.e. load an address for a symbol that they
know.

-eric

-- 
Eric Christopher <echristo@redhat.com>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 15:53               ` Eric Christopher
@ 2004-06-04 16:06                 ` Andreas Schwab
  2004-06-04 16:28                   ` Thiemo Seufer
       [not found]                 ` <mailpost.1086364462.17870@news-sj1-1>
  2004-06-04 16:38                 ` Thiemo Seufer
  2 siblings, 1 reply; 47+ messages in thread
From: Andreas Schwab @ 2004-06-04 16:06 UTC (permalink / raw)
  To: Eric Christopher; +Cc: Thiemo Seufer, binutils

Eric Christopher <echristo@redhat.com> writes:

>> - Work around the problem by not using "m" constraints for (d)la in
>>   the inline assembler, that is instead of
>> 
>> 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
>> 
>>   something like
>> 
>> 	asm("dla\t%0,foo" : "=r" (result));
>
> I like this I think the most. It fits with what people are trying to do
> with the la instruction, i.e. load an address for a symbol that they
> know.

For "load address" and "push address" type insns there is the "p"
constraint letter.  Wouldn't that be the correct constraint here?

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
       [not found]                 ` <mailpost.1086364462.17870@news-sj1-1>
@ 2004-06-04 16:25                   ` cgd
  2004-06-11 23:48                     ` Maciej W. Rozycki
  0 siblings, 1 reply; 47+ messages in thread
From: cgd @ 2004-06-04 16:25 UTC (permalink / raw)
  To: echristo; +Cc: Thiemo Seufer, binutils

At Fri, 4 Jun 2004 15:54:22 +0000 (UTC), "Eric Christopher" wrote:
> > - Work around the problem by not using "m" constraints for (d)la in
> >   the inline assembler, that is instead of
> > 
> > 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> > 
> >   something like
> > 
> > 	asm("dla\t%0,foo" : "=r" (result));
> 
> I like this I think the most. It fits with what people are trying to do
> with the la instruction, i.e. load an address for a symbol that they
> know.

FWIW, I don't think using 'dla' or 'la' in this way is a great idea,
but...

assuming there are no other references to 'foo' in the file, this can
lose w/ unit-at-a-time compilation (e.g., if 'foo' is a static data
object).  Need to reference 'foo' from C code.

Also, historically speaking, putting 'foo' in the asm might have been
a bad idea, because of of the question of underscores or not at the
start of C symbols.  Nicer to let the compiler take care of it for
you.  (not clear that this matters today, though.)


chris

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 16:06                 ` Andreas Schwab
@ 2004-06-04 16:28                   ` Thiemo Seufer
  2004-06-04 16:37                     ` Paul Koning
  0 siblings, 1 reply; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-04 16:28 UTC (permalink / raw)
  To: binutils

Andreas Schwab wrote:
> Eric Christopher <echristo@redhat.com> writes:
> 
> >> - Work around the problem by not using "m" constraints for (d)la in
> >>   the inline assembler, that is instead of
> >> 
> >> 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> >> 
> >>   something like
> >> 
> >> 	asm("dla\t%0,foo" : "=r" (result));
> >
> > I like this I think the most. It fits with what people are trying to do
> > with the la instruction, i.e. load an address for a symbol that they
> > know.
> 
> For "load address" and "push address" type insns there is the "p"
> constraint letter.  Wouldn't that be the correct constraint here?

Interestingly, "p" causes this expansion:

        lui     $2,%highest(foo)
	daddiu  $2,$2,%higher(foo)
	sll    $2,$2,16
	daddiu  $2,$2,%hi(foo)
	dsll    $2,$2,16
	ld      $2,%lo(foo)($2)
	#APP
	dla     $2,$2
	#NO_APP

So the inline assembler gets a fully loaded register for it.


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 16:28                   ` Thiemo Seufer
@ 2004-06-04 16:37                     ` Paul Koning
  2004-06-04 17:02                       ` Thiemo Seufer
  2004-06-11 23:38                       ` Maciej W. Rozycki
  0 siblings, 2 replies; 47+ messages in thread
From: Paul Koning @ 2004-06-04 16:37 UTC (permalink / raw)
  To: ica2_ts; +Cc: binutils

>>>>> "Thiemo" == Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:

 Thiemo> Andreas Schwab wrote:
 >> Eric Christopher <echristo@redhat.com> writes:
 >> 
 >> >> - Work around the problem by not using "m" constraints for
 >> (d)la in >> the inline assembler, that is instead of
 >> >> 
 >> >> asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
 >> >> 
 >> >> something like
 >> >> 
 >> >> asm("dla\t%0,foo" : "=r" (result));
 >> >
 >> > I like this I think the most. It fits with what people are
 >> trying to do > with the la instruction, i.e. load an address for a
 >> symbol that they > know.
 >> 
 >> For "load address" and "push address" type insns there is the "p"
 >> constraint letter.  Wouldn't that be the correct constraint here?

 Thiemo> Interestingly, "p" causes this expansion:

 Thiemo> lui $2,%highest(foo) daddiu $2,$2,%higher(foo) sll $2,$2,16
 Thiemo> daddiu $2,$2,%hi(foo) dsll $2,$2,16 ld $2,%lo(foo)($2) #APP
 Thiemo> dla $2,$2 #NO_APP

 Thiemo> So the inline assembler gets a fully loaded register for it.

That sounds like a bug -- it does not match what the documentation
says it should do, and it doesn't make any real sense either.

My view is that the built-in macro stuff of the MIPS assembler is a
mistake, and the compiler should always do the job, not the
assembler, because the compiler can do it better.  So for the compiler
to expand the multiple steps needed to load an address is correct.

For example, if I use an "m" constraint, I'd expect the corresponding
%x operand to become an offset and base register pair with a valid
offset and the base register loaded with the rest of the address.

       paul


 Thiemo> Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 15:53               ` Eric Christopher
  2004-06-04 16:06                 ` Andreas Schwab
       [not found]                 ` <mailpost.1086364462.17870@news-sj1-1>
@ 2004-06-04 16:38                 ` Thiemo Seufer
  2004-06-04 16:41                   ` Paul Koning
  2 siblings, 1 reply; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-04 16:38 UTC (permalink / raw)
  To: binutils

Eric Christopher wrote:
> 
> > - Work around the problem by not using "m" constraints for (d)la in
> >   the inline assembler, that is instead of
> > 
> > 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> > 
> >   something like
> > 
> > 	asm("dla\t%0,foo" : "=r" (result));
> 
> I like this I think the most. It fits with what people are trying to do
> with the la instruction, i.e. load an address for a symbol that they
> know.

I don't, because it means "m" can't be used for 32bit Code any more
without the risk of silently breaking the relocation handling. It
results in reordered code even for

	__asm__ __volatile__ (".set noreorder\n ...


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04  8:55     ` Maciej W. Rozycki
@ 2004-06-04 16:41       ` Nigel Stephens
  2004-06-04 19:22         ` Eric Christopher
  0 siblings, 1 reply; 47+ messages in thread
From: Nigel Stephens @ 2004-06-04 16:41 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Thiemo Seufer, Dominic Sweetman, binutils



Maciej W. Rozycki wrote:

>which I find consistent with my assumption addresses should be handled
>uniformly universally.  The book was largely written by Dominic Sweetman
>and Nigel Stephens, so perhaps they can express their opinions whether
>using "la" for anything beyond symbol literals is broken or not.  I find
>it a natural consequence of the macro being "load *address*" after all.
>
>  
>

I agree with Maciej. The definition of the "la" macro surely requires 
that it must accept any address syntax that would be valid for "lw".

> The "li" macro naturally rejects any non-immediate addresses as it's
>"load *immediate*".
>
>  
>
Yes, "la" is a superset of "li".

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 16:38                 ` Thiemo Seufer
@ 2004-06-04 16:41                   ` Paul Koning
  2004-06-04 17:06                     ` Thiemo Seufer
  0 siblings, 1 reply; 47+ messages in thread
From: Paul Koning @ 2004-06-04 16:41 UTC (permalink / raw)
  To: ica2_ts; +Cc: binutils

>>>>> "Thiemo" == Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:

 Thiemo> Eric Christopher wrote:
 >> > - Work around the problem by not using "m" constraints for (d)la
 >> in > the inline assembler, that is instead of
 >> > 
 >> > asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
 >> > 
 >> > something like
 >> > 
 >> > asm("dla\t%0,foo" : "=r" (result));
 >> 
 >> I like this I think the most. It fits with what people are trying
 >> to do with the la instruction, i.e. load an address for a symbol
 >> that they know.

 Thiemo> I don't, because it means "m" can't be used for 32bit Code
 Thiemo> any more without the risk of silently breaking the relocation
 Thiemo> handling. It results in reordered code even for

 Thiemo> __asm__ __volatile__ (".set noreorder\n ...

But surely it is a BUG if reordering is done (silently) when
"noreorder" is in effect.

	    paul

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 16:37                     ` Paul Koning
@ 2004-06-04 17:02                       ` Thiemo Seufer
  2004-06-04 17:21                         ` Paul Koning
  2004-06-14 14:06                         ` Richard Sandiford
  2004-06-11 23:38                       ` Maciej W. Rozycki
  1 sibling, 2 replies; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-04 17:02 UTC (permalink / raw)
  To: binutils

Paul Koning wrote:
[snip]
>  Thiemo> Interestingly, "p" causes this expansion:
> 
>  Thiemo> lui $2,%highest(foo) daddiu $2,$2,%higher(foo) sll $2,$2,16
>  Thiemo> daddiu $2,$2,%hi(foo) dsll $2,$2,16 ld $2,%lo(foo)($2) #APP
>  Thiemo> dla $2,$2 #NO_APP
> 
>  Thiemo> So the inline assembler gets a fully loaded register for it.
> 
> That sounds like a bug -- it does not match what the documentation
> says it should do, and it doesn't make any real sense either.
> 
> My view is that the built-in macro stuff of the MIPS assembler is a
> mistake,

Well, I disagree. It's nice for hand-written assembler code. :-)

> and the compiler should always do the job, not the
> assembler, because the compiler can do it better.  So for the compiler
> to expand the multiple steps needed to load an address is correct.

Sure, as far as no hand-written (inline) assembler code is affected.

> For example, if I use an "m" constraint, I'd expect the corresponding
> %x operand to become an offset and base register pair with a valid
> offset and the base register loaded with the rest of the address.

That's not the way gcc up to 3.3 works for mips. So far, it was
possible to write

	asm("ld\t%0,%1(%2)" : "=r" (foo) : "m" (bar), "r" (baz));

and get something like

#APP
	ld      $2,bar($2)
#NO_APP

but now this results in

#APP
	ld      $2,%lo(bar)($3)($2)
#NO_APP
	 
which is of course invalid.


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 16:41                   ` Paul Koning
@ 2004-06-04 17:06                     ` Thiemo Seufer
  0 siblings, 0 replies; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-04 17:06 UTC (permalink / raw)
  To: binutils

Paul Koning wrote:
[snip]
>  Thiemo> I don't, because it means "m" can't be used for 32bit Code
>  Thiemo> any more without the risk of silently breaking the relocation
>  Thiemo> handling. It results in reordered code even for
> 
>  Thiemo> __asm__ __volatile__ (".set noreorder\n ...
> 
> But surely it is a BUG if reordering is done (silently) when
> "noreorder" is in effect.

The compiler does this reordering, the "noreorder" is part of a
inline asm string of which the compiler knows nothing about.


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 17:02                       ` Thiemo Seufer
@ 2004-06-04 17:21                         ` Paul Koning
  2004-06-04 17:59                           ` Thiemo Seufer
  2004-06-14 14:06                         ` Richard Sandiford
  1 sibling, 1 reply; 47+ messages in thread
From: Paul Koning @ 2004-06-04 17:21 UTC (permalink / raw)
  To: ica2_ts; +Cc: binutils

>>>>> "Thiemo" == Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:

 Thiemo> Paul Koning wrote: [snip] 
 >> and the compiler should always do the job, not the assembler,
 >> because the compiler can do it better.  So for the compiler to
 >> expand the multiple steps needed to load an address is correct.

 Thiemo> Sure, as far as no hand-written (inline) assembler code is
 Thiemo> affected.

Certainly.

 >> For example, if I use an "m" constraint, I'd expect the
 >> corresponding %x operand to become an offset and base register
 >> pair with a valid offset and the base register loaded with the
 >> rest of the address.

 Thiemo> That's not the way gcc up to 3.3 works for mips. So far, it
 Thiemo> was possible to write

 Thiemo> asm("ld\t%0,%1(%2)" : "=r" (foo) : "m" (bar), "r" (baz));

 Thiemo> and get something like

 Thiemo> #APP ld $2,bar($2) #NO_APP

That certainly is not what I expect from the documentation.  If you
need "bar" as a displacement, then it clearly is not a memory location
-- which is what "m" means.

 Thiemo> but now this results in

 Thiemo> #APP ld $2,%lo(bar)($3)($2) #NO_APP
	 
 Thiemo> which is of course invalid.

Yes, but that IS what the documentation says your asm statement
meant.  So I would argue that the current compiler is doing what you
asked for, and the previous compiler was doing something strange and
undocumented. 

I must admit I find myself fighting with constraints on MIPS at times
because things are not completely clear.  But I have always expected
(and, typically, observed) "m" to mean the "new" result you described,
certainly never the "old" result.

	  paul


 Thiemo> Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 17:21                         ` Paul Koning
@ 2004-06-04 17:59                           ` Thiemo Seufer
  2004-06-04 18:07                             ` Paul Koning
  0 siblings, 1 reply; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-04 17:59 UTC (permalink / raw)
  To: binutils

Paul Koning wrote:
[snip]
>  Thiemo> That's not the way gcc up to 3.3 works for mips. So far, it
>  Thiemo> was possible to write
> 
>  Thiemo> asm("ld\t%0,%1(%2)" : "=r" (foo) : "m" (bar), "r" (baz));
> 
>  Thiemo> and get something like
> 
>  Thiemo> #APP ld $2,bar($2) #NO_APP
> 
> That certainly is not what I expect from the documentation.  If you
> need "bar" as a displacement, then it clearly is not a memory location
> -- which is what "m" means.

I need "bar" as a symbol reference. The "m" constraint used to provide
this. ATM, there is no constraint available which actually provides the
address of a symbol.

If the new behaviour of "m" is correct and remains that way, we need a
working "p", and there's quite an amount of code to change.


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 17:59                           ` Thiemo Seufer
@ 2004-06-04 18:07                             ` Paul Koning
  2004-06-04 18:21                               ` Thiemo Seufer
  0 siblings, 1 reply; 47+ messages in thread
From: Paul Koning @ 2004-06-04 18:07 UTC (permalink / raw)
  To: ica2_ts; +Cc: binutils

>>>>> "Thiemo" == Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:

 Thiemo> Paul Koning wrote: [snip] That's not the way gcc up to 3.3
 Thiemo> works for mips. So far, it was possible to write
 >>
 Thiemo> asm("ld\t%0,%1(%2)" : "=r" (foo) : "m" (bar), "r" (baz));
 >>
 Thiemo> and get something like
 >>
 Thiemo> #APP ld $2,bar($2) #NO_APP
 >> That certainly is not what I expect from the documentation.  If
 >> you need "bar" as a displacement, then it clearly is not a memory
 >> location -- which is what "m" means.

 Thiemo> I need "bar" as a symbol reference.

Doesn't "i" do what you need for this?

	paul


^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 18:07                             ` Paul Koning
@ 2004-06-04 18:21                               ` Thiemo Seufer
  2004-06-04 18:26                                 ` Ian Lance Taylor
  2004-06-04 20:13                                 ` Andreas Schwab
  0 siblings, 2 replies; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-04 18:21 UTC (permalink / raw)
  To: binutils

Paul Koning wrote:
[snip]
>  >> That certainly is not what I expect from the documentation.  If
>  >> you need "bar" as a displacement, then it clearly is not a memory
>  >> location -- which is what "m" means.
> 
>  Thiemo> I need "bar" as a symbol reference.
> 
> Doesn't "i" do what you need for this?

The symbol's address is not an assembly-time constant.


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 18:21                               ` Thiemo Seufer
@ 2004-06-04 18:26                                 ` Ian Lance Taylor
  2004-06-04 18:43                                   ` Thiemo Seufer
  2004-06-04 20:13                                 ` Andreas Schwab
  1 sibling, 1 reply; 47+ messages in thread
From: Ian Lance Taylor @ 2004-06-04 18:26 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:

> Paul Koning wrote:
> [snip]
> >  >> That certainly is not what I expect from the documentation.  If
> >  >> you need "bar" as a displacement, then it clearly is not a memory
> >  >> location -- which is what "m" means.
> > 
> >  Thiemo> I need "bar" as a symbol reference.
> > 
> > Doesn't "i" do what you need for this?
> 
> The symbol's address is not an assembly-time constant.

How about "o"?

Ian

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 18:26                                 ` Ian Lance Taylor
@ 2004-06-04 18:43                                   ` Thiemo Seufer
  0 siblings, 0 replies; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-04 18:43 UTC (permalink / raw)
  To: binutils

Ian Lance Taylor wrote:
[snip]
> > >  Thiemo> I need "bar" as a symbol reference.
> > > 
> > > Doesn't "i" do what you need for this?
> > 
> > The symbol's address is not an assembly-time constant.
> 
> How about "o"?

Does the same as "m".


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 16:41       ` Nigel Stephens
@ 2004-06-04 19:22         ` Eric Christopher
  0 siblings, 0 replies; 47+ messages in thread
From: Eric Christopher @ 2004-06-04 19:22 UTC (permalink / raw)
  To: Nigel Stephens
  Cc: Maciej W. Rozycki, Thiemo Seufer, Dominic Sweetman, binutils


> I agree with Maciej. The definition of the "la" macro surely requires 
> that it must accept any address syntax that would be valid for "lw".

Of course, I'm tempted to say that if you are using explicit-relocs then
you either don't use macros or turn off explicit-relocs. i.e. make .set
nomacro to not be dependent on asm instructions.

Not sure what others think though.

-eric

-- 
Eric Christopher <echristo@redhat.com>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 18:21                               ` Thiemo Seufer
  2004-06-04 18:26                                 ` Ian Lance Taylor
@ 2004-06-04 20:13                                 ` Andreas Schwab
  2004-06-04 21:01                                   ` Thiemo Seufer
  1 sibling, 1 reply; 47+ messages in thread
From: Andreas Schwab @ 2004-06-04 20:13 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:

> Paul Koning wrote:
> [snip]
>>  >> That certainly is not what I expect from the documentation.  If
>>  >> you need "bar" as a displacement, then it clearly is not a memory
>>  >> location -- which is what "m" means.
>> 
>>  Thiemo> I need "bar" as a symbol reference.
>> 
>> Doesn't "i" do what you need for this?
>
> The symbol's address is not an assembly-time constant.

I think "assembly-time constant" includes entities that require link-time
relocation, but are not otherwise changed at runtime.  But note that you
probably need to use %c0 to substitute the argument.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 20:13                                 ` Andreas Schwab
@ 2004-06-04 21:01                                   ` Thiemo Seufer
  0 siblings, 0 replies; 47+ messages in thread
From: Thiemo Seufer @ 2004-06-04 21:01 UTC (permalink / raw)
  To: binutils

Andreas Schwab wrote:
[snip]
> >>  Thiemo> I need "bar" as a symbol reference.
> >> 
> >> Doesn't "i" do what you need for this?
> >
> > The symbol's address is not an assembly-time constant.
> 
> I think "assembly-time constant" includes entities that require link-time
> relocation, but are not otherwise changed at runtime.  But note that you
> probably need to use %c0 to substitute the argument.

	"i" (foo)

gives

	error: impossible constraint in asm

but then I haven't understood what you meant with "use %c0 to substitute".


Thiemo

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 16:37                     ` Paul Koning
  2004-06-04 17:02                       ` Thiemo Seufer
@ 2004-06-11 23:38                       ` Maciej W. Rozycki
  1 sibling, 0 replies; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-06-11 23:38 UTC (permalink / raw)
  To: Paul Koning; +Cc: ica2_ts, binutils

On Fri, 4 Jun 2004, Paul Koning wrote:

> For example, if I use an "m" constraint, I'd expect the corresponding
> %x operand to become an offset and base register pair with a valid
> offset and the base register loaded with the rest of the address.

 Note that if you absolutely require a machine-expressable address, then
you can use the "R" constraint to limit the addresses emitted by gcc to
these being a sum of a register and a signed 16-bit displacement.  It used
not to work reliably with 2.95.x (you could get an "impossible constraint
in `asm'" error), but it appears to work fine now.  With the "m"  
constraint gcc emits any address acceptable by gas including these
requiring multiple instructions to load.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 16:25                   ` cgd
@ 2004-06-11 23:48                     ` Maciej W. Rozycki
  0 siblings, 0 replies; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-06-11 23:48 UTC (permalink / raw)
  To: cgd; +Cc: echristo, Thiemo Seufer, binutils

On Fri, 4 Jun 2004 cgd@broadcom.com wrote:

> > > - Work around the problem by not using "m" constraints for (d)la in
> > >   the inline assembler, that is instead of
> > > 
> > > 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> > > 
> > >   something like
> > > 
> > > 	asm("dla\t%0,foo" : "=r" (result));
> > 
> > I like this I think the most. It fits with what people are trying to do
> > with the la instruction, i.e. load an address for a symbol that they
> > know.
[...]
> assuming there are no other references to 'foo' in the file, this can
> lose w/ unit-at-a-time compilation (e.g., if 'foo' is a static data
> object).  Need to reference 'foo' from C code.
> 
> Also, historically speaking, putting 'foo' in the asm might have been
> a bad idea, because of of the question of underscores or not at the
> start of C symbols.  Nicer to let the compiler take care of it for
> you.  (not clear that this matters today, though.)

 I suppose this should work anyway with the asm label GCC extension, like 
this:

int foo asm ("foo");

It doesn't work for automatic variables, though (no surprise).

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 17:02                       ` Thiemo Seufer
  2004-06-04 17:21                         ` Paul Koning
@ 2004-06-14 14:06                         ` Richard Sandiford
  2004-06-15 12:25                           ` Maciej W. Rozycki
  1 sibling, 1 reply; 47+ messages in thread
From: Richard Sandiford @ 2004-06-14 14:06 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

Catching up after a week's holiday, so sorry if this is repeating
something that has already been said...

Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:
> 	asm("ld\t%0,%1(%2)" : "=r" (foo) : "m" (bar), "r" (baz));

As Paul says, this is definitely invalid.  It might have happened to
give you the asm code you wanted, but that was just a fluke.

If you want "bar" to be a symbolic constant, you should use a constraint
for a symbolic constant.  "s" is what you want for that.  E.g.:

int foo ()
{
  extern char bar[];
  int tmp;
  asm ("la %0,%1" : "=d" (tmp), "s" (bar));
  return tmp;
}

gives:

#APP
        la $2,bar
#NO_APP

"i", which someone suggested later, is more general than "s" and
gives the same thing (at least with gcc 3.4.0).

On the other hand, the above asm should just be written:

> 	asm("ld\t%0,%1" : "=r" (foo) : "m" (bar[baz]));

So far, folks have been using toy cut-down examples (usually the most
helpful thing to do, of course).  But Thiemo's example was invalid, and
Maciej's was too if you believe the current gas behaviour to be correct.
And both of the asms could be done easily enough in C.

So I'm curious: what's the "real" asm that started off this whole thing?

Richard

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 15:10             ` Thiemo Seufer
  2004-06-04 15:53               ` Eric Christopher
@ 2004-06-14 14:17               ` Richard Sandiford
  2004-06-16 18:08               ` Maciej W. Rozycki
  2 siblings, 0 replies; 47+ messages in thread
From: Richard Sandiford @ 2004-06-14 14:17 UTC (permalink / raw)
  To: Thiemo Seufer; +Cc: binutils

Thiemo Seufer <ica2_ts@csv.ica.uni-stuttgart.de> writes:
> The case which led to this whole thing is IMHO a compiler bug/feature

't ain't a bug!

> which leads to invalid memory references fed to the dla macro.
> Basically, I see three ways to handle this:
>
> - Add a "memory address" constraint to the compiler in addition to
>   the "memory content" aka "m" constraint.

There already is a memory address constaint ("p"), but I'm not sure
whether it can be reliably used in asms.  It wouldn't help anyway.
The whole point is that, as far as gcc is concerned, "%lo(symbol)($reg)"
is a valid memory address.  (An expression is only a valid memory reference
for "m" if the address is also valid.)

> - Work around the problem by not using "m" constraints for (d)la in
>   the inline assembler, that is instead of
>
> 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
>
>   something like
>
> 	asm("dla\t%0,foo" : "=r" (result));

The current gas behaviour makes the original asm invalid.  If you
believe that the current gas behaviour is correct, then I don't see
this option as a workaround.  I think it's the correct solution.

Richard

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-14 14:06                         ` Richard Sandiford
@ 2004-06-15 12:25                           ` Maciej W. Rozycki
  0 siblings, 0 replies; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-06-15 12:25 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: Thiemo Seufer, binutils

On Mon, 14 Jun 2004, Richard Sandiford wrote:

> So far, folks have been using toy cut-down examples (usually the most
> helpful thing to do, of course).  But Thiemo's example was invalid, and
> Maciej's was too if you believe the current gas behaviour to be correct.
> And both of the asms could be done easily enough in C.

 My point was and still is, with "la", etc. gas rejects a legitimate
address, which is accepted for other macros/instructions expecting an
address.  I know C code can be rewritten to work this problem around, but
it is not an excuse for keeping the bug in gas.

> So I'm curious: what's the "real" asm that started off this whole thing?

 The exact code is of course irrelevant -- the provided test cases were
sufficient to describe the bug unambiguously, though I see no problem with
disclosing it.  The relevant part of C source as well as generated
assembly is provided below.  They are modified Linux 2.4.x sources.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

semaphore.h
static inline void up(struct semaphore * sem)
{
	unsigned long tmp, tmp2, ptr;
	int count;

#if WAITQUEUE_DEBUG
	CHECK_MAGIC(sem->__magic);
#endif
	/*
	 * We must manipulate count and waking simultaneously and atomically.
	 * Otherwise we have races between up and __down_failed_interruptible
	 * waking up on a signal.
	 */

	__asm__ __volatile__(
	"	.set	mips3		# up			\n"
	"	dla	%3, %4					\n"
	"	sync						\n"
	"1:	lld	%1, (%3)				\n"
	"	dsra32	%0, %1, 0	# extract count to %0	\n"
	"	daddiu	%0, 1		# count += 1		\n"
	"	slti	%2, %0, 1	# %3 = (%0 <= 0)	\n"
	"	daddu	%1, %2		# waking += %3		\n"
	"	dsll32 %1, %1, 0	# zero-extend %1	\n"
	"	dsrl32 %1, %1, 0				\n"
	"	dsll32	%2, %0, 0	# Reassemble union	\n"
	"	or	%1, %2		# from count and waking	\n"
	"	scd	%1, (%3)				\n"
	"	beqz	%1, 1b					\n"
	"	.set	mips0					\n"
	: "=&r"(count), "=&r"(tmp), "=&r"(tmp2), "=&r"(ptr), "+m"(*sem)
	:
	: "memory");

	if (unlikely(count <= 0))
		__up_wakeup(sem);
}

printk.s
	.align	3
.L67:
	lui	$2,%highest(console_may_schedule)
	.set	noat
	addiu	$1,$0,%higher(console_may_schedule)
	daddu	$2,$2,$1
	.set	at
	lui	$6,%highest(console_sem)
	dsll	$2,$2,16
	.set	noat
	addiu	$1,$0,%higher(console_sem)
	daddu	$6,$6,$1
	.set	at
	.set	noat
	addiu	$1,$0,%hi(console_may_schedule)
	daddu	$2,$2,$1
	.set	at
	dsll	$6,$6,16
	dsll	$2,$2,16
	.set	noat
	addiu	$1,$0,%hi(console_sem)
	daddu	$6,$6,$1
	.set	at
	sw	$0,%lo(console_may_schedule)($2)
	dsll	$6,$6,16
#APP
		.set	mips3		# up			
	dla	$3, %lo(console_sem)($6)					
	sync						
1:	lld	$5, ($3)				
	dsra32	$2, $5, 0	# extract count to $2	
	daddiu	$2, 1		# count += 1		
	slti	$4, $2, 1	# $3 = ($2 <= 0)	
	daddu	$5, $4		# waking += $3		
	dsll32 $5, $5, 0	# zero-extend $5	
	dsrl32 $5, $5, 0				
	dsll32	$4, $2, 0	# Reassemble union	
	or	$5, $4		# from count and waking	
	scd	$5, ($3)				
	beqz	$5, 1b					
	.set	mips0					

#NO_APP
	sll	$2,$2,0
	slt	$2,$2,1
	dsll	$2,$2,32
	dsrl	$2,$2,32
	bne	$2,$0,.L104

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-04 15:10             ` Thiemo Seufer
  2004-06-04 15:53               ` Eric Christopher
  2004-06-14 14:17               ` Richard Sandiford
@ 2004-06-16 18:08               ` Maciej W. Rozycki
  2004-06-16 18:28                 ` Richard Sandiford
  2004-06-16 18:30                 ` Eric Christopher
  2 siblings, 2 replies; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-06-16 18:08 UTC (permalink / raw)
  To: Thiemo Seufer, Richard Sandiford; +Cc: binutils

On Fri, 4 Jun 2004, Thiemo Seufer wrote:

> - Try to workaround it in the assembler. This can't be done easily,
>   since the 32bit relocation handling code assumes an LO16 reloc to
>   reference to the same address than the preceding HI16 reloc.

 This is actually an independent problem with explicit relocs passed to
the inside of an asm with the o32 ABI (or REL relocations, to be exact).  
Consider the following (perhaps a bit useless, but valid) code.

asm(
	"lw	%0,%2\n\t"
	"lw	%1,%3"
	: "=r" (r0), "=&r" (r1)
	: "m" (*m0), "m" (*m1));

If built for o32, non-PIC it's bad *by definition* if "%lo" is a part of
"%2" and "%3", as HI16 and LO16 relocs need to be paired, as you say.  
Actually the ABI requires them not to be separated with any other reloc,
but we are a bit less strict in BFD.

 I'm not sure what solution would be the best.  I think "%lo" may be
safely passed to an asm if there's only a single memory constraint used
("+m"  should be safe, too, but I'm told it's treated as a pair of
constraints consisting of an input and an output one internally) and
should be used then for performance (atomic operations using ll/sc would
benefit here, for example).  With more then a single memory constraint
they should probably all be forced into registers and expanded as
"0($reg)" to be valid address expressions.  Perhaps one corresponding to
the last HI16 reloc emitted by gcc before an asm can be retained as a
"%lo" expression.

 This is purely an abstract consideration based on performance
optimization without looking into GCC code, though.  Perhaps it would be
much too involving for and simply no "%lo" should be passed into an asm 
for the o32 ABI.

 New ABIs that use RELA relocations are certainly safe.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-16 18:08               ` Maciej W. Rozycki
@ 2004-06-16 18:28                 ` Richard Sandiford
  2004-06-16 19:24                   ` Maciej W. Rozycki
  2004-06-16 18:30                 ` Eric Christopher
  1 sibling, 1 reply; 47+ messages in thread
From: Richard Sandiford @ 2004-06-16 18:28 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Thiemo Seufer, binutils

"Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes:
>  This is actually an independent problem with explicit relocs passed to
> the inside of an asm with the o32 ABI (or REL relocations, to be exact).  
> Consider the following (perhaps a bit useless, but valid) code.
>
> asm(
> 	"lw	%0,%2\n\t"
> 	"lw	%1,%3"
> 	: "=r" (r0), "=&r" (r1)
> 	: "m" (*m0), "m" (*m1));
>
> If built for o32, non-PIC it's bad *by definition* if "%lo" is a part of
> "%2" and "%3", as HI16 and LO16 relocs need to be paired, as you say.  

But relocs don't have to be in increasing address order.  We already reorder
them so that R_MIPS_LO16s follow R_MIPS_HI16s, and have done for years.
See tc-mips.c:mips_frob_file().

Richard

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-16 18:08               ` Maciej W. Rozycki
  2004-06-16 18:28                 ` Richard Sandiford
@ 2004-06-16 18:30                 ` Eric Christopher
  1 sibling, 0 replies; 47+ messages in thread
From: Eric Christopher @ 2004-06-16 18:30 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Thiemo Seufer, Richard Sandiford, binutils

I think that we should disallow explicit relocs for macros. It's simple.
It solves a lot of problems, and really explicit relocations were
designed so that we didn't have to worry about macros in the first
place. If someone wants to come up with the necessary patches I'll
approve them. Otherwise I'll do it myself. (It will likely be just an
error message in gas unless I can come up with a way for gcc to not emit
explicit relocs if it knows it has a macro asm statement)

-eric

-- 
Eric Christopher <echristo@redhat.com>

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [patch] MIPS gas problems with gcc's explicit relocs
  2004-06-16 18:28                 ` Richard Sandiford
@ 2004-06-16 19:24                   ` Maciej W. Rozycki
  0 siblings, 0 replies; 47+ messages in thread
From: Maciej W. Rozycki @ 2004-06-16 19:24 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: Thiemo Seufer, binutils

On Wed, 16 Jun 2004, Richard Sandiford wrote:

> But relocs don't have to be in increasing address order.  We already reorder
> them so that R_MIPS_LO16s follow R_MIPS_HI16s, and have done for years.

 OK then -- I've missed that.

> See tc-mips.c:mips_frob_file().

 Thanks for the hint.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

^ permalink raw reply	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2004-06-16 19:24 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-05-28 19:00 [patch] MIPS gas problems with gcc's explicit relocs Maciej W. Rozycki
2004-05-28 21:50 ` Thiemo Seufer
2004-05-28 21:59   ` Zack Weinberg
2004-05-28 22:00     ` Thiemo Seufer
2004-05-28 22:31       ` Maciej W. Rozycki
2004-05-28 22:20   ` Maciej W. Rozycki
2004-05-28 23:32     ` Thiemo Seufer
2004-05-29  3:59       ` Maciej W. Rozycki
2004-06-03 18:50         ` Thiemo Seufer
2004-06-04  9:05           ` Maciej W. Rozycki
2004-06-04 15:10             ` Thiemo Seufer
2004-06-04 15:53               ` Eric Christopher
2004-06-04 16:06                 ` Andreas Schwab
2004-06-04 16:28                   ` Thiemo Seufer
2004-06-04 16:37                     ` Paul Koning
2004-06-04 17:02                       ` Thiemo Seufer
2004-06-04 17:21                         ` Paul Koning
2004-06-04 17:59                           ` Thiemo Seufer
2004-06-04 18:07                             ` Paul Koning
2004-06-04 18:21                               ` Thiemo Seufer
2004-06-04 18:26                                 ` Ian Lance Taylor
2004-06-04 18:43                                   ` Thiemo Seufer
2004-06-04 20:13                                 ` Andreas Schwab
2004-06-04 21:01                                   ` Thiemo Seufer
2004-06-14 14:06                         ` Richard Sandiford
2004-06-15 12:25                           ` Maciej W. Rozycki
2004-06-11 23:38                       ` Maciej W. Rozycki
     [not found]                 ` <mailpost.1086364462.17870@news-sj1-1>
2004-06-04 16:25                   ` cgd
2004-06-11 23:48                     ` Maciej W. Rozycki
2004-06-04 16:38                 ` Thiemo Seufer
2004-06-04 16:41                   ` Paul Koning
2004-06-04 17:06                     ` Thiemo Seufer
2004-06-14 14:17               ` Richard Sandiford
2004-06-16 18:08               ` Maciej W. Rozycki
2004-06-16 18:28                 ` Richard Sandiford
2004-06-16 19:24                   ` Maciej W. Rozycki
2004-06-16 18:30                 ` Eric Christopher
2004-05-29  6:39 ` Richard Sandiford
     [not found]   ` <mailpost.1085811082.16442@news-sj1-1>
2004-05-29 22:24     ` cgd
2004-05-31 16:05   ` Maciej W. Rozycki
2004-06-03 16:31     ` Richard Sandiford
2004-06-03 17:06       ` Maciej W. Rozycki
2004-06-03 18:28     ` Thiemo Seufer
2004-06-03 18:20   ` Thiemo Seufer
2004-06-04  8:55     ` Maciej W. Rozycki
2004-06-04 16:41       ` Nigel Stephens
2004-06-04 19:22         ` Eric Christopher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).