[llvm-branch-commits] [llvm-gcc-branch] r76143 - in /llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc: c-common.c c-parser.c c-typeck.c config/asm.h config/i386/i386.c config/i386/i386.h cp/parser.c llvm-convert.cpp testsuite/g++.apple/asm-block-54.C testsuite/gcc.apple/asm-block-54.c
Bill Wendling
isanbard at gmail.com
Thu Jul 16 19:17:28 PDT 2009
Author: void
Date: Thu Jul 16 21:17:21 2009
New Revision: 76143
URL: http://llvm.org/viewvc/llvm-project?rev=76143&view=rev
Log:
--- Merging r74342 into '.':
U gcc/llvm-convert.cpp
--- Merging r74544 into '.':
G gcc/llvm-convert.cpp
--- Merging r74545 into '.':
G gcc/llvm-convert.cpp
--- Merging r74570 into '.':
G gcc/llvm-convert.cpp
--- Merging r74575 into '.':
G gcc/llvm-convert.cpp
--- Merging r74721 into '.':
G gcc/llvm-convert.cpp
--- Merging r74723 into '.':
G gcc/llvm-convert.cpp
--- Merging r75068 into '.':
U gcc/cp/parser.c
U gcc/c-common.c
U gcc/c-parser.c
U gcc/config/asm.h
--- Merging r75078 into '.':
G gcc/c-common.c
--- Merging r75140 into '.':
G gcc/c-common.c
--- Merging r75171 into '.':
U gcc/testsuite/gcc.apple/asm-block-54.c
U gcc/testsuite/g++.apple/asm-block-54.C
--- Merging r75306 into '.':
U gcc/config/i386/i386.h
--- Merging r75555 into '.':
G gcc/llvm-convert.cpp
--- Merging r75681 into '.':
G gcc/llvm-convert.cpp
U gcc/config/i386/i386.c
--- Merging r75715 into '.':
U gcc/c-typeck.c
G gcc/c-common.c
Modified:
llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-common.c
llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-parser.c
llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-typeck.c
llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/asm.h
llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/i386/i386.c
llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/i386/i386.h
llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/cp/parser.c
llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/llvm-convert.cpp
llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/testsuite/g++.apple/asm-block-54.C
llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/testsuite/gcc.apple/asm-block-54.c
Modified: llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-common.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-common.c?rev=76143&r1=76142&r2=76143&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-common.c (original)
+++ llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-common.c Thu Jul 16 21:17:21 2009
@@ -286,6 +286,10 @@
int flag_iasm_blocks;
/* APPLE LOCAL end CW asm blocks */
+/* LLVM LOCAL begin CW asm blocks */
+int iasm_label_counter;
+/* LLVM LOCAL end CW asm blocks */
+
/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */
int flag_signed_bitfields = 1;
@@ -2602,31 +2606,34 @@
#ifdef ENABLE_LLVM
}
- /* In LLVM we want to represent this as &P[i], not as P+i*sizeof(*P). */
- /* Convert the pointer to char* if it is a pointer to a zero sized object. */
- if (!size_set)
- ptrop = convert(build_pointer_type(char_type_node), ptrop);
-
- /* If the code is a subtract, construct 0-(ptrdiff_t)val. */
- if (resultcode == MINUS_EXPR)
- intop = build_binary_op (MINUS_EXPR,
- convert (ssizetype, integer_zero_node),
- convert (ssizetype, intop), 1);
- {
- tree arrayref, result, folded;
- arrayref = build4 (ARRAY_REF, TREE_TYPE(TREE_TYPE(ptrop)), ptrop, intop,
- NULL_TREE, NULL_TREE);
- result = build_unary_op (ADDR_EXPR, arrayref, 0);
-
- folded = fold (result);
- if (folded == result)
- TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
-
- /* If the original was void* + int, we converted it to char* + int. Convert
- back to the appropriate void* result and match type qualifiers. */
- if (!size_set || TYPE_QUALS(result_type) != TYPE_QUALS(TREE_TYPE(folded)))
- folded = convert(result_type, folded);
- return folded;
+ if (!inside_iasm_block) {
+ /* In LLVM we want to represent this as &P[i], not as P+i*sizeof(*P). */
+ /* Convert the pointer to char* if it is a pointer to a zero sized object.*/
+ if (!size_set)
+ ptrop = convert(build_pointer_type(char_type_node), ptrop);
+
+ /* If the code is a subtract, construct 0-(ptrdiff_t)val. */
+ if (resultcode == MINUS_EXPR)
+ intop = build_binary_op (MINUS_EXPR,
+ convert (ssizetype, integer_zero_node),
+ convert (ssizetype, intop), 1);
+ {
+ tree arrayref, result, folded;
+ arrayref = build4 (ARRAY_REF, TREE_TYPE(TREE_TYPE(ptrop)), ptrop, intop,
+ NULL_TREE, NULL_TREE);
+ result = build_unary_op (ADDR_EXPR, arrayref, 0);
+
+ folded = fold (result);
+ if (folded == result)
+ TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop);
+
+ /* If the original was void* + int, we converted it to char* + int.
+ Convert back to the appropriate void* result and match type
+ qualifiers. */
+ if (!size_set || TYPE_QUALS(result_type) != TYPE_QUALS(TREE_TYPE(folded)))
+ folded = convert(result_type, folded);
+ return folded;
+ }
}
#endif
/* LLVM LOCAL end */
@@ -8305,6 +8312,20 @@
sprintf (buf + strlen (buf), "%s", name);
break;
}
+/* LLVM LOCAL begin */
+#ifdef ENABLE_LLVM
+ /* Labels defined earlier in the asm block will have DECL_INITIAL set
+ at this point; labels we haven't seen yet won't. LABEL_DECL_UID
+ should be set in either case (when we saw the forward ref, we
+ assumed the target was inside the block; that's what gcc does). */
+ if (DECL_INITIAL (arg))
+ sprintf(buf + strlen(buf), HOST_WIDE_INT_PRINT_DEC "b",
+ LABEL_DECL_UID (arg));
+ else
+ sprintf(buf + strlen(buf), HOST_WIDE_INT_PRINT_DEC "f",
+ LABEL_DECL_UID (arg));
+#else
+/* LLVM LOCAL end */
TREE_USED (arg) = 1;
IASM_OFFSET_PREFIX (e, buf);
arg = build1 (ADDR_EXPR, ptr_type_node, arg);
@@ -8330,6 +8351,8 @@
#endif
iasm_get_register_var (arg, modifier, buf, argnum, must_be_reg, e);
iasm_force_constraint (0, e);
+/* LLVM LOCAL */
+#endif /* ENABLE_LLVM */
break;
case IDENTIFIER_NODE:
@@ -8628,16 +8651,15 @@
tree
iasm_label (tree labid, bool atsign)
{
-/* LLVM LOCAL begin */
-/* Unused variables resulting from code change below. */
-#ifdef ENABLE_LLVM
- tree stmt, label;
-#else
tree sexpr;
tree inputs = NULL_TREE, outputs = NULL_TREE, clobbers = NULL_TREE;
tree stmt;
+/* LLVM LOCAL begin */
+#ifndef ENABLE_LLVM
tree label, l;
tree str, one;
+#else
+ tree label;
#endif
/* LLVM LOCAL end */
STRIP_NOPS (labid);
@@ -8650,8 +8672,7 @@
iasm_buffer[0] = '\0';
label = iasm_define_label (labid);
-/* LLVM LOCAL */
-#ifdef ENABLE_LLVM
+#if 0
/* Ideally I'd like to do this, but, it moves the label in:
nop
@@ -8676,6 +8697,8 @@
#else
/* Arrange for the label to be a parameter to the ASM_EXPR, as only then will the
backend `manage it' for us, say, making a unique copy for inline expansion. */
+/* LLVM LOCAL */
+#ifndef ENABLE_LLVM
sprintf (iasm_buffer, "%%l0: # %s", IDENTIFIER_POINTER (DECL_NAME (label)));
l = build1 (ADDR_EXPR, ptr_type_node, label);
@@ -8687,6 +8710,13 @@
inputs = chainon (NULL_TREE, one);
sexpr = build_string (strlen (iasm_buffer), iasm_buffer);
+/* LLVM LOCAL begin */
+#else
+ sprintf (iasm_buffer, HOST_WIDE_INT_PRINT_DEC ": # %s",
+ LABEL_DECL_UID (label), IDENTIFIER_POINTER (DECL_NAME (label)));
+ sexpr = build_string (strlen (iasm_buffer), iasm_buffer);
+#endif
+/* LLVM LOCAL end */
/* Simple asm statements are treated as volatile. */
stmt = build_stmt (ASM_EXPR, sexpr, outputs, inputs, clobbers, NULL_TREE);
ASM_VOLATILE_P (stmt) = 1;
@@ -8826,6 +8856,10 @@
strcat (buf, labname);
newid = get_identifier (buf);
newid = lookup_label (newid);
+/* LLVM LOCAL begin */
+ if (LABEL_DECL_UID (newid) == -1)
+ LABEL_DECL_UID (newid) = iasm_label_counter++;
+/* LLVM LOCAL end */
return newid;
}
@@ -8853,6 +8887,10 @@
strcat (buf, labname);
newid = get_identifier (buf);
newid = define_label (input_location, newid);
+ /* LLVM LOCAL begin */
+ if (LABEL_DECL_UID (newid) == -1)
+ LABEL_DECL_UID (newid) = iasm_label_counter++;
+ /* LLVM LOCAL end */
return newid;
}
Modified: llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-parser.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-parser.c?rev=76143&r1=76142&r2=76143&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-parser.c (original)
+++ llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-parser.c Thu Jul 16 21:17:21 2009
@@ -4122,6 +4122,8 @@
iasm_state = iasm_asm;
inside_iasm_block = true;
iasm_kill_regs = true;
+ /* LLVM LOCAL */
+ iasm_label_counter = 0;
iasm_in_decl = false;
c_parser_iasm_line_seq_opt (parser);
stmt = NULL_TREE;
@@ -9021,6 +9023,8 @@
iasm_state = iasm_asm;
inside_iasm_block = true;
iasm_kill_regs = true;
+ /* LLVM LOCAL */
+ iasm_label_counter = 0;
stmt = c_begin_compound_stmt (true);
/* Parse an (optional) statement-seq. */
c_parser_iasm_line_seq_opt (parser);
@@ -9041,6 +9045,8 @@
iasm_state = iasm_asm;
inside_iasm_block = true;
iasm_kill_regs = true;
+ /* LLVM LOCAL */
+ iasm_label_counter = 0;
stmt = c_begin_compound_stmt (true);
if (!c_parser_iasm_bol (parser))
{
Modified: llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-typeck.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-typeck.c?rev=76143&r1=76142&r2=76143&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-typeck.c (original)
+++ llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/c-typeck.c Thu Jul 16 21:17:21 2009
@@ -3331,7 +3331,12 @@
/* LLVM LOCAL begin */
/* LLVM wants &x[y] to be kept as an &x[y] for better optimization. */
-#ifndef ENABLE_LLVM
+ /* However we shouldn't do this in asm blocks; we aren't going to be
+ doing anything complicated with addresses, and the asm block code
+ only understands array refs. */
+#ifdef ENABLE_LLVM
+ if (inside_iasm_block) {
+#endif
/* For &x[y], return x+y */
if (TREE_CODE (arg) == ARRAY_REF)
{
@@ -3344,6 +3349,8 @@
: op0),
TREE_OPERAND (arg, 1), 1);
}
+#ifdef ENABLE_LLVM
+ }
#endif
/* LLVM LOCAL end */
Modified: llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/asm.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/asm.h?rev=76143&r1=76142&r2=76143&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/asm.h (original)
+++ llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/asm.h Thu Jul 16 21:17:21 2009
@@ -25,6 +25,8 @@
extern bool iasm_kill_regs;
extern bool iasm_in_operands;
extern tree iasm_do_id (tree);
+/* LLVM LOCAL */
+extern int iasm_label_counter;
/* Maximum number of arguments. */
#define IASM_MAX_ARG 11
Modified: llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/i386/i386.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/i386/i386.c?rev=76143&r1=76142&r2=76143&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/i386/i386.c (original)
+++ llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/i386/i386.c Thu Jul 16 21:17:21 2009
@@ -22060,9 +22060,18 @@
enum machine_mode mode = VOIDmode;
if (IDENTIFIER_POINTER (arg)[1] == 'e')
mode = SImode;
+/* LLVM LOCAL begin */
+/* Accept H registers for LLVM, this totally obviates need for ASM_USES. */
+#ifndef ENABLE_LLVM
else if (/* IDENTIFIER_POINTER (arg)[2] == 'h'
|| */ IDENTIFIER_POINTER (arg)[2] == 'l')
mode = QImode;
+#else
+ else if (IDENTIFIER_POINTER (arg)[2] == 'h'
+ || IDENTIFIER_POINTER (arg)[2] == 'l')
+ mode = QImode;
+#endif
+/* LLVM LOCAL end */
else if (IDENTIFIER_POINTER (arg)[2] == 'x')
mode = HImode;
else if (IDENTIFIER_POINTER (arg)[1] == 'r')
Modified: llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/i386/i386.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/i386/i386.h?rev=76143&r1=76142&r2=76143&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/i386/i386.h (original)
+++ llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/config/i386/i386.h Thu Jul 16 21:17:21 2009
@@ -2512,6 +2512,7 @@
#define IASM_SEE_NO_IMMEDIATE(E) \
E->as_immediate = false
+/* LLVM LOCAL begin change some = to + */
/* Table of instructions that need extra constraints. Keep this table sorted. */
#undef TARGET_IASM_OP_CONSTRAINT
#define TARGET_IASM_OP_CONSTRAINT \
@@ -2592,81 +2593,81 @@
{ "cmovz", 2, "rm"}, \
{ "cmp", 1, rm8 "," rm16 "," rm32 C RM64 "," r8 "," r16 "," r32 C R64},\
{ "cmp", 2, ri8 "," ri16 "," ri32 C RI64 "," m8 "," m16 "," m32 C M64},\
- { "cmpeqpd", 1, "=x"}, \
+ { "cmpeqpd", 1, "+x"}, \
{ "cmpeqpd", 2, "xm"}, \
- { "cmpeqps", 1, "=x"}, \
+ { "cmpeqps", 1, "+x"}, \
{ "cmpeqps", 2, "xm"}, \
- { "cmpeqsd", 1, "=x"}, \
+ { "cmpeqsd", 1, "+x"}, \
{ "cmpeqsd", 2, "xm"}, \
- { "cmpeqss", 1, "=x"}, \
+ { "cmpeqss", 1, "+x"}, \
{ "cmpeqss", 2, "xm"}, \
- { "cmplepd", 1, "=x"}, \
+ { "cmplepd", 1, "+x"}, \
{ "cmplepd", 2, "xm"}, \
- { "cmpleps", 1, "=x"}, \
+ { "cmpleps", 1, "+x"}, \
{ "cmpleps", 2, "xm"}, \
- { "cmplesd", 1, "=x"}, \
+ { "cmplesd", 1, "+x"}, \
{ "cmplesd", 2, "xm"}, \
- { "cmpless", 1, "=x"}, \
+ { "cmpless", 1, "+x"}, \
{ "cmpless", 2, "xm"}, \
- { "cmpltpd", 1, "=x"}, \
+ { "cmpltpd", 1, "+x"}, \
{ "cmpltpd", 2, "xm"}, \
- { "cmpltps", 1, "=x"}, \
+ { "cmpltps", 1, "+x"}, \
{ "cmpltps", 2, "xm"}, \
- { "cmpltsd", 1, "=x"}, \
+ { "cmpltsd", 1, "+x"}, \
{ "cmpltsd", 2, "xm"}, \
- { "cmpltss", 1, "=x"}, \
+ { "cmpltss", 1, "+x"}, \
{ "cmpltss", 2, "xm"}, \
- { "cmpneqpd", 1, "=x"}, \
+ { "cmpneqpd", 1, "+x"}, \
{ "cmpneqpd", 2, "xm"}, \
- { "cmpneqps", 1, "=x"}, \
+ { "cmpneqps", 1, "+x"}, \
{ "cmpneqps", 2, "xm"}, \
- { "cmpneqsd", 1, "=x"}, \
+ { "cmpneqsd", 1, "+x"}, \
{ "cmpneqsd", 2, "xm"}, \
- { "cmpneqss", 1, "=x"}, \
+ { "cmpneqss", 1, "+x"}, \
{ "cmpneqss", 2, "xm"}, \
- { "cmpnlepd", 1, "=x"}, \
+ { "cmpnlepd", 1, "+x"}, \
{ "cmpnlepd", 2, "xm"}, \
- { "cmpnleps", 1, "=x"}, \
+ { "cmpnleps", 1, "+x"}, \
{ "cmpnleps", 2, "xm"}, \
- { "cmpnlesd", 1, "=x"}, \
+ { "cmpnlesd", 1, "+x"}, \
{ "cmpnlesd", 2, "xm"}, \
- { "cmpnless", 1, "=x"}, \
+ { "cmpnless", 1, "+x"}, \
{ "cmpnless", 2, "xm"}, \
- { "cmpnltpd", 1, "=x"}, \
+ { "cmpnltpd", 1, "+x"}, \
{ "cmpnltpd", 2, "xm"}, \
- { "cmpnltps", 1, "=x"}, \
+ { "cmpnltps", 1, "+x"}, \
{ "cmpnltps", 2, "xm"}, \
- { "cmpnltsd", 1, "=x"}, \
+ { "cmpnltsd", 1, "+x"}, \
{ "cmpnltsd", 2, "xm"}, \
- { "cmpnltss", 1, "=x"}, \
+ { "cmpnltss", 1, "+x"}, \
{ "cmpnltss", 2, "xm"}, \
- { "cmpordpd", 1, "=x"}, \
+ { "cmpordpd", 1, "+x"}, \
{ "cmpordpd", 2, "xm"}, \
- { "cmpordps", 1, "=x"}, \
+ { "cmpordps", 1, "+x"}, \
{ "cmpordps", 2, "xm"}, \
- { "cmpordsd", 1, "=x"}, \
+ { "cmpordsd", 1, "+x"}, \
{ "cmpordsd", 2, "xm"}, \
- { "cmpordss", 1, "=x"}, \
+ { "cmpordss", 1, "+x"}, \
{ "cmpordss", 2, "xm"}, \
- { "cmppd", 1, "=x"}, \
+ { "cmppd", 1, "+x"}, \
{ "cmppd", 2, "xm"}, \
{ "cmppd", 3, "i"}, \
- { "cmpps", 1, "=x"}, \
+ { "cmpps", 1, "+x"}, \
{ "cmpps", 2, "xm"}, \
{ "cmpps", 3, "i"}, \
- { "cmpsd", 1, "=x"}, \
+ { "cmpsd", 1, "+x"}, \
{ "cmpsd", 2, "xm"}, \
{ "cmpsd", 3, "i"}, \
- { "cmpss", 1, "=x"}, \
+ { "cmpss", 1, "+x"}, \
{ "cmpss", 2, "xm"}, \
{ "cmpss", 3, "i"}, \
- { "cmpunordpd", 1, "=x"}, \
+ { "cmpunordpd", 1, "+x"}, \
{ "cmpunordpd", 2, "xm"}, \
- { "cmpunordps", 1, "=x"}, \
+ { "cmpunordps", 1, "+x"}, \
{ "cmpunordps", 2, "xm"}, \
- { "cmpunordsd", 1, "=x"}, \
+ { "cmpunordsd", 1, "+x"}, \
{ "cmpunordsd", 2, "xm"}, \
- { "cmpunordss", 1, "=x"}, \
+ { "cmpunordss", 1, "+x"}, \
{ "cmpunordss", 2, "xm"}, \
{ "cmpxchg", 1, "+mr"}, \
{ "cmpxchg", 2, "r"}, \
@@ -2783,9 +2784,9 @@
{ "fldcw", 1, m16}, \
{ "fldenv", 1, "m"}, \
{ "fldt", 1, "m"}, \
- { "fmul", 1, "=f,t,@"}, \
+ { "fmul", 1, "+f,t,@"}, \
{ "fmul", 2, "t,f," m32fpm64fp},\
- { "fmulp", 1, "=f"}, \
+ { "fmulp", 1, "+f"}, \
{ "fmulp", 2, "t"}, \
{ "fnsave", 1, "=m"}, \
{ "fnstcw", 1, "m"}, \
@@ -2798,9 +2799,9 @@
{ "fstenv", 1, "=m"}, \
{ "fstp", 1, "=f" m32fpm64fpm80fp},\
{ "fstsw", 1, "=ma"}, \
- { "fsub", 1, "=f,t,@"}, \
+ { "fsub", 1, "+f,t,@"}, \
{ "fsub", 2, "t,f," m32fpm64fp},\
- { "fsubr", 1, "=f,t," m32fpm64fp},\
+ { "fsubr", 1, "+f,t," m32fpm64fp},\
{ "fsubr", 2, "t,f,@"}, \
{ "fucom", 1, "f"}, \
{ "fucomi", 1, "t"}, \
@@ -2977,13 +2978,13 @@
{ "movzx", 1, "=" r16 "," r32},\
{ "movzx", 2, rm8 "," rm8rm16},\
{ "mul", 1, rm8rm16rm32}, \
- { "mulpd", 1, "=x"}, \
+ { "mulpd", 1, "+x"}, \
{ "mulpd", 2, "xm"}, \
- { "mulps", 1, "=x"}, \
+ { "mulps", 1, "+x"}, \
{ "mulps", 2, "xm"}, \
- { "mulsd", 1, "=x"}, \
+ { "mulsd", 1, "+x"}, \
{ "mulsd", 2, "xm"}, \
- { "mulss", 1, "=x"}, \
+ { "mulss", 1, "+x"}, \
{ "mulss", 2, "xm"}, \
{ "neg", 1, "+" rm8rm16rm32}, \
{ "not", 1, "+" rm8rm16rm32}, \
@@ -3042,7 +3043,7 @@
{ "pextrw", 1, "=" r32R64}, \
{ "pextrw", 2, "xy"}, \
{ "pextrw", 3, "i"}, \
- { "pinsrw", 1, "=xy"}, \
+ { "pinsrw", 1, "+xy"}, \
{ "pinsrw", 2, r32R64 "m"}, \
{ "pinsrw", 3, "i"}, \
{ "pmaddwd", 1, "+x,y"}, \
@@ -3263,6 +3264,7 @@
{ "xorpd", 2, "xm"}, \
{ "xorps", 1, "+x"}, \
{ "xorps", 2, "xm"},
+/* LLVM LOCAL end change some = to + */
#define TARGET_IASM_EXTRA_CLOBBERS \
{ "rdtsc", { "edx", "eax"} }
Modified: llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/cp/parser.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/cp/parser.c?rev=76143&r1=76142&r2=76143&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/cp/parser.c (original)
+++ llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/cp/parser.c Thu Jul 16 21:17:21 2009
@@ -7095,6 +7095,8 @@
iasm_state = iasm_asm;
inside_iasm_block = true;
iasm_kill_regs = true;
+ /* LLVM LOCAL */
+ iasm_label_counter = 0;
cp_parser_iasm_line_seq_opt (parser);
iasm_state = iasm_none;
iasm_end_block ();
@@ -18063,6 +18065,8 @@
iasm_state = iasm_asm;
inside_iasm_block = true;
iasm_kill_regs = true;
+ /* LLVM LOCAL */
+ iasm_label_counter = 0;
if (!cp_parser_require (parser, CPP_OPEN_BRACE, "`{'"))
return error_mark_node;
/* Begin the compound-statement. */
@@ -18087,6 +18091,8 @@
iasm_state = iasm_asm;
inside_iasm_block = true;
iasm_kill_regs = true;
+ /* LLVM LOCAL */
+ iasm_label_counter = 0;
/* Begin the compound-statement. */
compound_stmt = begin_compound_stmt (/*has_no_scope=*/false);
if (!cp_lexer_iasm_bol (parser->lexer))
Modified: llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/llvm-convert.cpp?rev=76143&r1=76142&r2=76143&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/llvm-convert.cpp Thu Jul 16 21:17:21 2009
@@ -3900,19 +3900,250 @@
return Result;
}
+/// See if operand "exp" can use the indicated Constraint (which is
+/// terminated by a null or a comma).
+/// Returns: -1=no, 0=yes but auxiliary instructions needed, 1=yes and free
+int MatchWeight(const char *Constraint, tree Operand, bool isInput) {
+ const char *p = Constraint;
+ int RetVal = 0;
+ // Look for hard register operand. This matches only a constraint of a
+ // register class that includes that hard register, and it matches that
+ // perfectly, so we never return 0 in this case.
+ if (TREE_CODE(Operand) == VAR_DECL && DECL_HARD_REGISTER(Operand)) {
+ int RegNum = decode_reg_name(extractRegisterName(Operand));
+ RetVal = -1;
+ if (RegNum >= 0) {
+ do {
+ unsigned RegClass;
+ if (*p == 'r')
+ RegClass = GENERAL_REGS;
+ else
+ RegClass = REG_CLASS_FROM_CONSTRAINT(*p, p);
+ if (RegClass != NO_REGS &&
+ TEST_HARD_REG_BIT(reg_class_contents[RegClass], RegNum)) {
+ RetVal = 1;
+ break;
+ }
+ ++p;
+ } while (*p != ',' && *p != 0);
+ }
+ }
+ // Look for integer constant operand. This cannot match "m", and "i" is
+ // better than "r". FIXME target-dependent immediate letters are not handled
+ // yet; in general they require looking at the value.
+ if (TREE_CODE(Operand) == INTEGER_CST) {
+ do {
+ RetVal = -1;
+ if (*p == 'i' || *p == 'n') { // integer constant
+ RetVal = 1;
+ break;
+ }
+ if (*p != 'm' && *p != 'o' && *p != 'V') // not memory
+ RetVal = 0;
+ ++p;
+ } while (*p != ',' && *p != 0);
+ }
+ /// TEMPORARY. This has the effect that alternative 0 is always chosen,
+ /// except in the cases handled above.
+ return RetVal;
+}
+
+/// ChooseConstraintTuple: we know each of the NumInputs+NumOutputs strings
+/// in Constraints[] is a comma-separated list of NumChoices different
+/// constraints. Look through the operands and constraint possibilities
+/// and pick a tuple where all the operands match. Replace the strings
+/// in Constraints[] with the shorter strings from that tuple (malloc'ed,
+/// caller is responsible for cleaning it up). Later processing can alter what
+/// Constraints points to, so to make sure we delete everything, the addresses
+/// of everything we allocated also are returned in ReplacementStrings.
+/// Casting back and forth from char* to const char* is Ugly, but we have to
+/// interface with C code that expects const char*.
+///
+/// gcc's algorithm for picking "the best" tuple is quite complicated, and
+/// is performed after things like SROA, not before. At the moment we are
+/// just trying to pick one that will work. This may get refined.
+static void
+ChooseConstraintTuple (const char **Constraints, tree exp, unsigned NumInputs,
+ unsigned NumOutputs, unsigned NumChoices,
+ const char **ReplacementStrings)
+{
+ int MaxWeight = -1;
+ unsigned int CommasToSkip = 0;
+ int *Weights = (int *)alloca(NumChoices * sizeof(int));
+ // RunningConstraints is pointers into the Constraints strings which
+ // are incremented as we go to point to the beginning of each
+ // comma-separated alternative.
+ const char** RunningConstraints =
+ (const char**)alloca((NumInputs+NumOutputs)*sizeof(const char*));
+ memcpy(RunningConstraints, Constraints,
+ (NumInputs+NumOutputs) * sizeof(const char*));
+ // The entire point of this loop is to compute CommasToSkip.
+ for (unsigned int i=0; i<NumChoices; i++) {
+ Weights[i] = 0;
+ unsigned int j = 0;
+ for (tree Output = ASM_OUTPUTS(exp); j<NumOutputs;
+ j++, Output = TREE_CHAIN(Output)) {
+ if (i==0)
+ RunningConstraints[j]++; // skip leading =
+ const char* p = RunningConstraints[j];
+ while (*p=='*' || *p=='&' || *p=='%') // skip modifiers
+ p++;
+ if (Weights[i] != -1) {
+ int w = MatchWeight(p, TREE_VALUE(Output), false);
+ // Nonmatch means the entire tuple doesn't match. However, we
+ // keep scanning to set up RunningConstraints correctly for the
+ // next tuple.
+ if (w < 0)
+ Weights[i] = -1;
+ else
+ Weights[i] += w;
+ }
+ while (*p!=0 && *p!=',')
+ p++;
+ if (*p!=0) {
+ p++; // skip comma
+ while (*p=='*' || *p=='&' || *p=='%')
+ p++; // skip modifiers
+ }
+ RunningConstraints[j] = p;
+ }
+ assert(j==NumOutputs);
+ for (tree Input = ASM_INPUTS(exp); j<NumInputs+NumOutputs;
+ j++, Input = TREE_CHAIN(Input)) {
+ const char* p = RunningConstraints[j];
+ if (Weights[i] != -1) {
+ int w = MatchWeight(p, TREE_VALUE(Input), true);
+ if (w < 0)
+ Weights[i] = -1; // As above.
+ else
+ Weights[i] += w;
+ }
+ while (*p!=0 && *p!=',')
+ p++;
+ if (*p!=0)
+ p++;
+ RunningConstraints[j] = p;
+ }
+ if (Weights[i]>MaxWeight) {
+ CommasToSkip = i;
+ MaxWeight = Weights[i];
+ }
+ }
+ // We have picked an alternative (the CommasToSkip'th one).
+ // Change Constraints to point to malloc'd copies of the appropriate
+ // constraints picked out of the original strings.
+ for (unsigned int i=0; i<NumInputs+NumOutputs; i++) {
+ assert(*(RunningConstraints[i])==0); // sanity check
+ const char* start = Constraints[i];
+ if (i<NumOutputs)
+ start++; // skip '=' or '+'
+ const char* end = start;
+ while (*end != ',' && *end != 0)
+ end++;
+ for (unsigned int j=0; j<CommasToSkip; j++) {
+ start = end+1;
+ end = start;
+ while (*end != ',' && *end != 0)
+ end++;
+ }
+ // String we want is at start..end-1 inclusive.
+ // For outputs, copy the leading = or +.
+ char *newstring;
+ if (i<NumOutputs) {
+ newstring = (char *)xmalloc(end-start+1+1);
+ newstring[0] = *(Constraints[i]);
+ strncpy(newstring+1, start, end-start);
+ newstring[end-start+1] = 0;
+ } else {
+ newstring = (char *)xmalloc(end-start+1);
+ strncpy(newstring, start, end-start);
+ newstring[end-start] = 0;
+ }
+ Constraints[i] = (const char *)newstring;
+ ReplacementStrings[i] = (const char*)newstring;
+ }
+}
+
+static void FreeConstTupleStrings(const char **ReplacementStrings,
+ unsigned int Size) {
+ for (unsigned int i=0; i<Size; i++)
+ free((char *)ReplacementStrings[i]);
+}
Value *TreeToLLVM::EmitASM_EXPR(tree exp) {
unsigned NumInputs = list_length(ASM_INPUTS(exp));
unsigned NumOutputs = list_length(ASM_OUTPUTS(exp));
unsigned NumInOut = 0;
-
+
+ // Look for multiple alternative constraints: multiple alternatives separated
+ // by commas.
+ unsigned NumChoices = 0; // sentinal; real value is always at least 1.
+ const char* p;
+ for (tree t = ASM_INPUTS(exp); t; t = TREE_CHAIN(t)) {
+ unsigned NumInputChoices = 1;
+ for (p = TREE_STRING_POINTER(TREE_VALUE(TREE_PURPOSE(t))); *p; p++) {
+ if (*p == ',')
+ NumInputChoices++;
+ }
+ if (NumChoices==0)
+ NumChoices = NumInputChoices;
+ else if (NumChoices != NumInputChoices)
+ abort(); // invalid constraints
+ }
+ for (tree t = ASM_OUTPUTS(exp); t; t = TREE_CHAIN(t)) {
+ unsigned NumOutputChoices = 1;
+ for (p = TREE_STRING_POINTER(TREE_VALUE(TREE_PURPOSE(t))); *p; p++) {
+ if (*p == ',')
+ NumOutputChoices++;
+ }
+ if (NumChoices==0)
+ NumChoices = NumOutputChoices;
+ else if (NumChoices != NumOutputChoices)
+ abort(); // invalid constraints
+ }
+
/// Constraints - The output/input constraints, concatenated together in array
/// form instead of list form.
const char **Constraints =
(const char **)alloca((NumOutputs + NumInputs) * sizeof(const char *));
- // FIXME: CHECK ALTERNATIVES, something akin to check_operand_nalternatives.
-
+ // Process outputs.
+ int ValNum = 0;
+ for (tree Output = ASM_OUTPUTS(exp); Output;
+ Output = TREE_CHAIN(Output), ++ValNum) {
+ tree Operand = TREE_VALUE(Output);
+ tree type = TREE_TYPE(Operand);
+ // If there's an erroneous arg, emit no insn.
+ if (type == error_mark_node) return 0;
+
+ // Parse the output constraint.
+ const char *Constraint =
+ TREE_STRING_POINTER(TREE_VALUE(TREE_PURPOSE(Output)));
+ Constraints[ValNum] = Constraint;
+ }
+ // Process inputs.
+ for (tree Input = ASM_INPUTS(exp); Input; Input = TREE_CHAIN(Input),++ValNum){
+ tree Val = TREE_VALUE(Input);
+ tree type = TREE_TYPE(Val);
+ // If there's an erroneous arg, emit no insn.
+ if (type == error_mark_node) return 0;
+
+ const char *Constraint =
+ TREE_STRING_POINTER(TREE_VALUE(TREE_PURPOSE(Input)));
+ Constraints[ValNum] = Constraint;
+ }
+
+ // If there are multiple constraint tuples, pick one. Constraints is
+ // altered to point to shorter strings (which are malloc'ed), and everything
+ // below Just Works as in the NumChoices==1 case.
+ const char** ReplacementStrings = 0;
+ if (NumChoices>1) {
+ ReplacementStrings =
+ (const char **)alloca((NumOutputs + NumInputs) * sizeof(const char *));
+ ChooseConstraintTuple(Constraints, exp, NumInputs, NumOutputs, NumChoices,
+ ReplacementStrings);
+ }
+
std::vector<Value*> CallOps;
std::vector<const Type*> CallArgTypes;
std::string NewAsmStr = ConvertInlineAsmStr(exp, NumOutputs+NumInputs);
@@ -3924,26 +4155,24 @@
SmallVector<bool, 4> CallResultIsSigned;
// Process outputs.
- int ValNum = 0;
+ ValNum = 0;
for (tree Output = ASM_OUTPUTS(exp); Output;
Output = TREE_CHAIN(Output), ++ValNum) {
tree Operand = TREE_VALUE(Output);
tree type = TREE_TYPE(Operand);
- // If there's an erroneous arg, emit no insn.
- if (type == error_mark_node) return 0;
// Parse the output constraint.
- const char *Constraint =
- TREE_STRING_POINTER(TREE_VALUE(TREE_PURPOSE(Output)));
- Constraints[ValNum] = Constraint;
+ const char *Constraint = Constraints[ValNum];
bool IsInOut, AllowsReg, AllowsMem;
if (!parse_output_constraint(&Constraint, ValNum, NumInputs, NumOutputs,
- &AllowsMem, &AllowsReg, &IsInOut))
+ &AllowsMem, &AllowsReg, &IsInOut)) {
+ if (NumChoices>1)
+ FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
return 0;
-
+ }
assert(Constraint[0] == '=' && "Not an output constraint?");
- // Output constraints must be addressible if they aren't simple register
+ // Output constraints must be addressable if they aren't simple register
// constraints (this emits "address of register var" errors, etc).
if (!AllowsReg && (AllowsMem || IsInOut))
lang_hooks.mark_addressable(Operand);
@@ -3956,13 +4185,17 @@
// If this output register is pinned to a machine register, use that machine
// register instead of the specified constraint.
if (TREE_CODE(Operand) == VAR_DECL && DECL_HARD_REGISTER(Operand)) {
- int RegNum = decode_reg_name(extractRegisterName(Operand));
+ const char* RegName = extractRegisterName(Operand);
+ int RegNum = decode_reg_name(RegName);
if (RegNum >= 0) {
- unsigned RegNameLen = strlen(reg_names[RegNum]);
+ // Constraints don't have the leading %, the variable names do
+ if (*RegName == '%')
+ RegName++;
+ unsigned RegNameLen = strlen(RegName);
char *NewConstraint = (char*)alloca(RegNameLen+4);
NewConstraint[0] = '=';
NewConstraint[1] = '{';
- memcpy(NewConstraint+2, reg_names[RegNum], RegNameLen);
+ memcpy(NewConstraint+2, RegName, RegNameLen);
NewConstraint[RegNameLen+2] = '}';
NewConstraint[RegNameLen+3] = 0;
SimplifiedConstraint = NewConstraint;
@@ -4001,19 +4234,17 @@
for (tree Input = ASM_INPUTS(exp); Input; Input = TREE_CHAIN(Input),++ValNum){
tree Val = TREE_VALUE(Input);
tree type = TREE_TYPE(Val);
- // If there's an erroneous arg, emit no insn.
- if (type == error_mark_node) return 0;
- const char *Constraint =
- TREE_STRING_POINTER(TREE_VALUE(TREE_PURPOSE(Input)));
- Constraints[ValNum] = Constraint;
+ const char *Constraint = Constraints[ValNum];
bool AllowsReg, AllowsMem;
if (!parse_input_constraint(Constraints+ValNum, ValNum-NumOutputs,
NumInputs, NumOutputs, NumInOut,
- Constraints, &AllowsMem, &AllowsReg))
+ Constraints, &AllowsMem, &AllowsReg)) {
+ if (NumChoices>1)
+ FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
return 0;
-
+ }
bool isIndirect = false;
if (AllowsReg || !AllowsMem) { // Register operand.
const Type *LLVMTy = ConvertType(type);
@@ -4066,6 +4297,8 @@
error("%Hunsupported inline asm: input constraint with a matching "
"output constraint of incompatible type!",
&EXPR_LOCATION(exp));
+ if (NumChoices>1)
+ FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
return 0;
}
unsigned OTyBits = TD.getTypeSizeInBits(OTy);
@@ -4105,25 +4338,29 @@
// If this output register is pinned to a machine register, use that machine
// register instead of the specified constraint.
- int RegNum;
- if (TREE_CODE(Val) == VAR_DECL && DECL_HARD_REGISTER(Val) &&
- (RegNum = decode_reg_name(extractRegisterName(Val))) >= 0) {
- ConstraintStr += '{';
- ConstraintStr += reg_names[RegNum];
- ConstraintStr += '}';
- } else {
- // If there is a simpler form for the register constraint, use it.
- std::string Simplified = CanonicalizeConstraint(Constraint);
- ConstraintStr += Simplified;
+ if (TREE_CODE(Val) == VAR_DECL && DECL_HARD_REGISTER(Val)) {
+ const char *RegName = extractRegisterName(Val);
+ int RegNum = decode_reg_name(RegName);
+ if (RegNum >= 0) {
+ if (*RegName == '%') // Variables have leading %.
+ RegName++; // Constraints don't.
+ ConstraintStr += '{';
+ ConstraintStr += RegName;
+ ConstraintStr += '}';
+ continue;
+ }
}
+
+ // If there is a simpler form for the register constraint, use it.
+ std::string Simplified = CanonicalizeConstraint(Constraint);
+ ConstraintStr += Simplified;
}
- if (ASM_USES(exp)) {
- // FIXME: Figure out what ASM_USES means.
- error("%Hcode warrior/ms asm not supported yet in %qs", &EXPR_LOCATION(exp),
- TREE_STRING_POINTER(ASM_STRING(exp)));
- return 0;
- }
+ // ASM_USES contains info about certain hard regs which are used as inputs.
+ // gcc represents the xH registers on x86 this way because of deficiencies
+ // in the way gcc can represent registers internally. llvm-gcc can represent
+ // these as normal inputs, so we aren't using ASM_USES.
+ assert(ASM_USES(exp)==0);
// Process clobbers.
@@ -4139,6 +4376,8 @@
case -2: // Invalid.
error("%Hunknown register name %qs in %<asm%>", &EXPR_LOCATION(exp),
RegName);
+ if (NumChoices>1)
+ FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
return 0;
case -3: // cc
ConstraintStr += ",~{cc}";
@@ -4147,8 +4386,10 @@
ConstraintStr += ",~{memory}";
break;
default: // Normal register name.
+ if (*RegName == '%')
+ RegName++;
ConstraintStr += ",~{";
- ConstraintStr += reg_names[RegCode];
+ ConstraintStr += RegName;
ConstraintStr += "}";
break;
}
@@ -4175,6 +4416,8 @@
// Make sure we're created a valid inline asm expression.
if (!InlineAsm::Verify(FTy, ConstraintStr)) {
error("%HInvalid or unsupported inline assembly!", &EXPR_LOCATION(exp));
+ if (NumChoices>1)
+ FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
return 0;
}
@@ -4200,6 +4443,8 @@
if (const TargetAsmInfo *TAI = TheTarget->getTargetAsmInfo())
TAI->ExpandInlineAsm(CV);
+ if (NumChoices>1)
+ FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
return 0;
}
Modified: llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/testsuite/g++.apple/asm-block-54.C
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/testsuite/g%2B%2B.apple/asm-block-54.C?rev=76143&r1=76142&r2=76143&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/testsuite/g++.apple/asm-block-54.C (original)
+++ llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/testsuite/g++.apple/asm-block-54.C Thu Jul 16 21:17:21 2009
@@ -2,7 +2,8 @@
/* APPLE LOCAL x86_64 */
/* { dg-require-effective-target ilp32 } */
/* { dg-options { -fasm-blocks -msse3 } } */
-/* { dg-final { scan-assembler "movq -\(16|36\)\\\(%ebp\\\), %mm0" } } */
+/* LLVM LOCAL */
+/* { dg-final { scan-assembler "movq -\(16|36|24\)\\\(%ebp\\\), %mm0" } } */
/* Radar 4515069 */
void foo() {
Modified: llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/testsuite/gcc.apple/asm-block-54.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/testsuite/gcc.apple/asm-block-54.c?rev=76143&r1=76142&r2=76143&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/testsuite/gcc.apple/asm-block-54.c (original)
+++ llvm-gcc-4.2/branches/Apple/Bender-SWB/gcc/testsuite/gcc.apple/asm-block-54.c Thu Jul 16 21:17:21 2009
@@ -1,7 +1,8 @@
/* { dg-do compile { target i?86*-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options { -fasm-blocks -msse3 } } */
-/* { dg-final { scan-assembler "movq -\(16|36\)\\\(%ebp\\\), %mm0" } } */
+/* LLVM LOCAL */
+/* { dg-final { scan-assembler "movq -\(16|36|24\)\\\(%ebp\\\), %mm0" } } */
/* Radar 4515069 */
void foo() {
More information about the llvm-branch-commits
mailing list