Commit 041f25e6 by Richard Henderson Committed by Richard Henderson

ia64.c (reg_or_5bit_operand): New.

        * config/ia64/ia64.c (reg_or_5bit_operand): New.
        (ia64_depz_field_mask): New.
        * config/ia64/ia64.h (CONSTRAINT_OK_FOR_R): New.
        (PREDICATE_CODES): Update.
        * config/ia64/ia64.md: Update commentary.
        (depz_internal): New.
        (ashlsi3): Implement directly.
        (ashrsi3, lshrsi3): Simplify; rely on extv and extzv for constants.
        (ashldi3): Use shladd.
        * config/ia64/ia64-protos.h: Update.

From-SVN: r35802
parent 17ed19cb
2000-08-19 Richard Henderson <rth@cygnus.com>
* config/ia64/ia64.c (reg_or_5bit_operand): New.
(ia64_depz_field_mask): New.
* config/ia64/ia64.h (CONSTRAINT_OK_FOR_R): New.
(PREDICATE_CODES): Update.
* config/ia64/ia64.md: Update commentary.
(depz_internal): New.
(ashlsi3): Implement directly.
(ashrsi3, lshrsi3): Simplify; rely on extv and extzv for constants.
(ashldi3): Use shladd.
* config/ia64/ia64-protos.h: Update.
2000-08-18 Zack Weinberg <zack@wolery.cumb.org> 2000-08-18 Zack Weinberg <zack@wolery.cumb.org>
* toplev.c (independent_decode_option): Always process -g. * toplev.c (independent_decode_option): Always process -g.
......
...@@ -35,6 +35,7 @@ extern int function_operand PARAMS((rtx, enum machine_mode)); ...@@ -35,6 +35,7 @@ extern int function_operand PARAMS((rtx, enum machine_mode));
extern int setjmp_operand PARAMS((rtx, enum machine_mode)); extern int setjmp_operand PARAMS((rtx, enum machine_mode));
extern int move_operand PARAMS((rtx, enum machine_mode)); extern int move_operand PARAMS((rtx, enum machine_mode));
extern int reg_or_0_operand PARAMS((rtx, enum machine_mode)); extern int reg_or_0_operand PARAMS((rtx, enum machine_mode));
extern int reg_or_5bit_operand PARAMS((rtx, enum machine_mode));
extern int reg_or_6bit_operand PARAMS((rtx, enum machine_mode)); extern int reg_or_6bit_operand PARAMS((rtx, enum machine_mode));
extern int reg_or_8bit_operand PARAMS((rtx, enum machine_mode)); extern int reg_or_8bit_operand PARAMS((rtx, enum machine_mode));
extern int reg_or_8bit_adjusted_operand PARAMS((rtx, enum machine_mode)); extern int reg_or_8bit_adjusted_operand PARAMS((rtx, enum machine_mode));
...@@ -50,12 +51,6 @@ extern int normal_comparison_operator PARAMS((rtx, enum machine_mode)); ...@@ -50,12 +51,6 @@ extern int normal_comparison_operator PARAMS((rtx, enum machine_mode));
extern int adjusted_comparison_operator PARAMS((rtx, enum machine_mode)); extern int adjusted_comparison_operator PARAMS((rtx, enum machine_mode));
extern int call_multiple_values_operation PARAMS((rtx, enum machine_mode)); extern int call_multiple_values_operation PARAMS((rtx, enum machine_mode));
extern int destination_operand PARAMS((rtx, enum machine_mode)); extern int destination_operand PARAMS((rtx, enum machine_mode));
extern HOST_WIDE_INT ia64_initial_elimination_offset PARAMS((int, int));
extern void ia64_expand_prologue PARAMS((void));
extern void ia64_expand_epilogue PARAMS((void));
extern void ia64_function_prologue PARAMS((FILE *, int));
extern void ia64_function_epilogue PARAMS((FILE *, int));
extern int ia64_direct_return PARAMS((void));
extern int predicate_operator PARAMS((rtx, enum machine_mode)); extern int predicate_operator PARAMS((rtx, enum machine_mode));
extern int ar_lc_reg_operand PARAMS((rtx, enum machine_mode)); extern int ar_lc_reg_operand PARAMS((rtx, enum machine_mode));
extern int ar_ccv_reg_operand PARAMS((rtx, enum machine_mode)); extern int ar_ccv_reg_operand PARAMS((rtx, enum machine_mode));
...@@ -64,10 +59,18 @@ extern int destination_tfmode_operand PARAMS((rtx, enum machine_mode)); ...@@ -64,10 +59,18 @@ extern int destination_tfmode_operand PARAMS((rtx, enum machine_mode));
extern int tfreg_or_fp01_operand PARAMS((rtx, enum machine_mode)); extern int tfreg_or_fp01_operand PARAMS((rtx, enum machine_mode));
extern int ia64_move_ok PARAMS((rtx, rtx)); extern int ia64_move_ok PARAMS((rtx, rtx));
extern int ia64_depz_field_mask PARAMS((rtx, rtx));
extern rtx ia64_gp_save_reg PARAMS((int)); extern rtx ia64_gp_save_reg PARAMS((int));
extern rtx ia64_split_timode PARAMS((rtx[], rtx, rtx)); extern rtx ia64_split_timode PARAMS((rtx[], rtx, rtx));
extern rtx spill_tfmode_operand PARAMS((rtx, int)); extern rtx spill_tfmode_operand PARAMS((rtx, int));
extern HOST_WIDE_INT ia64_initial_elimination_offset PARAMS((int, int));
extern void ia64_expand_prologue PARAMS((void));
extern void ia64_expand_epilogue PARAMS((void));
extern void ia64_function_prologue PARAMS((FILE *, int));
extern void ia64_function_epilogue PARAMS((FILE *, int));
extern int ia64_direct_return PARAMS((void));
extern void ia64_expand_load_address PARAMS((rtx, rtx)); extern void ia64_expand_load_address PARAMS((rtx, rtx));
extern void ia64_expand_fetch_and_op PARAMS ((enum fetchop_code, extern void ia64_expand_fetch_and_op PARAMS ((enum fetchop_code,
enum machine_mode, rtx [])); enum machine_mode, rtx []));
......
...@@ -316,6 +316,18 @@ reg_or_0_operand (op, mode) ...@@ -316,6 +316,18 @@ reg_or_0_operand (op, mode)
return (op == const0_rtx || register_operand (op, mode)); return (op == const0_rtx || register_operand (op, mode));
} }
/* Return 1 if OP is a register operand, or a 5 bit immediate operand. */
int
reg_or_5bit_operand (op, mode)
rtx op;
enum machine_mode mode;
{
return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 32)
|| GET_CODE (op) == CONSTANT_P_RTX
|| register_operand (op, mode));
}
/* Return 1 if OP is a register operand, or a 6 bit immediate operand. */ /* Return 1 if OP is a register operand, or a 6 bit immediate operand. */
int int
...@@ -635,6 +647,23 @@ ia64_move_ok (dst, src) ...@@ -635,6 +647,23 @@ ia64_move_ok (dst, src)
return GET_CODE (src) == CONST_DOUBLE && CONST_DOUBLE_OK_FOR_G (src); return GET_CODE (src) == CONST_DOUBLE && CONST_DOUBLE_OK_FOR_G (src);
} }
/* Check if OP is a mask suitible for use with SHIFT in a dep.z instruction.
Return the length of the field, or <= 0 on failure. */
int
ia64_depz_field_mask (rop, rshift)
rtx rop, rshift;
{
unsigned HOST_WIDE_INT op = INTVAL (rop);
unsigned HOST_WIDE_INT shift = INTVAL (rshift);
/* Get rid of the zero bits we're shifting in. */
op >>= shift;
/* We must now have a solid block of 1's at bit 0. */
return exact_log2 (op + 1);
}
/* Expand a symbolic constant load. */ /* Expand a symbolic constant load. */
/* ??? Should generalize this, so that we can also support 32 bit pointers. */ /* ??? Should generalize this, so that we can also support 32 bit pointers. */
......
...@@ -1108,11 +1108,17 @@ enum reg_class ...@@ -1108,11 +1108,17 @@ enum reg_class
letters (`Q', `R', `S', `T', `U') that can be used to segregate specific letters (`Q', `R', `S', `T', `U') that can be used to segregate specific
types of operands, usually memory references, for the target machine. */ types of operands, usually memory references, for the target machine. */
/* Non-volatile memory for FP_REG loads/stores. */
#define CONSTRAINT_OK_FOR_Q(VALUE) \ #define CONSTRAINT_OK_FOR_Q(VALUE) \
(memory_operand((VALUE), VOIDmode) && ! MEM_VOLATILE_P (VALUE)) (memory_operand((VALUE), VOIDmode) && ! MEM_VOLATILE_P (VALUE))
/* 1..4 for shladd arguments. */
#define CONSTRAINT_OK_FOR_R(VALUE) \
(GET_CODE (VALUE) == CONST_INT && INTVAL (VALUE) >= 1 && INTVAL (VALUE) <= 4)
#define EXTRA_CONSTRAINT(VALUE, C) \ #define EXTRA_CONSTRAINT(VALUE, C) \
((C) == 'Q' ? CONSTRAINT_OK_FOR_Q (VALUE) : 0) ((C) == 'Q' ? CONSTRAINT_OK_FOR_Q (VALUE) \
: (C) == 'R' ? CONSTRAINT_OK_FOR_R (VALUE) \
: 0)
/* Basic Stack Layout */ /* Basic Stack Layout */
...@@ -2639,6 +2645,7 @@ do { \ ...@@ -2639,6 +2645,7 @@ do { \
{ "move_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \ { "move_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
CONSTANT_P_RTX, SYMBOL_REF, CONST, LABEL_REF}}, \ CONSTANT_P_RTX, SYMBOL_REF, CONST, LABEL_REF}}, \
{ "reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \ { "reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \
{ "reg_or_5bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{ "reg_or_6bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ { "reg_or_6bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{ "reg_or_8bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ { "reg_or_8bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{ "reg_or_8bit_adjusted_operand", {SUBREG, REG, CONST_INT, \ { "reg_or_8bit_adjusted_operand", {SUBREG, REG, CONST_INT, \
......
...@@ -1113,9 +1113,6 @@ ...@@ -1113,9 +1113,6 @@
;; :: ;; ::
;; :::::::::::::::::::: ;; ::::::::::::::::::::
;; ??? It would be useful to have SImode versions of the extract and insert
;; patterns.
(define_insn "extv" (define_insn "extv"
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
(sign_extract:DI (match_operand:DI 1 "register_operand" "r") (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
...@@ -1229,6 +1226,21 @@ ...@@ -1229,6 +1226,21 @@
"dep %0 = %3, %0, %2, %1" "dep %0 = %3, %0, %2, %1"
[(set_attr "type" "I")]) [(set_attr "type" "I")])
;; Combine doesn't like to create bitfield insertions into zero.
(define_insn "*depz_internal"
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "const_int_operand" "n"))
(match_operand:DI 3 "const_int_operand" "n")))]
"CONST_OK_FOR_M (INTVAL (operands[2]))
&& ia64_depz_field_mask (operands[3], operands[2]) > 0"
"*
{
operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2]));
return \"%,dep.z %0 = %1, %2, %3\";
}"
[(set_attr "type" "I")])
(define_insn "shift_mix4left" (define_insn "shift_mix4left"
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
(const_int 32) (const_int 0)) (const_int 32) (const_int 0))
...@@ -1238,9 +1250,6 @@ ...@@ -1238,9 +1250,6 @@
"#" "#"
[(set_attr "type" "unknown")]) [(set_attr "type" "unknown")])
;; ??? Need to emit an instruction group barrier here because this gets split
;; after md_reorg.
(define_split (define_split
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "") [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
(const_int 32) (const_int 0)) (const_int 32) (const_int 0))
...@@ -2003,89 +2012,59 @@ ...@@ -2003,89 +2012,59 @@
;; :: ;; ::
;; :::::::::::::::::::: ;; ::::::::::::::::::::
;; There is no sign-extend form of dep, so we only get 32 bits of valid result (define_insn "ashlsi3"
;; instead of 64 like the patterns below. [(set (match_operand:SI 0 "register_operand" "=r,r,r")
(ashift:SI (match_operand:SI 1 "register_operand" "r,r,r")
;; Using a predicate that accepts only constants doesn't work, because optabs (match_operand:SI 2 "reg_or_5bit_operand" "R,n,r")))]
;; will load the operand into a register and call the pattern if the predicate
;; did not accept it on the first try. So we use nonmemory_operand and then
;; verify that we have an appropriate constant in the expander.
(define_expand "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "")
(ashift:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
""
"
{
if (! shift_32bit_count_operand (operands[2], SImode))
FAIL;
}")
(define_insn "*ashlsi3_internal"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashift:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "shift_32bit_count_operand" "n")))]
"" ""
"dep.z %0 = %1, %2, %E2" "@
[(set_attr "type" "I")]) shladd %0 = %1, %2, r0
dep.z %0 = %1, %2, %E2
;; This is really an extract, but this is how combine canonicalizes the shl %0 = %1, %2"
;; operation. [(set_attr "type" "A,I,I")])
(define_expand "ashrsi3" (define_expand "ashrsi3"
[(set (match_dup 3) [(set (match_operand:SI 0 "register_operand" "")
(ashiftrt:DI (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 1 "register_operand" "")) (match_operand:SI 2 "reg_or_5bit_operand" "")))]
(match_operand:DI 2 "nonmemory_operand" "")))
(set (match_operand:SI 0 "register_operand" "") (match_dup 4))]
"" ""
" "
{ {
if (! shift_32bit_count_operand (operands[2], SImode)) rtx subtarget = gen_reg_rtx (DImode);
FAIL; if (GET_CODE (operands[2]) == CONST_INT)
emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
operands[3] = gen_reg_rtx (DImode); GEN_INT (32 - INTVAL (operands[2])), operands[2]));
operands[4] = gen_lowpart (SImode, operands[3]); else
{
emit_insn (gen_extendsidi2 (subtarget, operands[1]));
emit_insn (gen_ashrdi3 (subtarget, subtarget,
gen_lowpart (DImode, operands[2])));
}
emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
DONE;
}") }")
(define_insn "*ashrsi3_internal"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashiftrt:DI (sign_extend:DI
(match_operand:SI 1 "register_operand" "r"))
(match_operand:DI 2 "shift_32bit_count_operand" "n")))]
""
"extr %0 = %1, %2, %E2"
[(set_attr "type" "I")])
;; This is really an extract, but this is how combine canonicalizes the
;; operation.
(define_expand "lshrsi3" (define_expand "lshrsi3"
[(set (match_dup 3) [(set (match_operand:SI 0 "register_operand" "")
(lshiftrt:DI (zero_extend:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 1 "register_operand" "")) (match_operand:SI 2 "reg_or_5bit_operand" "")))]
(match_operand:DI 2 "nonmemory_operand" "")))
(set (match_operand:SI 0 "register_operand" "") (match_dup 4))]
"" ""
" "
{ {
if (! shift_32bit_count_operand (operands[2], SImode)) rtx subtarget = gen_reg_rtx (DImode);
FAIL; if (GET_CODE (operands[2]) == CONST_INT)
emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
operands[3] = gen_reg_rtx (DImode); GEN_INT (32 - INTVAL (operands[2])), operands[2]));
operands[4] = gen_lowpart (SImode, operands[3]); else
{
emit_insn (gen_zero_extendsidi2 (subtarget, operands[1]));
emit_insn (gen_lshrdi3 (subtarget, subtarget,
gen_lowpart (DImode, operands[2])));
}
emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget);
DONE;
}") }")
(define_insn "*lshrsi3_internal"
[(set (match_operand:DI 0 "register_operand" "=r")
(lshiftrt:DI (zero_extend:DI
(match_operand:SI 1 "register_operand" "r"))
(match_operand:DI 2 "shift_32bit_count_operand" "n")))]
""
"extr.u %0 = %1, %2, %E2"
[(set_attr "type" "I")])
;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result ;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result
;; here, instead of 64 like the patterns above. ;; here, instead of 64 like the patterns above.
...@@ -2102,11 +2081,9 @@ ...@@ -2102,11 +2081,9 @@
{ {
if (! shift_32bit_count_operand (operands[2], SImode)) if (! shift_32bit_count_operand (operands[2], SImode))
FAIL; FAIL;
operands[3] = gen_reg_rtx (DImode); operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_lowpart (SImode, operands[3]); operands[4] = gen_lowpart (SImode, operands[3]);
}") }")
;; :::::::::::::::::::: ;; ::::::::::::::::::::
;; :: ;; ::
...@@ -2115,12 +2092,14 @@ ...@@ -2115,12 +2092,14 @@
;; :::::::::::::::::::: ;; ::::::::::::::::::::
(define_insn "ashldi3" (define_insn "ashldi3"
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r,r")
(ashift:DI (match_operand:DI 1 "register_operand" "r") (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
(match_operand:DI 2 "reg_or_6bit_operand" "rM")))] (match_operand:DI 2 "reg_or_6bit_operand" "R,rM")))]
"" ""
"shl %0 = %1, %2" "@
[(set_attr "type" "I")]) shladd %0 = %1, %2, r0
shl %0 = %1, %2"
[(set_attr "type" "A,I")])
;; ??? Maybe combine this with the multiply and add instruction? ;; ??? Maybe combine this with the multiply and add instruction?
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment