[PATCH 02/15] MIPS: Make the LD/SD macro consistent on o32
Maciej W. Rozycki
macro@linux-mips.org
Sun Oct 3 19:40:00 GMT 2010
More information about the Binutils mailing list
Sun Oct 3 19:40:00 GMT 2010
- Previous message (by thread): [PATCH 08/15] MIPS/GAS/test: Remove MIPS III bits from LD tests
- Next message (by thread): [PATCH 02/15] MIPS: Make the LD/SD macro consistent on o32
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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
- Previous message (by thread): [PATCH 08/15] MIPS/GAS/test: Remove MIPS III bits from LD tests
- Next message (by thread): [PATCH 02/15] MIPS: Make the LD/SD macro consistent on o32
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list