This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 02/15] MIPS: Make the LD/SD macro consistent on o32


Hi,

 While converting the LD test case to a multi-arch setup I have triggered 
inconsistent behaviour of the LD/SD macro when assembled for the o32 ABI 
with a 64-bit ISA.  Considering the following program:

$ cat ld.s
	ld	$5,32767($4)
	ld	$5,32768($4)

we get the following output:

$ mips-linux-as -32 -mips3 -o ld.o ld.s
$ mips-linux-objdump -d ld.o

ld.o:     file format elf32-tradbigmips


Disassembly of section .text:

00000000 <.text>:
   0:	dc857fff 	ld	a1,32767(a0)
   4:	3c010001 	lui	at,0x1
   8:	00810821 	addu	at,a0,at
   c:	8c258000 	lw	a1,-32768(at)
  10:	8c268004 	lw	a2,-32764(at)
	...

Oops!

 This is because on MIPS III and above the M_LD_OB/M_SD_OB macro is 
overridden by a hardware instruction, but no such thing happens for the 
M_LD_AB/M_SD_AB macro.  As the o32 ABI implies 32-bit registers, I think 
the correct fix is to make LW/SW hardware instructions to be generated 
from LD/SD in all cases.  The following change implements it.  For the 
sake of odd corner cases such as sometimes needed by the Linux kernel or 
suchlike the hardware LD/SD instructions are still available for o32 with 
".set nomacro".

 This change triggered a regression in a GAS test case which I discovered 
was an n32 assembly output from GCC.  Assembling n32 code may not be 
supported on some targets, so rather than trying to figure out how to make 
this piece of code fit, I have converted it to o32.  This is meant to test 
line numbers, so it shouldn't care about the ABI used and the choice of 
n32 was a bit unfortunate.

2010-10-03  Maciej W. Rozycki  <macro@linux-mips.org>

	opcodes/
	* mips-opc.c (mips_builtin_opcodes): Move M_LD_OB and M_SD_OB 
	macros before their corresponding MIPS III hardware instructions.

	gas/
	* config/tc-mips.c (macro)[M_LD_OB, M_SD_OB]: Handle 64-bit ABIs.

	gas/testsuite/
	* gas/mips/lineno.s: Convert to o32.
	* gas/mips/lineno.d: Adjust patterns accordingly.  Force the o32 
	ABI.

 OK to apply?

  Maciej

binutils-2.20.51-20100925-mips-gas-ldsd-o32.patch
Index: binutils-2.20.51/gas/config/tc-mips.c
===================================================================
--- binutils-2.20.51.orig/gas/config/tc-mips.c
+++ binutils-2.20.51/gas/config/tc-mips.c
@@ -7364,15 +7364,18 @@ macro (struct mips_cl_insn *ip)
       break;
 
     case M_LD_OB:
-      s = "lw";
+      s = HAVE_64BIT_GPRS ? "ld" : "lw";
       goto sd_ob;
     case M_SD_OB:
-      s = "sw";
+      s = HAVE_64BIT_GPRS ? "sd" : "sw";
     sd_ob:
-      gas_assert (HAVE_32BIT_ADDRESSES);
       macro_build (&offset_expr, s, "t,o(b)", treg, BFD_RELOC_LO16, breg);
-      offset_expr.X_add_number += 4;
-      macro_build (&offset_expr, s, "t,o(b)", treg + 1, BFD_RELOC_LO16, breg);
+      if (!HAVE_64BIT_GPRS)
+	{
+	  offset_expr.X_add_number += 4;
+	  macro_build (&offset_expr, s, "t,o(b)", treg + 1,
+		       BFD_RELOC_LO16, breg);
+	}
       break;
 
    /* New code added to support COPZ instructions.
Index: binutils-2.20.51/gas/testsuite/gas/mips/lineno.d
===================================================================
--- binutils-2.20.51.orig/gas/testsuite/gas/mips/lineno.d
+++ binutils-2.20.51/gas/testsuite/gas/mips/lineno.d
@@ -1,6 +1,6 @@
 #objdump: -d -l -mmips:4000
 #name: assembly line numbers
-#as: --gstabs -march=r4000
+#as: --gstabs -32 -march=r4000
 
 
 .*: +file format .*mips.*
@@ -17,9 +17,9 @@ main\(\):
 .*lineno.s:16
 .*10:.*addiu.*
 .*lineno.s:17
-.*14:.*sd.*
+.*14:.*sw.*
 .*lineno.s:18
-.*18:.*sd.*
+.*18:.*sw.*
 .*lineno.s:19
 .*1c:.*move.*
 .*lineno.s:20
@@ -59,9 +59,9 @@ main\(\):
 .*lineno.s:34
 .*60:.*move.*
 .*lineno.s:35
-.*64:.*ld.*
+.*64:.*lw.*
 .*lineno.s:36
-.*68:.*ld.*
+.*68:.*lw.*
 .*lineno.s:37
 .*6c:.*addiu.*
 .*lineno.s:38
@@ -73,7 +73,7 @@ g\(\):
 .*lineno.s:47
 .*78:.*addiu.*
 .*lineno.s:48
-.*7c:.*sd.*
+.*7c:.*sw.*
 .*lineno.s:49
 .*80:.*move.*
 .*lineno.s:50
@@ -92,7 +92,7 @@ g\(\):
 .*lineno.s:56
 .*9c:.*move.*
 .*lineno.s:57
-.*a0:.*ld.*
+.*a0:.*lw.*
 .*lineno.s:58
 .*a4:.*addiu.*
 .*lineno.s:59
Index: binutils-2.20.51/opcodes/mips-opc.c
===================================================================
--- binutils-2.20.51.orig/opcodes/mips-opc.c
+++ binutils-2.20.51/opcodes/mips-opc.c
@@ -743,8 +743,9 @@ const struct mips_opcode mips_builtin_op
 {"lbu",     "t,o(b)",	0x90000000, 0xfc000000,	LDD|RD_b|WR_t,		0,		I1	},
 {"lbu",     "t,A(b)",	0,    (int) M_LBU_AB,	INSN_MACRO,		0,		I1	},
 {"lca",     "t,A(b)",	0,    (int) M_LCA_AB,	INSN_MACRO,		0,		I1	},
-{"ld",	    "t,o(b)",   0xdc000000, 0xfc000000, WR_t|RD_b,		0,		I3	},
+/* The macro has to be first to handle o32 correctly.  */
 {"ld",      "t,o(b)",	0,    (int) M_LD_OB,	INSN_MACRO,		0,		I1	},
+{"ld",      "t,o(b)",   0xdc000000, 0xfc000000, WR_t|RD_b,		0,		I3	},
 {"ld",      "t,A(b)",	0,    (int) M_LD_AB,	INSN_MACRO,		0,		I1	},
 {"ldaddw",  "t,b",	0x70000010, 0xfc00ffff,	SM|RD_t|WR_t|RD_b,	0,		XLR	},
 {"ldaddwu", "t,b",	0x70000011, 0xfc00ffff,	SM|RD_t|WR_t|RD_b,	0,		XLR	},
@@ -1173,8 +1174,9 @@ const struct mips_opcode mips_builtin_op
 {"sc",	    "t,A(b)",	0,    (int) M_SC_AB,	INSN_MACRO,		0,		I2	},
 {"scd",	    "t,o(b)",	0xf0000000, 0xfc000000, SM|RD_t|WR_t|RD_b,	0,		I3	},
 {"scd",	    "t,A(b)",	0,    (int) M_SCD_AB,	INSN_MACRO,		0,		I3	},
-{"sd",	    "t,o(b)",	0xfc000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I3	},
+/* The macro has to be first to handle o32 correctly.  */
 {"sd",      "t,o(b)",	0,    (int) M_SD_OB,	INSN_MACRO,		0,		I1	},
+{"sd",      "t,o(b)",	0xfc000000, 0xfc000000,	SM|RD_t|RD_b,		0,		I3	},
 {"sd",      "t,A(b)",	0,    (int) M_SD_AB,	INSN_MACRO,		0,		I1	},
 {"sdbbp",   "",		0x0000000e, 0xffffffff,	TRAP,           	0,		G2	},
 {"sdbbp",   "c",	0x0000000e, 0xfc00ffff,	TRAP,			0,		G2	},
Index: binutils-2.20.51/gas/testsuite/gas/mips/lineno.s
===================================================================
--- binutils-2.20.51.orig/gas/testsuite/gas/mips/lineno.s
+++ binutils-2.20.51/gas/testsuite/gas/mips/lineno.s
@@ -7,15 +7,15 @@
 	.word	0xdeadbeef
 
 # some real code, compiled from a toy C program
-	        .globl  main
+        .globl  main
         .ent    main
 main:
-        .frame  $fp,32,$31              # vars= 16, regs= 2/0, args= 0, extra= 0
+        .frame  $fp,24,$31              # vars= 16, regs= 2/0, args= 0, extra= 0
         .mask   0xc0000000,-8
         .fmask  0x00000000,0
-        subu    $sp,$sp,32
-        sd      $31,24($sp)
-        sd      $fp,16($sp)
+        subu    $sp,$sp,24
+        sw      $31,20($sp)
+        sw      $fp,16($sp)
         move    $fp,$sp
         jal     __main
         li      $2,2                    # 0x2
@@ -32,20 +32,20 @@ main:
         b       $L1
 $L1:
         move    $sp,$fp
-        ld      $31,24($sp)
-        ld      $fp,16($sp)
-        addu    $sp,$sp,32
+        lw      $31,20($sp)
+        lw      $fp,16($sp)
+        addu    $sp,$sp,24
         j       $31
         .end    main
         .align  2
         .globl  g
         .ent    g
 g:
-        .frame  $fp,32,$31              # vars= 16, regs= 1/0, args= 0, extra= 0
+        .frame  $fp,24,$31              # vars= 16, regs= 1/0, args= 0, extra= 0
         .mask   0x40000000,-16
         .fmask  0x00000000,0
-        subu    $sp,$sp,32
-        sd      $fp,16($sp)
+        subu    $sp,$sp,24
+        sw      $fp,16($sp)
         move    $fp,$sp
         sw      $4,0($fp)
         lw      $2,0($fp)
@@ -54,7 +54,7 @@ g:
         b       $L2
 $L2:
         move    $sp,$fp
-        ld      $fp,16($sp)
-        addu    $sp,$sp,32
+        lw      $fp,16($sp)
+        addu    $sp,$sp,24
         j       $31
         .end    g


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]