This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Patch for constant %hi()s on MIPS
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: 05 Aug 2002 15:59:06 +0100
- Subject: Patch for constant %hi()s on MIPS
This patch fixes a problem with %hi() being applied to constants
(named or otherwise). With a constant "addr", and a sequence:
lui $4,%hi(addr)
lb $2,$4,%lo(addr)
gas will emit code that loads addr-0x10000 if bit 15 of addr is set.
The problem seems to be in some crufty-looking constant-handling code
in mips_ip(). I don't think we need it, since append_insn() can handle
constants too, and gets them right.
Patch fixes the attached test case and causes no regressions
on mips-elf or mips64-elf. OK to install?
Richard
[gas/]
* config/tc-mips.c (mips_ip): Don't work out the value of
constant %hi()s here.
[gas/testsuite/]
* gas/mips/elf-consthilo.[sd]: New test.
* gas/mips/mips.exp: Run it.
Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.156
diff -c -d -p -r1.156 tc-mips.c
*** gas/config/tc-mips.c 1 Aug 2002 20:14:46 -0000 1.156
--- gas/config/tc-mips.c 5 Aug 2002 14:36:00 -0000
*************** mips_ip (str, ip)
*** 8515,8523 ****
{
if (c != S_EX_LO)
{
! if (imm_expr.X_op == O_constant)
! imm_expr.X_add_number =
! (imm_expr.X_add_number >> 16) & 0xffff;
#ifdef OBJ_ELF
else if (c == S_EX_HIGHEST)
*imm_reloc = BFD_RELOC_MIPS_HIGHEST;
--- 8515,8525 ----
{
if (c != S_EX_LO)
{
! if (c == S_EX_HI)
! {
! *imm_reloc = BFD_RELOC_HI16_S;
! imm_unmatched_hi = true;
! }
#ifdef OBJ_ELF
else if (c == S_EX_HIGHEST)
*imm_reloc = BFD_RELOC_MIPS_HIGHEST;
*************** mips_ip (str, ip)
*** 8543,8553 ****
}
}
#endif
- else if (c == S_EX_HI)
- {
- *imm_reloc = BFD_RELOC_HI16_S;
- imm_unmatched_hi = true;
- }
else
*imm_reloc = BFD_RELOC_HI16;
}
--- 8545,8550 ----
*************** mips_ip (str, ip)
*** 8648,8657 ****
{
if (c != S_EX_LO)
{
! if (imm_expr.X_op == O_constant)
! imm_expr.X_add_number =
! (imm_expr.X_add_number >> 16) & 0xffff;
! else if (c == S_EX_HI)
{
*imm_reloc = BFD_RELOC_HI16_S;
imm_unmatched_hi = true;
--- 8645,8651 ----
{
if (c != S_EX_LO)
{
! if (c == S_EX_HI)
{
*imm_reloc = BFD_RELOC_HI16_S;
imm_unmatched_hi = true;
*************** mips_ip (str, ip)
*** 8685,8693 ****
else if (imm_expr.X_op == O_constant)
imm_expr.X_add_number &= 0xffff;
}
! if (imm_expr.X_op == O_constant
! && (imm_expr.X_add_number < 0
! || imm_expr.X_add_number >= 0x10000))
as_bad (_("lui expression not in range 0..65535"));
s = expr_end;
continue;
--- 8679,8687 ----
else if (imm_expr.X_op == O_constant)
imm_expr.X_add_number &= 0xffff;
}
! else if (imm_expr.X_op == O_constant
! && (imm_expr.X_add_number < 0
! || imm_expr.X_add_number >= 0x10000))
as_bad (_("lui expression not in range 0..65535"));
s = expr_end;
continue;
Index: gas/testsuite/gas/mips/mips.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/mips.exp,v
retrieving revision 1.39
diff -c -d -p -r1.39 mips.exp
*** gas/testsuite/gas/mips/mips.exp 1 Aug 2002 20:14:49 -0000 1.39
--- gas/testsuite/gas/mips/mips.exp 5 Aug 2002 14:36:00 -0000
*************** if { [istarget mips*-*-*] } then {
*** 215,219 ****
--- 215,220 ----
run_dump_test "${tmips}mips${el}16-e"
run_dump_test "${tmips}mips${el}16-f"
}
+ run_dump_test "elf-consthilo"
}
}
*** /dev/null Tue Nov 14 21:44:43 2000
--- gas/testsuite/gas/mips/elf-consthilo.d Mon Aug 5 15:03:23 2002
***************
*** 0 ****
--- 1,10 ----
+ #objdump: --prefix-addresses -dr
+ #name: MIPS constant hi/lo
+
+ .*: +file format elf.*mips.*
+
+ Disassembly of section \.text:
+ 0+00 <.*> lui a0,0xdeae
+ 0+04 <.*> jr ra
+ 0+08 <.*> lb v0,-16657\(a0\)
+ #pass
*** /dev/null Tue Nov 14 21:44:43 2000
--- gas/testsuite/gas/mips/elf-consthilo.s Mon Aug 5 14:56:00 2002
***************
*** 0 ****
--- 1,12 ----
+ .set noreorder
+ .set nomacro
+ .set noat
+ .set nomips16
+
+ .equ addr, 0xdeadbeef
+ .ent foo
+ foo:
+ lui $4,%hi(addr)
+ jr $31
+ lb $2,%lo(addr)($4)
+ .end foo