This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
While it always seemed wrong to me that there's no way to avoid the default "flags" and "fpsr" clobbers, the regression the fix for PR/60663 introduced (see PR/63637) makes it even more desirable to have such a mechanism: This way, at least asm()s with a single output and no explicit clobbers can again be made subject to CSE. gcc: 2014-10-31 Jan Beulich <jbeulich@suse.com> * config/i386/i386.c (ix86_target_string): Add -mno-default-asm-clobbers. (ix86_valid_target_attribute_inner_p): Handle -m{,no-}default-asm-clobbers. (ix86_md_asm_clobbers): Handle "inverse" clobbers. * config/i386/i386.h (NOCC_REGNUM, NOFPSR_REGNUM): Define. (ADDITIONAL_REGISTER_NAMES): Add "cc", "!cc", "!flags", and "!fpsr". * config/i386/i386.opt: Add mdefault-asm-clobbers and mno-default-asm-clobbers. * varasm.c (decode_reg_name_and_count): Permit negative register numbers in ADDITIONAL_REGISTER_NAMES. gcc/testsuite: 2014-10-31 Jan Beulich <jbeulich@suse.com> * gcc.target/i386/20060218-1.c: Adjust expected error. * gcc.target/i386/invclbr[123].c: New. --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2664,6 +2664,7 @@ ix86_target_string (HOST_WIDE_INT isa, i { "-minline-stringops-dynamically", MASK_INLINE_STRINGOPS_DYNAMICALLY }, { "-mms-bitfields", MASK_MS_BITFIELD_LAYOUT }, { "-mno-align-stringops", MASK_NO_ALIGN_STRINGOPS }, + { "-mno-default-asm-clobbers", MASK_NO_DEFAULT_ASM_CLOBBERS }, { "-mno-fancy-math-387", MASK_NO_FANCY_MATH_387 }, { "-mno-push-args", MASK_NO_PUSH_ARGS }, { "-mno-red-zone", MASK_NO_RED_ZONE }, @@ -4649,6 +4650,10 @@ ix86_valid_target_attribute_inner_p (tre OPT_mno_align_stringops, MASK_NO_ALIGN_STRINGOPS), + IX86_ATTR_NO ("default-asm-clobbers", + OPT_mno_default_asm_clobbers, + MASK_NO_DEFAULT_ASM_CLOBBERS), + IX86_ATTR_YES ("recip", OPT_mrecip, MASK_RECIP), @@ -44165,10 +44170,31 @@ ix86_c_mode_for_suffix (char suffix) static tree ix86_md_asm_clobbers (tree, tree, tree clobbers) { - clobbers = tree_cons (NULL_TREE, build_string (5, "flags"), - clobbers); - clobbers = tree_cons (NULL_TREE, build_string (4, "fpsr"), - clobbers); + tree clobber; + bool flags_used = false, fpsr_used = false; + bool nocc_used = false, nofpsr_used = false; + + if (!TARGET_DEFAULT_ASM_CLOBBERS) + return clobbers; + + for (clobber = clobbers; clobber; clobber = TREE_CHAIN (clobber)) + switch (decode_reg_name (TREE_STRING_POINTER (TREE_VALUE (clobber)))) + { + case FLAGS_REG: flags_used = true; break; + case FPSR_REG: fpsr_used = true; break; + case NOCC_REGNUM: nocc_used = true; break; + case NOFPSR_REGNUM: nofpsr_used = true; break; + } + + if ((flags_used && nocc_used) || (fpsr_used && nofpsr_used)) + error ("conflicting clobbers in %<asm%>"); + + if (!flags_used && !nocc_used) + clobbers = tree_cons (NULL_TREE, build_string (5, "flags"), + clobbers); + if (!fpsr_used && !nofpsr_used) + clobbers = tree_cons (NULL_TREE, build_string (4, "fpsr"), + clobbers); return clobbers; } --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1242,6 +1242,11 @@ extern const char *host_detect_local_cpu ? INVALID_REGNUM \ : REAL_PIC_OFFSET_TABLE_REGNUM) +/* Fake register numbers to be used as "inverse" asm() clobber specifiers. + Any negative numbers below the range used by decode_reg_name () will do. */ +#define NOCC_REGNUM (-127) +#define NOFPSR_REGNUM (-126) + #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_" /* This is overridden by <cygwin.h>. */ @@ -2059,7 +2064,9 @@ do { \ { "zmm16", 53}, { "zmm17", 54}, { "zmm18", 55}, { "zmm19", 56}, \ { "zmm20", 57}, { "zmm21", 58}, { "zmm22", 59}, { "zmm23", 60}, \ { "zmm24", 61}, { "zmm25", 62}, { "zmm26", 63}, { "zmm27", 64}, \ - { "zmm28", 65}, { "zmm29", 66}, { "zmm30", 67}, { "zmm31", 68} } + { "zmm28", 65}, { "zmm29", 66}, { "zmm30", 67}, { "zmm31", 68}, \ + { "cc", FLAGS_REG }, { "!cc", NOCC_REGNUM }, \ + { "!flags", NOCC_REGNUM }, { "!fpsr", NOFPSR_REGNUM } } /* Note we are omitting these since currently I don't know how to get gcc to use these, since they want the same but different --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -287,6 +287,10 @@ Enum(pmode) String(long) Value(PMODE_DI) mcpu= Target RejectNegative Joined Undocumented Alias(mtune=) Warn(%<-mcpu=%> is deprecated; use %<-mtune=%> or %<-march=%> instead) +mdefault-asm-clobbers +Target RejectNegative Report InverseMask(NO_DEFAULT_ASM_CLOBBERS, DEFAULT_ASM_CLOBBERS) Undocumented Save +Attach compatibility clobbers (flags and fpsr) to every asm(). + mfancy-math-387 Target RejectNegative Report InverseMask(NO_FANCY_MATH_387, USE_FANCY_MATH_387) Save Generate sin, cos, sqrt for FPU @@ -355,6 +359,10 @@ Use native (MS) bitfield layout mno-align-stringops Target RejectNegative Report Mask(NO_ALIGN_STRINGOPS) Undocumented Save +mno-default-asm-clobbers +Target RejectNegative Report Mask(NO_DEFAULT_ASM_CLOBBERS) Save +Don't attach compatibility clobbers (flags and fpsr) to every asm(). + mno-fancy-math-387 Target RejectNegative Report Mask(NO_FANCY_MATH_387) Undocumented Save --- a/gcc/testsuite/gcc.target/i386/20060218-1.c +++ b/gcc/testsuite/gcc.target/i386/20060218-1.c @@ -3,6 +3,6 @@ void foo (void) { - register int cc __asm ("cc"); /* { dg-error "invalid register name" } */ + register int cc __asm ("cc"); /* { dg-error "register specified .* not general enough" } */ __asm ("" : : "r" (cc) : "cc"); } --- a/gcc/testsuite/gcc.target/i386/invclbr1.c +++ b/gcc/testsuite/gcc.target/i386/invclbr1.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ + +void test(void) +{ + asm ("" ::: "cc" ); + asm ("" ::: "!cc" ); + asm ("" ::: "flags" ); + asm ("" ::: "!flags" ); + asm ("" ::: "fpsr" ); + asm ("" ::: "!fpsr" ); + + asm ("" ::: "cc", "!cc" ); /* { dg-error "conflicting clobbers" } */ + asm ("" ::: "flags", "!cc" ); /* { dg-error "conflicting clobbers" } */ + asm ("" ::: "cc", "!flags" ); /* { dg-error "conflicting clobbers" } */ + asm ("" ::: "flags", "!flags" ); /* { dg-error "conflicting clobbers" } */ + asm ("" ::: "fpsr", "!fpsr" ); /* { dg-error "conflicting clobbers" } */ + + asm ("" ::: "cc", "!fpsr" ); + asm ("" ::: "flags", "!fpsr" ); + asm ("" ::: "fpsr", "!flags" ); + asm ("" ::: "fpsr", "!cc" ); +} --- a/gcc/testsuite/gcc.target/i386/invclbr2.c +++ b/gcc/testsuite/gcc.target/i386/invclbr2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-expand" } */ + +void test(void) +{ + asm ("" ::: "!cc", "!fpsr" ); + asm ("" ::: "!fpsr", "!flags" ); +} + +/* { dg-final { scan-rtl-dump-not "clobber" "expand" } } */ +/* { dg-final { cleanup-rtl-dump "expand" } } */ --- a/gcc/testsuite/gcc.target/i386/invclbr3.c +++ b/gcc/testsuite/gcc.target/i386/invclbr3.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-rtl-expand" } */ + +void test(void) +{ + asm ("" ::: "!cc"); + asm ("" ::: "!flags"); + asm ("" ::: "!fpsr"); +} + +/* { dg-final { scan-rtl-dump-times "\\(clobber \\(reg\[^()\]* fpsr\\)\\)" 2 "expand" } } */ +/* { dg-final { scan-rtl-dump-times "\\(clobber \\(reg\[^()\]* flags\\)\\)" 1 "expand" } } */ +/* { dg-final { cleanup-rtl-dump "expand" } } */ --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -936,7 +936,7 @@ decode_reg_name_and_count (const char *a for (i = 0; i < (int) ARRAY_SIZE (table); i++) if (table[i].name[0] && ! strcmp (asmspec, table[i].name) - && reg_names[table[i].number][0]) + && (table[i].number < 0 || reg_names[table[i].number][0])) return table[i].number; } #endif /* ADDITIONAL_REGISTER_NAMES */
Attachment:
gcc-trunk-x86-no-default-asm-clobbers.patch
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |