aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2005-11-11 00:56:21 +0000
committerMike Stump <mrs@apple.com>2005-11-11 00:56:21 +0000
commit447e7eaf8ef1ee08147519687dc50cdfbffec65f (patch)
treea38cb7c2b6f228098c49416c6112a3e08e5abdff
parent23638de8168aea5f1c4de820067548581d147bbb (diff)
4300193 MS asm: unable to find register to spillapple/gcc-5303
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/apple-local-200502-branch@106773 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.apple-ppc11
-rw-r--r--gcc/c-common.c151
-rw-r--r--gcc/config/i386/i386.h2
-rw-r--r--gcc/testsuite/ChangeLog.apple-ppc6
-rw-r--r--gcc/testsuite/g++.dg/asm-block-33.C27
-rw-r--r--gcc/testsuite/gcc.apple/asm-block-33.c27
6 files changed, 223 insertions, 1 deletions
diff --git a/gcc/ChangeLog.apple-ppc b/gcc/ChangeLog.apple-ppc
index 2999f6c82f7..4ef3372f316 100644
--- a/gcc/ChangeLog.apple-ppc
+++ b/gcc/ChangeLog.apple-ppc
@@ -1,3 +1,14 @@
+2005-11-10 Mike Stump <mrs@apple.com>
+
+ Radar 4300193
+ * c-common.c (cw_num_constraints): Add.
+ (cw_set_constraints): Add.
+ (cw_asm_stmt): Call cw_set_constraints to update contraints.
+ (cw_type_for): Add.
+ (print_cw_asm_operand): Transform registers into VAR_DECLs for x86.
+
+ * config/i386/i386.h (TARGET_CW_OP_CONSTRAINT): xchg's 2nd arg is an update.
+
2005-11-10 Dale Johannesen <dalej@apple.com>
Radar 4321079
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 63e3d17c800..370fd9f8978 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -6604,6 +6604,99 @@ cw_is_prefix (tree ARG_UNUSED (id))
return false;
}
+/* Find the number of constraints in any constraints string that has a
+ ",", as it must have the correct number of constraints, otherwise
+ return 0. The ones with no "," have been generated, and only every
+ have one constraint. */
+
+static int
+cw_num_constraints (tree inputs, tree outputs)
+{
+ int num = 0;
+ while (inputs)
+ {
+ const char *constraints = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (inputs)));
+ while (*++constraints)
+ if (constraints[0] == ',')
+ ++num;
+ if (num)
+ return num+1;
+ inputs = TREE_CHAIN (inputs);
+ }
+ while (outputs)
+ {
+ const char *constraints = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (outputs)));
+ while (*++constraints)
+ if (constraints[0] == ',')
+ ++num;
+ outputs = TREE_CHAIN (outputs);
+ if (num)
+ return num+1;
+ }
+ return num;
+}
+
+/* Add alternatives to all constraints that don't have any
+ alternatives so that all constraints have the same number of
+ constraints. Thia ia necessary, as sometimes we force certain
+ operands to have a given contraint, but when we do that no
+ alternatives are ever given. */
+
+static void
+cw_set_constraints (int num, tree inputs, tree outputs)
+{
+ if (num < 2)
+ return;
+
+ while (inputs)
+ {
+ int i;
+ const char *constraints = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (inputs)));
+
+ if (strchr (constraints, ',') == 0)
+ {
+ char *buf = alloca (strlen (constraints) * num + num);
+ char *p = buf;
+ while (*constraints == '+' || *constraints == '&' || *constraints == '=')
+ {
+ *p++ = *constraints++;
+ }
+ for (i = 0; i < num; ++i)
+ {
+ p = stpcpy (p, constraints);
+ *p++ = ',';
+ }
+ p[-1] = 0;
+ TREE_VALUE (TREE_PURPOSE (inputs)) = build_string (strlen (buf), buf);
+ }
+ inputs = TREE_CHAIN (inputs);
+ }
+
+ while (outputs)
+ {
+ int i;
+ const char *constraints = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (outputs)));
+
+ if (strchr (constraints, ',') == 0)
+ {
+ char *buf = alloca (strlen (constraints) * num + num);
+ char *p = buf;
+ while (*constraints == '+' || *constraints == '&' || *constraints == '=')
+ {
+ *p++ = *constraints++;
+ }
+ for (i = 0; i < num; ++i)
+ {
+ p = stpcpy (p, constraints);
+ *p++ = ',';
+ }
+ p[-1] = 0;
+ TREE_VALUE (TREE_PURPOSE (outputs)) = build_string (strlen (buf), buf);
+ }
+ outputs = TREE_CHAIN (outputs);
+ }
+}
+
/* Build an asm statement from CW-syntax bits. */
tree
cw_asm_stmt (tree expr, tree args, int lineno)
@@ -6773,6 +6866,9 @@ cw_asm_stmt (tree expr, tree args, int lineno)
for (tail = inputs; tail; tail = TREE_CHAIN (tail))
TREE_VALUE (tail) = cw_asm_default_function_conversion (TREE_VALUE (tail));
+ /* Readjust all the constraints so that the number of alternatives match. */
+ cw_set_constraints (cw_num_constraints (inputs, outputs), inputs, outputs);
+
/* Treat as volatile always. */
stmt = build_stmt (ASM_EXPR, sexpr, outputs, inputs, clobbers, uses);
ASM_VOLATILE_P (stmt) = 1;
@@ -6854,6 +6950,32 @@ cw_force_constraint (const char *c, cw_md_extra_info *e)
e->dat[e->num].constraint = c;
}
+#if defined(TARGET_386)
+static tree
+cw_type_for (tree arg)
+{
+ tree type = NULL_TREE;
+
+ if (IDENTIFIER_LENGTH (arg) > 2
+ && IDENTIFIER_POINTER (arg)[0] == '%')
+ {
+ enum machine_mode mode = VOIDmode;
+ if (IDENTIFIER_POINTER (arg)[1] == 'e')
+ mode = SImode;
+ else if (/* IDENTIFIER_POINTER (arg)[2] == 'h'
+ || */ IDENTIFIER_POINTER (arg)[2] == 'l')
+ mode = QImode;
+ else if (IDENTIFIER_POINTER (arg)[2] == 'x')
+ mode = HImode;
+
+ if (mode != VOIDmode)
+ type = c_common_type_for_mode (mode, 1);
+ }
+
+ return type;
+}
+#endif
+
/* Print an operand according to its tree type. MUST_BE_REG is true,
iff we know the operand must be a register. MUST_NOT_BE_REG is true,
iff we know the operand must not be a register. */
@@ -6890,6 +7012,35 @@ print_cw_asm_operand (char *buf, tree arg, unsigned argnum,
break;
case IDENTIFIER_NODE:
+#if defined(TARGET_386)
+ {
+ int regno = decode_reg_name (IDENTIFIER_POINTER (arg));
+ if (regno >= 0)
+ {
+ tree decl = NULL_TREE;
+
+ /* decl = cw_regs[arg]; */
+ if (decl == 0)
+ {
+ tree type = cw_type_for (arg);
+ if (type)
+ {
+ decl = /* cw_regs[arg] = */ build_decl (VAR_DECL, arg, type);
+ DECL_REGISTER (decl) = 1;
+ C_DECL_REGISTER (decl) = 1;
+ DECL_HARD_REGISTER (decl) = 1;
+ change_decl_assembler_name (decl, arg);
+ }
+ }
+
+ if (decl)
+ {
+ cw_asm_get_register_var (decl, "", buf, argnum, must_be_reg, e);
+ break;
+ }
+ }
+ }
+#endif
if (IDENTIFIER_LENGTH (arg) > 0 && IDENTIFIER_POINTER (arg)[0] == '%')
strcat (buf, "%");
strcat (buf, IDENTIFIER_POINTER (arg));
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index ad536b4632a..c2170d9e91c 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -3384,7 +3384,7 @@ extern tree x86_canonicalize_operands (const char **, tree, void *);
{ "xadd", 1, "+" rm8 "," rm16 "," rm32},\
{ "xadd", 2, r8 "," r16 "," r32},\
{ "xchg", 1, "+rm,r"}, \
- { "xchg", 2, "&r,m"}, \
+ { "xchg", 2, "+r,m"}, \
{ "xlat", 1, U("m")}, \
{ "xor", 1, "+rm,r"}, \
{ "xor", 2, "ri,m"}, \
diff --git a/gcc/testsuite/ChangeLog.apple-ppc b/gcc/testsuite/ChangeLog.apple-ppc
index dcfc7a758ec..bed1bdcb737 100644
--- a/gcc/testsuite/ChangeLog.apple-ppc
+++ b/gcc/testsuite/ChangeLog.apple-ppc
@@ -1,3 +1,9 @@
+2005-11-09 Mike Stump <mrs@apple.com>
+
+ Radar 4300193
+ * gcc.apple/asm-block-33.c: Add.
+ * g++.dg/asm-block-33.C: Add.
+
2005-11-08 Fariborz Jahanian <fjahanian@apple.com>
Radar 4330422
diff --git a/gcc/testsuite/g++.dg/asm-block-33.C b/gcc/testsuite/g++.dg/asm-block-33.C
new file mode 100644
index 00000000000..8244be08398
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asm-block-33.C
@@ -0,0 +1,27 @@
+/* APPLE LOCAL file CW asm blocks */
+/* { dg-do assemble { target i?86*-*-darwin* } } */
+/* { dg-options { -fasm-blocks -msse3 } } */
+/* Radar 4300193 */
+
+int i, j, k;
+int rows;
+
+void foo() {
+ int r;
+ for (r = 0; r < rows; r++) {
+ }
+ asm {
+ mov ah, 1
+ push eax
+ mov al, 1
+ push eax
+ mov esi, eax
+ mov ebx, i
+ mov edi, j
+ mov edx, ecx
+ push esi
+ push ebx
+ push edi
+ push edx
+ }
+}
diff --git a/gcc/testsuite/gcc.apple/asm-block-33.c b/gcc/testsuite/gcc.apple/asm-block-33.c
new file mode 100644
index 00000000000..8244be08398
--- /dev/null
+++ b/gcc/testsuite/gcc.apple/asm-block-33.c
@@ -0,0 +1,27 @@
+/* APPLE LOCAL file CW asm blocks */
+/* { dg-do assemble { target i?86*-*-darwin* } } */
+/* { dg-options { -fasm-blocks -msse3 } } */
+/* Radar 4300193 */
+
+int i, j, k;
+int rows;
+
+void foo() {
+ int r;
+ for (r = 0; r < rows; r++) {
+ }
+ asm {
+ mov ah, 1
+ push eax
+ mov al, 1
+ push eax
+ mov esi, eax
+ mov ebx, i
+ mov edi, j
+ mov edx, ecx
+ push esi
+ push ebx
+ push edi
+ push edx
+ }
+}