From adcf2b9d57947670171b53a4e73251cbf1ae460a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 15 Feb 1995 20:43:57 +0000 Subject: * config/tc-mips.c (macro): Handle M_U{L,S}D[_A] (unaligned double loads and stores). --- gas/ChangeLog | 11 +-- gas/config/tc-mips.c | 203 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 124 insertions(+), 90 deletions(-) (limited to 'gas') diff --git a/gas/ChangeLog b/gas/ChangeLog index 5585fd6..f0e6a0c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,8 +1,3 @@ -Wed Feb 15 15:31:57 1995 Ian Lance Taylor - - * config/tc-i386.c (tc_i386_fix_adjustable): Do adjust global - symbols if OBJ_AOUT. - Wed Feb 15 15:07:00 1995 Michael Meissner * config/tc-ppc.c (md_pseudo_table): If ELF, go to ppc_elf_cons @@ -26,6 +21,12 @@ Wed Feb 15 15:07:00 1995 Michael Meissner Wed Feb 15 11:46:02 1995 Ian Lance Taylor + * config/tc-mips.c (macro): Handle M_U{L,S}D[_A] (unaligned double + loads and stores). + + * config/tc-i386.c (tc_i386_fix_adjustable): Do adjust global + symbols if OBJ_AOUT. + * config/tc-mips.c (macro): Don't use the target register as a base register when building the address for M_L{W,D}{L,R}_AB. diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 6110ca7..b42299d 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -1843,6 +1843,7 @@ macro (ip) int coproc = 0; int lr = 0; offsetT maxnum; + int off; bfd_reloc_code_real_type r; char *p; int hold_mips_optimize; @@ -3569,6 +3570,8 @@ macro2 (ip) int likely = 0; int dbl = 0; int coproc = 0; + int lr = 0; + int off; offsetT maxnum; bfd_reloc_code_real_type r; char *p; @@ -4029,58 +4032,73 @@ macro2 (ip) macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg, treg, AT); break; + case M_ULD: + s = "ldl"; + s2 = "ldr"; + off = 7; + goto ulw; case M_ULW: - if (offset_expr.X_add_number >= 0x7ffd) + s = "lwl"; + s2 = "lwr"; + off = 3; + ulw: + if (offset_expr.X_add_number >= 0x8000 - off) as_bad ("operand overflow"); if (byte_order == LITTLE_ENDIAN) - offset_expr.X_add_number += 3; - macro_build ((char *) NULL, &icnt, &offset_expr, "lwl", "t,o(b)", treg, + offset_expr.X_add_number += off; + macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg, (int) BFD_RELOC_LO16, breg); if (byte_order == LITTLE_ENDIAN) - offset_expr.X_add_number -= 3; + offset_expr.X_add_number -= off; else - offset_expr.X_add_number += 3; - macro_build ((char *) NULL, &icnt, &offset_expr, "lwr", "t,o(b)", treg, + offset_expr.X_add_number += off; + macro_build ((char *) NULL, &icnt, &offset_expr, s2, "t,o(b)", treg, (int) BFD_RELOC_LO16, breg); return; + case M_ULD_A: + s = "ldl"; + s2 = "ldr"; + off = 7; + goto ulwa; + case M_ULW_A: + s = "lwl"; + s2 = "lwr"; + off = 3; + ulwa: + load_address (&icnt, AT, &offset_expr); + if (byte_order == LITTLE_ENDIAN) + expr1.X_add_number = off; + else + expr1.X_add_number = 0; + macro_build ((char *) NULL, &icnt, &expr1, s, "t,o(b)", treg, + (int) BFD_RELOC_LO16, AT); + if (byte_order == LITTLE_ENDIAN) + expr1.X_add_number = 0; + else + expr1.X_add_number = off; + macro_build ((char *) NULL, &icnt, &expr1, s2, "t,o(b)", treg, + (int) BFD_RELOC_LO16, AT); + break; + case M_ULH_A: case M_ULHU_A: - case M_ULW_A: load_address (&icnt, AT, &offset_expr); - if (mask == M_ULW_A) - { - if (byte_order == LITTLE_ENDIAN) - expr1.X_add_number = 3; - else - expr1.X_add_number = 0; - macro_build ((char *) NULL, &icnt, &expr1, "lwl", "t,o(b)", treg, - (int) BFD_RELOC_LO16, AT); - if (byte_order == LITTLE_ENDIAN) - expr1.X_add_number = 0; - else - expr1.X_add_number = 3; - macro_build ((char *) NULL, &icnt, &expr1, "lwr", "t,o(b)", treg, - (int) BFD_RELOC_LO16, AT); - } + if (byte_order == BIG_ENDIAN) + expr1.X_add_number = 0; + macro_build ((char *) NULL, &icnt, &expr1, + mask == M_ULH_A ? "lb" : "lbu", "t,o(b)", treg, + (int) BFD_RELOC_LO16, AT); + if (byte_order == BIG_ENDIAN) + expr1.X_add_number = 1; else - { - if (byte_order == BIG_ENDIAN) - expr1.X_add_number = 0; - macro_build ((char *) NULL, &icnt, &expr1, - mask == M_ULH_A ? "lb" : "lbu", "t,o(b)", treg, - (int) BFD_RELOC_LO16, AT); - if (byte_order == BIG_ENDIAN) - expr1.X_add_number = 1; - else - expr1.X_add_number = 0; - macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT, - (int) BFD_RELOC_LO16, AT); - macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg, - treg, 8); - macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg, - treg, AT); - } + expr1.X_add_number = 0; + macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT, + (int) BFD_RELOC_LO16, AT); + macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg, + treg, 8); + macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg, + treg, AT); break; case M_USH: @@ -4099,64 +4117,79 @@ macro2 (ip) (int) BFD_RELOC_LO16, breg); break; + case M_USD: + s = "sdl"; + s2 = "sdr"; + off = 7; + goto usw; case M_USW: - if (offset_expr.X_add_number >= 0x7ffd) + s = "swl"; + s2 = "swr"; + off = 3; + usw: + if (offset_expr.X_add_number >= 0x8000 - off) as_bad ("operand overflow"); if (byte_order == LITTLE_ENDIAN) - offset_expr.X_add_number += 3; - macro_build ((char *) NULL, &icnt, &offset_expr, "swl", "t,o(b)", treg, + offset_expr.X_add_number += off; + macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg, (int) BFD_RELOC_LO16, breg); if (byte_order == LITTLE_ENDIAN) - offset_expr.X_add_number -= 3; + offset_expr.X_add_number -= off; else - offset_expr.X_add_number += 3; - macro_build ((char *) NULL, &icnt, &offset_expr, "swr", "t,o(b)", treg, + offset_expr.X_add_number += off; + macro_build ((char *) NULL, &icnt, &offset_expr, s2, "t,o(b)", treg, (int) BFD_RELOC_LO16, breg); return; - case M_USH_A: + case M_USD_A: + s = "sdl"; + s2 = "sdr"; + off = 7; + goto uswa; case M_USW_A: + s = "swl"; + s2 = "swr"; + off = 3; + uswa: load_address (&icnt, AT, &offset_expr); - if (mask == M_USW_A) - { - if (byte_order == LITTLE_ENDIAN) - expr1.X_add_number = 3; - else - expr1.X_add_number = 0; - macro_build ((char *) NULL, &icnt, &expr1, "swl", "t,o(b)", treg, - (int) BFD_RELOC_LO16, AT); - if (byte_order == LITTLE_ENDIAN) - expr1.X_add_number = 0; - else - expr1.X_add_number = 3; - macro_build ((char *) NULL, &icnt, &expr1, "swr", "t,o(b)", treg, - (int) BFD_RELOC_LO16, AT); - } + if (byte_order == LITTLE_ENDIAN) + expr1.X_add_number = off; else - { - if (byte_order == LITTLE_ENDIAN) - expr1.X_add_number = 0; - macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg, - (int) BFD_RELOC_LO16, AT); - macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", treg, - treg, 8); - if (byte_order == LITTLE_ENDIAN) - expr1.X_add_number = 1; - else - expr1.X_add_number = 0; - macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg, - (int) BFD_RELOC_LO16, AT); - if (byte_order == LITTLE_ENDIAN) - expr1.X_add_number = 0; - else - expr1.X_add_number = 1; - macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT, - (int) BFD_RELOC_LO16, AT); - macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg, - treg, 8); - macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg, - treg, AT); - } + expr1.X_add_number = 0; + macro_build ((char *) NULL, &icnt, &expr1, s, "t,o(b)", treg, + (int) BFD_RELOC_LO16, AT); + if (byte_order == LITTLE_ENDIAN) + expr1.X_add_number = 0; + else + expr1.X_add_number = off; + macro_build ((char *) NULL, &icnt, &expr1, s2, "t,o(b)", treg, + (int) BFD_RELOC_LO16, AT); + break; + + case M_USH_A: + load_address (&icnt, AT, &offset_expr); + if (byte_order == LITTLE_ENDIAN) + expr1.X_add_number = 0; + macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg, + (int) BFD_RELOC_LO16, AT); + macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", treg, + treg, 8); + if (byte_order == LITTLE_ENDIAN) + expr1.X_add_number = 1; + else + expr1.X_add_number = 0; + macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg, + (int) BFD_RELOC_LO16, AT); + if (byte_order == LITTLE_ENDIAN) + expr1.X_add_number = 0; + else + expr1.X_add_number = 1; + macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT, + (int) BFD_RELOC_LO16, AT); + macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg, + treg, 8); + macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg, + treg, AT); break; default: -- cgit v1.1