summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog19
-rw-r--r--bfd/elfxx-mips.c213
-rw-r--r--bfd/elfxx-mips.h2
-rw-r--r--include/opcode/ChangeLog5
-rw-r--r--include/opcode/mips.h3
-rw-r--r--opcodes/ChangeLog5
-rw-r--r--opcodes/micromips-opc.c9
7 files changed, 216 insertions, 40 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 967d2aae949..55370917383 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,22 @@
+2013-06-25 Maciej W. Rozycki <macro@codesourcery.com>
+ Paul Brook <paul@codesourcery.com>
+
+ * elfxx-mips.h (_bfd_mips_elf_insn32): New prototype.
+ * elfxx-mips.c (mips_elf_link_hash_table): Add insn32 member.
+ (STUB_MOVE32_MICROMIPS, STUB_JALR32_MICROMIPS): New macros.
+ (MICROMIPS_INSN32_FUNCTION_STUB_NORMAL_SIZE): Likewise.
+ (MICROMIPS_INSN32_FUNCTION_STUB_BIG_SIZE): Likewise.
+ (micromips_insn32_o32_exec_plt0_entry): New variable.
+ (micromips_insn32_o32_exec_plt_entry): Likewise.
+ (_bfd_mips_elf_adjust_dynamic_symbol): Handle insn32 mode.
+ (mips_elf_estimate_stub_size): Likewise.
+ (_bfd_mips_elf_size_dynamic_sections): Likewise.
+ (_bfd_mips_elf_finish_dynamic_symbol): Likewise.
+ (mips_finish_exec_plt): Likewise.
+ (_bfd_mips_elf_relax_section): Likewise.
+ (_bfd_mips_elf_insn32): New function.
+ (_bfd_mips_elf_get_synthetic_symtab): Handle insn32 PLT.
+
2013-06-24 Maciej W. Rozycki <macro@codesourcery.com>
* elfxx-mips.h (_bfd_mips_elf_get_synthetic_symtab): New
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index dd61049a17e..63fb508b873 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -437,6 +437,9 @@ struct mips_elf_link_hash_table
/* True if we can generate copy relocs and PLTs. */
bfd_boolean use_plts_and_copy_relocs;
+ /* True if we can only use 32-bit microMIPS instructions. */
+ bfd_boolean insn32;
+
/* True if we're generating code for VxWorks. */
bfd_boolean is_vxworks;
@@ -904,9 +907,14 @@ static bfd *reldyn_sorting_bfd;
? 0xdf3c8010 /* ld t9,0x8010(gp) */ \
: 0xff3c8010) /* lw t9,0x8010(gp) */
#define STUB_MOVE_MICROMIPS 0x0dff /* move t7,ra */
+#define STUB_MOVE32_MICROMIPS(abfd) \
+ (ABI_64_P (abfd) \
+ ? 0x581f7950 /* daddu t7,ra,zero */ \
+ : 0x001f7950) /* addu t7,ra,zero */
#define STUB_LUI_MICROMIPS(VAL) \
(0x41b80000 + (VAL)) /* lui t8,VAL */
#define STUB_JALR_MICROMIPS 0x45d9 /* jalr t9 */
+#define STUB_JALR32_MICROMIPS 0x03f90f3c /* jalr ra,t9 */
#define STUB_ORI_MICROMIPS(VAL) \
(0x53180000 + (VAL)) /* ori t8,t8,VAL */
#define STUB_LI16U_MICROMIPS(VAL) \
@@ -920,6 +928,8 @@ static bfd *reldyn_sorting_bfd;
#define MIPS_FUNCTION_STUB_BIG_SIZE 20
#define MICROMIPS_FUNCTION_STUB_NORMAL_SIZE 12
#define MICROMIPS_FUNCTION_STUB_BIG_SIZE 16
+#define MICROMIPS_INSN32_FUNCTION_STUB_NORMAL_SIZE 16
+#define MICROMIPS_INSN32_FUNCTION_STUB_BIG_SIZE 20
/* The name of the dynamic interpreter. This is put in the .interp
section. */
@@ -1050,6 +1060,20 @@ static const bfd_vma micromips_o32_exec_plt0_entry[] =
0x0c00 /* nop */
};
+/* The format of the microMIPS first PLT entry in an O32 executable
+ in the insn32 mode. */
+static const bfd_vma micromips_insn32_o32_exec_plt0_entry[] =
+{
+ 0x41bc, 0x0000, /* lui $28, %hi(&GOTPLT[0]) */
+ 0xff3c, 0x0000, /* lw $25, %lo(&GOTPLT[0])($28) */
+ 0x339c, 0x0000, /* addiu $28, $28, %lo(&GOTPLT[0]) */
+ 0x0398, 0xc1d0, /* subu $24, $24, $28 */
+ 0x001f, 0x7950, /* move $15, $31 */
+ 0x0318, 0x1040, /* srl $24, $24, 2 */
+ 0x03f9, 0x0f3c, /* jalr $25 */
+ 0x3318, 0xfffe /* subu $24, $24, 2 */
+};
+
/* The format of subsequent standard PLT entries. */
static const bfd_vma mips_exec_plt_entry[] =
{
@@ -1083,6 +1107,15 @@ static const bfd_vma micromips_o32_exec_plt_entry[] =
0x0f02 /* move $24, $2 */
};
+/* The format of subsequent microMIPS o32 PLT entries in the insn32 mode. */
+static const bfd_vma micromips_insn32_o32_exec_plt_entry[] =
+{
+ 0x41af, 0x0000, /* lui $15, %hi(.got.plt entry) */
+ 0xff2f, 0x0000, /* lw $25, %lo(.got.plt entry)($15) */
+ 0x0019, 0x0f3c, /* jr $25 */
+ 0x330f, 0x0000 /* addiu $24, $15, %lo(.got.plt entry) */
+};
+
/* The format of the first PLT entry in a VxWorks executable. */
static const bfd_vma mips_vxworks_exec_plt0_entry[] =
{
@@ -8802,19 +8835,26 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
else if (newabi_p)
htab->plt_mips_entry_size
= 4 * ARRAY_SIZE (mips_exec_plt_entry);
- else if (micromips_p)
+ else if (!micromips_p)
{
htab->plt_mips_entry_size
= 4 * ARRAY_SIZE (mips_exec_plt_entry);
htab->plt_comp_entry_size
- = 2 * ARRAY_SIZE (micromips_o32_exec_plt_entry);
+ = 2 * ARRAY_SIZE (mips16_o32_exec_plt_entry);
+ }
+ else if (htab->insn32)
+ {
+ htab->plt_mips_entry_size
+ = 4 * ARRAY_SIZE (mips_exec_plt_entry);
+ htab->plt_comp_entry_size
+ = 2 * ARRAY_SIZE (micromips_insn32_o32_exec_plt_entry);
}
else
{
htab->plt_mips_entry_size
= 4 * ARRAY_SIZE (mips_exec_plt_entry);
htab->plt_comp_entry_size
- = 2 * ARRAY_SIZE (mips16_o32_exec_plt_entry);
+ = 2 * ARRAY_SIZE (micromips_o32_exec_plt_entry);
}
}
@@ -9128,15 +9168,19 @@ mips_elf_estimate_stub_size (bfd *output_bfd, struct bfd_link_info *info)
from using microMIPS code here, so for the sake of pure-microMIPS
binaries we prefer it whenever there's any microMIPS code in
output produced at all. This has a benefit of stubs being
- shorter by 4 bytes each too. */
- if (MICROMIPS_P (output_bfd))
- htab->function_stub_size = (dynsymcount > 0x10000
- ? MICROMIPS_FUNCTION_STUB_BIG_SIZE
- : MICROMIPS_FUNCTION_STUB_NORMAL_SIZE);
- else
+ shorter by 4 bytes each too, unless in the insn32 mode. */
+ if (!MICROMIPS_P (output_bfd))
htab->function_stub_size = (dynsymcount > 0x10000
? MIPS_FUNCTION_STUB_BIG_SIZE
: MIPS_FUNCTION_STUB_NORMAL_SIZE);
+ else if (htab->insn32)
+ htab->function_stub_size = (dynsymcount > 0x10000
+ ? MICROMIPS_INSN32_FUNCTION_STUB_BIG_SIZE
+ : MICROMIPS_INSN32_FUNCTION_STUB_NORMAL_SIZE);
+ else
+ htab->function_stub_size = (dynsymcount > 0x10000
+ ? MICROMIPS_FUNCTION_STUB_BIG_SIZE
+ : MICROMIPS_FUNCTION_STUB_NORMAL_SIZE);
htab->sstubs->size = htab->lazy_stub_count * htab->function_stub_size;
}
@@ -9341,6 +9385,8 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
size = 4 * ARRAY_SIZE (mips_n32_exec_plt0_entry);
else if (!micromips_p)
size = 4 * ARRAY_SIZE (mips_o32_exec_plt0_entry);
+ else if (htab->insn32)
+ size = 2 * ARRAY_SIZE (micromips_insn32_o32_exec_plt0_entry);
else
size = 2 * ARRAY_SIZE (micromips_o32_exec_plt0_entry);
@@ -10293,7 +10339,32 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
loc = htab->splt->contents + plt_offset;
/* Fill in the PLT entry itself. */
- if (MICROMIPS_P (output_bfd))
+ if (!MICROMIPS_P (output_bfd))
+ {
+ const bfd_vma *plt_entry = mips16_o32_exec_plt_entry;
+
+ bfd_put_16 (output_bfd, plt_entry[0], loc);
+ bfd_put_16 (output_bfd, plt_entry[1], loc + 2);
+ bfd_put_16 (output_bfd, plt_entry[2], loc + 4);
+ bfd_put_16 (output_bfd, plt_entry[3], loc + 6);
+ bfd_put_16 (output_bfd, plt_entry[4], loc + 8);
+ bfd_put_16 (output_bfd, plt_entry[5], loc + 10);
+ bfd_put_32 (output_bfd, got_address, loc + 12);
+ }
+ else if (htab->insn32)
+ {
+ const bfd_vma *plt_entry = micromips_insn32_o32_exec_plt_entry;
+
+ bfd_put_16 (output_bfd, plt_entry[0], loc);
+ bfd_put_16 (output_bfd, got_address_high, loc + 2);
+ bfd_put_16 (output_bfd, plt_entry[2], loc + 4);
+ bfd_put_16 (output_bfd, got_address_low, loc + 6);
+ bfd_put_16 (output_bfd, plt_entry[4], loc + 8);
+ bfd_put_16 (output_bfd, plt_entry[5], loc + 10);
+ bfd_put_16 (output_bfd, plt_entry[6], loc + 12);
+ bfd_put_16 (output_bfd, got_address_low, loc + 14);
+ }
+ else
{
const bfd_vma *plt_entry = micromips_o32_exec_plt_entry;
bfd_signed_vma gotpc_offset;
@@ -10326,18 +10397,6 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
bfd_put_16 (output_bfd, plt_entry[4], loc + 8);
bfd_put_16 (output_bfd, plt_entry[5], loc + 10);
}
- else
- {
- const bfd_vma *plt_entry = mips16_o32_exec_plt_entry;
-
- bfd_put_16 (output_bfd, plt_entry[0], loc);
- bfd_put_16 (output_bfd, plt_entry[1], loc + 2);
- bfd_put_16 (output_bfd, plt_entry[2], loc + 4);
- bfd_put_16 (output_bfd, plt_entry[3], loc + 6);
- bfd_put_16 (output_bfd, plt_entry[4], loc + 8);
- bfd_put_16 (output_bfd, plt_entry[5], loc + 10);
- bfd_put_32 (output_bfd, got_address, loc + 12);
- }
}
/* Emit an R_MIPS_JUMP_SLOT relocation against the .got.plt entry. */
@@ -10369,10 +10428,12 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
bfd_vma isa_bit = micromips_p;
bfd_vma stub_big_size;
- if (micromips_p)
- stub_big_size = MICROMIPS_FUNCTION_STUB_BIG_SIZE;
- else
+ if (!micromips_p)
stub_big_size = MIPS_FUNCTION_STUB_BIG_SIZE;
+ else if (htab->insn32)
+ stub_big_size = MICROMIPS_INSN32_FUNCTION_STUB_BIG_SIZE;
+ else
+ stub_big_size = MICROMIPS_FUNCTION_STUB_BIG_SIZE;
/* This symbol has a stub. Set it up. */
@@ -10393,8 +10454,18 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
bfd_put_micromips_32 (output_bfd, STUB_LW_MICROMIPS (output_bfd),
stub + idx);
idx += 4;
- bfd_put_16 (output_bfd, STUB_MOVE_MICROMIPS, stub + idx);
- idx += 2;
+ if (htab->insn32)
+ {
+ bfd_put_micromips_32 (output_bfd,
+ STUB_MOVE32_MICROMIPS (output_bfd),
+ stub + idx);
+ idx += 4;
+ }
+ else
+ {
+ bfd_put_16 (output_bfd, STUB_MOVE_MICROMIPS, stub + idx);
+ idx += 2;
+ }
if (stub_size == stub_big_size)
{
long dynindx_hi = (h->dynindx >> 16) & 0x7fff;
@@ -10404,8 +10475,17 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
stub + idx);
idx += 4;
}
- bfd_put_16 (output_bfd, STUB_JALR_MICROMIPS, stub + idx);
- idx += 2;
+ if (htab->insn32)
+ {
+ bfd_put_micromips_32 (output_bfd, STUB_JALR32_MICROMIPS,
+ stub + idx);
+ idx += 4;
+ }
+ else
+ {
+ bfd_put_16 (output_bfd, STUB_JALR_MICROMIPS, stub + idx);
+ idx += 2;
+ }
/* If a large stub is not required and sign extension is not a
problem, then use legacy code in the stub. */
@@ -10828,10 +10908,12 @@ mips_finish_exec_plt (bfd *output_bfd, struct bfd_link_info *info)
plt_entry = mips_n64_exec_plt0_entry;
else if (ABI_N32_P (output_bfd))
plt_entry = mips_n32_exec_plt0_entry;
- else if (htab->plt_header_is_comp)
- plt_entry = micromips_o32_exec_plt0_entry;
- else
+ else if (!htab->plt_header_is_comp)
plt_entry = mips_o32_exec_plt0_entry;
+ else if (htab->insn32)
+ plt_entry = micromips_insn32_o32_exec_plt0_entry;
+ else
+ plt_entry = micromips_o32_exec_plt0_entry;
/* Calculate the value of .got.plt. */
gotplt_value = (htab->sgotplt->output_section->vma
@@ -10876,6 +10958,19 @@ mips_finish_exec_plt (bfd *output_bfd, struct bfd_link_info *info)
for (i = 2; i < ARRAY_SIZE (micromips_o32_exec_plt0_entry); i++)
bfd_put_16 (output_bfd, plt_entry[i], loc + (i * 2));
}
+ else if (plt_entry == micromips_insn32_o32_exec_plt0_entry)
+ {
+ size_t i;
+
+ bfd_put_16 (output_bfd, plt_entry[0], loc);
+ bfd_put_16 (output_bfd, gotplt_value_high, loc + 2);
+ bfd_put_16 (output_bfd, plt_entry[2], loc + 4);
+ bfd_put_16 (output_bfd, gotplt_value_low, loc + 6);
+ bfd_put_16 (output_bfd, plt_entry[4], loc + 8);
+ bfd_put_16 (output_bfd, gotplt_value_low, loc + 10);
+ for (i = 6; i < ARRAY_SIZE (micromips_insn32_o32_exec_plt0_entry); i++)
+ bfd_put_16 (output_bfd, plt_entry[i], loc + (i * 2));
+ }
else
{
bfd_put_32 (output_bfd, plt_entry[0] | gotplt_value_high, loc);
@@ -12929,6 +13024,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
struct bfd_link_info *link_info,
bfd_boolean *again)
{
+ bfd_boolean insn32 = mips_elf_hash_table (link_info)->insn32;
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Rela *internal_relocs;
Elf_Internal_Rela *irel, *irelend;
@@ -13211,7 +13307,13 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
&& irel->r_offset + 5 < sec->size
&& ((fndopc = find_match (opcode, bz_rs_insns_32)) >= 0
|| (fndopc = find_match (opcode, bz_rt_insns_32)) >= 0)
- && MATCH (bfd_get_16 (abfd, ptr + 4), nop_insn_16))
+ && ((!insn32
+ && (delcnt = MATCH (bfd_get_16 (abfd, ptr + 4),
+ nop_insn_16) ? 2 : 0))
+ || (irel->r_offset + 7 < sec->size
+ && (delcnt = MATCH (bfd_get_micromips_32 (abfd,
+ ptr + 4),
+ nop_insn_32) ? 4 : 0))))
{
unsigned long reg;
@@ -13224,15 +13326,15 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
bfd_put_micromips_32 (abfd, opcode, ptr);
- /* Delete the 16-bit delay slot NOP: two bytes from
- irel->offset + 4. */
- delcnt = 2;
+ /* Delete the delay slot NOP: two or four bytes from
+ irel->offset + 4; delcnt has already been set above. */
deloff = 4;
}
/* R_MICROMIPS_PC16_S1 relaxation to R_MICROMIPS_PC10_S1. We need
to check the distance from the next instruction, so subtract 2. */
- else if (r_type == R_MICROMIPS_PC16_S1
+ else if (!insn32
+ && r_type == R_MICROMIPS_PC16_S1
&& IS_BITSIZE (pcrval - 2, 11)
&& find_match (opcode, b_insns_32) >= 0)
{
@@ -13252,7 +13354,8 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
/* R_MICROMIPS_PC16_S1 relaxation to R_MICROMIPS_PC7_S1. We need
to check the distance from the next instruction, so subtract 2. */
- else if (r_type == R_MICROMIPS_PC16_S1
+ else if (!insn32
+ && r_type == R_MICROMIPS_PC16_S1
&& IS_BITSIZE (pcrval - 2, 8)
&& (((fndopc = find_match (opcode, bz_rs_insns_32)) >= 0
&& OP16_VALID_REG (OP32_SREG (opcode)))
@@ -13279,7 +13382,8 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
}
/* R_MICROMIPS_26_S1 -- JAL to JALS relaxation for microMIPS targets. */
- else if (r_type == R_MICROMIPS_26_S1
+ else if (!insn32
+ && r_type == R_MICROMIPS_26_S1
&& target_is_micromips_code_p
&& irel->r_offset + 7 < sec->size
&& MATCH (opcode, jal_insn_32_bd32))
@@ -13437,6 +13541,15 @@ _bfd_mips_elf_use_plts_and_copy_relocs (struct bfd_link_info *info)
{
mips_elf_hash_table (info)->use_plts_and_copy_relocs = TRUE;
}
+
+/* A function that the linker calls to select between all or only
+ 32-bit microMIPS instructions. */
+
+void
+_bfd_mips_elf_insn32 (struct bfd_link_info *info, bfd_boolean on)
+{
+ mips_elf_hash_table (info)->insn32 = on;
+}
/* We need to use a special link routine to handle the .reginfo and
the .mdebug sections. We need to merge all instances of these
@@ -14999,6 +15112,13 @@ _bfd_mips_elf_get_synthetic_symtab (bfd *abfd,
plt0_size = 2 * ARRAY_SIZE (micromips_o32_exec_plt0_entry);
other = STO_MICROMIPS;
}
+ else if (opcode == 0x0398c1d0)
+ {
+ if (!micromips_p)
+ return -1;
+ plt0_size = 2 * ARRAY_SIZE (micromips_insn32_o32_exec_plt0_entry);
+ other = STO_MICROMIPS;
+ }
else
{
plt0_size = 4 * ARRAY_SIZE (mips_o32_exec_plt0_entry);
@@ -15042,7 +15162,7 @@ _bfd_mips_elf_get_synthetic_symtab (bfd *abfd,
suffix = m16suffix;
other = STO_MIPS16;
}
- /* Likewise the expected microMIPS instruction. */
+ /* Likewise the expected microMIPS instruction (no insn32 mode). */
else if (opcode == 0xff220000)
{
if (!micromips_p)
@@ -15058,6 +15178,19 @@ _bfd_mips_elf_get_synthetic_symtab (bfd *abfd,
suffix = microsuffix;
other = STO_MICROMIPS;
}
+ /* Likewise the expected microMIPS instruction (insn32 mode). */
+ else if ((opcode & 0xffff0000) == 0xff2f0000)
+ {
+ gotplt_hi = bfd_get_16 (abfd, plt_data + plt_offset + 2) & 0xffff;
+ gotplt_lo = bfd_get_16 (abfd, plt_data + plt_offset + 6) & 0xffff;
+ gotplt_hi = ((gotplt_hi ^ 0x8000) - 0x8000) << 16;
+ gotplt_lo = (gotplt_lo ^ 0x8000) - 0x8000;
+ gotplt_addr = gotplt_hi + gotplt_lo;
+ entry_size = 2 * ARRAY_SIZE (micromips_insn32_o32_exec_plt_entry);
+ suffixlen = sizeof (microsuffix);
+ suffix = microsuffix;
+ other = STO_MICROMIPS;
+ }
/* Otherwise assume standard MIPS code. */
else
{
diff --git a/bfd/elfxx-mips.h b/bfd/elfxx-mips.h
index 45ccabb2090..f27dc15aad0 100644
--- a/bfd/elfxx-mips.h
+++ b/bfd/elfxx-mips.h
@@ -147,6 +147,8 @@ extern bfd_boolean _bfd_mips_elf_ignore_undef_symbol
(struct elf_link_hash_entry *);
extern void _bfd_mips_elf_use_plts_and_copy_relocs
(struct bfd_link_info *);
+extern void _bfd_mips_elf_insn32
+ (struct bfd_link_info *, bfd_boolean);
extern bfd_boolean _bfd_mips_elf_init_stubs
(struct bfd_link_info *,
asection *(*) (const char *, asection *, asection *));
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index 189a1d4176c..9aa75d90216 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,3 +1,8 @@
+2013-06-25 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * mips.h: Add M_JRADDIUSP, M_JRC and M_MOVEP anonymous enum
+ values.
+
2013-06-23 Richard Sandiford <rdsandiford@googlemail.com>
* mips.h: Fix comment typo: "G" is _RS rather than _RD for microMIPS.
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index e62ecd6e6db..ec9b6ba1908 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -1064,6 +1064,8 @@ enum
M_JALS_1,
M_JALS_2,
M_JALS_A,
+ M_JRADDIUSP,
+ M_JRC,
M_L_DOB,
M_L_DAB,
M_LA_AB,
@@ -1148,6 +1150,7 @@ enum
M_MSGWAIT,
M_MSGWAIT_T,
M_MOVE,
+ M_MOVEP,
M_MUL,
M_MUL_I,
M_MULO,
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 6a62974c7ba..034a27ff275 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,8 @@
+2013-06-25 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * micromips-opc.c (micromips_opcodes): Add "jraddiusp", "jrc"
+ and "movep" macros.
+
2013-06-24 Maciej W. Rozycki <macro@codesourcery.com>
* mips-dis.c (is_mips16_plt_tail): New function.
diff --git a/opcodes/micromips-opc.c b/opcodes/micromips-opc.c
index 34e7b124f64..c583d7a5481 100644
--- a/opcodes/micromips-opc.c
+++ b/opcodes/micromips-opc.c
@@ -548,7 +548,13 @@ const struct mips_opcode micromips_opcodes[] =
{"jr", "s", 0x00000f3c, 0xffe0ffff, UBD|RD_s, BD32, I1 }, /* jalr */
{"jrs", "s", 0x00004f3c, 0xffe0ffff, UBD|RD_s, BD16, I1 }, /* jalrs */
{"jraddiusp", "mP", 0x4700, 0xffe0, NODS, UBR|RD_31|WR_sp|RD_sp, I1 },
+/* This macro is after the real instruction so that it only matches with
+ -minsn32. */
+{"jraddiusp", "mP", 0, (int) M_JRADDIUSP, INSN_MACRO, 0, I1 },
{"jrc", "mj", 0x45a0, 0xffe0, NODS, UBR|RD_mj, I1 },
+/* This macro is after the real instruction so that it only matches with
+ -minsn32. */
+{"jrc", "s", 0, (int) M_JRC, INSN_MACRO, 0, I1 },
{"jr.hb", "s", 0x00001f3c, 0xffe0ffff, UBD|RD_s, BD32, I1 }, /* jalr.hb */
{"jrs.hb", "s", 0x00005f3c, 0xffe0ffff, UBD|RD_s, BD16, I1 }, /* jalrs.hb */
{"j", "mj", 0x4580, 0xffe0, UBD, RD_mj, I1 }, /* jr */
@@ -704,6 +710,9 @@ const struct mips_opcode micromips_opcodes[] =
{"mov.s", "T,S", 0x5400007b, 0xfc00ffff, WR_T|RD_S|FP_S, 0, I1 },
{"mov.ps", "T,S", 0x5400407b, 0xfc00ffff, WR_T|RD_S|FP_D, 0, I1 },
{"movep", "mh,mi,mm,mn", 0x8400, 0xfc01, NODS, WR_mhi|RD_mmn, I1 },
+/* This macro is after the real instruction so that it only matches with
+ -minsn32. */
+{"movep", "mh,mi,mm,mn", 0, (int) M_MOVEP, INSN_MACRO, 0, I1 },
{"movf", "t,s,M", 0x5400017b, 0xfc001fff, WR_t|RD_s|RD_CC|FP_S|FP_D, 0, I1 },
{"movf.d", "T,S,M", 0x54000220, 0xfc001fff, WR_T|RD_S|RD_CC|FP_D, 0, I1 },
{"movf.s", "T,S,M", 0x54000020, 0xfc001fff, WR_T|RD_S|RD_CC|FP_S, 0, I1 },