extern int setjmp_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_5bit_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_adjusted_operand 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 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 ar_lc_reg_operand PARAMS((rtx, enum machine_mode));
extern int ar_ccv_reg_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_depz_field_mask PARAMS((rtx, rtx));
extern rtx ia64_gp_save_reg PARAMS((int));
extern rtx ia64_split_timode PARAMS((rtx[], rtx, rtx));
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_fetch_and_op PARAMS ((enum fetchop_code,
enum machine_mode, rtx []));
letters (`Q', `R', `S', `T', `U') that can be used to segregate specific
types of operands, usually memory references, for the target machine. */
+/* Non-volatile memory for FP_REG loads/stores. */
#define CONSTRAINT_OK_FOR_Q(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) \
- ((C) == 'Q' ? CONSTRAINT_OK_FOR_Q (VALUE) : 0)
+ ((C) == 'Q' ? CONSTRAINT_OK_FOR_Q (VALUE) \
+ : (C) == 'R' ? CONSTRAINT_OK_FOR_R (VALUE) \
+ : 0)
\f
/* Basic Stack Layout */
{ "move_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
CONSTANT_P_RTX, SYMBOL_REF, CONST, LABEL_REF}}, \
{ "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_8bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \
{ "reg_or_8bit_adjusted_operand", {SUBREG, REG, CONST_INT, \
;; ::
;; ::::::::::::::::::::
-;; ??? It would be useful to have SImode versions of the extract and insert
-;; patterns.
-
(define_insn "extv"
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
"dep %0 = %3, %0, %2, %1"
[(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"
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
(const_int 32) (const_int 0))
"#"
[(set_attr "type" "unknown")])
-;; ??? Need to emit an instruction group barrier here because this gets split
-;; after md_reorg.
-
(define_split
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
(const_int 32) (const_int 0))
;; ::
;; ::::::::::::::::::::
-;; There is no sign-extend form of dep, so we only get 32 bits of valid result
-;; instead of 64 like the patterns below.
-
-;; Using a predicate that accepts only constants doesn't work, because optabs
-;; 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")))]
+(define_insn "ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (ashift:SI (match_operand:SI 1 "register_operand" "r,r,r")
+ (match_operand:SI 2 "reg_or_5bit_operand" "R,n,r")))]
""
- "dep.z %0 = %1, %2, %E2"
- [(set_attr "type" "I")])
-
-;; This is really an extract, but this is how combine canonicalizes the
-;; operation.
+ "@
+ shladd %0 = %1, %2, r0
+ dep.z %0 = %1, %2, %E2
+ shl %0 = %1, %2"
+ [(set_attr "type" "A,I,I")])
(define_expand "ashrsi3"
- [(set (match_dup 3)
- (ashiftrt:DI (sign_extend:DI
- (match_operand:SI 1 "register_operand" ""))
- (match_operand:DI 2 "nonmemory_operand" "")))
- (set (match_operand:SI 0 "register_operand" "") (match_dup 4))]
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "reg_or_5bit_operand" "")))]
""
"
{
- if (! shift_32bit_count_operand (operands[2], SImode))
- FAIL;
-
- operands[3] = gen_reg_rtx (DImode);
- operands[4] = gen_lowpart (SImode, operands[3]);
+ rtx subtarget = gen_reg_rtx (DImode);
+ if (GET_CODE (operands[2]) == CONST_INT)
+ emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]),
+ GEN_INT (32 - INTVAL (operands[2])), operands[2]));
+ 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"
- [(set (match_dup 3)
- (lshiftrt:DI (zero_extend:DI
- (match_operand:SI 1 "register_operand" ""))
- (match_operand:DI 2 "nonmemory_operand" "")))
- (set (match_operand:SI 0 "register_operand" "") (match_dup 4))]
+ [(set (match_operand:SI 0 "register_operand" "")
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "reg_or_5bit_operand" "")))]
""
"
{
- if (! shift_32bit_count_operand (operands[2], SImode))
- FAIL;
-
- operands[3] = gen_reg_rtx (DImode);
- operands[4] = gen_lowpart (SImode, operands[3]);
+ rtx subtarget = gen_reg_rtx (DImode);
+ if (GET_CODE (operands[2]) == CONST_INT)
+ emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]),
+ GEN_INT (32 - INTVAL (operands[2])), operands[2]));
+ 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
;; here, instead of 64 like the patterns above.
{
if (! shift_32bit_count_operand (operands[2], SImode))
FAIL;
-
operands[3] = gen_reg_rtx (DImode);
operands[4] = gen_lowpart (SImode, operands[3]);
}")
-
\f
;; ::::::::::::::::::::
;; ::
;; ::::::::::::::::::::
(define_insn "ashldi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "reg_or_6bit_operand" "rM")))]
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
+ (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?