@@ -1,3 +1,14 @@
+2011-07-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.c (ix86_simplify_base_disp): Renamed to ...
+ (ix86_simplify_base_index_disp): This. Handle index.
+ (ix86_simplify_base_disp): Updated.
+
+ * config/i386/i386.md (*lea_1_x32): Renamed to ...
+ (*lea_2_x32): This.
+ (*lea_2_zext_x32): New.
+ (X32 LEA zero-extend split): Likewise.
+
2011-07-06 H.J. Lu <hongjiu.lu@intel.com>
* config.gcc: Check with_multilib_list instead of enable_x32.
@@ -11054,6 +11054,17 @@ ix86_live_on_entry (bitmap regs)
(const (plus:SI (symbol_ref:SI ("A.193.2210"))
(const_int CONST))))
+ We also translate
+
+ (plus:SI (reg:SI 0 ax [orig:74 D.4067 ] [74])
+ (subreg:SI (plus:DI (reg/f:DI 7 sp)
+ (const_int 64 [0x40])) 0))
+
+ into
+
+ (plus:SI (reg:SI 0 ax [orig:74 D.4067 ] [74])
+ (plus:SI (reg/f:SI 7 sp) (const_int 64 [0x40])))
+
If PLUS is true, we also translate
(set (reg:SI 40 r11)
@@ -11072,10 +11083,11 @@ ix86_live_on_entry (bitmap regs)
*/
static void
-ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, bool plus)
+ix86_simplify_base_index_disp (rtx *base_p, rtx *index_p, rtx *disp_p,
+ bool plus)
{
rtx base = *base_p;
- rtx disp;
+ rtx disp, index, op0, op1;
if (!base || GET_MODE (base) != ptr_mode)
return;
@@ -11091,10 +11103,11 @@ ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, bool plus)
if (GET_CODE (base) == PLUS)
{
- rtx op0 = XEXP (base, 0);
- rtx op1 = XEXP (base, 1);
rtx addend;
+ op0 = XEXP (base, 0);
+ op1 = XEXP (base, 1);
+
if ((REG_P (op0)
|| (!plus
&& GET_CODE (op0) == PLUS
@@ -11160,6 +11173,25 @@ ix86_simplify_base_disp (rtx *base_p, rtx *disp_p, bool plus)
*base_p = base;
}
}
+ else if (!plus
+ && (disp == NULL_RTX || disp == const0_rtx)
+ && index_p
+ && (index = *index_p) != NULL_RTX
+ && GET_CODE (index) == SUBREG
+ && GET_MODE (index) == ptr_mode)
+ {
+ index = SUBREG_REG (index);
+ if (GET_CODE (index) == PLUS && GET_MODE (index) == Pmode)
+ {
+ op0 = XEXP (index, 0);
+ op1 = XEXP (index, 1);
+ if (REG_P (op0) && CONST_INT_P (op1))
+ {
+ *index_p = gen_rtx_REG (ptr_mode, REGNO (op0));
+ *disp_p = op1;
+ }
+ }
+ }
}
/* Extract the parts of an RTL expression that is a valid memory address
@@ -11208,12 +11240,14 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
{
op = XEXP (op, 0);
if (n == 1)
- ix86_simplify_base_disp (&op, &addends[0], false);
+ ix86_simplify_base_index_disp (&op, NULL,
+ &addends[0], false);
}
else if (n == 1
&& GET_CODE (op) == PLUS
&& GET_MODE (op) == ptr_mode)
- ix86_simplify_base_disp (&op, &addends[0], true);
+ ix86_simplify_base_index_disp (&op, NULL, &addends[0],
+ true);
}
}
while (GET_CODE (op) == PLUS);
@@ -11308,14 +11342,14 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
scale = INTVAL (scale_rtx);
}
- index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
+ if (TARGET_X32 && reload_completed)
+ ix86_simplify_base_index_disp (&base, &index, &disp, false);
/* Avoid useless 0 displacement. */
if (disp == const0_rtx && (base || index))
disp = NULL_RTX;
- if (TARGET_X32 && reload_completed)
- ix86_simplify_base_disp (&base, &disp, false);
+ index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base;
@@ -5477,18 +5477,20 @@
[(set_attr "type" "lea")
(set_attr "mode" "<MODE>")])
-(define_insn "*lea_1_x32"
+(define_insn "*lea_2"
[(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "no_seg_address_operand" "p"))]
- "TARGET_X32"
+ (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
+ "TARGET_64BIT"
"lea{l}\t{%a1, %0|%0, %a1}"
[(set_attr "type" "lea")
(set_attr "mode" "SI")])
-(define_insn "*lea_2"
+;; Place this after lea_2 since 64bit version doesn't have address
+;; size override.
+(define_insn "*lea_2_x32"
[(set (match_operand:SI 0 "register_operand" "=r")
- (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
- "TARGET_64BIT"
+ (match_operand:SI 1 "no_seg_address_operand" "p"))]
+ "TARGET_X32"
"lea{l}\t{%a1, %0|%0, %a1}"
[(set_attr "type" "lea")
(set_attr "mode" "SI")])
@@ -5502,6 +5504,15 @@
[(set_attr "type" "lea")
(set_attr "mode" "SI")])
+(define_insn "*lea_2_zext_x32"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (match_operand:SI 1 "no_seg_address_operand" "p")))]
+ "TARGET_X32"
+ "lea{l}\t{%a1, %k0|%k0, %a1}"
+ [(set_attr "type" "lea")
+ (set_attr "mode" "SI")])
+
(define_insn "*add<mode>_1"
[(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
(plus:SWI48
@@ -5908,6 +5919,19 @@
operands[2] = gen_lowpart (DImode, operands[2]);
})
+;; Convert lea to the lea pattern to avoid flags dependency.
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" ""))))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_X32
+ && reload_completed
+ && ix86_lea_for_add_ok (insn, operands)"
+ [(set (match_dup 0)
+ (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
+
(define_insn "*add<mode>_2"
[(set (reg FLAGS_REG)
(compare