@@ -1,3 +1,10 @@
+2011-02-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/47744
+ * config/i386/i386.c (ix86_simplify_base_disp): New.
+ (ix86_decompose_address): Use it for TARGET_X32 after reload
+ is completed.
+
2011-02-17 H.J. Lu <hongjiu.lu@intel.com>
PR target/47715
@@ -11604,6 +11604,70 @@ ix86_live_on_entry (bitmap regs)
}
}
+/* For TARGET_X32, IRA may generate
+
+ (set (reg:SI 40 r11)
+ (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
+ (const_int 8))
+ (subreg:SI (plus:DI (reg/f:DI 7 sp)
+ (const_int CONST1)) 0))
+ (const_int CONST2)))
+
+ We translate it into
+
+ (set (reg:SI 40 r11)
+ (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
+ (const_int 8))
+ (reg/f:SI 7 sp))
+ (const_int [CONST1 + CONST2])))
+ */
+
+static void
+ix86_simplify_base_disp (rtx *base_p, rtx *disp_p)
+{
+ rtx base = *base_p;
+ rtx disp;
+
+ if (!base || GET_MODE (base) != ptr_mode)
+ return;
+
+ disp = *disp_p;
+ if (disp != NULL_RTX
+ && disp != const0_rtx
+ && !CONST_INT_P (disp))
+ return;
+
+ if (GET_CODE (base) == SUBREG)
+ base = SUBREG_REG (base);
+
+ if (GET_CODE (base) == PLUS)
+ {
+ rtx op0 = XEXP (base, 0);
+ rtx op1 = XEXP (base, 1);
+ rtx addend;
+
+ if (REG_P (op0) && CONST_INT_P (op1))
+ {
+ base = op0;
+ addend = op1;
+ }
+ else if (REG_P (op1) && CONST_INT_P (op0))
+ {
+ base = op1;
+ addend = op0;
+ }
+ else
+ return;
+
+ if (disp == NULL_RTX || disp == const0_rtx)
+ *disp_p = addend;
+ else
+ *disp_p = GEN_INT (INTVAL (disp) + INTVAL (addend));
+
+ *base_p = gen_rtx_REG (ptr_mode, REGNO (base));
+ }
+}
+
/* Extract the parts of an RTL expression that is a valid memory address
for an instruction. Return 0 if the structure of the address is
grossly off. Return -1 if the address contains ASHIFT, so it is not
@@ -11641,6 +11705,17 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
return 0;
addends[n++] = XEXP (op, 1);
op = XEXP (op, 0);
+ /* Support 32bit address in x32 mode. */
+ if (TARGET_X32
+ && reload_completed
+ && GET_CODE (op) == ZERO_EXTEND
+ && GET_MODE (op) == Pmode
+ && GET_CODE (XEXP (op, 0)) == PLUS)
+ {
+ op = XEXP (op, 0);
+ if (n == 1)
+ ix86_simplify_base_disp (&op, &addends[0]);
+ }
}
while (GET_CODE (op) == PLUS);
if (n >= 4)
@@ -11734,69 +11809,16 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
scale = INTVAL (scale_rtx);
}
- base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base;
index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
/* Avoid useless 0 displacement. */
if (disp == const0_rtx && (base || index))
disp = NULL_RTX;
- /* For TARGET_X32, IRA may generate
-
- (set (reg:SI 40 r11)
- (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
- (const_int 8))
- (subreg:SI (plus:DI (reg/f:DI 7 sp)
- (const_int CONST1)) 0))
- (const_int CONST2)))
-
- We translate it into
-
- (set (reg:SI 40 r11)
- (plus:SI (plus:SI (mult:SI (reg:SI 1 dx)
- (const_int 8))
- (reg/f:SI 7 sp))
- (const_int [CONST1 + CONST2])))
- */
+ if (TARGET_X32 && reload_completed)
+ ix86_simplify_base_disp (&base, &disp);
- if (TARGET_X32
- && base
- && GET_MODE (base) == ptr_mode
- && GET_CODE (base) == SUBREG
- && (disp == NULL_RTX
- || disp == const0_rtx
- || CONST_INT_P (disp))
- && GET_CODE (base_reg) == PLUS)
- {
- rtx op0 = XEXP (base_reg, 0);
- rtx op1 = XEXP (base_reg, 1);
- rtx addend;
- unsigned int base_regno;
-
- if (REG_P (op0) && CONST_INT_P (op1))
- {
- base_reg = op0;
- addend = op1;
- }
- else if (REG_P (op1) && CONST_INT_P (op0))
- {
- base_reg = op1;
- addend = op0;
- }
- else
- return 0;
-
- base_regno = REGNO (base_reg);
- if (base_regno != SP_REG && base_regno != BP_REG)
- return 0;
-
- if (disp == NULL_RTX || disp == const0_rtx)
- disp = addend;
- else
- disp = GEN_INT (INTVAL (disp) + INTVAL (addend));
-
- base = gen_rtx_REG (ptr_mode, base_regno);
- }
+ base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base;
/* Allow arg pointer and stack pointer as index if there is not scaling. */
if (base_reg && index_reg && scale == 1
@@ -1,3 +1,8 @@
+2011-02-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/47744
+ * gcc.dg/torture/pr47744-2.c: New.
+
2011-02-17 H.J. Lu <hongjiu.lu@intel.com>
PR target/47715
new file mode 100644
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-std=gnu99" } */
+
+typedef long unsigned int size_t;
+typedef long int ssize_t;
+typedef ssize_t index_type;
+typedef __int128_t GFC_INTEGER_16;
+typedef struct descriptor_dimension
+{
+ index_type _stride;
+ index_type _lbound;
+ index_type _ubound;
+}
+descriptor_dimension;
+typedef struct { GFC_INTEGER_16 *data; size_t offset; index_type dtype; descriptor_dimension dim[7];} gfc_array_i16;
+void
+matmul_i16 (gfc_array_i16 * const restrict retarray,
+ gfc_array_i16 * const restrict a,
+ GFC_INTEGER_16 bbase_yn)
+{
+ GFC_INTEGER_16 * restrict dest;
+ index_type rxstride, rystride;
+ index_type x, y, n, count, xcount;
+ GFC_INTEGER_16 * restrict dest_y;
+ GFC_INTEGER_16 s;
+ const GFC_INTEGER_16 * restrict abase_n;
+ rxstride = ((retarray)->dim[0]._stride);
+ rystride = ((retarray)->dim[1]._stride);
+ xcount = ((a)->dim[0]._ubound + 1 - (a)->dim[0]._lbound);
+ dest = retarray->data;
+ dest_y = &dest[y*rystride];
+ for (x = 0; x < xcount; x++)
+ dest_y[x] += abase_n[x] * bbase_yn;
+ for (x = 0; x < xcount; x++)
+ {
+ for (n = 0; n < count; n++)
+ dest_y[x*rxstride] = (GFC_INTEGER_16) 0;
+ }
+}