diff options
author | Maciej W. Rozycki <macro@imgtec.com> | 2017-06-14 23:26:40 +0000 |
---|---|---|
committer | Maciej W. Rozycki <macro@gcc.gnu.org> | 2017-06-14 23:26:40 +0000 |
commit | 3466430f382b6adc2363721056b9abde3acd790a (patch) | |
tree | e6cdacfffb0e4b8b67ce1c67ba25a40f0e722b26 | |
parent | cdd17d6e9956853892e4c097cc33afc2156df69e (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 58 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/data-sym-jump.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/pr51513-1.c | 48 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/mips/pr51513-2.c | 56 |
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. */ |