From e64af278469a4101a3fa515bda4d2d977051b8d4 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 1 Nov 2012 22:49:28 +0000 Subject: [PATCH] gas/ * 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) : Likewise gas/testsuite/ * 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. --- gas/ChangeLog | 8 ++++ gas/config/tc-mips.c | 27 +++++++++++--- gas/testsuite/ChangeLog | 13 +++++++ gas/testsuite/gas/mips/micromips-branch-delay.l | 4 +- .../gas/mips/micromips-warn-branch-delay-1.d | 41 +++++++++++++++++++++ .../gas/mips/micromips-warn-branch-delay-1.s | 43 ++++++++++++++++++++++ .../gas/mips/micromips-warn-branch-delay.d | 26 +++++++++++++ .../gas/mips/micromips-warn-branch-delay.l | 8 ++++ .../gas/mips/micromips-warn-branch-delay.s | 20 ++++++++++ gas/testsuite/gas/mips/mips.exp | 2 + 10 files changed, 185 insertions(+), 7 deletions(-) create mode 100644 gas/testsuite/gas/mips/micromips-warn-branch-delay-1.d create mode 100644 gas/testsuite/gas/mips/micromips-warn-branch-delay-1.s create mode 100644 gas/testsuite/gas/mips/micromips-warn-branch-delay.d create mode 100644 gas/testsuite/gas/mips/micromips-warn-branch-delay.l create mode 100644 gas/testsuite/gas/mips/micromips-warn-branch-delay.s diff --git a/gas/ChangeLog b/gas/ChangeLog index ca46fe7..65fbfab 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2012-11-01 Maciej W. Rozycki + + * 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) : Likewise + 2012-10-31 David Holsgrove * config/tc-microblaze.c: Check for weak symbols before diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index e866010..dcea7bc 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -2301,7 +2301,18 @@ is_size_valid (const struct mips_opcode *mo) } /* 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) @@ -2310,7 +2321,8 @@ 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; @@ -5328,7 +5340,8 @@ macro_build_jalr (expressionS *ep, int cprestore) 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); @@ -7768,7 +7781,9 @@ macro (struct mips_cl_insn *ip) 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); @@ -7783,7 +7798,9 @@ macro (struct mips_cl_insn *ip) 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); diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 9bfb4b3..4ea1ff1 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2012-11-01 Chao-ying Fu + Maciej W. Rozycki + + * 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 * gas/microblaze: New. diff --git a/gas/testsuite/gas/mips/micromips-branch-delay.l b/gas/testsuite/gas/mips/micromips-branch-delay.l index 5ec081f..a70eb41 100644 --- a/gas/testsuite/gas/mips/micromips-branch-delay.l +++ b/gas/testsuite/gas/mips/micromips-branch-delay.l @@ -1,6 +1,6 @@ .*: 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 diff --git a/gas/testsuite/gas/mips/micromips-warn-branch-delay-1.d b/gas/testsuite/gas/mips/micromips-warn-branch-delay-1.d new file mode 100644 index 0000000..b2d820e --- /dev/null +++ b/gas/testsuite/gas/mips/micromips-warn-branch-delay-1.d @@ -0,0 +1,41 @@ +#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 + \.\.\. diff --git a/gas/testsuite/gas/mips/micromips-warn-branch-delay-1.s b/gas/testsuite/gas/mips/micromips-warn-branch-delay-1.s new file mode 100644 index 0000000..f352de5 --- /dev/null +++ b/gas/testsuite/gas/mips/micromips-warn-branch-delay-1.s @@ -0,0 +1,43 @@ +# 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 diff --git a/gas/testsuite/gas/mips/micromips-warn-branch-delay.d b/gas/testsuite/gas/mips/micromips-warn-branch-delay.d new file mode 100644 index 0000000..fde0af5 --- /dev/null +++ b/gas/testsuite/gas/mips/micromips-warn-branch-delay.d @@ -0,0 +1,26 @@ +#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]+ : +[ 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 diff --git a/gas/testsuite/gas/mips/micromips-warn-branch-delay.l b/gas/testsuite/gas/mips/micromips-warn-branch-delay.l new file mode 100644 index 0000000..12a0e9b --- /dev/null +++ b/gas/testsuite/gas/mips/micromips-warn-branch-delay.l @@ -0,0 +1,8 @@ +.*: 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 diff --git a/gas/testsuite/gas/mips/micromips-warn-branch-delay.s b/gas/testsuite/gas/mips/micromips-warn-branch-delay.s new file mode 100644 index 0000000..e8f8b96 --- /dev/null +++ b/gas/testsuite/gas/mips/micromips-warn-branch-delay.s @@ -0,0 +1,20 @@ +# 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 diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp index b1e38b5..ac1d24b 100644 --- a/gas/testsuite/gas/mips/mips.exp +++ b/gas/testsuite/gas/mips/mips.exp @@ -1113,6 +1113,8 @@ if { [istarget mips*-*-vxworks*] } { 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 \ -- 2.7.4