This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
I387 commutative fpop patterns
- To: egcs-patches at egcs dot cygnus dot com, rth at cygnus dot com
- Subject: I387 commutative fpop patterns
- From: Jan Hubicka <hubicka at atrey dot karlin dot mff dot cuni dot cz>
- Date: Fri, 19 Nov 1999 01:43:17 +0100
Hi
There is some code to handle the "two address" instructions (ie those that
contains "0" in constraint.
Because i387 patterns are modeled universally, they don't fall into this category.
This patch add separate patterns for ADD/MUL instructions that can be modeled in this
way. It saves roughly 8Kb on XaoS binarry.
There is problem with reg-stack. It does substitue registers and prevents patterns
from matching. Until reg-stack is redone I've solved this by letting the "default"
patterns match the insn after reload and changed reg-stack to clear recog cache.
This is good idea anyway, because some insns may get changed (or deleted) by regstack.
Fri Nov 18 18:54:36 CET 1999 Jan Hubicka <hubicka@freesoft.cz>
* i386.md (fop_?f_comm): New patterns
(fop_?f_1): Do not match commutative operators before reload.
* reg-stack.c (convert_regs_1): Clear recog cache for modified insns.
* i386.h (PREDICATE_CODES): Add commutative_fp_operator.
* i386.c (commutative_fp_operator): New function.
* i386-protos.h (commutative_fp_operator): Declare.
*** i386.md.noc Thu Nov 18 07:50:23 1999
--- i386.md Thu Nov 18 18:47:51 1999
***************
*** 6802,6813 ****
;; SImode if the target mode DFmode, but only SImode if the target mode
;; is SFmode.
(define_insn "*fop_sf_1"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(match_operator:SF 3 "binary_fp_operator"
[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
(match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
! "TARGET_80387"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(cond [(match_operand:SF 3 "mult_operator" "")
--- 6984,7040 ----
;; SImode if the target mode DFmode, but only SImode if the target mode
;; is SFmode.
+ ;; Gcc is slightly more smart about handling "standard" two address
+ ;; instructions so declare commutative operations separately.
+ ;; Sadly reg-stack prevents this patterns from matching, so fall back to
+ ;; default ones after reload.
+ (define_insn "*fop_sf_comm"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (match_operator:SF 3 "commutative_fp_operator"
+ [(match_operand:SF 1 "register_operand" "%0")
+ (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
+ "TARGET_80387 && !reload_completed"
+ "* return output_387_binary_op (insn, operands);"
+ [(set (attr "type")
+ (cond [(match_operand:SF 3 "mult_operator" "")
+ (const_string "fmul")
+ ]
+ (const_string "fop")))])
+
+ (define_insn "*fop_df_comm"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (match_operator:DF 3 "commutative_fp_operator"
+ [(match_operand:DF 1 "register_operand" "%0")
+ (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
+ "TARGET_80387 && !reload_completed"
+ "* return output_387_binary_op (insn, operands);"
+ [(set (attr "type")
+ (cond [(match_operand:DF 3 "mult_operator" "")
+ (const_string "fmul")
+ ]
+ (const_string "fop")))])
+
+ (define_insn "*fop_xf_comm"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (match_operator:XF 3 "commutative_fp_operator"
+ [(match_operand:XF 1 "register_operand" "%0")
+ (match_operand:XF 2 "register_operand" "f")]))]
+ "TARGET_80387 && !reload_completed"
+ "* return output_387_binary_op (insn, operands);"
+ [(set (attr "type")
+ (cond [(match_operand:XF 3 "mult_operator" "")
+ (const_string "fmul")
+ ]
+ (const_string "fop")))])
+
+
(define_insn "*fop_sf_1"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(match_operator:SF 3 "binary_fp_operator"
[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
(match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
! "TARGET_80387
! && (reload_completed || ! commutative_fp_operator (operands[3], SFmode))"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(cond [(match_operand:SF 3 "mult_operator" "")
***************
*** 6856,6862 ****
(match_operator:DF 3 "binary_fp_operator"
[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
(match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
! "TARGET_80387"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(cond [(match_operand:DF 3 "mult_operator" "")
--- 7083,7090 ----
(match_operator:DF 3 "binary_fp_operator"
[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
(match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
! "TARGET_80387
! && (reload_completed || ! commutative_fp_operator (operands[3], DFmode))"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(cond [(match_operand:DF 3 "mult_operator" "")
***************
*** 6936,6942 ****
(match_operator:XF 3 "binary_fp_operator"
[(match_operand:XF 1 "register_operand" "0,f")
(match_operand:XF 2 "register_operand" "f,0")]))]
! "TARGET_80387"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(cond [(match_operand:XF 3 "mult_operator" "")
--- 7164,7171 ----
(match_operator:XF 3 "binary_fp_operator"
[(match_operand:XF 1 "register_operand" "0,f")
(match_operand:XF 2 "register_operand" "f,0")]))]
! "TARGET_80387
! && (reload_completed || ! commutative_fp_operator (operands[3], XFmode))"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(cond [(match_operand:XF 3 "mult_operator" "")
*** reg-stack.c.noc Thu Nov 18 15:50:25 1999
--- reg-stack.c Thu Nov 18 18:42:09 1999
*************** convert_regs_1 (file, block)
*** 2429,2434 ****
--- 2429,2435 ----
print_stack (file, ®stack);
}
subst_stack_regs (insn, ®stack);
+ INSN_CODE (insn) = -1;
}
}
while (next);
*** i386.c.noc Thu Nov 18 06:36:16 1999
--- i386.c Thu Nov 18 14:01:53 1999
*************** ext_register_operand (op, mode)
*** 1135,1140 ****
--- 1175,1201 ----
return register_operand (op, VOIDmode);
}
+ /* Return 1 if this is a valid commutative floating-point operation.
+ OP is the expression matched, and MODE is its mode. */
+
+ int
+ commutative_fp_operator (op, mode)
+ register rtx op;
+ enum machine_mode mode;
+ {
+ if (mode != VOIDmode && mode != GET_MODE (op))
+ return 0;
+
+ switch (GET_CODE (op))
+ {
+ case PLUS:
+ case MULT:
+ return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
+
+ default:
+ return 0;
+ }
+ }
/* Return 1 if this is a valid binary floating-point operation.
OP is the expression matched, and MODE is its mode. */
*** i386.h.nonoc Sat Oct 30 21:43:20 1999
--- i386.h Thu Nov 18 14:00:48 1999
*************** do { long l; \
*** 2390,2395 ****
--- 2420,2426 ----
{"cmp_fp_expander_operand", {CONST_DOUBLE, SUBREG, REG, MEM}}, \
{"ext_register_operand", {SUBREG, REG}}, \
{"binary_fp_operator", {PLUS, MINUS, MULT, DIV}}, \
+ {"commutative_fp_operator", {PLUS, MULT}}, \
{"mult_operator", {MULT}}, \
{"div_operator", {DIV}}, \
{"arith_or_logical_operator", {PLUS, MULT, AND, IOR, XOR, SMIN, SMAX, \
*** i386-protos.h.noc Thu Nov 18 14:01:13 1999
--- i386-protos.h Thu Nov 18 14:01:26 1999
*************** extern int fcmov_comparison_operator PRO
*** 57,62 ****
--- 57,63 ----
extern int cmp_fp_expander_operand PROTO((rtx, enum machine_mode));
extern int ext_register_operand PROTO((rtx, enum machine_mode));
extern int binary_fp_operator PROTO((rtx, enum machine_mode));
+ extern int commutative_fp_operator PROTO((rtx, enum machine_mode));
extern int mult_operator PROTO((rtx, enum machine_mode));
extern int div_operator PROTO((rtx, enum machine_mode));
extern int arith_or_logical_operator PROTO((rtx, enum machine_mode));