aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2006-02-03 02:56:58 +0000
committerMike Stump <mrs@apple.com>2006-02-03 02:56:58 +0000
commitb12cef2cce90b7a027a1341512c5a51c96a5d95b (patch)
treebc775c748f96853eb728da990e89efd5bfc9facc
parent8524e68c62d7e0ad393d4ca8d3463f935c4f3bbc (diff)
2006-02-02 Mike Stump <mrs@apple.com>
Radar 4433955 * c-common.c (cw_asm_get_register_var): Remove static. (pointer_int_sum): Build up ARRAY_REFs when possible. * config/i386/i386.c (cw_canonicalize_bracket): Let forms with pointer types through to optimizer and print_operand. (cw_print_op): Likewise. * config/asm.h (cw_asm_get_register_var): Add. 2006-02-02 Mike Stump <mrs@apple.com> Radar 4433955 * gcc.apple/asm-block-37.c: Add. * g++.dg/asm-block-37.C: Add. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/apple-local-200502-branch@110532 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.apple-ppc10
-rw-r--r--gcc/c-common.c62
-rw-r--r--gcc/config/asm.h2
-rw-r--r--gcc/config/i386/i386.c30
-rw-r--r--gcc/testsuite/ChangeLog.apple-ppc6
-rw-r--r--gcc/testsuite/g++.dg/asm-block-37.C18
-rw-r--r--gcc/testsuite/gcc.apple/asm-block-37.c18
7 files changed, 141 insertions, 5 deletions
diff --git a/gcc/ChangeLog.apple-ppc b/gcc/ChangeLog.apple-ppc
index 4a637f4e1da..5650f15d14a 100644
--- a/gcc/ChangeLog.apple-ppc
+++ b/gcc/ChangeLog.apple-ppc
@@ -1,3 +1,13 @@
+2006-02-02 Mike Stump <mrs@apple.com>
+
+ Radar 4399388
+ * c-common.c (cw_asm_get_register_var): Remove static.
+ (pointer_int_sum): Build up ARRAY_REFs when possible.
+ * config/i386/i386.c (cw_canonicalize_bracket): Let forms with
+ pointer types through to optimizer and print_operand.
+ (cw_print_op): Likewise.
+ * config/asm.h (cw_asm_get_register_var): Add.
+
2006-02-01 Stuart Hastings <stuart@apple.com>
Radar 4429317
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 2320bb3cb6e..5129fa7a762 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -598,9 +598,6 @@ static char *cw_asm_buffer;
block, to unique global labels that the assembler will like. */
static GTY(()) varray_type cw_asm_labels;
static GTY(()) varray_type cw_asm_labels_uniq;
-
-static void cw_asm_get_register_var (tree, const char *, char *,
- unsigned, bool, cw_md_extra_info*);
static tree cw_asm_identifier (tree expr);
/* Return true iff the opcode wants memory to be stable. We arrange
@@ -2423,6 +2420,63 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
intop = convert (c_common_type_for_size (TYPE_PRECISION (sizetype),
TYPE_UNSIGNED (sizetype)), intop);
+ /* APPLE LOCAL begin CW asm blocks */
+ /* We want to canonicalize PLUS_EXPR into ARRAY_REF for data
+ pointers as ARRAY_REFs can be converted into RTL code without
+ introducing additional temporaries when not optimizing, which is
+ useful as otherwise when all registers are in use by the
+ assembly code, we can run reload out of registers. */
+
+ if (inside_cw_asm_block
+ && flag_ms_asms
+ && resultcode == PLUS_EXPR
+ && TREE_CODE (ptrop) == ADDR_EXPR
+ && !(TREE_CODE (TREE_TYPE (TREE_TYPE (ptrop))) == FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (ptrop))) == METHOD_TYPE))
+ {
+ tree type;
+ tree array = ptrop;
+ tree r;
+ tree new_i;
+
+ size_exp = convert (TREE_TYPE (intop), size_exp);
+
+ /* We have to ensure that when ARRAY_REF is used, it will
+ calculate the offset correctly as it is element based, and we
+ are byte based. */
+ new_i = fold (build_binary_op (CEIL_DIV_EXPR, intop, size_exp, 1));
+ if (build_binary_op (MULT_EXPR, new_i, size_exp, 1) == intop)
+ {
+ array = TREE_OPERAND (array, 0);
+ type = TREE_TYPE (TREE_TYPE (array));
+ if (TREE_CODE (type) != ARRAY_TYPE)
+ type = TYPE_MAIN_VARIANT (type);
+ r = build4 (ARRAY_REF, type, array, new_i, NULL_TREE, NULL_TREE);
+ TREE_READONLY (r)
+ |= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array)))
+ | TREE_READONLY (array));
+ TREE_SIDE_EFFECTS (r)
+ |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
+ | TREE_SIDE_EFFECTS (array));
+ TREE_THIS_VOLATILE (r)
+ |= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
+ /* This was added by rms on 16 Nov 91.
+ It fixes vol struct foo *a; a->elts[1]
+ in an inline function.
+ Hope it doesn't break something else. */
+ | TREE_THIS_VOLATILE (array));
+ r = fold (r);
+ r = build1 (ADDR_EXPR, result_type, r);
+ r = fold (r);
+ return r;
+ }
+ }
+
+ /* foo+4 is &(char*)foo + 4 in MS asm land, not foo + 4*(elt size). */
+ if (inside_cw_asm_block && flag_ms_asms)
+ size_exp = integer_one_node;
+ /* APPLE LOCAL end CW asm blocks */
+
/* Replace the integer argument with a suitable product by the object size.
Do this multiplication as signed, then convert to the appropriate
pointer type (actually unsigned integral). */
@@ -7316,7 +7370,7 @@ print_cw_asm_operand (char *buf, tree arg, unsigned argnum,
%1, etc in the asm string. MUST_BE_REG is true, iff we know the
operand must be a register. */
-static void
+void
cw_asm_get_register_var (tree var, const char *modifier, char *buf, unsigned argnum,
bool must_be_reg, cw_md_extra_info *e)
{
diff --git a/gcc/config/asm.h b/gcc/config/asm.h
index 3e1b371b2d5..3c3c2e389b5 100644
--- a/gcc/config/asm.h
+++ b/gcc/config/asm.h
@@ -75,4 +75,6 @@ extern bool cw_is_prefix (tree);
extern void cw_skip_to_eol (void);
extern void cw_force_constraint (const char *c, cw_md_extra_info *e);
extern tree cw_ptr_conv (tree type, tree exp);
+extern void cw_asm_get_register_var (tree var, const char *modifier, char *buf,
+ unsigned argnum, bool must_be_reg, cw_md_extra_info *e);
#endif
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index c0f1b3db664..21228d72185 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -18540,6 +18540,14 @@ cw_canonicalize_bracket (tree arg)
if (TREE_OPERAND (arg, 1) == NULL_TREE)
{
tree arg0 = TREE_OPERAND (arg, 0);
+ /* Let the normal operand printer output this without trying to
+ decompose it into parts so that things like (%esp + 20) + 4
+ can be output as 24(%esp) by the optimizer instead of 4(%0)
+ and burning an "R" with (%esp + 20). */
+ if (TREE_TYPE (arg0)
+ && POINTER_TYPE_P (TREE_TYPE (arg0)))
+ return;
+
if (TREE_CODE (arg0) == PLUS_EXPR)
{
if (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
@@ -18581,7 +18589,8 @@ cw_canonicalize_bracket (tree arg)
tree arg0 = TREE_OPERAND (arg, 0);
tree arg1 = TREE_OPERAND (arg, 1);
- while ((TREE_CODE (arg1) == PLUS_EXPR || TREE_CODE (arg1) == MINUS_EXPR)
+ while (arg1
+ && (TREE_CODE (arg1) == PLUS_EXPR || TREE_CODE (arg1) == MINUS_EXPR)
&& cw_is_offset (TREE_OPERAND (arg1, 1)))
{
tree swp = TREE_OPERAND (arg1, 0);
@@ -18810,6 +18819,24 @@ cw_print_op (char *buf, tree arg, unsigned argnum, tree *uses,
op0 = NULL_TREE;
}
+ if (op1 == NULL_TREE
+ && op3 == NULL_TREE
+ && op2
+ && TREE_TYPE (op2)
+ && POINTER_TYPE_P (TREE_TYPE (op2)))
+ {
+ /* Let the normal operand printer output this without trying to
+ decompose it into parts so that things like (%esp + 20) + 4
+ can be output as 24(%esp) by the optimizer instead of 4(%0)
+ and burning an "R" with (%esp + 20). */
+ cw_force_constraint ("m", e);
+ op2 = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (op2)), op2);
+ op2 = fold (op2);
+ cw_asm_get_register_var (op2, "", buf, argnum, must_be_reg, e);
+ cw_force_constraint (0, e);
+ break;
+ }
+
if (ASSEMBLER_DIALECT == ASM_INTEL)
strcat (buf, "[");
@@ -18893,6 +18920,7 @@ cw_print_op (char *buf, tree arg, unsigned argnum, tree *uses,
}
else
strcat (buf, "0");
+
if (ASSEMBLER_DIALECT == ASM_INTEL)
strcat (buf, "]");
if (ASSEMBLER_DIALECT == ASM_INTEL)
diff --git a/gcc/testsuite/ChangeLog.apple-ppc b/gcc/testsuite/ChangeLog.apple-ppc
index 375506d99a5..05c2e4ce1d4 100644
--- a/gcc/testsuite/ChangeLog.apple-ppc
+++ b/gcc/testsuite/ChangeLog.apple-ppc
@@ -1,3 +1,9 @@
+2006-02-02 Mike Stump <mrs@apple.com>
+
+ Radar 4399388
+ * gcc.apple/asm-block-37.c: Add.
+ * g++.dg/asm-block-37.C: Add.
+
2006-02-01 Devang Patel <dpatel@apple.com>
Radar 4208007
diff --git a/gcc/testsuite/g++.dg/asm-block-37.C b/gcc/testsuite/g++.dg/asm-block-37.C
new file mode 100644
index 00000000000..a3961146575
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asm-block-37.C
@@ -0,0 +1,18 @@
+/* APPLE LOCAL file CW asm blocks */
+/* { dg-do assemble { target i?86*-*-darwin* } } */
+/* { dg-options { -fasm-blocks -msse3 -O1 } } */
+/* Radar 4399388 */
+
+void X2_Interpolate2DNoPinFourCol(const char *sPtr,
+ int sRowBytes)
+{
+ int rowfraclo[2];
+ asm {
+ movd [rowfraclo+4], mm6
+ // mov esi, edx
+ movzx ebx, byte ptr [esi + eax]
+ movq mm2, [edx+32]
+ mov ecx, ecx
+ mov edi, edi
+ }
+}
diff --git a/gcc/testsuite/gcc.apple/asm-block-37.c b/gcc/testsuite/gcc.apple/asm-block-37.c
new file mode 100644
index 00000000000..a3961146575
--- /dev/null
+++ b/gcc/testsuite/gcc.apple/asm-block-37.c
@@ -0,0 +1,18 @@
+/* APPLE LOCAL file CW asm blocks */
+/* { dg-do assemble { target i?86*-*-darwin* } } */
+/* { dg-options { -fasm-blocks -msse3 -O1 } } */
+/* Radar 4399388 */
+
+void X2_Interpolate2DNoPinFourCol(const char *sPtr,
+ int sRowBytes)
+{
+ int rowfraclo[2];
+ asm {
+ movd [rowfraclo+4], mm6
+ // mov esi, edx
+ movzx ebx, byte ptr [esi + eax]
+ movq mm2, [edx+32]
+ mov ecx, ecx
+ mov edi, edi
+ }
+}