summaryrefslogtreecommitdiff
path: root/gcc/config/vax
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2004-11-28 12:01:20 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2004-11-28 12:01:20 +0000
commit79ede3bd3d5c378b54e7c06a757ed2bcf2e5eddd (patch)
treecbc410ed8e447946a1d8d0de3c7e6ff94ce0b213 /gcc/config/vax
parent30cd62039743aa0fe04b096eed3efd34193e0984 (diff)
downloadgcc-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.h5
-rw-r--r--gcc/config/vax/vax.md105
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")