--- gcc/config/i386.h 2018/04/24 17:51:31 1.1.1.1 +++ gcc/config/i386.h 2018/04/24 17:58:31 1.1.1.3 @@ -19,7 +19,7 @@ the Free Software Foundation, 675 Mass A /* The purpose of this file is to define the characteristics of the i386, - independant of assembler syntax or operating system. + independent of assembler syntax or operating system. Three other files build on this one to describe a specific assembler syntax: bsd386.h, att386.h, and sun386.h. @@ -57,6 +57,15 @@ extern int target_flags; and is not intended to be usable on this cpu. */ #define TARGET_REGPARM (target_flags & 020) +/* Put uninitialized locals into bss, not data. + Meaningful only on svr3. */ +#define TARGET_SVR3_SHLIB (target_flags & 040) + +/* Use IEEE floating point comparisons. These handle correctly the cases + where the result of a comparison is unordered. Normally SIGFPE is + generated in such cases, in which case this isn't needed. */ +#define TARGET_IEEE_FP (target_flags & 0100) + /* Macro to define tables used to set the flags. This is a list in braces of pairs in braces, each pair being { "NAME", VALUE } @@ -73,6 +82,10 @@ extern int target_flags; { "nortd", -8}, \ { "regparm", 020}, \ { "noregparm", -020}, \ + { "svr3-shlib", 040}, \ + { "nosvr3-shlib", -040}, \ + { "ieee-fp", 0100}, \ + { "noieee-fp", -0100}, \ { "", TARGET_DEFAULT}} /* target machine storage layout */ @@ -91,7 +104,7 @@ extern int target_flags; /* Not true for 80386 */ #define WORDS_BIG_ENDIAN 0 -/* number of bits in an addressible storage unit */ +/* number of bits in an addressable storage unit */ #define BITS_PER_UNIT 8 /* Width in bits of a "word", which is the contents of a machine register. @@ -129,9 +142,9 @@ extern int target_flags; quantities, but these can be aligned on any 32-bit boundary. */ #define BIGGEST_ALIGNMENT 32 -/* Define this if move instructions will actually fail to work +/* Set this non-zero if move instructions will actually fail to work when given unaligned data. */ -/* #define STRICT_ALIGNMENT */ +#define STRICT_ALIGNMENT 0 /* If bit field type is int, don't let it cross an int, and give entire struct the alignment of an int. */ @@ -309,13 +322,16 @@ extern int target_flags; in a smaller-numbered class. For any two classes, it is very desirable that there be another - class that represents their union. */ - + class that represents their union. + + It might seem that class BREG is unnecessary, since no useful 386 + opcode needs reg %ebx. But some systems pass args to the OS in ebx, + and the "b" register constraint is useful in asms for syscalls. */ enum reg_class { NO_REGS, - AREG, DREG, CREG, + AREG, DREG, CREG, BREG, Q_REGS, /* %eax %ebx %ecx %edx */ SIREG, DIREG, INDEX_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp */ @@ -331,7 +347,7 @@ enum reg_class #define REG_CLASS_NAMES \ { "NO_REGS", \ - "AREG", "DREG", "CREG", \ + "AREG", "DREG", "CREG", "BREG", \ "Q_REGS", \ "SIREG", "DIREG", \ "INDEX_REGS", \ @@ -346,7 +362,7 @@ enum reg_class #define REG_CLASS_CONTENTS \ { 0, \ - 0x1, 0x2, 0x4, /* AREG, DREG, CREG */ \ + 0x1, 0x2, 0x4, 0x8, /* AREG, DREG, CREG, BREG */ \ 0xf, /* Q_REGS */ \ 0x10, 0x20, /* SIREG, DIREG */ \ 0x1007f, /* INDEX_REGS */ \ @@ -409,6 +425,7 @@ extern enum reg_class regclass_map[FIRST (C) == 't' ? FP_TOP_REG : \ (C) == 'u' ? FP_SECOND_REG : \ (C) == 'a' ? AREG : \ + (C) == 'b' ? BREG : \ (C) == 'c' ? CREG : \ (C) == 'd' ? DREG : \ (C) == 'D' ? DIREG : \ @@ -435,10 +452,12 @@ extern enum reg_class regclass_map[FIRST 0) /* Similar, but for floating constants, and defining letters G and H. - Here VALUE is the CONST_DOUBLE rtx itself. */ + Here VALUE is the CONST_DOUBLE rtx itself. We allow constants even if + TARGET_387 isn't set, because the stack register converter may need to + load 0.0 into the function value register. */ #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - ((C) == 'G' ? (TARGET_80387 && standard_80387_constant_p (VALUE)) : 0) + ((C) == 'G' ? standard_80387_constant_p (VALUE) : 0) /* Place additional restrictions on the register class to use when it is necessary to be able to hold a value of mode @var{mode} in a reload @@ -988,7 +1007,7 @@ do { \ differently depending on something about the variable or function named by the symbol (such as what section it is in). - On i386, if using PIC, mark a SYMBOL_REF for a static declaration + On i386, if using PIC, mark a SYMBOL_REF for a non-global symbol so that we may access it directly in the GOT. */ #define ENCODE_SECTION_INFO(DECL) \ @@ -996,9 +1015,11 @@ do \ { \ if (flag_pic) \ { \ - rtx decl_rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) == 'c' \ - ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ - SYMBOL_REF_FLAG (XEXP (decl_rtl, 0)) = ! TREE_PUBLIC (DECL); \ + rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ + SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ + = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + || ! TREE_PUBLIC (DECL)); \ } \ } \ while (0) @@ -1079,14 +1100,19 @@ while (0) /* Provide the costs of a rtl expression. This is in the body of a switch on CODE. */ -#define RTX_COSTS(X,CODE) \ +#define RTX_COSTS(X,CODE,OUTER_CODE) \ case MULT: \ return COSTS_N_INSNS (10); \ case DIV: \ case UDIV: \ case MOD: \ case UMOD: \ - return COSTS_N_INSNS (40); + return COSTS_N_INSNS (40); \ + case PLUS: \ + if (GET_CODE (XEXP (X, 0)) == REG \ + && GET_CODE (XEXP (X, 1)) == CONST_INT) \ + return 1; \ + break; /* Compute the cost of computing a constant rtl expression RTX @@ -1094,7 +1120,7 @@ while (0) of a switch statement. If the code is computed here, return it with a return statement. Otherwise, break from the switch. */ -#define CONST_COSTS(RTX,CODE) \ +#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ case CONST_INT: \ case CONST: \ case LABEL_REF: \ @@ -1106,11 +1132,7 @@ while (0) return code == 1 ? 0 : \ code == 2 ? 1 : \ 2; \ - } \ - case PLUS: \ - if (GET_CODE (XEXP (RTX, 0)) == REG \ - && GET_CODE (XEXP (RTX, 1)) == CONST_INT) \ - return 1; + } /* Compute the cost of an address. This is meant to approximate the size and/or execution delay of an insn using that address. If the cost is @@ -1132,6 +1154,33 @@ while (0) : REG_P (RTX) ? 1 \ : 2) +/* Add any extra modes needed to represent the condition code. + + For the i386, we need separate modes when floating-point equality + comparisons are being done. */ + +#define EXTRA_CC_MODES CCFPEQmode + +/* Define the names for the modes specified above. */ +#define EXTRA_CC_NAMES "CCFPEQ" + +/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, + return the mode to be used for the comparison. + + For floating-point equality comparisons, CCFPEQmode should be used. + VOIDmode should be used in all other cases. */ + +#define SELECT_CC_MODE(OP,X) \ + (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ + && ((OP) == EQ || (OP) == NE) ? CCFPEQmode : CCmode) + +/* Define the information needed to generate branch and scc insns. This is + stored from the compare operation. Note that we can't use "rtx" here + since it hasn't been defined! */ + +extern struct rtx_def *i386_compare_op0, *i386_compare_op1; +extern struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)(); + /* Tell final.c how to eliminate redundant test instructions. */ /* Here we define machine-dependent flags and fields in cc_status @@ -1201,7 +1250,7 @@ to get gcc to use these, since they want number as al, and ax. */ -/* note the last four are not really qi_registsers, but +/* note the last four are not really qi_registers, but the md will have to never output movb into one of them only a movw . There is no movb into the last four regs */