bfd/
* 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. gas/ * config/tc-mips.c (mips_set_options): Add insn32 member. (mips_opts): Initialize it. (NOP_INSN, NOP_INSN_SIZE): Handle insn32 mode. (options): Add OPTION_INSN32 and OPTION_NO_INSN32 enum values. (md_longopts): Add "minsn32" and "mno-insn32" options. (is_size_valid): Handle insn32 mode. (md_assemble): Pass instruction string down to macro. (brk_fmt): Add second dimension and insn32 mode initializers. (mfhl_fmt): Likewise. (BRK_FMT, MFHL_FMT): Handle insn32 mode. (macro_build) <'c'>: Handle microMIPS 32-bit BREAK encoding. (macro_build_jalr, move_register): Handle insn32 mode. (macro_build_branch_rs): Likewise. (macro): Handle insn32 mode. <M_JRADDIUSP>, <M_JRC>, <M_MOVEP>: New cases. (mips_ip): Handle insn32 mode. (md_parse_option): Handle OPTION_INSN32 and OPTION_NO_INSN32. (s_mipsset): Handle "insn32" and "noinsn32" pseudo-ops. (mips_handle_align): Handle insn32 mode. (md_show_usage): Add -minsn32 and -mno-insn32. * doc/as.texinfo (Target MIPS options): Add -minsn32 and -mno-insn32 options. (-minsn32, -mno-insn32): New options. * doc/c-mips.texi (MIPS Opts): Add -minsn32 and -mno-insn32 options. (MIPS assembly options): New node. Document .set insn32 and .set noinsn32. (MIPS-Dependent): List the new node. gas/testsuite/ * gas/mips/micromips-insn32.d: New test. * gas/mips/micromips-noinsn32.d: Likewise. * gas/mips/micromips.l: Rename to... * gas/mips/micromips-warn.l: ... this. * gas/mips/micromips.d: Update accordingly. * gas/mips/micromips-trap.d: Likewise. * gas/mips/micromips.l: New list test. * gas/mips/micromips.s: Add conditionals. * gas/mips/mips.exp: Run the new tests. include/opcode/ * mips.h: Add M_JRADDIUSP, M_JRC and M_MOVEP anonymous enum values. ld/ * emultempl/mipself.em (insn32): New variable. (mips_create_output_section_statements): Handle insn32 mode. (PARSE_AND_LIST_PROLOGUE): New macro. (PARSE_AND_LIST_LONGOPTS): Likewise. (PARSE_AND_LIST_OPTIONS): Likewise. * gen-doc.texi: Set MIPS. * ld.texinfo: Likewise. (Options specific to MIPS targets): New section. (ld and MIPS family): New node. (Top, Machine Dependent): List the new node. opcodes/ * micromips-opc.c (micromips_opcodes): Add "jraddiusp", "jrc" and "movep" macros.
This commit is contained in:
parent
6e2048d3e3
commit
833794fc12
24 changed files with 16401 additions and 86 deletions
|
@ -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
|
||||
|
|
213
bfd/elfxx-mips.c
213
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
|
||||
{
|
||||
|
|
|
@ -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 *));
|
||||
|
|
|
@ -1,3 +1,35 @@
|
|||
2013-06-25 Maciej W. Rozycki <macro@codesourcery.com>
|
||||
|
||||
* config/tc-mips.c (mips_set_options): Add insn32 member.
|
||||
(mips_opts): Initialize it.
|
||||
(NOP_INSN, NOP_INSN_SIZE): Handle insn32 mode.
|
||||
(options): Add OPTION_INSN32 and OPTION_NO_INSN32 enum values.
|
||||
(md_longopts): Add "minsn32" and "mno-insn32" options.
|
||||
(is_size_valid): Handle insn32 mode.
|
||||
(md_assemble): Pass instruction string down to macro.
|
||||
(brk_fmt): Add second dimension and insn32 mode initializers.
|
||||
(mfhl_fmt): Likewise.
|
||||
(BRK_FMT, MFHL_FMT): Handle insn32 mode.
|
||||
(macro_build) <'c'>: Handle microMIPS 32-bit BREAK encoding.
|
||||
(macro_build_jalr, move_register): Handle insn32 mode.
|
||||
(macro_build_branch_rs): Likewise.
|
||||
(macro): Handle insn32 mode.
|
||||
<M_JRADDIUSP>, <M_JRC>, <M_MOVEP>: New cases.
|
||||
(mips_ip): Handle insn32 mode.
|
||||
(md_parse_option): Handle OPTION_INSN32 and OPTION_NO_INSN32.
|
||||
(s_mipsset): Handle "insn32" and "noinsn32" pseudo-ops.
|
||||
(mips_handle_align): Handle insn32 mode.
|
||||
(md_show_usage): Add -minsn32 and -mno-insn32.
|
||||
|
||||
* doc/as.texinfo (Target MIPS options): Add -minsn32 and
|
||||
-mno-insn32 options.
|
||||
(-minsn32, -mno-insn32): New options.
|
||||
* doc/c-mips.texi (MIPS Opts): Add -minsn32 and -mno-insn32
|
||||
options.
|
||||
(MIPS assembly options): New node. Document .set insn32 and
|
||||
.set noinsn32.
|
||||
(MIPS-Dependent): List the new node.
|
||||
|
||||
2013-06-25 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* config/tc-msp430.c (msp430_srcoperand): Do not allow the use of
|
||||
|
|
|
@ -231,6 +231,10 @@ struct mips_set_options
|
|||
/* Non-zero if we should not autoextend mips16 instructions.
|
||||
Changed by `.set autoextend' and `.set noautoextend'. */
|
||||
int noautoextend;
|
||||
/* True if we should only emit 32-bit microMIPS instructions.
|
||||
Changed by `.set insn32' and `.set noinsn32', and the -minsn32
|
||||
and -mno-insn32 command line options. */
|
||||
bfd_boolean insn32;
|
||||
/* Restrict general purpose registers and floating point registers
|
||||
to 32 bit. This is initially determined when -mgp32 or -mfp32
|
||||
is passed but can changed if the assembler code uses .set mipsN. */
|
||||
|
@ -272,8 +276,8 @@ static struct mips_set_options mips_opts =
|
|||
{
|
||||
/* isa */ ISA_UNKNOWN, /* ase */ 0, /* mips16 */ -1, /* micromips */ -1,
|
||||
/* noreorder */ 0, /* at */ ATREG, /* warn_about_macros */ 0,
|
||||
/* nomove */ 0, /* nobopt */ 0, /* noautoextend */ 0, /* gp32 */ 0,
|
||||
/* fp32 */ 0, /* arch */ CPU_UNKNOWN, /* sym32 */ FALSE,
|
||||
/* nomove */ 0, /* nobopt */ 0, /* noautoextend */ 0, /* insn32 */ FALSE,
|
||||
/* gp32 */ 0, /* fp32 */ 0, /* arch */ CPU_UNKNOWN, /* sym32 */ FALSE,
|
||||
/* soft_float */ FALSE, /* single_float */ FALSE
|
||||
};
|
||||
|
||||
|
@ -686,11 +690,18 @@ static struct mips_cl_insn micromips_nop16_insn;
|
|||
static struct mips_cl_insn micromips_nop32_insn;
|
||||
|
||||
/* The appropriate nop for the current mode. */
|
||||
#define NOP_INSN (mips_opts.mips16 ? &mips16_nop_insn \
|
||||
: (mips_opts.micromips ? µmips_nop16_insn : &nop_insn))
|
||||
#define NOP_INSN (mips_opts.mips16 \
|
||||
? &mips16_nop_insn \
|
||||
: (mips_opts.micromips \
|
||||
? (mips_opts.insn32 \
|
||||
? µmips_nop32_insn \
|
||||
: µmips_nop16_insn) \
|
||||
: &nop_insn))
|
||||
|
||||
/* The size of NOP_INSN in bytes. */
|
||||
#define NOP_INSN_SIZE (HAVE_CODE_COMPRESSION ? 2 : 4)
|
||||
#define NOP_INSN_SIZE ((mips_opts.mips16 \
|
||||
|| (mips_opts.micromips && !mips_opts.insn32)) \
|
||||
? 2 : 4)
|
||||
|
||||
/* If this is set, it points to a frag holding nop instructions which
|
||||
were inserted before the start of a noreorder section. If those
|
||||
|
@ -1276,7 +1287,7 @@ static void mips16_macro_build
|
|||
static void load_register (int, expressionS *, int);
|
||||
static void macro_start (void);
|
||||
static void macro_end (void);
|
||||
static void macro (struct mips_cl_insn * ip);
|
||||
static void macro (struct mips_cl_insn *ip, char *str);
|
||||
static void mips16_macro (struct mips_cl_insn * ip);
|
||||
static void mips_ip (char *str, struct mips_cl_insn * ip);
|
||||
static void mips16_ip (char *str, struct mips_cl_insn * ip);
|
||||
|
@ -1418,6 +1429,8 @@ enum options
|
|||
OPTION_GP64,
|
||||
OPTION_RELAX_BRANCH,
|
||||
OPTION_NO_RELAX_BRANCH,
|
||||
OPTION_INSN32,
|
||||
OPTION_NO_INSN32,
|
||||
OPTION_MSHARED,
|
||||
OPTION_MNO_SHARED,
|
||||
OPTION_MSYM32,
|
||||
|
@ -1524,6 +1537,8 @@ struct option md_longopts[] =
|
|||
{"mgp64", no_argument, NULL, OPTION_GP64},
|
||||
{"relax-branch", no_argument, NULL, OPTION_RELAX_BRANCH},
|
||||
{"no-relax-branch", no_argument, NULL, OPTION_NO_RELAX_BRANCH},
|
||||
{"minsn32", no_argument, NULL, OPTION_INSN32},
|
||||
{"mno-insn32", no_argument, NULL, OPTION_NO_INSN32},
|
||||
{"mshared", no_argument, NULL, OPTION_MSHARED},
|
||||
{"mno-shared", no_argument, NULL, OPTION_MNO_SHARED},
|
||||
{"msym32", no_argument, NULL, OPTION_MSYM32},
|
||||
|
@ -2636,6 +2651,13 @@ is_size_valid (const struct mips_opcode *mo)
|
|||
if (!mips_opts.micromips)
|
||||
return TRUE;
|
||||
|
||||
if (mips_opts.insn32)
|
||||
{
|
||||
if (mo->pinfo != INSN_MACRO && micromips_insn_length (mo) != 4)
|
||||
return FALSE;
|
||||
if ((mo->pinfo2 & INSN2_BRANCH_DELAY_16BIT) != 0)
|
||||
return FALSE;
|
||||
}
|
||||
if (!forced_insn_length)
|
||||
return TRUE;
|
||||
if (mo->pinfo == INSN_MACRO)
|
||||
|
@ -2966,7 +2988,7 @@ md_assemble (char *str)
|
|||
if (mips_opts.mips16)
|
||||
mips16_macro (&insn);
|
||||
else
|
||||
macro (&insn);
|
||||
macro (&insn, str);
|
||||
macro_end ();
|
||||
}
|
||||
else
|
||||
|
@ -5209,21 +5231,21 @@ macro_end (void)
|
|||
/* Instruction operand formats used in macros that vary between
|
||||
standard MIPS and microMIPS code. */
|
||||
|
||||
static const char * const brk_fmt[2] = { "c", "mF" };
|
||||
static const char * const brk_fmt[2][2] = { { "c", "c" }, { "mF", "c" } };
|
||||
static const char * const cop12_fmt[2] = { "E,o(b)", "E,~(b)" };
|
||||
static const char * const jalr_fmt[2] = { "d,s", "t,s" };
|
||||
static const char * const lui_fmt[2] = { "t,u", "s,u" };
|
||||
static const char * const mem12_fmt[2] = { "t,o(b)", "t,~(b)" };
|
||||
static const char * const mfhl_fmt[2] = { "d", "mj" };
|
||||
static const char * const mfhl_fmt[2][2] = { { "d", "d" }, { "mj", "s" } };
|
||||
static const char * const shft_fmt[2] = { "d,w,<", "t,r,<" };
|
||||
static const char * const trap_fmt[2] = { "s,t,q", "s,t,|" };
|
||||
|
||||
#define BRK_FMT (brk_fmt[mips_opts.micromips])
|
||||
#define BRK_FMT (brk_fmt[mips_opts.micromips][mips_opts.insn32])
|
||||
#define COP12_FMT (cop12_fmt[mips_opts.micromips])
|
||||
#define JALR_FMT (jalr_fmt[mips_opts.micromips])
|
||||
#define LUI_FMT (lui_fmt[mips_opts.micromips])
|
||||
#define MEM12_FMT (mem12_fmt[mips_opts.micromips])
|
||||
#define MFHL_FMT (mfhl_fmt[mips_opts.micromips])
|
||||
#define MFHL_FMT (mfhl_fmt[mips_opts.micromips][mips_opts.insn32])
|
||||
#define SHFT_FMT (shft_fmt[mips_opts.micromips])
|
||||
#define TRAP_FMT (trap_fmt[mips_opts.micromips])
|
||||
|
||||
|
@ -5382,8 +5404,7 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
|
|||
continue;
|
||||
|
||||
case 'c':
|
||||
gas_assert (!mips_opts.micromips);
|
||||
INSERT_OPERAND (0, CODE, insn, va_arg (args, int));
|
||||
INSERT_OPERAND (mips_opts.micromips, CODE, insn, va_arg (args, int));
|
||||
continue;
|
||||
|
||||
case 'W':
|
||||
|
@ -5750,8 +5771,10 @@ macro_build_jalr (expressionS *ep, int cprestore)
|
|||
}
|
||||
if (mips_opts.micromips)
|
||||
{
|
||||
jalr = mips_opts.noreorder && !cprestore ? "jalr" : "jalrs";
|
||||
jalr = ((mips_opts.noreorder && !cprestore) || mips_opts.insn32
|
||||
? "jalr" : "jalrs");
|
||||
if (MIPS_JALR_HINT_P (ep)
|
||||
|| mips_opts.insn32
|
||||
|| (history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
|
||||
macro_build (NULL, jalr, "t,s", RA, PIC_CALL_REG);
|
||||
else
|
||||
|
@ -6432,6 +6455,7 @@ move_register (int dest, int source)
|
|||
/* Prefer to use a 16-bit microMIPS instruction unless the previous
|
||||
instruction specifically requires a 32-bit one. */
|
||||
if (mips_opts.micromips
|
||||
&& !mips_opts.insn32
|
||||
&& !(history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
|
||||
macro_build (NULL, "move", "mp,mj", dest, source);
|
||||
else
|
||||
|
@ -6628,7 +6652,7 @@ macro_build_branch_rs (int type, expressionS *ep, unsigned int sreg)
|
|||
break;
|
||||
case M_BGEZALL:
|
||||
gas_assert (mips_opts.micromips);
|
||||
br = "bgezals";
|
||||
br = mips_opts.insn32 ? "bgezal" : "bgezals";
|
||||
brneg = "bltz";
|
||||
call = 1;
|
||||
break;
|
||||
|
@ -6655,7 +6679,7 @@ macro_build_branch_rs (int type, expressionS *ep, unsigned int sreg)
|
|||
break;
|
||||
case M_BLTZALL:
|
||||
gas_assert (mips_opts.micromips);
|
||||
br = "bltzals";
|
||||
br = mips_opts.insn32 ? "bltzal" : "bltzals";
|
||||
brneg = "bgez";
|
||||
call = 1;
|
||||
break;
|
||||
|
@ -6727,7 +6751,7 @@ macro_build_branch_rsrt (int type, expressionS *ep,
|
|||
* we're missing.
|
||||
*/
|
||||
static void
|
||||
macro (struct mips_cl_insn *ip)
|
||||
macro (struct mips_cl_insn *ip, char *str)
|
||||
{
|
||||
unsigned int treg, sreg, dreg, breg;
|
||||
unsigned int tempreg;
|
||||
|
@ -8149,6 +8173,11 @@ macro (struct mips_cl_insn *ip)
|
|||
/* Fall through. */
|
||||
case M_JALS_2:
|
||||
gas_assert (mips_opts.micromips);
|
||||
if (mips_opts.insn32)
|
||||
{
|
||||
as_bad (_("Opcode not supported in the `insn32' mode `%s'"), str);
|
||||
break;
|
||||
}
|
||||
jals = 1;
|
||||
goto jal;
|
||||
case M_JAL_1:
|
||||
|
@ -8160,6 +8189,7 @@ macro (struct mips_cl_insn *ip)
|
|||
{
|
||||
s = jals ? "jalrs" : "jalr";
|
||||
if (mips_opts.micromips
|
||||
&& !mips_opts.insn32
|
||||
&& dreg == RA
|
||||
&& !(history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
|
||||
macro_build (NULL, s, "mj", sreg);
|
||||
|
@ -8174,9 +8204,12 @@ macro (struct mips_cl_insn *ip)
|
|||
if (sreg != PIC_CALL_REG)
|
||||
as_warn (_("MIPS PIC call to register other than $25"));
|
||||
|
||||
s = (mips_opts.micromips && (!mips_opts.noreorder || cprestore)
|
||||
s = ((mips_opts.micromips
|
||||
&& !mips_opts.insn32
|
||||
&& (!mips_opts.noreorder || cprestore))
|
||||
? "jalrs" : "jalr");
|
||||
if (mips_opts.micromips
|
||||
&& !mips_opts.insn32
|
||||
&& dreg == RA
|
||||
&& !(history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
|
||||
macro_build (NULL, s, "mj", sreg);
|
||||
|
@ -8215,6 +8248,11 @@ macro (struct mips_cl_insn *ip)
|
|||
|
||||
case M_JALS_A:
|
||||
gas_assert (mips_opts.micromips);
|
||||
if (mips_opts.insn32)
|
||||
{
|
||||
as_bad (_("Opcode not supported in the `insn32' mode `%s'"), str);
|
||||
break;
|
||||
}
|
||||
jals = 1;
|
||||
/* Fall through. */
|
||||
case M_JAL_A:
|
||||
|
@ -9227,6 +9265,24 @@ macro (struct mips_cl_insn *ip)
|
|||
|
||||
break;
|
||||
|
||||
case M_JRADDIUSP:
|
||||
gas_assert (mips_opts.micromips);
|
||||
gas_assert (mips_opts.insn32);
|
||||
start_noreorder ();
|
||||
macro_build (NULL, "jr", "s", RA);
|
||||
expr1.X_add_number = EXTRACT_OPERAND (1, IMMP, *ip) << 2;
|
||||
macro_build (&expr1, "addiu", "t,r,j", SP, SP, BFD_RELOC_LO16);
|
||||
end_noreorder ();
|
||||
break;
|
||||
|
||||
case M_JRC:
|
||||
gas_assert (mips_opts.micromips);
|
||||
gas_assert (mips_opts.insn32);
|
||||
macro_build (NULL, "jr", "s", sreg);
|
||||
if (mips_opts.noreorder)
|
||||
macro_build (NULL, "nop", "");
|
||||
break;
|
||||
|
||||
case M_LI:
|
||||
case M_LI_S:
|
||||
load_register (treg, &imm_expr, 0);
|
||||
|
@ -9784,6 +9840,17 @@ macro (struct mips_cl_insn *ip)
|
|||
move_register (dreg, sreg);
|
||||
break;
|
||||
|
||||
case M_MOVEP:
|
||||
gas_assert (mips_opts.micromips);
|
||||
gas_assert (mips_opts.insn32);
|
||||
dreg = micromips_to_32_reg_h_map[EXTRACT_OPERAND (1, MH, *ip)];
|
||||
breg = micromips_to_32_reg_i_map[EXTRACT_OPERAND (1, MI, *ip)];
|
||||
sreg = micromips_to_32_reg_m_map[EXTRACT_OPERAND (1, MM, *ip)];
|
||||
treg = micromips_to_32_reg_n_map[EXTRACT_OPERAND (1, MN, *ip)];
|
||||
move_register (dreg, sreg);
|
||||
move_register (breg, treg);
|
||||
break;
|
||||
|
||||
case M_DMUL:
|
||||
dbl = 1;
|
||||
case M_MUL:
|
||||
|
@ -11343,6 +11410,8 @@ mips_ip (char *str, struct mips_cl_insn *ip)
|
|||
sprintf (buf, _("Opcode not supported on this processor: %s (%s)"),
|
||||
mips_cpu_info_from_arch (mips_opts.arch)->name,
|
||||
mips_cpu_info_from_isa (mips_opts.isa)->name);
|
||||
else if (mips_opts.insn32)
|
||||
sprintf (buf, _("Opcode not supported in the `insn32' mode"));
|
||||
else
|
||||
sprintf (buf, _("Unrecognized %u-bit version of microMIPS opcode"),
|
||||
8 * forced_insn_length);
|
||||
|
@ -15135,6 +15204,14 @@ md_parse_option (int c, char *arg)
|
|||
mips_relax_branch = 0;
|
||||
break;
|
||||
|
||||
case OPTION_INSN32:
|
||||
mips_opts.insn32 = TRUE;
|
||||
break;
|
||||
|
||||
case OPTION_NO_INSN32:
|
||||
mips_opts.insn32 = FALSE;
|
||||
break;
|
||||
|
||||
case OPTION_MSHARED:
|
||||
mips_in_shared = TRUE;
|
||||
break;
|
||||
|
@ -16547,6 +16624,10 @@ s_mipsset (int x ATTRIBUTE_UNUSED)
|
|||
mips_opts.noautoextend = 0;
|
||||
else if (strcmp (name, "noautoextend") == 0)
|
||||
mips_opts.noautoextend = 1;
|
||||
else if (strcmp (name, "insn32") == 0)
|
||||
mips_opts.insn32 = TRUE;
|
||||
else if (strcmp (name, "noinsn32") == 0)
|
||||
mips_opts.insn32 = FALSE;
|
||||
else if (strcmp (name, "push") == 0)
|
||||
{
|
||||
struct mips_option_stack *s;
|
||||
|
@ -18854,7 +18935,7 @@ mips_handle_align (fragS *fragp)
|
|||
*p++ = '\0';
|
||||
/* Fall through. */
|
||||
case 2:
|
||||
if (nop_opcode == NOP_OPCODE_MICROMIPS)
|
||||
if (nop_opcode == NOP_OPCODE_MICROMIPS && !mips_opts.insn32)
|
||||
{
|
||||
p = write_compressed_insn (p, micromips_nop16_insn.insn_opcode, 2);
|
||||
break;
|
||||
|
@ -19580,6 +19661,9 @@ MIPS options:\n\
|
|||
-mvirt generate Virtualization instructions\n\
|
||||
-mno-virt do not generate Virtualization instructions\n"));
|
||||
fprintf (stream, _("\
|
||||
-minsn32 only generate 32-bit microMIPS instructions\n\
|
||||
-mno-insn32 generate all microMIPS instructions\n"));
|
||||
fprintf (stream, _("\
|
||||
-mfix-loongson2f-jump work around Loongson2F JUMP instructions\n\
|
||||
-mfix-loongson2f-nop work around Loongson2F NOP errata\n\
|
||||
-mfix-vr4120 work around certain VR4120 errata\n\
|
||||
|
|
|
@ -412,6 +412,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
|
|||
[@b{-mdspr2}] [@b{-mno-dspr2}]
|
||||
[@b{-mmt}] [@b{-mno-mt}]
|
||||
[@b{-mmcu}] [@b{-mno-mcu}]
|
||||
[@b{-minsn32}] [@b{-mno-insn32}]
|
||||
[@b{-mfix7000}] [@b{-mno-fix7000}]
|
||||
[@b{-mfix-vr4120}] [@b{-mno-fix-vr4120}]
|
||||
[@b{-mfix-vr4130}] [@b{-mno-fix-vr4130}]
|
||||
|
@ -1341,6 +1342,16 @@ Generate code for the MCU Application Specific Extension.
|
|||
This tells the assembler to accept MCU instructions.
|
||||
@samp{-mno-mcu} turns off this option.
|
||||
|
||||
@item -minsn32
|
||||
@itemx -mno-insn32
|
||||
Only use 32-bit instruction encodings when generating code for the
|
||||
microMIPS processor. This option inhibits the use of any 16-bit
|
||||
instructions. This is equivalent to putting @code{.set insn32} at
|
||||
the start of the assembly file. @samp{-mno-insn32} turns off this
|
||||
option. This is equivalent to putting @code{.set noinsn32} at the
|
||||
start of the assembly file. By default @samp{-mno-insn32} is
|
||||
selected, allowing all instructions to be used.
|
||||
|
||||
@item --construct-floats
|
||||
@itemx --no-construct-floats
|
||||
The @samp{--no-construct-floats} option disables the construction of
|
||||
|
|
|
@ -27,6 +27,7 @@ Assembly Language Programming'' in the same work.
|
|||
* MIPS Symbol Sizes:: Directives to override the size of symbols
|
||||
* MIPS Small Data:: Controlling the use of small data accesses
|
||||
* MIPS ISA:: Directives to override the ISA level
|
||||
* MIPS assembly options:: Directives to control code generation
|
||||
* MIPS autoextend:: Directives for extending MIPS 16 bit instructions
|
||||
* MIPS insn:: Directive to mark data as an instruction
|
||||
* MIPS Option Stack:: Directives to save and restore options
|
||||
|
@ -186,6 +187,16 @@ Generate code for the Virtualization Application Specific Extension.
|
|||
This tells the assembler to accept Virtualization instructions.
|
||||
@samp{-mno-virt} turns off this option.
|
||||
|
||||
@item -minsn32
|
||||
@itemx -mno-insn32
|
||||
Only use 32-bit instruction encodings when generating code for the
|
||||
microMIPS processor. This option inhibits the use of any 16-bit
|
||||
instructions. This is equivalent to putting @code{.set insn32} at
|
||||
the start of the assembly file. @samp{-mno-insn32} turns off this
|
||||
option. This is equivalent to putting @code{.set noinsn32} at the
|
||||
start of the assembly file. By default @samp{-mno-insn32} is
|
||||
selected, allowing all instructions to be used.
|
||||
|
||||
@item -mfix7000
|
||||
@itemx -mno-fix7000
|
||||
Cause nops to be inserted if the read of the destination register
|
||||
|
@ -649,6 +660,20 @@ in which it will assemble instructions for the microMIPS processor. Use
|
|||
|
||||
Traditional MIPS assemblers do not support this directive.
|
||||
|
||||
@node MIPS assembly options
|
||||
@section Directives to control code generation
|
||||
|
||||
@cindex MIPS 32-bit microMIPS instruction generation override
|
||||
@kindex @code{.set insn32}
|
||||
@kindex @code{.set noinsn32}
|
||||
The directive @code{.set insn32} makes the assembler only use 32-bit
|
||||
instruction encodings when generating code for the microMIPS processor.
|
||||
This directive inhibits the use of any 16-bit instructions from that
|
||||
point on in the assembly. The @code{.set noinsn32} directive allows
|
||||
16-bit instructions to be accepted.
|
||||
|
||||
Traditional MIPS assemblers do not support this directive.
|
||||
|
||||
@node MIPS autoextend
|
||||
@section Directives for extending MIPS 16 bit instructions
|
||||
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
2013-06-25 Maciej W. Rozycki <macro@codesourcery.com>
|
||||
|
||||
* gas/mips/micromips-insn32.d: New test.
|
||||
* gas/mips/micromips-noinsn32.d: Likewise.
|
||||
* gas/mips/micromips.l: Rename to...
|
||||
* gas/mips/micromips-warn.l: ... this.
|
||||
* gas/mips/micromips.d: Update accordingly.
|
||||
* gas/mips/micromips-trap.d: Likewise.
|
||||
* gas/mips/micromips.l: New list test.
|
||||
* gas/mips/micromips.s: Add conditionals.
|
||||
* gas/mips/mips.exp: Run the new tests.
|
||||
|
||||
2013-06-24 Roland McGrath <mcgrathr@google.com>
|
||||
|
||||
* gas/arm/macro-vld1.s: Add a case with whitespace before '}'.
|
||||
|
|
7885
gas/testsuite/gas/mips/micromips-insn32.d
Normal file
7885
gas/testsuite/gas/mips/micromips-insn32.d
Normal file
File diff suppressed because it is too large
Load diff
7840
gas/testsuite/gas/mips/micromips-noinsn32.d
Normal file
7840
gas/testsuite/gas/mips/micromips-noinsn32.d
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
|||
#objdump: -dr --show-raw-insn
|
||||
#name: microMIPS for MIPS32r2 (w/traps)
|
||||
#as: -mips32r2 -32 -trap -mfp64 -EB
|
||||
#stderr: micromips.l
|
||||
#stderr: micromips-warn.l
|
||||
#source: micromips.s
|
||||
|
||||
.*: +file format .*mips.*
|
||||
|
|
27
gas/testsuite/gas/mips/micromips-warn.l
Normal file
27
gas/testsuite/gas/mips/micromips-warn.l
Normal file
|
@ -0,0 +1,27 @@
|
|||
.*: Assembler messages:
|
||||
.*:578: Warning: Divide by zero.
|
||||
.*:581: Warning: Divide by zero.
|
||||
.*:594: Warning: Divide by zero.
|
||||
.*:1559: Warning: Divide by zero.
|
||||
.*:1562: Warning: Divide by zero.
|
||||
.*:1575: Warning: Divide by zero.
|
||||
.*:2622: Warning: Branch bge is always true
|
||||
.*:2625: Warning: Branch bgeu is always true
|
||||
.*:2634: Warning: Branch bgeu is always true
|
||||
.*:2709: Warning: Branch ble is always true
|
||||
.*:2724: Warning: Branch bleu is always true
|
||||
.*:2730: Warning: Branch bleu is always true
|
||||
.*:2733: Warning: Branch bleu is always true
|
||||
.*:2832: Warning: Branch bgel is always true
|
||||
.*:2835: Warning: Branch bgeul is always true
|
||||
.*:2844: Warning: Branch bgeul is always true
|
||||
.*:2919: Warning: Branch blel is always true
|
||||
.*:2934: Warning: Branch bleul is always true
|
||||
.*:2940: Warning: Branch bleul is always true
|
||||
.*:2943: Warning: Branch bleul is always true
|
||||
.*:4759: Warning: Divide by zero.
|
||||
.*:4762: Warning: Divide by zero.
|
||||
.*:4775: Warning: Divide by zero.
|
||||
.*:5180: Warning: Divide by zero.
|
||||
.*:5190: Warning: Divide by zero.
|
||||
.*:5200: Warning: Divide by zero.
|
|
@ -1,7 +1,7 @@
|
|||
#objdump: -dr --show-raw-insn
|
||||
#name: microMIPS for MIPS32r2
|
||||
#as: -mips32r2 -32 -mfp64 -EB
|
||||
#stderr: micromips.l
|
||||
#stderr: micromips-warn.l
|
||||
#source: micromips.s
|
||||
|
||||
.*: +file format .*mips.*
|
||||
|
|
|
@ -1,27 +1,107 @@
|
|||
.*: Assembler messages:
|
||||
.*:560: Warning: Divide by zero.
|
||||
.*:563: Warning: Divide by zero.
|
||||
.*:576: Warning: Divide by zero.
|
||||
.*:1541: Warning: Divide by zero.
|
||||
.*:1544: Warning: Divide by zero.
|
||||
.*:1557: Warning: Divide by zero.
|
||||
.*:2604: Warning: Branch bge is always true
|
||||
.*:2607: Warning: Branch bgeu is always true
|
||||
.*:2616: Warning: Branch bgeu is always true
|
||||
.*:2691: Warning: Branch ble is always true
|
||||
.*:2706: Warning: Branch bleu is always true
|
||||
.*:2712: Warning: Branch bleu is always true
|
||||
.*:2715: Warning: Branch bleu is always true
|
||||
.*:2814: Warning: Branch bgel is always true
|
||||
.*:2817: Warning: Branch bgeul is always true
|
||||
.*:2826: Warning: Branch bgeul is always true
|
||||
.*:2901: Warning: Branch blel is always true
|
||||
.*:2916: Warning: Branch bleul is always true
|
||||
.*:2922: Warning: Branch bleul is always true
|
||||
.*:2925: Warning: Branch bleul is always true
|
||||
.*:4739: Warning: Divide by zero.
|
||||
.*:4742: Warning: Divide by zero.
|
||||
.*:4755: Warning: Divide by zero.
|
||||
.*:5160: Warning: Divide by zero.
|
||||
.*:5170: Warning: Divide by zero.
|
||||
.*:39: Error: Opcode not supported in the `insn32' mode `nop16'
|
||||
.*:98: Error: Opcode not supported in the `insn32' mode `move16 \$2,\$22'
|
||||
.*:99: Error: Opcode not supported in the `insn32' mode `move16 \$22,\$2'
|
||||
.*:106: Error: Opcode not supported in the `insn32' mode `b16 test'
|
||||
.*:111: Error: Opcode not supported in the `insn32' mode `b16 1f'
|
||||
.*:117: Error: Opcode not supported in the `insn32' mode `b16 1b'
|
||||
.*:277: Error: Opcode not supported in the `insn32' mode `and16 \$2,\$2,\$3'
|
||||
.*:315: Error: Opcode not supported in the `insn32' mode `andi16 \$7,65535'
|
||||
.*:387: Error: Opcode not supported in the `insn32' mode `beqz16 \$16,test2'
|
||||
.*:475: Error: Opcode not supported in the `insn32' mode `bnez16 \$16,test3'
|
||||
.*:578: Warning: Divide by zero.
|
||||
.*:581: Warning: Divide by zero.
|
||||
.*:594: Warning: Divide by zero.
|
||||
.*:1559: Warning: Divide by zero.
|
||||
.*:1562: Warning: Divide by zero.
|
||||
.*:1575: Warning: Divide by zero.
|
||||
.*:2622: Warning: Branch bge is always true
|
||||
.*:2625: Warning: Branch bgeu is always true
|
||||
.*:2634: Warning: Branch bgeu is always true
|
||||
.*:2709: Warning: Branch ble is always true
|
||||
.*:2724: Warning: Branch bleu is always true
|
||||
.*:2730: Warning: Branch bleu is always true
|
||||
.*:2733: Warning: Branch bleu is always true
|
||||
.*:2832: Warning: Branch bgel is always true
|
||||
.*:2835: Warning: Branch bgeul is always true
|
||||
.*:2844: Warning: Branch bgeul is always true
|
||||
.*:2919: Warning: Branch blel is always true
|
||||
.*:2934: Warning: Branch bleul is always true
|
||||
.*:2940: Warning: Branch bleul is always true
|
||||
.*:2943: Warning: Branch bleul is always true
|
||||
.*:3010: Error: Opcode not supported in the `insn32' mode `addiur1sp \$2,0'
|
||||
.*:3011: Error: Opcode not supported in the `insn32' mode `addiur1sp \$2,1<<2'
|
||||
.*:3012: Error: Opcode not supported in the `insn32' mode `addiur1sp \$2,2<<2'
|
||||
.*:3013: Error: Opcode not supported in the `insn32' mode `addiur1sp \$2,3<<2'
|
||||
.*:3014: Error: Opcode not supported in the `insn32' mode `addiur1sp \$2,4<<2'
|
||||
.*:3015: Error: Opcode not supported in the `insn32' mode `addiur1sp \$2,63<<2'
|
||||
.*:3016: Error: Opcode not supported in the `insn32' mode `addiur1sp \$3,63<<2'
|
||||
.*:3017: Error: Opcode not supported in the `insn32' mode `addiur1sp \$4,63<<2'
|
||||
.*:3018: Error: Opcode not supported in the `insn32' mode `addiur1sp \$5,63<<2'
|
||||
.*:3019: Error: Opcode not supported in the `insn32' mode `addiur1sp \$6,63<<2'
|
||||
.*:3020: Error: Opcode not supported in the `insn32' mode `addiur1sp \$7,63<<2'
|
||||
.*:3021: Error: Opcode not supported in the `insn32' mode `addiur1sp \$16,63<<2'
|
||||
.*:3022: Error: Opcode not supported in the `insn32' mode `addiur1sp \$17,63<<2'
|
||||
.*:3024: Error: Opcode not supported in the `insn32' mode `addiur2 \$2,\$2,-1'
|
||||
.*:3025: Error: Opcode not supported in the `insn32' mode `addiur2 \$2,\$3,-1'
|
||||
.*:3026: Error: Opcode not supported in the `insn32' mode `addiur2 \$2,\$4,-1'
|
||||
.*:3027: Error: Opcode not supported in the `insn32' mode `addiur2 \$2,\$5,-1'
|
||||
.*:3028: Error: Opcode not supported in the `insn32' mode `addiur2 \$2,\$6,-1'
|
||||
.*:3029: Error: Opcode not supported in the `insn32' mode `addiur2 \$2,\$7,-1'
|
||||
.*:3030: Error: Opcode not supported in the `insn32' mode `addiur2 \$2,\$16,-1'
|
||||
.*:3031: Error: Opcode not supported in the `insn32' mode `addiur2 \$2,\$17,-1'
|
||||
.*:3032: Error: Opcode not supported in the `insn32' mode `addiur2 \$3,\$17,-1'
|
||||
.*:3033: Error: Opcode not supported in the `insn32' mode `addiur2 \$4,\$17,-1'
|
||||
.*:3034: Error: Opcode not supported in the `insn32' mode `addiur2 \$5,\$17,-1'
|
||||
.*:3035: Error: Opcode not supported in the `insn32' mode `addiur2 \$6,\$17,-1'
|
||||
.*:3036: Error: Opcode not supported in the `insn32' mode `addiur2 \$7,\$17,-1'
|
||||
.*:3037: Error: Opcode not supported in the `insn32' mode `addiur2 \$16,\$17,-1'
|
||||
.*:3038: Error: Opcode not supported in the `insn32' mode `addiur2 \$17,\$17,-1'
|
||||
.*:3039: Error: Opcode not supported in the `insn32' mode `addiur2 \$17,\$17,1'
|
||||
.*:3040: Error: Opcode not supported in the `insn32' mode `addiur2 \$17,\$17,4'
|
||||
.*:3041: Error: Opcode not supported in the `insn32' mode `addiur2 \$17,\$17,8'
|
||||
.*:3042: Error: Opcode not supported in the `insn32' mode `addiur2 \$17,\$17,12'
|
||||
.*:3043: Error: Opcode not supported in the `insn32' mode `addiur2 \$17,\$17,16'
|
||||
.*:3044: Error: Opcode not supported in the `insn32' mode `addiur2 \$17,\$17,20'
|
||||
.*:3045: Error: Opcode not supported in the `insn32' mode `addiur2 \$17,\$17,24'
|
||||
.*:3047: Error: Opcode not supported in the `insn32' mode `addiusp 2<<2'
|
||||
.*:3048: Error: Opcode not supported in the `insn32' mode `addiusp 3<<2'
|
||||
.*:3049: Error: Opcode not supported in the `insn32' mode `addiusp 254<<2'
|
||||
.*:3050: Error: Opcode not supported in the `insn32' mode `addiusp 255<<2'
|
||||
.*:3051: Error: Opcode not supported in the `insn32' mode `addiusp 256<<2'
|
||||
.*:3052: Error: Opcode not supported in the `insn32' mode `addiusp 257<<2'
|
||||
.*:3053: Error: Opcode not supported in the `insn32' mode `addiusp -3<<2'
|
||||
.*:3054: Error: Opcode not supported in the `insn32' mode `addiusp -4<<2'
|
||||
.*:3055: Error: Opcode not supported in the `insn32' mode `addiusp -255<<2'
|
||||
.*:3056: Error: Opcode not supported in the `insn32' mode `addiusp -256<<2'
|
||||
.*:3057: Error: Opcode not supported in the `insn32' mode `addiusp -257<<2'
|
||||
.*:3058: Error: Opcode not supported in the `insn32' mode `addiusp -258<<2'
|
||||
.*:3060: Error: Opcode not supported in the `insn32' mode `addius5 \$0,0'
|
||||
.*:3061: Error: Opcode not supported in the `insn32' mode `addius5 \$2,0'
|
||||
.*:3062: Error: Opcode not supported in the `insn32' mode `addius5 \$3,0'
|
||||
.*:3063: Error: Opcode not supported in the `insn32' mode `addius5 \$30,0'
|
||||
.*:3064: Error: Opcode not supported in the `insn32' mode `addius5 \$31,0'
|
||||
.*:3065: Error: Opcode not supported in the `insn32' mode `addius5 \$31,1'
|
||||
.*:3066: Error: Opcode not supported in the `insn32' mode `addius5 \$31,2'
|
||||
.*:3067: Error: Opcode not supported in the `insn32' mode `addius5 \$31,3'
|
||||
.*:3068: Error: Opcode not supported in the `insn32' mode `addius5 \$31,7'
|
||||
.*:3069: Error: Opcode not supported in the `insn32' mode `addius5 \$31,-6'
|
||||
.*:3070: Error: Opcode not supported in the `insn32' mode `addius5 \$31,-7'
|
||||
.*:3071: Error: Opcode not supported in the `insn32' mode `addius5 \$31,-8'
|
||||
.*:4759: Warning: Divide by zero.
|
||||
.*:4762: Warning: Divide by zero.
|
||||
.*:4775: Warning: Divide by zero.
|
||||
.*:5180: Warning: Divide by zero.
|
||||
.*:5190: Warning: Divide by zero.
|
||||
.*:5200: Warning: Divide by zero.
|
||||
.*:5568: Error: Opcode not supported in the `insn32' mode `jalr16 \$2'
|
||||
.*:5572: Error: Opcode not supported in the `insn32' mode `jr16 \$2'
|
||||
.*:5579: Error: Opcode not supported in the `insn32' mode `jals test_delay_slot'
|
||||
.*:5580: Error: Opcode not supported in the `insn32' mode `jalrs16 \$2'
|
||||
.*:5581: Error: Opcode not supported in the `insn32' mode `jalrs32 \$2'
|
||||
.*:5582: Error: Opcode not supported in the `insn32' mode `jrs \$2'
|
||||
.*:5583: Error: Opcode not supported in the `insn32' mode `jalrs\.hb \$2'
|
||||
.*:5584: Error: Opcode not supported in the `insn32' mode `jrs\.hb \$2'
|
||||
.*:5665: Error: Opcode not supported in the `insn32' mode `bals test_spec107'
|
||||
.*:5667: Error: Opcode not supported in the `insn32' mode `bgezals \$2,test_spec107'
|
||||
.*:5669: Error: Opcode not supported in the `insn32' mode `bltzals \$2,test_spec107'
|
||||
|
|
|
@ -35,7 +35,9 @@ test:
|
|||
pref 3, -32768($2)
|
||||
|
||||
nop
|
||||
.ifndef insn32
|
||||
nop16
|
||||
.endif
|
||||
nop32
|
||||
ssnop
|
||||
ehb
|
||||
|
@ -92,20 +94,28 @@ test:
|
|||
move $0, $31
|
||||
|
||||
move $22, $2
|
||||
.ifndef insn32
|
||||
move16 $2, $22
|
||||
move16 $22, $2
|
||||
.endif
|
||||
move32 $2, $22
|
||||
move32 $22, $2
|
||||
|
||||
b test
|
||||
.ifndef insn32
|
||||
b16 test
|
||||
.endif
|
||||
b32 test
|
||||
b 1f
|
||||
.ifndef insn32
|
||||
b16 1f
|
||||
.endif
|
||||
b32 1f
|
||||
1:
|
||||
b 1b
|
||||
.ifndef insn32
|
||||
b16 1b
|
||||
.endif
|
||||
b32 1b
|
||||
|
||||
abs $2, $3
|
||||
|
@ -263,7 +273,9 @@ test:
|
|||
and $2, $3
|
||||
and $2, $2, $3
|
||||
and $2, $3, $2
|
||||
.ifndef insn32
|
||||
and16 $2, $2, $3
|
||||
.endif
|
||||
and32 $2, $2, $3
|
||||
|
||||
andi $2,$2,1
|
||||
|
@ -299,7 +311,9 @@ test:
|
|||
|
||||
andi $7,$7,65535
|
||||
andi $7,65535
|
||||
.ifndef insn32
|
||||
andi16 $7,65535
|
||||
.endif
|
||||
andi32 $7,65535
|
||||
|
||||
and32 $2, $3, $4
|
||||
|
@ -369,7 +383,9 @@ test2:
|
|||
beq $0, $16, test2
|
||||
beq $0, $17, test2
|
||||
|
||||
.ifndef insn32
|
||||
beqz16 $16, test2
|
||||
.endif
|
||||
beqz32 $16, test2
|
||||
beqz $17, test2
|
||||
beqz32 $17, test2
|
||||
|
@ -455,7 +471,9 @@ test2:
|
|||
bne $0, $16, test3
|
||||
bne $0, $17, test3
|
||||
|
||||
.ifndef insn32
|
||||
bnez16 $16, test3
|
||||
.endif
|
||||
bnez32 $16, test3
|
||||
bnez $17, test2
|
||||
bnez32 $17, test2
|
||||
|
@ -2988,6 +3006,7 @@ test3:
|
|||
bnel $9, 1, test
|
||||
addu $3, $4, $5
|
||||
|
||||
.ifndef insn32
|
||||
addiur1sp $2, 0
|
||||
addiur1sp $2, 1<<2
|
||||
addiur1sp $2, 2<<2
|
||||
|
@ -3050,6 +3069,7 @@ test3:
|
|||
addius5 $31, -6
|
||||
addius5 $31, -7
|
||||
addius5 $31, -8
|
||||
.endif
|
||||
|
||||
sd $3, 4
|
||||
sd $3, 4($0)
|
||||
|
@ -5544,19 +5564,25 @@ test_delay_slot:
|
|||
bltzall $3, test_delay_slot
|
||||
jal test_delay_slot
|
||||
jalx test_delay_slot
|
||||
.ifndef insn32
|
||||
jalr16 $2
|
||||
.endif
|
||||
jalr32 $2
|
||||
.ifndef insn32
|
||||
jr16 $2
|
||||
.endif
|
||||
jr32 $2
|
||||
jalr.hb $2
|
||||
jr.hb $2
|
||||
|
||||
.ifndef insn32
|
||||
jals test_delay_slot
|
||||
jalrs16 $2
|
||||
jalrs32 $2
|
||||
jrs $2
|
||||
jalrs.hb $2
|
||||
jrs.hb $2
|
||||
.endif
|
||||
|
||||
.end test_delay_slot
|
||||
|
||||
|
@ -5635,12 +5661,14 @@ test_spec107:
|
|||
movep $4, $7, $20, $18
|
||||
movep $4, $7, $20, $19
|
||||
movep $4, $7, $20, $20
|
||||
.ifndef insn32
|
||||
bals test_spec107
|
||||
nop
|
||||
bgezals $2, test_spec107
|
||||
nop
|
||||
bltzals $2, test_spec107
|
||||
nop
|
||||
.endif
|
||||
bal test_spec107
|
||||
nop
|
||||
bgezal $2, test_spec107
|
||||
|
|
|
@ -1074,6 +1074,10 @@ if { [istarget mips*-*-vxworks*] } {
|
|||
|
||||
run_dump_test "micromips"
|
||||
run_dump_test "micromips-trap"
|
||||
run_dump_test "micromips-insn32"
|
||||
run_dump_test "micromips-noinsn32"
|
||||
run_list_test "micromips" "-mips32r2 -32 -mfp64 -minsn32" \
|
||||
"microMIPS for MIPS32r2 (instructions invalid in insn32 mode)"
|
||||
run_list_test "micromips-size-0" \
|
||||
"-32 -march=mips64 -mmicromips" "microMIPS instruction size 0"
|
||||
run_dump_test "micromips-size-1"
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
14
ld/ChangeLog
14
ld/ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2013-06-25 Maciej W. Rozycki <macro@codesourcery.com>
|
||||
|
||||
* emultempl/mipself.em (insn32): New variable.
|
||||
(mips_create_output_section_statements): Handle insn32 mode.
|
||||
(PARSE_AND_LIST_PROLOGUE): New macro.
|
||||
(PARSE_AND_LIST_LONGOPTS): Likewise.
|
||||
(PARSE_AND_LIST_OPTIONS): Likewise.
|
||||
|
||||
* gen-doc.texi: Set MIPS.
|
||||
* ld.texinfo: Likewise.
|
||||
(Options specific to MIPS targets): New section.
|
||||
(ld and MIPS family): New node.
|
||||
(Top, Machine Dependent): List the new node.
|
||||
|
||||
2013-06-24 Maciej W. Rozycki <macro@codesourcery.com>
|
||||
|
||||
* emulparams/elf32btsmip.sh: Arrange for .got.plt to be placed
|
||||
|
|
|
@ -33,6 +33,8 @@ fragment <<EOF
|
|||
static lang_input_statement_type *stub_file;
|
||||
static bfd *stub_bfd;
|
||||
|
||||
static bfd_boolean insn32;
|
||||
|
||||
static void
|
||||
mips_after_parse (void)
|
||||
{
|
||||
|
@ -199,6 +201,12 @@ mips_add_stub_section (const char *stub_sec_name, asection *input_section,
|
|||
static void
|
||||
mips_create_output_section_statements (void)
|
||||
{
|
||||
struct elf_link_hash_table *htab;
|
||||
|
||||
htab = elf_hash_table (&link_info);
|
||||
if (is_elf_hash_table (htab) && is_mips_elf (link_info.output_bfd))
|
||||
_bfd_mips_elf_insn32 (&link_info, insn32);
|
||||
|
||||
if (is_mips_elf (link_info.output_bfd))
|
||||
_bfd_mips_elf_init_stubs (&link_info, mips_add_stub_section);
|
||||
}
|
||||
|
@ -241,6 +249,38 @@ mips_lang_for_each_input_file (void (*func) (lang_input_statement_type *))
|
|||
|
||||
EOF
|
||||
|
||||
# Define some shell vars to insert bits of code into the standard elf
|
||||
# parse_args and list_options functions.
|
||||
#
|
||||
PARSE_AND_LIST_PROLOGUE='
|
||||
#define OPTION_INSN32 301
|
||||
#define OPTION_NO_INSN32 (OPTION_INSN32 + 1)
|
||||
'
|
||||
|
||||
PARSE_AND_LIST_LONGOPTS='
|
||||
{ "insn32", no_argument, NULL, OPTION_INSN32 },
|
||||
{ "no-insn32", no_argument, NULL, OPTION_NO_INSN32 },
|
||||
'
|
||||
|
||||
PARSE_AND_LIST_OPTIONS='
|
||||
fprintf (file, _("\
|
||||
--insn32 Only generate 32-bit microMIPS instructions\n"
|
||||
));
|
||||
fprintf (file, _("\
|
||||
--no-insn32 Generate all microMIPS instructions\n"
|
||||
));
|
||||
'
|
||||
|
||||
PARSE_AND_LIST_ARGS_CASES='
|
||||
case OPTION_INSN32:
|
||||
insn32 = TRUE;
|
||||
break;
|
||||
|
||||
case OPTION_NO_INSN32:
|
||||
insn32 = FALSE;
|
||||
break;
|
||||
'
|
||||
|
||||
LDEMUL_AFTER_PARSE=mips_after_parse
|
||||
LDEMUL_BEFORE_ALLOCATION=mips_before_allocation
|
||||
LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=mips_create_output_section_statements
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
@set I960
|
||||
@set M68HC11
|
||||
@set M68K
|
||||
@set MIPS
|
||||
@set MMIX
|
||||
@set MSP430
|
||||
@set POWERPC
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
@set I960
|
||||
@set M68HC11
|
||||
@set M68K
|
||||
@set MIPS
|
||||
@set MMIX
|
||||
@set MSP430
|
||||
@set POWERPC
|
||||
|
@ -146,6 +147,9 @@ in the section entitled ``GNU Free Documentation License''.
|
|||
@ifset M68K
|
||||
* M68K:: ld and Motorola 68K family
|
||||
@end ifset
|
||||
@ifset MIPS
|
||||
* MIPS:: ld and MIPS family
|
||||
@end ifset
|
||||
@ifset POWERPC
|
||||
* PowerPC ELF32:: ld and PowerPC 32-bit ELF Support
|
||||
@end ifset
|
||||
|
@ -2732,6 +2736,32 @@ Info entry for @file{ld}.
|
|||
@c man end
|
||||
@end ifset
|
||||
|
||||
@ifset MIPS
|
||||
@subsection Options specific to MIPS targets
|
||||
|
||||
@c man begin OPTIONS
|
||||
|
||||
The following options are supported to control microMIPS instruction
|
||||
generation when linking for MIPS targets.
|
||||
|
||||
@table @gcctabopt
|
||||
|
||||
@kindex --insn32
|
||||
@item --insn32
|
||||
@kindex --no-insn32
|
||||
@itemx --no-insn32
|
||||
These options control the choice of microMIPS instructions used in code
|
||||
generated by the linker, such as that in the PLT or lazy binding stubs,
|
||||
or in relaxation. If @samp{--insn32} is used, then the linker only uses
|
||||
32-bit instruction encodings. By default or if @samp{--no-insn32} is
|
||||
used, all instruction encodings are used, including 16-bit ones where
|
||||
possible.
|
||||
|
||||
@end table
|
||||
|
||||
@c man end
|
||||
@end ifset
|
||||
|
||||
@ifset UsesEnvVars
|
||||
@node Environment
|
||||
@section Environment Variables
|
||||
|
@ -6033,6 +6063,9 @@ functionality are not listed.
|
|||
@ifset M68K
|
||||
* M68K:: @command{ld} and the Motorola 68K family
|
||||
@end ifset
|
||||
@ifset MIPS
|
||||
* MIPS:: @command{ld} and the MIPS family
|
||||
@end ifset
|
||||
@ifset MMIX
|
||||
* MMIX:: @command{ld} and MMIX
|
||||
@end ifset
|
||||
|
@ -6531,6 +6564,29 @@ files might access different GOTs. Not all environments support such GOTs.
|
|||
@end ifclear
|
||||
@end ifset
|
||||
|
||||
@ifset MIPS
|
||||
@ifclear GENERIC
|
||||
@raisesections
|
||||
@end ifclear
|
||||
|
||||
@node MIPS
|
||||
@section @command{ld} and the MIPS family
|
||||
|
||||
@cindex MIPS microMIPS instruction choice selection
|
||||
@kindex --insn32
|
||||
@kindex --no-insn32
|
||||
The @samp{--insn32} and @samp{--no-insn32} options control the choice of
|
||||
microMIPS instructions used in code generated by the linker, such as that
|
||||
in the PLT or lazy binding stubs, or in relaxation. If @samp{--insn32} is
|
||||
used, then the linker only uses 32-bit instruction encodings. By default
|
||||
or if @samp{--no-insn32} is used, all instruction encodings are used,
|
||||
including 16-bit ones where possible.
|
||||
|
||||
@ifclear GENERIC
|
||||
@lowersections
|
||||
@end ifclear
|
||||
@end ifset
|
||||
|
||||
@ifset MMIX
|
||||
@ifclear GENERIC
|
||||
@raisesections
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 },
|
||||
|
|
Loading…
Add table
Reference in a new issue