diff options
author | gkm <gkm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-12 18:40:58 +0000 |
---|---|---|
committer | gkm <gkm@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-12 18:40:58 +0000 |
commit | ea98ee5207227717f7cd3b6a5cec6f9d00f527b5 (patch) | |
tree | 93c6f2d62aaecc62c9172d737563813c5dfe8a12 /gcc/config/mips/mips.c | |
parent | c87aba630389d4463e9131b703e81f45508c54f8 (diff) | |
download | gcc-ea98ee5207227717f7cd3b6a5cec6f9d00f527b5.tar.gz |
* config/mips/mips-protos.h
(trap_cmp_op, mips_gen_conditional_trap): New func decls.
* config/mips/mips.h (ISA_HAS_COND_TRAP): New macro.
(PREDICATE_CODES): Add "trap_cmp_op".
* config/mips/mips.c
(trap_cmp_op, mips_gen_conditional_trap): New functions.
* config/mips/mips.md (trap, conditional_trap): New patterns.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36371 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/mips/mips.c')
-rw-r--r-- | gcc/config/mips/mips.c | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index f059dddd616..860ce956d7b 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -188,8 +188,8 @@ int num_refs[3]; /* registers to check for load delay */ rtx mips_load_reg, mips_load_reg2, mips_load_reg3, mips_load_reg4; -/* Cached operands, and operator to compare for use in set/branch on - condition codes. */ +/* Cached operands, and operator to compare for use in set/branch/trap + on condition codes. */ rtx branch_cmp[2]; /* what type of branch to use */ @@ -964,6 +964,34 @@ cmp_op (op, mode) return GET_RTX_CLASS (GET_CODE (op)) == '<'; } +/* Return nonzero if the code is a relational operation suitable for a + conditional trap instructuion (only EQ, NE, LT, LTU, GE, GEU). + We need this in the insn that expands `trap_if' in order to prevent + combine from erroneously altering the condition. */ + +int +trap_cmp_op (op, mode) + rtx op; + enum machine_mode mode; +{ + if (mode != GET_MODE (op)) + return 0; + + switch (GET_CODE (op)) + { + case EQ: + case NE: + case LT: + case LTU: + case GE: + case GEU: + return 1; + + default: + return 0; + } +} + /* Return nonzero if the operand is either the PC or a label_ref. */ int @@ -3139,6 +3167,46 @@ gen_conditional_move (operands) CONST0_RTX (SImode)), operands[2], operands[3]))); } + +/* Emit the common code for conditional moves. OPERANDS is the array + of operands passed to the conditional move defined_expand. */ + +void +mips_gen_conditional_trap (operands) + rtx operands[]; +{ + rtx op0, op1; + enum rtx_code cmp_code = GET_CODE (operands[0]); + enum machine_mode mode = GET_MODE (branch_cmp[0]); + + /* MIPS conditional trap machine instructions don't have GT or LE + flavors, so we must invert the comparison and convert to LT and + GE, respectively. */ + switch (cmp_code) + { + case GT: cmp_code = LT; break; + case LE: cmp_code = GE; break; + case GTU: cmp_code = LTU; break; + case LEU: cmp_code = GEU; break; + default: break; + } + if (cmp_code == GET_CODE (operands[0])) + { + op0 = force_reg (mode, branch_cmp[0]); + op1 = branch_cmp[1]; + } + else + { + op0 = force_reg (mode, branch_cmp[1]); + op1 = branch_cmp[0]; + } + if (GET_CODE (op1) == CONST_INT && ! SMALL_INT (op1)) + op1 = force_reg (mode, op1); + + emit_insn (gen_rtx_TRAP_IF (VOIDmode, + gen_rtx (cmp_code, GET_MODE (operands[0]), op0, op1), + operands[1])); +} /* Write a loop to move a constant number of bytes. Generate load/stores as follows: |