This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Updated patch for DImode operations on i386
- To: egcs at cygnus dot com
- Subject: Updated patch for DImode operations on i386
- From: Bernd Schmidt <crux at pool dot informatik dot rwth-aachen dot de>
- Date: Mon, 2 Mar 1998 13:13:30 +0100 (MET)
Here's an updated patch for logical DImode operations on the i386.
Changes since the last one:
- now the new patterns use exactly the same constrains as subdi3, to avoid
reload problems
- now uses change_address in split_di to create new MEMs, to preserve
MEM_* bits.
Bernd
* i386.c (ix86_logical_operator): New function.
(split_di): Ensure that when a MEM is split, the resulting MEMs have
SImode.
* i386.md (anddi3, xordi3, iordi3): New patterns. Add a define_split
to implement them.
Index: config/i386/i386.c
===================================================================
RCS file: /usr/local/cvs/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.1.3.7
diff -c -p -r1.1.3.7 i386.c
*** i386.c 1998/02/16 19:05:44 1.1.3.7
--- i386.c 1998/02/25 19:39:30
*************** arithmetic_comparison_operator (op, mode
*** 1698,1703 ****
--- 1698,1712 ----
return (code != GT && code != LE);
}
+
+ int
+ ix86_logical_operator (op, mode)
+ register rtx op;
+ enum machine_mode mode;
+ {
+ return GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR;
+ }
+
/* Returns 1 if OP contains a symbol reference */
*************** split_di (operands, num, lo_half, hi_hal
*** 3688,3704 ****
{
while (num--)
{
! if (GET_CODE (operands[num]) == REG)
{
! lo_half[num] = gen_rtx_REG (SImode, REGNO (operands[num]));
! hi_half[num] = gen_rtx_REG (SImode, REGNO (operands[num]) + 1);
}
! else if (CONSTANT_P (operands[num]))
! split_double (operands[num], &lo_half[num], &hi_half[num]);
! else if (offsettable_memref_p (operands[num]))
! {
! lo_half[num] = operands[num];
! hi_half[num] = adj_offsettable_operand (operands[num], 4);
}
else
abort();
--- 3697,3716 ----
{
while (num--)
{
! rtx op = operands[num];
! if (GET_CODE (op) == REG)
{
! lo_half[num] = gen_rtx_REG (SImode, REGNO (op));
! hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1);
}
! else if (CONSTANT_P (op))
! split_double (op, &lo_half[num], &hi_half[num]);
! else if (offsettable_memref_p (op))
! {
! rtx lo_addr = XEXP (op, 0);
! rtx hi_addr = XEXP (adj_offsettable_operand (op, 4), 0);
! lo_half[num] = change_address (op, SImode, lo_addr);
! hi_half[num] = change_address (op, SImode, hi_addr);
}
else
abort();
Index: config/i386/i386.md
===================================================================
RCS file: /usr/local/cvs/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.1.3.7
diff -c -p -r1.1.3.7 i386.md
*** i386.md 1998/02/25 08:53:40 1.1.3.7
--- i386.md 1998/02/25 19:50:58
*************** byte_xor_operation:
*** 4241,4246 ****
--- 4241,4347 ----
""
"* return AS2 (xor%B0,%2,%0);")
+ ;; logical operations for DImode
+
+
+ (define_insn "anddi3"
+ [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
+ (and:DI (match_operand:DI 1 "general_operand" "%0,0,0iF,or,roiF,roiF")
+ (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
+ (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
+ ""
+ "#")
+
+ (define_insn "iordi3"
+ [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
+ (ior:DI (match_operand:DI 1 "general_operand" "%0,0,0iF,or,roiF,roiF")
+ (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
+ (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
+ ""
+ "#")
+
+ (define_insn "xordi3"
+ [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
+ (xor:DI (match_operand:DI 1 "general_operand" "%0,0,0iF,or,roiF,roiF")
+ (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")))
+ (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
+ ""
+ "#")
+
+ (define_split
+ [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o")
+ (match_operator:DI 4 "ix86_logical_operator"
+ [(match_operand:DI 1 "general_operand" "%0,0,0iF,or,roiF,roiF")
+ (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF")]))
+ (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))]
+ "reload_completed"
+ [(const_int 0)]
+ "
+ {
+ rtx low[3], high[3], xops[7], temp;
+ rtx (*genfunc)() = (GET_CODE (operands[4]) == AND ? gen_andsi3
+ : GET_CODE (operands[4]) == IOR ? gen_iorsi3
+ : GET_CODE (operands[4]) == XOR ? gen_xorsi3
+ : 0);
+
+ if (rtx_equal_p (operands[0], operands[2]))
+ {
+ temp = operands[1];
+ operands[1] = operands[2];
+ operands[2] = temp;
+ }
+
+ split_di (operands, 3, low, high);
+ if (!rtx_equal_p (operands[0], operands[1]))
+ {
+ xops[0] = high[0];
+ xops[1] = low[0];
+ xops[2] = high[1];
+ xops[3] = low[1];
+
+ if (GET_CODE (operands[0]) != MEM)
+ {
+ emit_insn (gen_movsi (xops[1], xops[3]));
+ emit_insn (gen_movsi (xops[0], xops[2]));
+ }
+ else
+ {
+ xops[4] = high[2];
+ xops[5] = low[2];
+ xops[6] = operands[3];
+ emit_insn (gen_movsi (xops[6], xops[3]));
+ emit_insn ((*genfunc) (xops[6], xops[6], xops[5]));
+ emit_insn (gen_movsi (xops[1], xops[6]));
+ emit_insn (gen_movsi (xops[6], xops[2]));
+ emit_insn ((*genfunc) (xops[6], xops[6], xops[4]));
+ emit_insn (gen_movsi (xops[0], xops[6]));
+ DONE;
+ }
+ }
+
+ if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
+ {
+ xops[0] = high[0];
+ xops[1] = low[0];
+ xops[2] = high[2];
+ xops[3] = low[2];
+ xops[4] = operands[3];
+
+ emit_insn (gen_movsi (xops[4], xops[3]));
+ emit_insn ((*genfunc) (xops[1], xops[1], xops[4]));
+ emit_insn (gen_movsi (xops[4], xops[2]));
+ emit_insn ((*genfunc) (xops[0], xops[0], xops[4]));
+ }
+
+ else
+ {
+ emit_insn ((*genfunc) (low[0], low[0], low[2]));
+ emit_insn ((*genfunc) (high[0], high[0], high[2]));
+ }
+
+ DONE;
+ }")
+
;;- negation instructions
(define_insn "negdi2"