diff options
author | Mike Stump <mrs@apple.com> | 2005-11-11 00:56:21 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2005-11-11 00:56:21 +0000 |
commit | 447e7eaf8ef1ee08147519687dc50cdfbffec65f (patch) | |
tree | a38cb7c2b6f228098c49416c6112a3e08e5abdff | |
parent | 23638de8168aea5f1c4de820067548581d147bbb (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-ppc | 11 | ||||
-rw-r--r-- | gcc/c-common.c | 151 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog.apple-ppc | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/asm-block-33.C | 27 | ||||
-rw-r--r-- | gcc/testsuite/gcc.apple/asm-block-33.c | 27 |
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 + } +} |