+2012-11-01 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * config/tc-mips.c (is_delay_slot_valid): Don't accept macros
+ in 16-bit delay slots.
+ (macro_build_jalr): Emit 32-bit JALR if placed in a 32-bit delay
+ slot.
+ (macro) <M_JAL_2>: Likewise
+
2012-10-31 David Holsgrove <david.holsgrove@xilinx.com>
* config/tc-microblaze.c: Check for weak symbols before
}
/* Return TRUE if the microMIPS opcode MO is valid for the delay slot
- of the preceding instruction. Always TRUE in the standard MIPS mode. */
+ of the preceding instruction. Always TRUE in the standard MIPS mode.
+
+ We don't accept macros in 16-bit delay slots to avoid a case where
+ a macro expansion fails because it relies on a preceding 32-bit real
+ instruction to have matched and does not handle the operands correctly.
+ The only macros that may expand to 16-bit instructions are JAL that
+ cannot be placed in a delay slot anyway, and corner cases of BALIGN
+ and BGT (that likewise cannot be placed in a delay slot) that decay to
+ a NOP. In all these cases the macros precede any corresponding real
+ instruction definitions in the opcode table, so they will match in the
+ second pass where the size of the delay slot is ignored and therefore
+ produce correct code. */
static bfd_boolean
is_delay_slot_valid (const struct mips_opcode *mo)
return TRUE;
if (mo->pinfo == INSN_MACRO)
- return TRUE;
+ return ((history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_16BIT) == 0
+ ? TRUE : FALSE);
if ((history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT) != 0
&& micromips_insn_length (mo) != 4)
return FALSE;
if (mips_opts.micromips)
{
jalr = mips_opts.noreorder && !cprestore ? "jalr" : "jalrs";
- if (MIPS_JALR_HINT_P (ep))
+ if (MIPS_JALR_HINT_P (ep)
+ || (history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
macro_build (NULL, jalr, "t,s", RA, PIC_CALL_REG);
else
macro_build (NULL, jalr, "mj", PIC_CALL_REG);
if (mips_pic == NO_PIC)
{
s = jals ? "jalrs" : "jalr";
- if (mips_opts.micromips && dreg == RA)
+ if (mips_opts.micromips
+ && dreg == RA
+ && !(history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
macro_build (NULL, s, "mj", sreg);
else
macro_build (NULL, s, JALR_FMT, dreg, sreg);
s = (mips_opts.micromips && (!mips_opts.noreorder || cprestore)
? "jalrs" : "jalr");
- if (mips_opts.micromips && dreg == RA)
+ if (mips_opts.micromips
+ && dreg == RA
+ && !(history[0].insn_mo->pinfo2 & INSN2_BRANCH_DELAY_32BIT))
macro_build (NULL, s, "mj", sreg);
else
macro_build (NULL, s, JALR_FMT, dreg, sreg);
+2012-11-01 Chao-ying Fu <fu@mips.com>
+ Maciej W. Rozycki <macro@codesourcery.com>
+
+ * gas/mips/micromips-branch-delay.l: Update messages for 16-bit
+ delay slot changes.
+ * gas/mips/micromips-warn-branch-delay.d: New test.
+ * gas/mips/micromips-warn-branch-delay.l: Stderr output for the
+ new test.
+ * gas/mips/micromips-warn-branch-delay-1.d: New test.
+ * gas/mips/micromips-warn-branch-delay.s: New test source.
+ * gas/mips/micromips-warn-branch-delay-1.s: New test source.
+ * gas/mips/mips.exp: Run the new tests.
+
2012-10-31 David Holsgrove <david.holsgrove@xilinx.com>
* gas/microblaze: New.
.*: Assembler messages:
-.*:17: Warning: Macro instruction expanded into a wrong size instruction in a 16-bit branch delay slot
-.*:19: Warning: Macro instruction expanded into a wrong size instruction in a 16-bit branch delay slot
+.*:17: Warning: Wrong size instruction in a 16-bit branch delay slot
+.*:19: Warning: Wrong size instruction in a 16-bit branch delay slot
.*:21: Warning: Macro instruction expanded into a wrong size instruction in a 16-bit branch delay slot
.*:40: Warning: Wrong size instruction in a 16-bit branch delay slot
.*:44: Warning: Wrong size instruction in a 16-bit branch delay slot
--- /dev/null
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: microMIPS fixed-size branch delay slots 1
+#as: -32 -mmicromips
+#source: micromips-warn-branch-delay-1.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+([0-9a-f]+) <[^>]*> 4220 fffe bltzals zero,\1 <.*>
+[ ]*[0-9a-f]+: R_MICROMIPS_PC16_S1 .*
+[0-9a-f]+ <[^>]*> 0c00 nop
+[0-9a-f]+ <[^>]*> 0c00 nop
+([0-9a-f]+) <[^>]*> 4220 fffe bltzals zero,\1 <.*>
+[ ]*[0-9a-f]+: R_MICROMIPS_PC16_S1 .*
+[0-9a-f]+ <[^>]*> 0c00 nop
+[0-9a-f]+ <[^>]*> 0c00 nop
+([0-9a-f]+) <[^>]*> 4220 fffe bltzals zero,\1 <.*>
+[ ]*[0-9a-f]+: R_MICROMIPS_PC16_S1 .*
+[0-9a-f]+ <[^>]*> 45e2 jalrs v0
+[0-9a-f]+ <[^>]*> 0c00 nop
+([0-9a-f]+) <[^>]*> 4220 fffe bltzals zero,\1 <.*>
+[ ]*[0-9a-f]+: R_MICROMIPS_PC16_S1 .*
+[0-9a-f]+ <[^>]*> 0c00 nop
+[0-9a-f]+ <[^>]*> 0c00 nop
+([0-9a-f]+) <[^>]*> 4020 fffe bltzal zero,\1 <.*>
+[ ]*[0-9a-f]+: R_MICROMIPS_PC16_S1 .*
+[0-9a-f]+ <[^>]*> 0000 0000 nop
+[0-9a-f]+ <[^>]*> 0c00 nop
+([0-9a-f]+) <[^>]*> 4020 fffe bltzal zero,\1 <.*>
+[ ]*[0-9a-f]+: R_MICROMIPS_PC16_S1 .*
+[0-9a-f]+ <[^>]*> 0000 0000 nop
+[0-9a-f]+ <[^>]*> 0c00 nop
+([0-9a-f]+) <[^>]*> 4020 fffe bltzal zero,\1 <.*>
+[ ]*[0-9a-f]+: R_MICROMIPS_PC16_S1 .*
+[0-9a-f]+ <[^>]*> 03e2 4f3c jalrs v0
+[0-9a-f]+ <[^>]*> 0c00 nop
+([0-9a-f]+) <[^>]*> 4020 fffe bltzal zero,\1 <.*>
+[ ]*[0-9a-f]+: R_MICROMIPS_PC16_S1 .*
+[0-9a-f]+ <[^>]*> 0000 0000 nop
+[0-9a-f]+ <[^>]*> 0c00 nop
+ \.\.\.
--- /dev/null
+# Source code used to test correct macro expansion in microMIPS fixed-size
+# branch delay slots.
+
+ .text
+ .set dspr2
+ .set noreorder
+ .set noat
+test:
+ bltzals $0, .
+ nop
+ nop
+
+ bltzals $0, .
+ bgt $2, 0x7fffffff, .
+ nop
+
+ bltzals $0, .
+ jals $2
+ nop
+
+ bltzals $0, .
+ balign $2, $2, 0
+ nop
+
+ bltzal $0, .
+ nop
+ nop
+
+ bltzal $0, .
+ bgt $2, 0x7fffffff, .
+ nop
+
+ bltzal $0, .
+ jals $2
+ nop
+
+ bltzal $0, .
+ balign $2, $2, 0
+ nop
+
+# Force some (non-delay-slot) zero bytes, to make 'objdump' print ...
+ .align 4, 0
+ .space 16
--- /dev/null
+#objdump: -dr --show-raw-insn
+#name: microMIPS fixed-size branch delay slots
+#as: -mmicromips
+#source: micromips-warn-branch-delay.s
+#stderr: micromips-warn-branch-delay.l
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+
+[0-9a-f]+ <foo>:
+[ 0-9a-f]+: 45e2 jalrs v0
+[ 0-9a-f]+: 0083 1250 and v0,v1,a0
+[ 0-9a-f]+: 45e2 jalrs v0
+[ 0-9a-f]+: 6043 9000 swr v0,0\(v1\)
+[ 0-9a-f]+: 45e2 jalrs v0
+[ 0-9a-f]+: 6043 8000 swl v0,0\(v1\)
+[ 0-9a-f]+: 45e2 jalrs v0
+[ 0-9a-f]+: 0272 8210 mul s0,s2,s3
+[ 0-9a-f]+: 45e2 jalrs v0
+[ 0-9a-f]+: 001f 8b90 sltu s1,ra,zero
+[ 0-9a-f]+: 45e2 jalrs v0
+[ 0-9a-f]+: 0220 8910 add s1,zero,s1
+[ 0-9a-f]+: 45e2 jalrs v0
+[ 0-9a-f]+: 01b1 8990 sub s1,s1,t5
+#pass
--- /dev/null
+.*: Assembler messages:
+.*:8: Warning: Wrong size instruction in a 16-bit branch delay slot
+.*:10: Warning: Wrong size instruction in a 16-bit branch delay slot
+.*:12: Warning: Wrong size instruction in a 16-bit branch delay slot
+.*:14: Warning: Wrong size instruction in a 16-bit branch delay slot
+.*:16: Warning: Wrong size instruction in a 16-bit branch delay slot
+.*:18: Warning: Wrong size instruction in a 16-bit branch delay slot
+.*:20: Warning: Wrong size instruction in a 16-bit branch delay slot
--- /dev/null
+# Source file used to test microMIPS fixed-size branch delay slots.
+
+ .text
+ .set noreorder
+ .set noat
+foo:
+ jalrs $2
+ and $2,$3,$4
+ jalrs $2
+ swr $2,0($3)
+ jalrs $2
+ swl $2,0($3)
+ jalrs $2
+ mul $16,$18,$19
+ jalrs $2
+ sltu $17,$31,$0
+ jalrs $2
+ add $17,$0,$17
+ jalrs $2
+ sub $17,$17,$13
run_dump_test "micromips-branch-relax"
run_dump_test "micromips-branch-relax-pic"
run_dump_test "micromips-branch-delay"
+ run_dump_test "micromips-warn-branch-delay"
+ run_dump_test "micromips-warn-branch-delay-1"
}
run_dump_test_arches "mcu" [mips_arch_list_matching mips32r2 \