diff options
author | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-28 12:01:20 +0000 |
---|---|---|
committer | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-28 12:01:20 +0000 |
commit | 79ede3bd3d5c378b54e7c06a757ed2bcf2e5eddd (patch) | |
tree | cbc410ed8e447946a1d8d0de3c7e6ff94ce0b213 /gcc/config/vax | |
parent | 30cd62039743aa0fe04b096eed3efd34193e0984 (diff) | |
download | gcc-79ede3bd3d5c378b54e7c06a757ed2bcf2e5eddd.tar.gz |
* config/vax/vax.h (CASE_DROPS_THROUGH): Don't define.
* config/vax/vax.md (casesi): Emit a test-and-branch to make sure
that the case is in range, to make sure the casesi insn is always
in range and never falls through.
(casesi1): Add comment to explain why casesi never falls through.
Remove the unnamed special case casesi pattern.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91417 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/vax')
-rw-r--r-- | gcc/config/vax/vax.h | 5 | ||||
-rw-r--r-- | gcc/config/vax/vax.md | 105 |
2 files changed, 50 insertions, 60 deletions
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index 1cfcd51f871..5efd790dde4 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -784,11 +784,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES }; Do not define this if the table should contain absolute addresses. */ #define CASE_VECTOR_PC_RELATIVE 1 -/* Define this if the case instruction drops through after the table - when the index is out of range. Don't define it if the case insn - jumps to the default label instead. */ -#define CASE_DROPS_THROUGH - /* Indicate that jump tables go in the text section. This is necessary when compiling PIC code. */ #define JUMP_TABLES_IN_TEXT_SECTION 1 diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 1d7774ec96b..bd25875ecdb 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -1960,68 +1960,63 @@ "jmp (%0)") ;; This is here to accept 5 arguments (as passed by expand_end_case) -;; and pass the first 4 along to the casesi1 pattern that really does the work. +;; and pass the first 4 along to the casesi1 pattern that really does +;; the actual casesi work. We emit a jump here to the default label +;; _before_ the casesi so that we can be sure that the casesi never +;; drops through. +;; This is suboptimal perhaps, but so is much of the rest of this +;; machine description. For what it's worth, HPPA uses the same trick. +;; +;; operand 0 is index +;; operand 1 is the minimum bound (a const_int) +;; operand 2 is the maximum bound - minimum bound + 1 (also a const_int) +;; operand 3 is CODE_LABEL for the table; +;; operand 4 is the CODE_LABEL to go to if index out of range (ie. default). +;; +;; We emit: +;; i = index - minimum_bound +;; if (i > (maximum_bound - minimum_bound + 1) goto default; +;; casesi (i, 0, table); +;; (define_expand "casesi" - [(match_operand:SI 0 "general_operand" "") ; index - (match_operand:SI 1 "general_operand" "") ; lower - (match_operand:SI 2 "general_operand" "") ; upper-lower - (match_operand 3 "" "") ; table label - (match_operand 4 "" "")] ; default label + [(match_operand:SI 0 "general_operand" "") + (match_operand:SI 1 "general_operand" "") + (match_operand:SI 2 "general_operand" "") + (match_operand 3 "" "") + (match_operand 4 "" "")] "" { - emit_jump_insn (gen_casesi1 (operands[0], operands[1], - operands[2], operands[3])); + /* i = index - minimum_bound; + But only if the lower bound is not already zero. */ + if (operands[1] != const0_rtx) + { + rtx index = gen_reg_rtx (SImode); + emit_insn (gen_addsi3 (index, + operands[0], + GEN_INT (-INTVAL (operands[1])))); + operands[0] = index; + } + + /* if (i > (maximum_bound - minimum_bound + 1) goto default; */ + emit_insn (gen_cmpsi (operands[0], operands[2])); + emit_jump_insn (gen_bgtu (operands[4])); + + /* casesi (i, 0, table); */ + emit_jump_insn (gen_casesi1 (operands[0], operands[2], operands[3])); DONE; }) +;; This insn is a bit of a lier. It actually falls through if no case +;; matches. But, we prevent that from ever happening by emiting a jump +;; before this, see the define_expand above. (define_insn "casesi1" - [(set (pc) - (if_then_else - (leu (minus:SI (match_operand:SI 0 "general_operand" "g") - (match_operand:SI 1 "general_operand" "g")) - (match_operand:SI 2 "general_operand" "g")) - (plus:SI (sign_extend:SI - (mem:HI (plus:SI (mult:SI (minus:SI (match_dup 0) - (match_dup 1)) - (const_int 2)) - (pc)))) - (label_ref:SI (match_operand 3 "" ""))) - (pc)))] - "" - "casel %0,%1,%2") - -;; This can arise by simplification when operand 1 is a constant int. -(define_insn "" - [(set (pc) - (if_then_else - (leu (plus:SI (match_operand:SI 0 "general_operand" "g") - (match_operand:SI 1 "const_int_operand" "n")) - (match_operand:SI 2 "general_operand" "g")) - (plus:SI (sign_extend:SI - (mem:HI (plus:SI (mult:SI (plus:SI (match_dup 0) - (match_dup 1)) - (const_int 2)) - (pc)))) - (label_ref:SI (match_operand 3 "" ""))) - (pc)))] - "" - "* -{ - operands[1] = GEN_INT (-INTVAL (operands[1])); - return \"casel %0,%1,%2\"; -}") - -;; This can arise by simplification when the base for the case insn is zero. -(define_insn "" - [(set (pc) - (if_then_else (leu (match_operand:SI 0 "general_operand" "g") - (match_operand:SI 1 "general_operand" "g")) - (plus:SI (sign_extend:SI - (mem:HI (plus:SI (mult:SI (match_dup 0) - (const_int 2)) - (pc)))) - (label_ref:SI (match_operand 2 "" ""))) - (pc)))] + [(match_operand:SI 1 "const_int_operand" "n") + (set (pc) + (plus:SI (sign_extend:SI + (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "g") + (const_int 2)) + (pc)))) + (label_ref:SI (match_operand 2 "" ""))))] "" "casel %0,$0,%1") |