aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2006-02-10 00:40:27 +0000
committerMike Stump <mrs@apple.com>2006-02-10 00:40:27 +0000
commitcaed2aa822ba4585538c5ec9ee895de95bf3b142 (patch)
tree198f858986cb8634e52f02a148493e28d24b4dab
parent13717060a8feb0ce58e063114b46307f9623d625 (diff)
Radar 4399388apple/gcc-5321
* config/i386/i386.c (cw_canonicalize_bracket_1): Add. (cw_canonicalize_bracket): Improve. (cw_is_offset): Add NEGATE_EXPR support. (cw_print_op): Improve BRACKET_EXPR handling. * c-common.c (print_cw_asm_operand): Add parens around NEGATE_EXPR. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/apple-local-200502-branch@110828 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.apple-ppc10
-rw-r--r--gcc/c-common.c3
-rw-r--r--gcc/config/i386/i386.c271
-rw-r--r--gcc/testsuite/ChangeLog.apple-ppc6
-rw-r--r--gcc/testsuite/g++.dg/asm-block-42.C11
-rw-r--r--gcc/testsuite/gcc.apple/asm-block-42.c11
6 files changed, 182 insertions, 130 deletions
diff --git a/gcc/ChangeLog.apple-ppc b/gcc/ChangeLog.apple-ppc
index a2e05c90892..93f773990c4 100644
--- a/gcc/ChangeLog.apple-ppc
+++ b/gcc/ChangeLog.apple-ppc
@@ -1,3 +1,13 @@
+2006-02-09 Mike Stump <mrs@apple.com>
+
+ Radar 4399388
+ * config/i386/i386.c (cw_canonicalize_bracket_1): Add.
+ (cw_canonicalize_bracket): Improve.
+ (cw_is_offset): Add NEGATE_EXPR support.
+ (cw_print_op): Improve BRACKET_EXPR handling.
+ * c-common.c (print_cw_asm_operand): Add parens around
+ NEGATE_EXPR.
+
2006-02-08 Stuart Hastings <stuart@apple.com>
Radar 4176531 (revised version of 27jan06 patch)
diff --git a/gcc/c-common.c b/gcc/c-common.c
index a284c230ddf..1b010de0d0c 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -7344,9 +7344,10 @@ print_cw_asm_operand (char *buf, tree arg, unsigned argnum,
break;
case NEGATE_EXPR:
- strcat (buf, "-");
+ strcat (buf, "-(");
print_cw_asm_operand (buf, TREE_OPERAND (arg, 0), argnum, uses,
must_be_reg, must_not_be_reg, e);
+ strcat (buf, ")");
break;
case INDIRECT_REF:
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 2fca38d6b87..74819970205 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -18855,81 +18855,141 @@ cw_is_offset (tree v)
&& cw_is_offset (TREE_OPERAND (v, 0))
&& cw_is_offset (TREE_OPERAND (v, 1)))
return true;
-
+ if (TREE_CODE (v) == NEGATE_EXPR
+ && cw_is_offset (TREE_OPERAND (v, 0)))
+ return true;
+
return false;
}
/* We canonicalize the inputs form of bracket expressions as the input
- forms are less constrained than what the assembler will accept. */
+ forms are less constrained than what the assembler will accept.
+
+ TOP is the top of the canonical tree we're generating and
+ TREE_OPERAND (, 0) is the offset portion of the expression. ARGP
+ points to the current part of the tree we're walking.
+
+ Thee tranformations we do:
+
+ (A+O) ==> A
+ (A-O) ==> A
+ (O+A) ==> A
+
+ where O are offset expressions. */
static void
-cw_canonicalize_bracket (tree arg)
+cw_canonicalize_bracket_1 (tree* argp, tree top)
{
- if (TREE_OPERAND (arg, 1) == NULL_TREE)
+ tree arg = *argp;
+ tree offset = TREE_OPERAND (top, 0);
+ tree arg0, arg1;
+
+ switch (TREE_CODE (arg))
{
- 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;
+ case BRACKET_EXPR:
+ case PLUS_EXPR:
+ arg0 = TREE_OPERAND (arg, 0);
+ arg1 = TREE_OPERAND (arg, 1);
- if (TREE_CODE (arg0) == PLUS_EXPR)
+ if (cw_is_offset (arg0))
{
- if (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
- {
- tree op1 = cw_build_bracket (TREE_OPERAND (arg0, 1), NULL_TREE);
- TREE_OPERAND (arg, 0) = op1;
- TREE_OPERAND (arg, 1) = TREE_OPERAND (arg0, 0);
- }
- else
- {
- tree op1 = cw_build_bracket (TREE_OPERAND (arg0, 1), NULL_TREE);
- TREE_OPERAND (arg, 0) = op1;
- TREE_OPERAND (arg, 1) = TREE_OPERAND (arg0, 0);
- }
+ if (offset != integer_zero_node)
+ arg0 = build2 (PLUS_EXPR, void_type_node, arg0, offset);
+ TREE_OPERAND (top, 0) = arg0;
+
+ *argp = arg1;
+ if (arg1)
+ cw_canonicalize_bracket_1 (argp, top);
+ }
+ else if (arg1 && cw_is_offset (arg1))
+ {
+ if (offset != integer_zero_node)
+ arg1 = build2 (PLUS_EXPR, void_type_node, arg1, offset);
+ TREE_OPERAND (top, 0) = arg1;
+ *argp = arg0;
+ cw_canonicalize_bracket_1 (argp, top);
}
- else if (TREE_CODE (arg0) == MINUS_EXPR)
+ else
{
- tree val = TREE_OPERAND (arg0, 1);
- if (TREE_CODE (val) == INTEGER_CST)
+ cw_canonicalize_bracket_1 (&TREE_OPERAND (arg, 0), top);
+ if (arg1)
+ cw_canonicalize_bracket_1 (&TREE_OPERAND (arg, 1), top);
+ if (TREE_OPERAND (arg, 0) == NULL_TREE)
{
- val = fold (build1 (NEGATE_EXPR,
- TREE_TYPE (val),
- val));
- TREE_OPERAND (arg, 0) = cw_build_bracket (val, NULL_TREE);
- TREE_OPERAND (arg, 1) = TREE_OPERAND (arg0, 0);
+ if (TREE_OPERAND (arg, 1))
+ {
+ TREE_OPERAND (arg, 0) = TREE_OPERAND (arg, 1);
+ TREE_OPERAND (arg, 1) = NULL_TREE;
+ }
+ else
+ *argp = NULL_TREE;
}
}
- }
+ break;
- if (TREE_CODE (arg) != BRACKET_EXPR)
- return;
+ case MINUS_EXPR:
+ cw_canonicalize_bracket_1 (&TREE_OPERAND (arg, 0), top);
+ arg0 = TREE_OPERAND (arg, 0);
+ arg1 = TREE_OPERAND (arg, 1);
+ if (cw_is_offset (arg1))
+ {
+ offset = TREE_OPERAND (top, 0);
+ if (offset == integer_zero_node)
+ arg1 = fold (build1 (NEGATE_EXPR,
+ TREE_TYPE (arg1),
+ arg1));
+ else
+ arg1 = build2 (MINUS_EXPR, void_type_node, offset, arg1);
+ TREE_OPERAND (top, 0) = arg1;
+ *argp = arg0;
+ cw_canonicalize_bracket_1 (argp, top);
+ }
+ break;
+ default:
+ break;
+ }
+}
- if (cw_is_offset (TREE_OPERAND (arg, 0)))
- TREE_OPERAND (arg, 0) = cw_build_bracket (TREE_OPERAND (arg, 0), NULL_TREE);
+/* We canonicalize the inputs form of bracket expressions as the input
+ forms are less constrained than what the assembler will accept. */
- if (TREE_CODE (TREE_OPERAND (arg, 0)) == BRACKET_EXPR
- && cw_is_offset (TREE_OPERAND (TREE_OPERAND (arg, 0), 0)))
- {
- tree arg0 = TREE_OPERAND (arg, 0);
- tree arg1 = TREE_OPERAND (arg, 1);
+static void
+cw_canonicalize_bracket (tree arg)
+{
+ gcc_assert (TREE_CODE (arg) == BRACKET_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);
- TREE_OPERAND (arg1, 0) = TREE_OPERAND (arg0, 0);
- TREE_OPERAND (arg0, 0) = arg1;
- TREE_OPERAND (arg, 1) = swp;
+ /* 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_OPERAND (arg, 1) == NULL_TREE
+ && TREE_TYPE (TREE_OPERAND (arg, 0))
+ && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg, 0))))
+ return;
- arg0 = TREE_OPERAND (arg, 0);
- arg1 = TREE_OPERAND (arg, 1);
- }
+ /* Ensure that 0 is an offset */
+ if (TREE_OPERAND (arg, 0)
+ && cw_is_offset (TREE_OPERAND (arg, 0)))
+ {
+ /* we win if 0 is an offset already. */
+ }
+ else if (TREE_OPERAND (arg, 1) == NULL_TREE)
+ {
+ /* Move 0 to 1, if 1 is empty and 0 isn't already an offset */
+ TREE_OPERAND (arg, 1) = TREE_OPERAND (arg, 0);
+ TREE_OPERAND (arg, 0) = integer_zero_node;
}
+ else
+ {
+ tree swp;
+ /* Just have to force it now */
+ swp = cw_build_bracket (TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
+ TREE_OPERAND (arg, 0) = integer_zero_node;
+ TREE_OPERAND (arg, 1) = swp;
+ }
+
+ if (TREE_OPERAND (arg, 1))
+ cw_canonicalize_bracket_1 (&TREE_OPERAND (arg, 1), arg);
}
/* We canonicalize the instruction by swapping operands and rewritting
@@ -19132,19 +19192,35 @@ cw_print_op (char *buf, tree arg, unsigned argnum, tree *uses,
{
case BRACKET_EXPR:
{
- tree op2 = TREE_OPERAND (arg, 0);
- tree op3 = TREE_OPERAND (arg, 1);
- tree op0 = NULL_TREE, op1 = NULL_TREE;
+ tree op1 = TREE_OPERAND (arg, 0);
+ tree op2 = TREE_OPERAND (arg, 1);
+ tree op0 = NULL_TREE, op3 = NULL_TREE;
tree scale = NULL_TREE;
+ if (op2 == NULL_TREE
+ && TREE_TYPE (op1)
+ && POINTER_TYPE_P (TREE_TYPE (op1)))
+ {
+ /* 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);
+ op1 = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (op1)), op1);
+ op1 = fold (op1);
+ cw_asm_get_register_var (op1, "", buf, argnum, must_be_reg, e);
+ cw_force_constraint (0, e);
+ break;
+ }
+
if (TREE_CODE (op2) == BRACKET_EXPR)
{
- op1 = TREE_OPERAND (op2, 0);
- op2 = TREE_OPERAND (op2, 1);
- if (TREE_CODE (op1) == BRACKET_EXPR)
+ op3 = TREE_OPERAND (op2, 1);
+ op2 = TREE_OPERAND (op2, 0);
+ if (TREE_CODE (op2) == BRACKET_EXPR)
{
- op0 = TREE_OPERAND (op1, 1);
- op1 = TREE_OPERAND (op1, 0);
+ op0 = TREE_OPERAND (op2, 1);
+ op2 = TREE_OPERAND (op2, 0);
}
}
if (op0)
@@ -19156,40 +19232,9 @@ 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, "[");
- if (op3 && cw_is_offset (op3))
- {
- tree tmp = op1;
- op1 = op3;
- op3 = tmp;
- }
- else if (cw_is_offset (op2))
- {
- tree tmp = op1;
- op1 = op2;
- op2 = op3;
- op3 = tmp;
- }
if (op3 == NULL_TREE
&& op2 && TREE_CODE (op2) == PLUS_EXPR)
{
@@ -19203,33 +19248,6 @@ cw_print_op (char *buf, tree arg, unsigned argnum, tree *uses,
op3 = op2;
op2 = t;
}
- if (op1 == NULL_TREE)
- {
- if (op2 && TREE_CODE (op2) == PLUS_EXPR
- && cw_is_offset (TREE_OPERAND (op2, 0)))
- {
- op1 = TREE_OPERAND (op2, 0);
- op2 = TREE_OPERAND (op2, 1);
- }
- else if (op2 && TREE_CODE (op2) == PLUS_EXPR
- && cw_is_offset (TREE_OPERAND (op2, 1)))
- {
- op1 = TREE_OPERAND (op2, 1);
- op2 = TREE_OPERAND (op2, 0);
- }
- else if (op3 && TREE_CODE (op3) == PLUS_EXPR
- && cw_is_offset (TREE_OPERAND (op3, 0)))
- {
- op1 = TREE_OPERAND (op3, 0);
- op3 = TREE_OPERAND (op3, 1);
- }
- else if (op3 && TREE_CODE (op3) == PLUS_EXPR
- && cw_is_offset (TREE_OPERAND (op3, 1)))
- {
- op1 = TREE_OPERAND (op3, 1);
- op3 = TREE_OPERAND (op3, 0);
- }
- }
/* Crack out the scaling, if any. */
if (ASSEMBLER_DIALECT == ASM_ATT
@@ -19248,15 +19266,10 @@ cw_print_op (char *buf, tree arg, unsigned argnum, tree *uses,
}
}
- if (op1)
- {
- e->as_immediate = true;
- print_cw_asm_operand (buf, op1, argnum, uses,
- must_be_reg, must_not_be_reg, e);
- e->as_immediate = false;
- }
- else
- strcat (buf, "0");
+ e->as_immediate = true;
+ print_cw_asm_operand (buf, op1, argnum, uses,
+ must_be_reg, must_not_be_reg, e);
+ e->as_immediate = false;
if (ASSEMBLER_DIALECT == ASM_INTEL)
strcat (buf, "]");
diff --git a/gcc/testsuite/ChangeLog.apple-ppc b/gcc/testsuite/ChangeLog.apple-ppc
index f6dac617399..b7533c60211 100644
--- a/gcc/testsuite/ChangeLog.apple-ppc
+++ b/gcc/testsuite/ChangeLog.apple-ppc
@@ -1,3 +1,9 @@
+2006-02-09 Mike Stump <mrs@apple.com>
+
+ Radar 4399388
+ * gcc.apple/asm-block-42.c: Add.
+ * g++.dg/asm-block-42.C: Add.
+
2006-02-08 Mike Stump <mrs@apple.com>
Radar 4429851
diff --git a/gcc/testsuite/g++.dg/asm-block-42.C b/gcc/testsuite/g++.dg/asm-block-42.C
new file mode 100644
index 00000000000..3f9c674f4d5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asm-block-42.C
@@ -0,0 +1,11 @@
+/* APPLE LOCAL file CW asm blocks */
+/* { dg-do assemble { target i?86*-*-darwin* } } */
+/* { dg-options { -fasm-blocks -msse3 } } */
+/* Radar 4399388 */
+
+void foo() {
+ asm movd [edi-4][edx], mm3
+
+ asm movd mm1, [esi + 4 - 1];
+ asm movd mm2, [esi + 4 + 2];
+}
diff --git a/gcc/testsuite/gcc.apple/asm-block-42.c b/gcc/testsuite/gcc.apple/asm-block-42.c
new file mode 100644
index 00000000000..3f9c674f4d5
--- /dev/null
+++ b/gcc/testsuite/gcc.apple/asm-block-42.c
@@ -0,0 +1,11 @@
+/* APPLE LOCAL file CW asm blocks */
+/* { dg-do assemble { target i?86*-*-darwin* } } */
+/* { dg-options { -fasm-blocks -msse3 } } */
+/* Radar 4399388 */
+
+void foo() {
+ asm movd [edi-4][edx], mm3
+
+ asm movd mm1, [esi + 4 - 1];
+ asm movd mm2, [esi + 4 + 2];
+}