aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@imgtec.com>2017-06-14 23:26:40 +0000
committerMaciej W. Rozycki <macro@gcc.gnu.org>2017-06-14 23:26:40 +0000
commit3466430f382b6adc2363721056b9abde3acd790a (patch)
treee6cdacfffb0e4b8b67ce1c67ba25a40f0e722b26
parentcdd17d6e9956853892e4c097cc33afc2156df69e (diff)
downloadgcc-3466430f382b6adc2363721056b9abde3acd790a.zip
gcc-3466430f382b6adc2363721056b9abde3acd790a.tar.gz
gcc-3466430f382b6adc2363721056b9abde3acd790a.tar.bz2
MIPS16/GCC: Emit bounds checking as RTL in `casesi'
gcc/ * config/mips/mips.md (MIPS16_T_REGNUM): Remove constant. (casesi): Emit bounds checking as RTL. (casesi_internal_mips16_<mode>): Remove bounds checking. gcc/testsuite/ * gcc.target/mips/data-sym-jump.c: Adjust for whitespace changes. * gcc.target/mips/pr51513-1.c: New test. * gcc.target/mips/pr51513-2.c: New test. From-SVN: r249207
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/mips/mips.md58
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/mips/data-sym-jump.c4
-rw-r--r--gcc/testsuite/gcc.target/mips/pr51513-1.c48
-rw-r--r--gcc/testsuite/gcc.target/mips/pr51513-2.c56
6 files changed, 141 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 09435d0..2d5110c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2017-06-14 Maciej W. Rozycki <macro@imgtec.com>
+
+ * config/mips/mips.md (MIPS16_T_REGNUM): Remove constant.
+ (casesi): Emit bounds checking as RTL.
+ (casesi_internal_mips16_<mode>): Remove bounds checking.
+
2017-06-14 Max Filippov <jcmvbkbc@gmail.com>
* config/xtensa/xtensa.c (xtensa_option_override): Append
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 28e0a44..971af6f 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -162,7 +162,6 @@
[(TLS_GET_TP_REGNUM 3)
(GET_FCSR_REGNUM 2)
(SET_FCSR_REGNUM 4)
- (MIPS16_T_REGNUM 24)
(PIC_FUNCTION_ADDR_REGNUM 25)
(RETURN_ADDR_REGNUM 31)
(CPRESTORE_SLOT_REGNUM 76)
@@ -6389,68 +6388,57 @@
if (!arith_operand (operands[0], SImode))
operands[0] = force_reg (SImode, operands[0]);
- operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
-
+ emit_cmp_and_jump_insns (operands[0], operands[2], GTU,
+ NULL_RTX, SImode, 1, operands[4]);
emit_jump_insn (PMODE_INSN (gen_casesi_internal_mips16,
- (operands[0], operands[2],
- operands[3], operands[4])));
-
+ (operands[0], operands[3])));
DONE;
})
(define_insn "casesi_internal_mips16_<mode>"
[(set (pc)
- (if_then_else
- (ltu (match_operand:SI 0 "register_operand" "d")
- (match_operand:SI 1 "arith_operand" "dI"))
- (unspec:P
- [(match_dup 0)
- (label_ref (match_operand 2 "" ""))]
- UNSPEC_CASESI_DISPATCH)
- (label_ref (match_operand 3 "" ""))))
- (clobber (match_scratch:P 4 "=d"))
- (clobber (match_scratch:P 5 "=d"))
- (clobber (reg:SI MIPS16_T_REGNUM))]
+ (unspec:P [(match_operand:SI 0 "register_operand" "d")
+ (label_ref (match_operand 1 "" ""))]
+ UNSPEC_CASESI_DISPATCH))
+ (clobber (match_scratch:P 2 "=d"))
+ (clobber (match_scratch:P 3 "=d"))]
"TARGET_MIPS16_SHORT_JUMP_TABLES"
{
- rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2])));
+ rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[1])));
gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
-
- output_asm_insn ("sltu\t%0, %1", operands);
- output_asm_insn ("bteqz\t%3", operands);
-
+
switch (GET_MODE (diff_vec))
{
case HImode:
- output_asm_insn ("sll\t%5, %0, 1", 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);
+ output_asm_insn ("sll\t%3,%0,1", operands);
+ output_asm_insn ("<d>la\t%2,%1", operands);
+ output_asm_insn ("<d>addu\t%3,%2,%3", operands);
+ output_asm_insn ("lh\t%3,0(%3)", operands);
break;
case SImode:
- output_asm_insn ("sll\t%5, %0, 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);
+ output_asm_insn ("sll\t%3,%0,2", operands);
+ output_asm_insn ("<d>la\t%2,%1", operands);
+ output_asm_insn ("<d>addu\t%3,%2,%3", operands);
+ output_asm_insn ("lw\t%3,0(%3)", operands);
break;
default:
gcc_unreachable ();
}
- output_asm_insn ("<d>addu\t%4, %4, %5", operands);
+ output_asm_insn ("<d>addu\t%2,%2,%3", operands);
if (GENERATE_MIPS16E)
- return "jrc\t%4";
+ return "jrc\t%2";
else
- return "jr\t%4";
+ return "jr\t%2";
}
[(set (attr "insn_count")
(if_then_else (match_test "GENERATE_MIPS16E")
- (const_string "10")
- (const_string "11")))])
+ (const_string "6")
+ (const_string "7")))])
;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well.
;; While it is possible to either pull it off the stack (in the
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a0c522e..dc82af0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2017-06-14 Maciej W. Rozycki <macro@imgtec.com>
+
+ * gcc.target/mips/data-sym-jump.c: Adjust for whitespace changes.
+ * gcc.target/mips/pr51513-1.c: New test.
+ * gcc.target/mips/pr51513-2.c: New test.
+
2017-06-14 Richard Biener <rguenther@suse.de>
PR tree-optimization/81083
diff --git a/gcc/testsuite/gcc.target/mips/data-sym-jump.c b/gcc/testsuite/gcc.target/mips/data-sym-jump.c
index c3ba294..ae48c0b 100644
--- a/gcc/testsuite/gcc.target/mips/data-sym-jump.c
+++ b/gcc/testsuite/gcc.target/mips/data-sym-jump.c
@@ -25,7 +25,7 @@ frob (int i)
/* Expect assembly like:
- la $2, $L4
+ la $2,$L4
# Anything goes here.
.type __jump_frob_4, @object # Symbol # must match label.
__jump_frob_4: # The symbol must match.
@@ -47,4 +47,4 @@ __jend_frob_4: # The symbol must match.
that is `__jump_*'/`__jend_*' symbols inserted around a jump table. */
-/* { dg-final { scan-assembler "\tla\t\\\$\[0-9\]+, (.L(\[0-9\]+))\n.*\t\\.type\t(__jump_frob_\\2), @object\n\\3:\n\\1:\n(?:\t\\.(?:half|word)\t.L\[0-9\]+-\\1\n)\{11\}\t\\.type\t(__jend_frob_\\2), @function\n\\4:\n\t\\.insn\n" } } */
+/* { dg-final { scan-assembler "\tla\t\\\$\[0-9\]+,(.L(\[0-9\]+))\n.*\t\\.type\t(__jump_frob_\\2), @object\n\\3:\n\\1:\n(?:\t\\.(?:half|word)\t.L\[0-9\]+-\\1\n)\{11\}\t\\.type\t(__jend_frob_\\2), @function\n\\4:\n\t\\.insn\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/pr51513-1.c b/gcc/testsuite/gcc.target/mips/pr51513-1.c
new file mode 100644
index 0000000..b5e0d69
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr51513-1.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-mips16 -mcode-readable=yes" } */
+
+/* PR tree-optimization/51513 verification variant for MIPS16, #1. */
+
+int __attribute__ ((weak))
+frob (int i)
+{
+ switch (i)
+ {
+ case -5:
+ return -2;
+ case -3:
+ return -1;
+ case 0:
+ return 0;
+ case 3:
+ return 1;
+ case 5:
+ break;
+ default:
+ __builtin_unreachable ();
+ }
+ return i;
+}
+
+/* Without the fix for PR tree-optimization/51513 truncated code
+ would be emitted for `frob', like:
+
+ .text
+ .align 2
+ .weak frob
+ .set mips16
+ .set nomicromips
+ .ent frob
+ .type frob, @function
+frob:
+ .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
+ .mask 0x00000000,0
+ .fmask 0x00000000,0
+ addiu $2,$4,5
+ .end frob
+ .size frob, .-frob
+
+ meaning `frob' will have no chance to return, let alone produce
+ the result expected. */
+
+/* { dg-final { scan-assembler "\tjrc?\t\\\$31\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/pr51513-2.c b/gcc/testsuite/gcc.target/mips/pr51513-2.c
new file mode 100644
index 0000000..b921904
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr51513-2.c
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+/* { dg-options "-mips16 -mcode-readable=yes" } */
+
+/* PR tree-optimization/51513 verification variant for MIPS16, #2. */
+
+int __attribute__ ((weak))
+frob (int i)
+{
+ switch (i)
+ {
+ case -5:
+ return -2;
+ case -3:
+ return -1;
+ case 0:
+ return 0;
+ case 3:
+ return 1;
+ case 5:
+ break;
+ default:
+ __builtin_unreachable ();
+ }
+ return i;
+}
+
+int
+main (void)
+{
+ return !(frob (-5) == -2
+ & frob (-3) == -1
+ & frob (0) == 0
+ & frob (3) == 1
+ & frob (5) == 5);
+}
+
+/* Without the fix for PR tree-optimization/51513 truncated code
+ would be emitted for `frob', like:
+
+ .text
+ .align 2
+ .weak frob
+ .set mips16
+ .set nomicromips
+ .ent frob
+ .type frob, @function
+frob:
+ .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
+ .mask 0x00000000,0
+ .fmask 0x00000000,0
+ addiu $2,$4,5
+ .end frob
+ .size frob, .-frob
+
+ meaning `frob' will have no chance to return, let alone produce
+ the result expected. */