Use 64-bit operations consistently for jump table address calculations across the assembly produced by the `casesi_internal_mips16_<mode>' insn where Pmode and consequently <mode> is DImode. Currently we have a mixture of 64-bit and 32-bit operations, which causes address truncation or undefined behaviour, depending on how the resulting binary is mapped.
gcc/ config/mips/mips.md (casesi_internal_mips16_<mode>): Add missing <d> instruction prefixes throughout. Correct formatting. gcc/testsuite/ * gcc.target/mips/code-readable-4.c (dg-final): Expect `dla' rather than `la'. --- OK to apply? Maciej gcc-mips16-casesi-di.diff Index: gcc/gcc/config/mips/mips.md =================================================================== --- gcc.orig/gcc/config/mips/mips.md 2016-11-12 10:51:56.000000000 +0000 +++ gcc/gcc/config/mips/mips.md 2016-11-14 02:05:52.853669422 +0000 @@ -6424,14 +6424,14 @@ { case HImode: output_asm_insn ("sll\t%5, %0, 1", operands); - output_asm_insn ("la\t%4, %2", operands); + output_asm_insn ("<d>la\t%4, %2", operands); output_asm_insn ("<d>addu\t%5, %4, %5", operands); output_asm_insn ("lh\t%5, 0(%5)", operands); break; case SImode: output_asm_insn ("sll\t%5, %0, 2", operands); - output_asm_insn ("la\t%4, %2", operands); + output_asm_insn ("<d>la\t%4, %2", operands); output_asm_insn ("<d>addu\t%5, %4, %5", operands); output_asm_insn ("lw\t%5, 0(%5)", operands); break; @@ -6439,9 +6439,9 @@ default: gcc_unreachable (); } - - output_asm_insn ("addu\t%4, %4, %5", operands); - + + output_asm_insn ("<d>addu\t%4, %4, %5", operands); + return "j\t%4"; } [(set_attr "insn_count" "16")]) Index: gcc/gcc/testsuite/gcc.target/mips/code-readable-4.c =================================================================== --- gcc.orig/gcc/testsuite/gcc.target/mips/code-readable-4.c 2015-05-17 22:30:27.000000000 +0100 +++ gcc/gcc/testsuite/gcc.target/mips/code-readable-4.c 2016-11-14 02:11:31.384173468 +0000 @@ -41,7 +41,7 @@ bar (void) return k; } -/* { dg-final { scan-assembler "\tla\t" } } */ +/* { dg-final { scan-assembler "\tdla\t" } } */ /* { dg-final { scan-assembler "\t\\.half\t" } } */ /* { dg-final { scan-assembler-not "%hi\\(\[^)\]*L" } } */ /* { dg-final { scan-assembler-not "%lo\\(\[^)\]*L" } } */