From: Richard Sandiford <rdsandiford@googlemail.com>
To: "Maciej W. Rozycki" <macro@codesourcery.com>
Cc: binutils@sourceware.org, Chao-ying Fu <fu@mips.com>,
Rich Fuhler <rich@mips.com>, David Lau <davidlau@mips.com>,
Kevin Mills <kevinm@mips.com>, Ilie Garbacea <ilie@mips.com>,
Catherine Moore <clm@codesourcery.com>,
Nathan Sidwell <nathan@codesourcery.com>,
Joseph Myers <joseph@codesourcery.com>,
Nathan Froyd <froydnj@codesourcery.com>
Subject: Re: [PATCH] MIPS: microMIPS ASE support
Date: Mon, 25 Jul 2011 07:49:00 -0000 [thread overview]
Message-ID: <87ipqrwyf4.fsf@firetop.home> (raw)
In-Reply-To: <87r5abs7ak.fsf@firetop.home> (Richard Sandiford's message of "Sun, 13 Mar 2011 09:23:31 +0000")
[-- Attachment #1: Type: text/plain, Size: 2104 bytes --]
Continuing this thread from March:
Richard Sandiford <rdsandiford@googlemail.com> writes:
> "Maciej W. Rozycki" <macro@codesourcery.com> writes:
>> As it has turned out in the course of sorting out some earlier concerns
>> the microMIPS change needs a couple of updates. For your reference I'm
>> sending the current version of the original patch as it had to be
>> regenerated. On top of this I'm sending the following updates:
>
> Everything except binutils-gas-umips-swap.diff is OK (as one commit,
> like you say), with the changes below.
It seemed a shame to get to the point of an approved version and not
actually commit it. I've now updated and regenerated the patch series,
made the changes from this approval, and applied a few other things I
noticed. I've attached the three patches separately.
Tested on
mips64-elf mips64el-unknown-kfreebsd-gnu mips64-linux-gnu
mips64octeon-linux-gnu mips64-unknown-kfreebsd-gnu
mipsel-unknown-kfreebsd-gnu mipsisa32el-linux-gnu mipsisa64-elf
mips-linux-gnu mips-unknown-kfreebsd-gnu mips-wrs-vxworks
Applied to trunk along with:
http://sourceware.org/ml/binutils/2010-12/msg00399.html
http://sourceware.org/ml/binutils/2011-02/msg00318.html
Maciej: I regenerated and updated each of your patches separately,
so if you'd like a copy of those individual patches, I can send them
privately.
I went on to say:
> If you don't agree with some of the requested changes, let me know.
and I gather from an off-list discussion a couple of months ago that
there were indeed some things that you didn't like. But I think it'd
be easier to deal with them as follow-ups. Please feel free to send
patches against trunk. Or, if you tell me what it is you disagree with,
I can try to fix it myself.
I'm sure there are things that we've both missed, but again,
we can deal with them as follow-ups.
Last, but not least, thanks for all your hard work on this series.
Thanks especially for perservering in the face of all my annoying
niggles. :-)
Richard
The regenerated version of your patch series (excluding umips-swap,
as per above):
[-- Attachment #2: combined.diff.bz2 --]
[-- Type: application/octet-stream, Size: 163019 bytes --]
[-- Attachment #3: Type: text/plain, Size: 27 bytes --]
The changes I asked for:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: approval.diff --]
[-- Type: text/x-diff, Size: 15355 bytes --]
Index: bfd/elfxx-mips.c
===================================================================
--- bfd/elfxx-mips.c 2011-07-24 15:06:40.000000000 +0100
+++ bfd/elfxx-mips.c 2011-07-24 15:07:48.000000000 +0100
@@ -5162,7 +5162,7 @@ mips_elf_calculate_relocation (bfd *abfd
target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (h->root.other);
/* If the output section is the PLT section,
then the target is not microMIPS. */
- target_is_micromips_code_p = ((htab->splt != sec)
+ target_is_micromips_code_p = (htab->splt != sec
&& ELF_ST_IS_MICROMIPS (h->root.other));
}
@@ -11910,18 +11910,9 @@ mips_elf_relax_delete_bytes (bfd *abfd,
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
isym = (Elf_Internal_Sym *) symtab_hdr->contents;
for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
- {
- bfd_vma value;
-
- if (isym->st_shndx != sec_shndx)
- continue;
-
- value = isym->st_value;
- if (ELF_ST_IS_MICROMIPS (isym->st_other))
- value &= MINUS_TWO;
- if (value > addr)
- isym->st_value -= count;
- }
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr)
+ isym->st_value -= count;
/* Now adjust the global symbols defined in this section. */
symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
@@ -11932,18 +11923,19 @@ mips_elf_relax_delete_bytes (bfd *abfd,
for (; sym_hashes < end_hashes; sym_hashes++)
{
struct elf_link_hash_entry *sym_hash = *sym_hashes;
- bfd_vma value;
-
- if ((sym_hash->root.type != bfd_link_hash_defined
- && sym_hash->root.type != bfd_link_hash_defweak)
- || sym_hash->root.u.def.section != sec)
- continue;
- value = sym_hash->root.u.def.value;
- if (ELF_ST_IS_MICROMIPS (sym_hash->other))
- value &= MINUS_TWO;
- if (value > addr)
- sym_hash->root.u.def.value -= count;
+ if ((sym_hash->root.type == bfd_link_hash_defined
+ || sym_hash->root.type == bfd_link_hash_defweak)
+ && sym_hash->root.u.def.section == sec)
+ {
+ bfd_vma value;
+
+ value = sym_hash->root.u.def.value;
+ if (ELF_ST_IS_MICROMIPS (sym_hash->other))
+ value &= MINUS_TWO;
+ if (value > addr)
+ sym_hash->root.u.def.value -= count;
+ }
}
return TRUE;
@@ -12279,6 +12271,27 @@ #define IS_BITSIZE(val, N) \
(((((val) & ((1ULL << (N)) - 1)) ^ (1ULL << ((N) - 1))) \
- (1ULL << ((N) - 1))) == (val))
+/* See if relocations [INTERNAL_RELOCS, IRELEND) confirm that there
+ is a 4-byte branch at offset OFFSET. */
+
+static bfd_boolean
+check_4byte_branch (Elf_Internal_Rela *internal_relocs,
+ Elf_Internal_Rela *irelend, bfd_vma offset)
+{
+ Elf_Internal_Rela *irel;
+ unsigned long r_type;
+
+ for (irel = internal_relocs; irel < irelend; irel++)
+ if (irel->r_offset == offset)
+ {
+ r_type = ELF32_R_TYPE (irel->r_info);
+ if (r_type == R_MICROMIPS_26_S1
+ || r_type == R_MICROMIPS_PC16_S1
+ || r_type == R_MICROMIPS_JALR)
+ return TRUE;
+ }
+ return FALSE;
+}
\f
bfd_boolean
_bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
@@ -12439,12 +12452,8 @@ _bfd_mips_elf_relax_section (bfd *abfd,
out the offset). */
if (r_type == R_MICROMIPS_HI16 && MATCH (opcode, lui_insn))
{
- Elf_Internal_Rela *ibrrel;
- bfd_boolean brc = FALSE;
- unsigned int br_r_type;
unsigned long nextopc;
unsigned long reg;
- int bdsize = -1;
bfd_vma offset;
/* Give up if the previous reloc was a HI16 against this symbol
@@ -12466,58 +12475,20 @@ _bfd_mips_elf_relax_section (bfd *abfd,
&& ELF32_R_SYM (irel[2].r_info) == r_symndx)
continue;
- /* See if there is a jump or a branch reloc preceding the
- LUI instruction immediately. */
- for (ibrrel = internal_relocs; ibrrel < irelend; ibrrel++)
- {
- offset = irel->r_offset - ibrrel->r_offset;
- if (offset != 2 && offset != 4)
- continue;
-
- br_r_type = ELF32_R_TYPE (ibrrel->r_info);
- if (offset == 2
- && (br_r_type == R_MICROMIPS_PC7_S1
- || br_r_type == R_MICROMIPS_PC10_S1
- || br_r_type == R_MICROMIPS_JALR))
- break;
- if (offset == 4
- && (br_r_type == R_MICROMIPS_26_S1
- || br_r_type == R_MICROMIPS_PC16_S1
- || br_r_type == R_MICROMIPS_JALR))
- {
- bfd_byte *ptr = contents + ibrrel->r_offset;
- unsigned long bropc;
-
- bropc = bfd_get_16 (abfd, ptr);
- bropc <<= 16;
- bropc |= bfd_get_16 (abfd, ptr + 2);
- /* Compact branches are OK. */
- if (find_match (opcode, bzc_insns_32) >= 0)
- brc = TRUE;
- break;
- }
- }
- /* A delay slot was found, give up, sigh... */
- if (!brc && ibrrel < irelend)
+ /* See if the LUI instruction *might* be in a branch delay slot. */
+ if (irel->r_offset >= 2
+ && check_br16_dslot (abfd, contents + irel->r_offset - 2) > 0
+ && !(irel->r_offset >= 4
+ /* If the instruction is actually a 4-byte branch,
+ the value of check_br16_dslot doesn't matter.
+ We should use check_br32_dslot to check whether
+ the branch has a delay slot. */
+ && check_4byte_branch (internal_relocs, irelend,
+ irel->r_offset - 4)))
+ continue;
+ if (irel->r_offset >= 4
+ && check_br32_dslot (abfd, contents + irel->r_offset - 4) > 0)
continue;
-
- /* Otherwise see if the LUI instruction *might* be in a
- branch delay slot. */
- if (!brc)
- {
- bfd_byte *ptr = contents + irel->r_offset;
-
- if (irel->r_offset >= 2)
- bdsize = check_br16_dslot (abfd, ptr - 2);
- /* A branch possibly found, give up, sigh... */
- if (bdsize > 0)
- continue;
- if (irel->r_offset >= 4)
- bdsize = check_br32_dslot (abfd, ptr - 4);
- /* A branch possibly found, give up, sigh... */
- if (bdsize > 0)
- continue;
- }
reg = OP32_SREG (opcode);
@@ -12545,7 +12516,8 @@ _bfd_mips_elf_relax_section (bfd *abfd,
nextopc = bfd_get_16 (abfd, contents + irel[1].r_offset ) << 16;
nextopc |= bfd_get_16 (abfd, contents + irel[1].r_offset + 2);
- /* Give up unless the same register used with both relocations. */
+ /* Give up unless the same register is used with both
+ relocations. */
if (OP32_SREG (nextopc) != reg)
continue;
Index: gas/config/tc-mips.c
===================================================================
--- gas/config/tc-mips.c 2011-07-24 15:07:45.000000000 +0100
+++ gas/config/tc-mips.c 2011-07-24 15:07:48.000000000 +0100
@@ -2150,7 +2150,7 @@ reglist_lookup (char **s, unsigned int t
unsigned int regmask;
unsigned int regno;
char *s_reset = *s;
- char *s_comma = *s;
+ char *s_end_of_list = *s;
while (reg_lookup (s, types, ®no))
{
@@ -2175,14 +2175,14 @@ reglist_lookup (char **s, unsigned int t
regmask ^= (1 << regno) - 1;
reglist |= regmask;
- s_comma = *s;
+ s_end_of_list = *s;
if (**s != ',')
break;
(*s)++;
}
if (ok)
- *s = s_comma;
+ *s = s_end_of_list;
else
*s = s_reset;
if (reglistp)
@@ -2663,24 +2663,41 @@ micromips_reloc_p (bfd_reloc_code_real_t
static inline bfd_boolean
got16_reloc_p (bfd_reloc_code_real_type reloc)
{
- return (reloc == BFD_RELOC_MIPS_GOT16 || reloc == BFD_RELOC_MIPS16_GOT16
+ return (reloc == BFD_RELOC_MIPS_GOT16
+ || reloc == BFD_RELOC_MIPS16_GOT16
|| reloc == BFD_RELOC_MICROMIPS_GOT16);
}
static inline bfd_boolean
hi16_reloc_p (bfd_reloc_code_real_type reloc)
{
- return (reloc == BFD_RELOC_HI16_S || reloc == BFD_RELOC_MIPS16_HI16_S
+ return (reloc == BFD_RELOC_HI16_S
+ || reloc == BFD_RELOC_MIPS16_HI16_S
|| reloc == BFD_RELOC_MICROMIPS_HI16_S);
}
static inline bfd_boolean
lo16_reloc_p (bfd_reloc_code_real_type reloc)
{
- return (reloc == BFD_RELOC_LO16 || reloc == BFD_RELOC_MIPS16_LO16
+ return (reloc == BFD_RELOC_LO16
+ || reloc == BFD_RELOC_MIPS16_LO16
|| reloc == BFD_RELOC_MICROMIPS_LO16);
}
+static inline bfd_boolean
+jmp_reloc_p (bfd_reloc_code_real_type reloc)
+{
+ return (reloc == BFD_RELOC_MIPS_JMP
+ || reloc == BFD_RELOC_MICROMIPS_JMP);
+}
+
+static inline bfd_boolean
+jalr_reloc_p (bfd_reloc_code_real_type reloc)
+{
+ return (reloc == BFD_RELOC_MIPS_JALR
+ || reloc == BFD_RELOC_MICROMIPS_JALR);
+}
+
/* Return true if the given relocation might need a matching %lo().
This is only "might" because SVR4 R_MIPS_GOT16 relocations only
need a matching %lo() when applied to local symbols. */
@@ -3761,7 +3778,7 @@ can_swap_branch_p (struct mips_cl_insn *
return FALSE;
/* If the previous instruction has an incorrect size for a fixed
- branch delay slot in the microMIPS mode, we cannot swap. */
+ branch delay slot in microMIPS mode, we cannot swap. */
if (mips_opts.micromips)
{
pinfo2 = ip->insn_mo->pinfo;
@@ -4030,11 +4047,9 @@ append_insn (struct mips_cl_insn *ip, ex
case BFD_RELOC_MIPS_JMP:
{
- bfd_reloc_code_real_type reloc;
int shift;
- reloc = micromips_map_reloc (*reloc_type);
- shift = reloc == BFD_RELOC_MICROMIPS_JMP ? 1 : 2;
+ shift = mips_opts.micromips ? 1 : 2;
if ((address_expr->X_add_number & ((1 << shift) - 1)) != 0)
as_bad (_("jump to misaligned address (0x%lx)"),
(unsigned long) address_expr->X_add_number);
@@ -4057,11 +4072,9 @@ append_insn (struct mips_cl_insn *ip, ex
case BFD_RELOC_16_PCREL_S2:
{
- bfd_reloc_code_real_type reloc;
int shift;
- reloc = micromips_map_reloc (*reloc_type);
- shift = reloc == BFD_RELOC_MICROMIPS_16_PCREL_S1 ? 1 : 2;
+ shift = mips_opts.micromips ? 1 : 2;
if ((address_expr->X_add_number & ((1 << shift) - 1)) != 0)
as_bad (_("branch to misaligned address (0x%lx)"),
(unsigned long) address_expr->X_add_number);
@@ -4313,32 +4326,32 @@ append_insn (struct mips_cl_insn *ip, ex
if (!ip->complete_p && *reloc_type < BFD_RELOC_UNUSED)
{
- bfd_reloc_code_real_type reloc;
+ bfd_reloc_code_real_type final_type[3];
reloc_howto_type *howto;
int i;
+ /* Perform any necessary conversion to microMIPS relocations
+ and find out how many relocations there actually are. */
+ for (i = 0; i < 3 && reloc_type[i] != BFD_RELOC_UNUSED; i++)
+ final_type[i] = micromips_map_reloc (reloc_type[i]);
+
/* In a compound relocation, it is the final (outermost)
operator that determines the relocated field. */
- for (i = 1; i < 3; i++)
- if (reloc_type[i] == BFD_RELOC_UNUSED)
- break;
-
- reloc = micromips_map_reloc (reloc_type[i - 1]);
- howto = bfd_reloc_type_lookup (stdoutput, reloc);
+ howto = bfd_reloc_type_lookup (stdoutput, final_type[i - 1]);
if (howto == NULL)
{
/* To reproduce this failure try assembling gas/testsuites/
gas/mips/mips16-intermix.s with a mips-ecoff targeted
assembler. */
- as_bad (_("Unsupported MIPS relocation number %d"), reloc);
+ as_bad (_("Unsupported MIPS relocation number %d"),
+ final_type[i - 1]);
howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
}
ip->fixp[0] = fix_new_exp (ip->frag, ip->where,
bfd_get_reloc_size (howto),
address_expr,
- howto->pc_relative,
- micromips_map_reloc (reloc_type[0]));
+ howto->pc_relative, final_type[0]);
/* Tag symbols that have a R_MIPS16_26 relocation against them. */
if (reloc_type[0] == BFD_RELOC_MIPS16_JMP
@@ -4352,7 +4365,6 @@ append_insn (struct mips_cl_insn *ip, ex
&& (reloc_type[0] == BFD_RELOC_16
|| reloc_type[0] == BFD_RELOC_32
|| reloc_type[0] == BFD_RELOC_MIPS_JMP
- || reloc_type[0] == BFD_RELOC_MICROMIPS_JMP
|| reloc_type[0] == BFD_RELOC_GPREL16
|| reloc_type[0] == BFD_RELOC_MIPS_LITERAL
|| reloc_type[0] == BFD_RELOC_GPREL32
@@ -4401,8 +4413,8 @@ append_insn (struct mips_cl_insn *ip, ex
if (reloc_type[i] != BFD_RELOC_UNUSED)
{
ip->fixp[i] = fix_new (ip->frag, ip->where,
- ip->fixp[0]->fx_size, NULL, 0, FALSE,
- micromips_map_reloc (reloc_type[i]));
+ ip->fixp[0]->fx_size, NULL, 0,
+ FALSE, final_type[i]);
/* Use fx_tcbit to mark compound relocs. */
ip->fixp[0]->fx_tcbit = 1;
@@ -17323,7 +17335,7 @@ md_estimate_size_before_relax (fragS *fr
length = relaxed_micromips_16bit_branch_length (fragp, segtype, FALSE);
if (length == 4 && RELAX_MICROMIPS_RELAX32 (fragp->fr_subtype))
length = relaxed_micromips_32bit_branch_length (fragp, segtype, FALSE);
- fragp->fr_var= length;
+ fragp->fr_var = length;
return length;
}
@@ -17385,9 +17397,7 @@ mips_fix_adjustable (fixS *fixp)
the in-place relocatable field if recalculated against the start
address of the symbol's containing section. */
if (HAVE_IN_PLACE_ADDENDS
- && (fixp->fx_pcrel
- || fixp->fx_r_type == BFD_RELOC_MIPS_JALR
- || fixp->fx_r_type == BFD_RELOC_MICROMIPS_JALR))
+ && (fixp->fx_pcrel || jalr_reloc_p (fixp->fx_r_type)))
return 0;
#ifdef OBJ_ELF
@@ -17439,8 +17449,7 @@ mips_fix_adjustable (fixS *fixp)
|| *symbol_get_tc (fixp->fx_addsy)
|| (HAVE_IN_PLACE_ADDENDS
&& ELF_ST_IS_MICROMIPS (S_GET_OTHER (fixp->fx_addsy))
- && (fixp->fx_r_type == BFD_RELOC_MIPS_JMP
- || fixp->fx_r_type == BFD_RELOC_MICROMIPS_JMP))))
+ && jmp_reloc_p (fixp->fx_r_type))))
return 0;
#endif
@@ -17781,12 +17790,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU
bfd_boolean compact = RELAX_MICROMIPS_COMPACT (fragp->fr_subtype);
bfd_boolean al = RELAX_MICROMIPS_LINK (fragp->fr_subtype);
int type = RELAX_MICROMIPS_TYPE (fragp->fr_subtype);
-
- /* Default to the long-delay-slot versions. */
- unsigned long jal = 0xf4000000; /* jal */
- unsigned long jalr = 0x45c0; /* jalr */
-
- unsigned long jr = compact ? 0x45a0 : 0x4580; /* jr/c */
+ unsigned long jal, jalr, jr;
unsigned long insn;
expressionS exp;
@@ -17798,7 +17802,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU
fragp->fr_fix += fragp->fr_var;
- /* Handle 16-bit branches that fit or forced to fit. */
+ /* Handle 16-bit branches that fit or are forced to fit. */
if (type != 0 && !RELAX_MICROMIPS_TOOFAR16 (fragp->fr_subtype))
{
/* We generate a fixup instead of applying it right now,
@@ -17906,6 +17910,12 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU
jal = 0x74000000; /* jals */
jalr = 0x45e0; /* jalrs */
}
+ else
+ {
+ jal = 0xf4000000; /* jal */
+ jalr = 0x45c0; /* jalr */
+ }
+ jr = compact ? 0x45a0 : 0x4580; /* jr/c */
if (!RELAX_MICROMIPS_UNCOND (fragp->fr_subtype))
{
Index: include/opcode/mips.h
===================================================================
--- include/opcode/mips.h 2011-07-24 15:06:40.000000000 +0100
+++ include/opcode/mips.h 2011-07-24 15:07:48.000000000 +0100
@@ -1330,7 +1330,7 @@ #define MIPS16_INSN_COND_BRANCH 0x0
extern const int bfd_mips16_num_opcodes;
/* These are the bitmasks and shift counts used for the different
- fields in the instruction formats. Other than OP, no masks are
+ fields in the instruction formats. Other than MAJOR, no masks are
provided for the fixed portions of an instruction, since they are
not needed. */
[-- Attachment #5: Type: text/plain, Size: 43 bytes --]
The other stuff I noticed while testing:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: extra.diff --]
[-- Type: text/x-diff, Size: 16480 bytes --]
Index: gas/config/tc-mips.c
===================================================================
--- gas/config/tc-mips.c 2011-07-24 15:07:48.000000000 +0100
+++ gas/config/tc-mips.c 2011-07-24 15:07:51.000000000 +0100
@@ -203,9 +203,6 @@ static bfd_boolean mips_in_shared = TRUE
pseudo-op. We use a struct so that .set push and .set pop are more
reliable. */
-/* Whether or not we emit branch likely macros. */
-static bfd_boolean emit_branch_likely_macro = FALSE;
-
struct mips_set_options
{
/* MIPS ISA (Instruction Set Architecture) level. This is set to -1
@@ -644,7 +641,7 @@ static struct hash_control *op_hash = NU
/* The opcode hash table we use for the mips16. */
static struct hash_control *mips16_op_hash = NULL;
-/* The opcode hash table we use for the micromips. */
+/* The opcode hash table we use for the microMIPS ASE. */
static struct hash_control *micromips_op_hash = NULL;
/* This array holds the chars that always start a comment. If the
@@ -745,7 +742,7 @@ #define MAX_NOPS 4
#define NOP_INSN (mips_opts.mips16 ? &mips16_nop_insn \
: (mips_opts.micromips ? µmips_nop16_insn : &nop_insn))
-/* The number of bytes NOP takes for the current mode. */
+/* The size of NOP_INSN in bytes. */
#define NOP_INSN_SIZE (HAVE_CODE_COMPRESSION ? 2 : 4)
/* If this is set, it points to a frag holding nop instructions which
@@ -1251,6 +1248,9 @@ #define MIPS16_EXTRACT_OPERAND(FIELD, IN
MIPS16OP_MASK_##FIELD, \
MIPS16OP_SH_##FIELD)
\f
+/* Whether or not we are emitting a branch-likely macro. */
+static bfd_boolean emit_branch_likely_macro = FALSE;
+
/* Global variables used when generating relaxable macros. See the
comment above RELAX_ENCODE for more details about how relaxation
is used. */
@@ -1292,12 +1292,14 @@ #define MIPS16_EXTRACT_OPERAND(FIELD, IN
is the length of the first instruction of the second alternative.
For non-relaxable macros, both elements give the length of the first
instruction in bytes.
+
Set to zero if we haven't yet seen the first instruction. */
unsigned int first_insn_sizes[2];
/* For relaxable macros, insns[0] is the number of instructions for the
first alternative and insns[1] is the number of instructions for the
second alternative.
+
For non-relaxable macros, both elements give the number of
instructions for the macro. */
unsigned int insns[2];
@@ -1542,10 +1544,11 @@ mips_clear_insn_labels (void)
}
}
+/* Mark instruction labels in MIPS16/microMIPS mode. */
+
static inline void
mips_mark_labels (void)
{
- /* Mark instruction labels in MIPS16/microMIPS mode. */
if (HAVE_CODE_COMPRESSION)
mips_compressed_mark_labels ();
}
@@ -2071,7 +2074,6 @@ static const struct regname reg_names_n3
{0, 0}
};
-
/* Check if S points at a valid register specifier according to TYPES.
If so, then return 1, advance S to consume the specifier and store
the register's number in REGNOP, otherwise return 0. */
@@ -3973,7 +3975,8 @@ micromips_map_reloc (bfd_reloc_code_real
/* Output an instruction. IP is the instruction information.
ADDRESS_EXPR is an operand of the instruction to be used with
- RELOC_TYPE. */
+ RELOC_TYPE. EXPANSIONP is true if the instruction is part of
+ a macro expansion. */
static void
append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
@@ -4209,12 +4212,12 @@ append_insn (struct mips_cl_insn *ip, ex
16-bit/32-bit instructions. */
&& !forced_insn_length);
- if (address_expr
+ if (!HAVE_CODE_COMPRESSION
+ && address_expr
&& relax32
&& *reloc_type == BFD_RELOC_16_PCREL_S2
&& (pinfo & INSN_UNCOND_BRANCH_DELAY || pinfo & INSN_COND_BRANCH_DELAY
- || pinfo & INSN_COND_BRANCH_LIKELY)
- && !HAVE_CODE_COMPRESSION)
+ || pinfo & INSN_COND_BRANCH_LIKELY))
{
relaxed_branch = TRUE;
add_relaxed_insn (ip, (relaxed_branch_length
@@ -4232,14 +4235,14 @@ append_insn (struct mips_cl_insn *ip, ex
address_expr->X_add_number);
*reloc_type = BFD_RELOC_UNUSED;
}
- else if (address_expr
+ else if (mips_opts.micromips
+ && address_expr
&& ((relax32 && *reloc_type == BFD_RELOC_16_PCREL_S2)
|| *reloc_type > BFD_RELOC_UNUSED)
&& (pinfo & INSN_UNCOND_BRANCH_DELAY
|| pinfo & INSN_COND_BRANCH_DELAY
|| (pinfo2 & ~INSN2_ALIAS) == INSN2_UNCOND_BRANCH
- || pinfo2 & INSN2_COND_BRANCH)
- && mips_opts.micromips)
+ || pinfo2 & INSN2_COND_BRANCH))
{
bfd_boolean relax16 = *reloc_type > BFD_RELOC_UNUSED;
int type = relax16 ? *reloc_type - BFD_RELOC_UNUSED : 0;
@@ -4348,6 +4351,7 @@ append_insn (struct mips_cl_insn *ip, ex
howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
}
+ howto = bfd_reloc_type_lookup (stdoutput, final_type[0]);
ip->fixp[0] = fix_new_exp (ip->frag, ip->where,
bfd_get_reloc_size (howto),
address_expr,
@@ -4503,12 +4507,10 @@ append_insn (struct mips_cl_insn *ip, ex
&& (history[0].insn_mo->pinfo & MIPS16_INSN_UNCOND_BRANCH)))
mips_no_prev_insn ();
- /* For branch likely macro, we need to emit a label at the end. */
+ /* We need to emit a label at the end of branch-likely macros. */
if (emit_branch_likely_macro)
{
emit_branch_likely_macro = FALSE;
-
- /* We need to generate a label. */
micromips_add_label ();
}
@@ -4723,8 +4725,7 @@ macro_end (void)
relax_substateT s;
const char *msg;
- s = (subtype
- & (RELAX_SECOND_LONGER | RELAX_NOMACRO | RELAX_DELAY_SLOT));
+ s = subtype & (RELAX_SECOND_LONGER | RELAX_NOMACRO | RELAX_DELAY_SLOT);
msg = macro_warning (s);
if (msg != NULL)
as_warn ("%s", msg);
@@ -5259,7 +5260,7 @@ macro_build_jalr (expressionS *ep, int c
static const bfd_reloc_code_real_type jalr_relocs[2]
= { BFD_RELOC_MIPS_JALR, BFD_RELOC_MICROMIPS_JALR };
bfd_reloc_code_real_type jalr_reloc = jalr_relocs[mips_opts.micromips];
- const char *jalr = mips_opts.noreorder && !cprestore ? "jalr" : "jalrs";
+ const char *jalr;
char *f = NULL;
if (MIPS_JALR_HINT_P (ep))
@@ -5269,10 +5270,14 @@ macro_build_jalr (expressionS *ep, int c
}
if (!mips_opts.micromips)
macro_build (NULL, "jalr", "d,s", RA, PIC_CALL_REG);
- else if (MIPS_JALR_HINT_P (ep))
- macro_build (NULL, jalr, "t,s", RA, PIC_CALL_REG);
else
- macro_build (NULL, jalr, "mj", PIC_CALL_REG);
+ {
+ jalr = mips_opts.noreorder && !cprestore ? "jalr" : "jalrs";
+ if (MIPS_JALR_HINT_P (ep))
+ macro_build (NULL, jalr, "t,s", RA, PIC_CALL_REG);
+ else
+ macro_build (NULL, jalr, "mj", PIC_CALL_REG);
+ }
if (MIPS_JALR_HINT_P (ep))
fix_new_exp (frag_now, f - frag_now->fr_literal, 4, ep, FALSE, jalr_reloc);
}
@@ -6031,23 +6036,28 @@ add_got_offset_hilo (int dest, expressio
/* Emit a sequence of instructions to emulate a branch likely operation.
BR is an ordinary branch corresponding to one to be emulated. BRNEG
is its complementing branch with the original condition negated.
- CALL is set if the original branch specified the link operation. EP,
- FMT, SREG and TREG specify the usual macro_build() parameters.
+ CALL is set if the original branch specified the link operation.
+ EP, FMT, SREG and TREG specify the usual macro_build() parameters.
Code like this is produced in the noreorder mode:
+
BRNEG <args>, 1f
nop
b <sym>
delay slot (executed only if branch taken)
1:
- or:
+
+ or, if CALL is set:
+
BRNEG <args>, 1f
nop
bal <sym>
delay slot (executed only if branch taken)
1:
- if CALL is set. In the reorder mode the delay slot would be filled
- with a nop anyway, so code produced is simply:
+
+ In the reorder mode the delay slot would be filled with a nop anyway,
+ so code produced is simply:
+
BR <args>, <sym>
nop
Index: gas/testsuite/gas/mips/dli.s
===================================================================
--- gas/testsuite/gas/mips/dli.s 2011-07-24 15:01:44.000000000 +0100
+++ gas/testsuite/gas/mips/dli.s 2011-07-24 15:07:51.000000000 +0100
@@ -62,6 +62,4 @@ foo:
dli $4,0x003ffc03ffffc000
# Round to a 16 byte boundary, for ease in testing multiple targets.
- nop
- nop
- nop
+ .p2align 4
Index: gas/testsuite/gas/mips/micromips-trap.d
===================================================================
--- gas/testsuite/gas/mips/micromips-trap.d 2011-07-24 15:05:46.000000000 +0100
+++ gas/testsuite/gas/mips/micromips-trap.d 2011-07-24 15:07:52.000000000 +0100
@@ -1,6 +1,6 @@
#objdump: -dr --show-raw-insn
#name: microMIPS for MIPS32r2 (w/traps)
-#as: -mips32r2 -32 -trap -mfp64
+#as: -mips32r2 -32 -trap -mfp64 -EB
#stderr: micromips.l
#source: micromips.s
Index: gas/testsuite/gas/mips/micromips.d
===================================================================
--- gas/testsuite/gas/mips/micromips.d 2011-07-24 15:05:46.000000000 +0100
+++ gas/testsuite/gas/mips/micromips.d 2011-07-24 15:07:52.000000000 +0100
@@ -1,6 +1,6 @@
#objdump: -dr --show-raw-insn
#name: microMIPS for MIPS32r2
-#as: -mips32r2 -32 -mfp64
+#as: -mips32r2 -32 -mfp64 -EB
#stderr: micromips.l
#source: micromips.s
Index: gas/testsuite/gas/mips/micromips@dli.d
===================================================================
--- gas/testsuite/gas/mips/micromips@dli.d 2011-07-24 15:05:46.000000000 +0100
+++ gas/testsuite/gas/mips/micromips@dli.d 2011-07-24 15:07:51.000000000 +0100
@@ -113,7 +113,4 @@ Disassembly of section \.text:
[0-9a-f]+ <[^>]*> 5084 ffff ori a0,a0,0xffff
[0-9a-f]+ <[^>]*> 5884 8000 dsll a0,a0,0x10
[0-9a-f]+ <[^>]*> 5084 c000 ori a0,a0,0xc000
-[0-9a-f]+ <[^>]*> 0c00 nop
-[0-9a-f]+ <[^>]*> 0c00 nop
-[0-9a-f]+ <[^>]*> 0c00 nop
-[0-9a-f]+ <[^>]*> 0c00 nop
+ \.\.\.
Index: gas/testsuite/gas/mips/micromips@elfel-rel2.d
===================================================================
--- /dev/null 2011-07-24 10:34:17.994719526 +0100
+++ gas/testsuite/gas/mips/micromips@elfel-rel2.d 2011-07-24 15:07:52.000000000 +0100
@@ -0,0 +1,28 @@
+#objdump: -sr -j .text
+#name: MIPS ELF reloc 2
+#source: elf-rel2.s
+#as: -mabi=o64
+
+# Test the GPREL and LITERAL generation (microMIPS).
+# FIXME: really this should check that the contents of .sdata, .lit4,
+# and .lit8 are correct too.
+
+.*: +file format .*mips.*
+
+RELOCATION RECORDS FOR \[\.text\]:
+OFFSET [ ]+ TYPE VALUE
+0+0000000 R_MICROMIPS_LITERAL \.lit8
+0+0000004 R_MICROMIPS_LITERAL \.lit8
+0+0000008 R_MICROMIPS_LITERAL \.lit8
+0+000000c R_MICROMIPS_LITERAL \.lit4
+0+0000010 R_MICROMIPS_LITERAL \.lit4
+0+0000014 R_MICROMIPS_LITERAL \.lit4
+0+0000018 R_MICROMIPS_GPREL16 \.sdata
+0+000001c R_MICROMIPS_GPREL16 \.sdata
+0+0000020 R_MICROMIPS_GPREL16 \.sdata
+
+
+Contents of section \.text:
+ 0000 5cbc0000 5cbc0800 5cbc1000 5c9c0000 .*
+ 0010 5c9c0400 5c9c0800 5cfc0000 5cfc0400 .*
+ 0020 5cfc0800 .*
Index: gas/testsuite/gas/mips/micromips@mips4-branch-likely.d
===================================================================
--- gas/testsuite/gas/mips/micromips@mips4-branch-likely.d 2011-07-24 15:05:46.000000000 +0100
+++ gas/testsuite/gas/mips/micromips@mips4-branch-likely.d 2011-07-24 15:07:51.000000000 +0100
@@ -1,6 +1,7 @@
#objdump: -dr --prefix-addresses --show-raw-insn
#name: MIPS mips4 branch-likely instructions
#source: mips4-branch-likely.s
+#as: -32
# Test mips4 branch-likely instructions (microMIPS).
Index: gas/testsuite/gas/mips/micromips@mips4-fp.d
===================================================================
--- gas/testsuite/gas/mips/micromips@mips4-fp.d 2011-07-24 15:05:46.000000000 +0100
+++ gas/testsuite/gas/mips/micromips@mips4-fp.d 2011-07-24 15:07:51.000000000 +0100
@@ -1,6 +1,7 @@
#objdump: -dr --prefix-addresses --show-raw-insn
#name: MIPS mips4 fp
#source: mips4-fp.s
+#as: -32
# Test mips4 fp instructions (microMIPS).
Index: gas/testsuite/gas/mips/mips.exp
===================================================================
--- gas/testsuite/gas/mips/mips.exp 2011-07-24 15:06:40.000000000 +0100
+++ gas/testsuite/gas/mips/mips.exp 2011-07-24 15:07:51.000000000 +0100
@@ -489,21 +489,31 @@ if { [istarget mips*-*-vxworks*] } {
run_dump_test "eret-1"
run_dump_test "eret-2"
run_dump_test "eret-3"
- run_dump_test_arches "24k-branch-delay-1" [mips_arch_list_matching mips1]
+ run_dump_test_arches "24k-branch-delay-1" \
+ [mips_arch_list_matching mips1 !micromips]
run_dump_test_arches "24k-triple-stores-1" \
- [mips_arch_list_matching mips32r2 !octeon]
- run_dump_test_arches "24k-triple-stores-2" [mips_arch_list_matching mips2]
- run_dump_test_arches "24k-triple-stores-3" [mips_arch_list_matching mips3]
- run_dump_test_arches "24k-triple-stores-4" [mips_arch_list_matching mips2]
- run_dump_test_arches "24k-triple-stores-5" [mips_arch_list_matching mips1]
- run_dump_test_arches "24k-triple-stores-6" [mips_arch_list_matching mips2]
- run_dump_test_arches "24k-triple-stores-7" [mips_arch_list_matching mips2]
- run_dump_test_arches "24k-triple-stores-8" [mips_arch_list_matching mips1]
- run_dump_test_arches "24k-triple-stores-9" [mips_arch_list_matching mips1]
- run_dump_test_arches "24k-triple-stores-10" [mips_arch_list_matching mips1]
+ [mips_arch_list_matching mips32r2 !octeon !micromips]
+ run_dump_test_arches "24k-triple-stores-2" \
+ [mips_arch_list_matching mips2 !micromips]
+ run_dump_test_arches "24k-triple-stores-3" \
+ [mips_arch_list_matching mips3 !micromips]
+ run_dump_test_arches "24k-triple-stores-4" \
+ [mips_arch_list_matching mips2 !micromips]
+ run_dump_test_arches "24k-triple-stores-5" \
+ [mips_arch_list_matching mips1 !micromips]
+ run_dump_test_arches "24k-triple-stores-6" \
+ [mips_arch_list_matching mips2 !micromips]
+ run_dump_test_arches "24k-triple-stores-7" \
+ [mips_arch_list_matching mips2 !micromips]
+ run_dump_test_arches "24k-triple-stores-8" \
+ [mips_arch_list_matching mips1 !micromips]
+ run_dump_test_arches "24k-triple-stores-9" \
+ [mips_arch_list_matching mips1 !micromips]
+ run_dump_test_arches "24k-triple-stores-10" \
+ [mips_arch_list_matching mips1 !micromips]
if $elf {
run_dump_test_arches "24k-triple-stores-11" \
- [mips_arch_list_matching mips1]
+ [mips_arch_list_matching mips1 !micromips]
}
if $elf {
Index: gas/testsuite/gas/mips/mipsel16-e.d
===================================================================
--- gas/testsuite/gas/mips/mipsel16-e.d 2011-07-24 15:01:44.000000000 +0100
+++ gas/testsuite/gas/mips/mipsel16-e.d 2011-07-24 15:07:52.000000000 +0100
@@ -1,4 +1,4 @@
-#objdump: -rst -mips16
+#objdump: -rst --special-syms -mips16
#name: MIPS16 reloc
#as: -32 -mips16
#source: mips16-e.s
Index: gas/testsuite/gas/mips/tmipsel16-e.d
===================================================================
--- gas/testsuite/gas/mips/tmipsel16-e.d 2011-07-24 15:01:44.000000000 +0100
+++ gas/testsuite/gas/mips/tmipsel16-e.d 2011-07-24 15:07:52.000000000 +0100
@@ -1,4 +1,4 @@
-#objdump: -rst -mips16
+#objdump: -rst --special-syms -mips16
#name: MIPS16 reloc
#as: -32 -mips16
#source: mips16-e.s
Index: ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
--- ld/testsuite/ld-mips-elf/mips-elf.exp 2011-07-24 15:05:46.000000000 +0100
+++ ld/testsuite/ld-mips-elf/mips-elf.exp 2011-07-24 15:07:51.000000000 +0100
@@ -129,19 +129,19 @@ run_dump_test "jalx-1"
if { $linux_gnu } {
run_ld_link_tests [list \
[list "Dummy shared library for JALX test 2" \
- "-shared -nostdlib" \
+ "-shared -nostdlib -melf32btsmip" \
"-G0 -EB -mmicromips -no-mdebug -mabi=32 -march=mips32r2 -KPIC" \
{ jalx-2-printf.s } \
{} \
"libjalx-2.so"] \
[list "Dummy external function for JALX test 2" \
- "-r" \
+ "-r -melf32btsmip" \
"-G0 -EB -no-mdebug -mabi=32 -march=mips32r2 -mno-shared -call_nonpic" \
{ jalx-2-ex.s } \
{} \
"jalx-2-ex.o.r"] \
[list "MIPS JALX test 2" \
- "-nostdlib -T jalx-2.ld tmpdir/libjalx-2.so tmpdir/jalx-2-ex.o.r" \
+ "-nostdlib -T jalx-2.ld tmpdir/libjalx-2.so tmpdir/jalx-2-ex.o.r -melf32btsmip" \
"-G0 -EB -mmicromips -no-mdebug -mabi=32 -march=mips32r2 -mno-shared -call_nonpic" \
{ jalx-2-main.s } \
{ { objdump -d jalx-2.dd } } \
next prev parent reply other threads:[~2011-07-24 14:23 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-18 18:19 [PATCH] MIPS: microMIPS and MCU ASE instruction set support Maciej W. Rozycki
2010-05-23 21:38 ` Richard Sandiford
2010-05-24 22:25 ` Fu, Chao-Ying
2010-05-26 19:47 ` Richard Sandiford
2010-06-01 14:21 ` Maciej W. Rozycki
2010-06-01 14:39 ` Catherine Moore
2010-06-01 22:04 ` Richard Sandiford
2010-06-01 22:47 ` Fu, Chao-Ying
2010-06-05 9:17 ` Richard Sandiford
2010-07-26 10:56 ` [PATCH] MIPS: microMIPS ASE support Maciej W. Rozycki
2010-07-26 13:25 ` Nathan Froyd
2010-07-26 13:53 ` Maciej W. Rozycki
2010-07-26 19:03 ` Richard Sandiford
2010-12-07 1:13 ` Maciej W. Rozycki
2010-12-12 14:59 ` Richard Sandiford
2010-12-14 13:30 ` Maciej W. Rozycki
2010-12-14 14:51 ` Richard Sandiford
2010-12-16 11:54 ` Maciej W. Rozycki
2010-12-18 10:26 ` Richard Sandiford
2010-12-14 17:56 ` Joseph S. Myers
2010-12-16 15:28 ` Maciej W. Rozycki
2010-12-17 20:56 ` Fu, Chao-Ying
2010-12-18 10:09 ` Richard Sandiford
2011-01-02 11:36 ` Richard Sandiford
2011-02-21 15:35 ` Maciej W. Rozycki
2011-02-22 20:12 ` Fu, Chao-Ying
2011-02-22 20:19 ` Fu, Chao-Ying
2011-02-24 10:46 ` Maciej W. Rozycki
2011-02-26 11:41 ` Richard Sandiford
2011-02-28 16:41 ` Maciej W. Rozycki
2011-02-26 0:00 ` Maciej W. Rozycki
2011-03-13 9:23 ` Richard Sandiford
2011-07-25 7:49 ` Richard Sandiford [this message]
2011-07-26 2:01 ` Maciej W. Rozycki
2011-07-29 0:58 ` Maciej W. Rozycki
2011-07-29 11:30 ` Richard Sandiford
2011-07-29 22:52 ` Maciej W. Rozycki
2011-02-26 11:36 ` Richard Sandiford
2011-07-26 14:00 ` Maciej W. Rozycki
2010-05-26 20:19 ` [PATCH] MIPS: microMIPS and MCU ASE instruction set support Richard Sandiford
2010-05-27 21:39 ` Richard Sandiford
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ipqrwyf4.fsf@firetop.home \
--to=rdsandiford@googlemail.com \
--cc=binutils@sourceware.org \
--cc=clm@codesourcery.com \
--cc=davidlau@mips.com \
--cc=froydnj@codesourcery.com \
--cc=fu@mips.com \
--cc=ilie@mips.com \
--cc=joseph@codesourcery.com \
--cc=kevinm@mips.com \
--cc=macro@codesourcery.com \
--cc=nathan@codesourcery.com \
--cc=rich@mips.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).