diff options
Diffstat (limited to 'gcc')
34 files changed, 957 insertions, 554 deletions
diff --git a/gcc/config/a29k/a29k.h b/gcc/config/a29k/a29k.h index be45772..b8e43cc 100644 --- a/gcc/config/a29k/a29k.h +++ b/gcc/config/a29k/a29k.h @@ -99,7 +99,7 @@ extern int target_flags; #define TARGET_DEFAULT 3 -/* Define this to change the optimizations peformed by default. */ +/* Define this to change the optimizations performed by default. */ #define OPTIMIZATION_OPTIONS(LEVEL) \ { \ @@ -141,7 +141,7 @@ extern int target_flags; for them. Might as well be consistent with bytes. */ #define WORDS_BIG_ENDIAN 1 -/* 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. @@ -172,6 +172,9 @@ extern int target_flags; /* Every structure's size must be a multiple of this. */ #define STRUCTURE_SIZE_BOUNDARY 8 +/* A bitfield declared as `int' forces `int' alignment for the struct. */ +#define PCC_BITFIELD_TYPE_MATTERS 1 + /* No data type wants to be aligned rounder than this. */ #define BIGGEST_ALIGNMENT 32 diff --git a/gcc/config/a29k/a29k.md b/gcc/config/a29k/a29k.md index 6ce6e67..c5707cd 100644 --- a/gcc/config/a29k/a29k.md +++ b/gcc/config/a29k/a29k.md @@ -23,7 +23,7 @@ ;; The insns in this file are presented in the same order as the AMD 29000 ;; User's Manual (i.e., alphabetical by machine op-code). ;; -;; DEFINE_EXPAND's are located near the first occurrance of the major insn +;; DEFINE_EXPAND's are located near the first occurrence of the major insn ;; that they generate. ;; The only attribute we have is the type. We only care about calls, branches, @@ -2025,17 +2025,17 @@ { if (GET_CODE (operands[1]) == REG && REGNO (operands[0]) == REGNO (operands[1]) + 1) { - operands[2] = operand_subword (operands[0], 1, 1, DFmode); - operands[3] = operand_subword (operands[1], 1, 1, DFmode); - operands[4] = operand_subword (operands[0], 0, 1, DFmode); - operands[5] = operand_subword (operands[1], 0, 1, DFmode); + operands[2] = operand_subword (operands[0], 1, 1, DImode); + operands[3] = operand_subword (operands[1], 1, 1, DImode); + operands[4] = operand_subword (operands[0], 0, 1, DImode); + operands[5] = operand_subword (operands[1], 0, 1, DImode); } else { - operands[2] = operand_subword (operands[0], 0, 1, DFmode); - operands[3] = operand_subword (operands[1], 0, 1, DFmode); - operands[4] = operand_subword (operands[0], 1, 1, DFmode); - operands[5] = operand_subword (operands[1], 1, 1, DFmode); + operands[2] = operand_subword (operands[0], 0, 1, DImode); + operands[3] = operand_subword (operands[1], 0, 1, DImode); + operands[4] = operand_subword (operands[0], 1, 1, DImode); + operands[5] = operand_subword (operands[1], 1, 1, DImode); } }") diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 547919c..862cc80 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -88,15 +88,15 @@ extern int target_flags; scheduling. Note that this only saves compilation time; it doesn't matter for the final code. */ #ifdef riscos -#define TARGET_WHEN_DEBUGING 3 +#define TARGET_WHEN_DEBUGGING 3 #else -#define TARGET_WHEN_DEBUGING 1 +#define TARGET_WHEN_DEBUGGING 1 #endif #define OVERRIDE_OPTIONS \ { \ if (write_symbols != NO_DEBUG) \ - target_flags |= TARGET_WHEN_DEBUGING; \ + target_flags |= TARGET_WHEN_DEBUGGING; \ else if (TARGET_POKE_FUNCTION_NAME) \ target_flags |= 1; \ if (TARGET_FPE) \ @@ -125,7 +125,7 @@ extern int target_flags; numbered. */ #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 #define BITS_PER_WORD 32 @@ -144,6 +144,9 @@ extern int target_flags; #define BIGGEST_ALIGNMENT 32 +/* Every structures size must be a multiple of 32 bits. */ +#define STRUCTURE_SIZE_BOUNDARY 32 + #define STRICT_ALIGNMENT 1 /* Define number of bits in most basic integer type. @@ -329,13 +332,13 @@ enum reg_class This macro defines what the ranges are. C is the letter, and VALUE is a constant value. Return 1 if VALUE is in the range specified by C. - I: immediate arithmetic operand (i.e. 8 bits shifted as requried). + I: immediate arithmetic operand (i.e. 8 bits shifted as required). J: valid indexing constants. */ #define CONST_OK_FOR_LETTER_P(VALUE, C) \ ((C) == 'I' ? const_ok_for_arm (VALUE) : \ (C) == 'J' ? (abs (VALUE) < 4096) : 0) -/* Constaint letter 'G' for the FPU immediate constants. */ +/* Constant letter 'G' for the FPU immediate constants. */ #define CONST_DOUBLE_OK_FOR_LETTER_P(X,C) \ ((C) == 'G' ? const_double_rtx_ok_for_fpu (X) : 0) @@ -1163,7 +1166,7 @@ do \ extern char *arm_condition_codes[]; \ int i; \ \ - fflush (STREAM); /* XXX for dubugging only. */ \ + fflush (STREAM); /* XXX for debugging only. */ \ if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) \ { \ fprintf (STREAM, "@ \t"); \ diff --git a/gcc/config/convex/convex.h b/gcc/config/convex/convex.h index cd1a02b..e916987 100644 --- a/gcc/config/convex/convex.h +++ b/gcc/config/convex/convex.h @@ -112,7 +112,7 @@ extern char *output_call (); /* Define this if most significant word of a multiword number is numbered. */ #define WORDS_BIG_ENDIAN 1 -/* 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. @@ -150,9 +150,9 @@ extern char *output_call (); /* beware of doubles in structs -- 64 is incompatible with pcc */ #define BIGGEST_ALIGNMENT 32 -/* Define this if move instructions will actually fail to work +/* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ -/* #define STRICT_ALIGNMENT */ +#define STRICT_ALIGNMENT 0 /* Define sizes of basic C types to conform to ordinary usage -- these types depend on BITS_PER_WORD otherwise. */ diff --git a/gcc/config/fx80/fx80.h b/gcc/config/fx80/fx80.h index 7bba566..806c3230 100644 --- a/gcc/config/fx80/fx80.h +++ b/gcc/config/fx80/fx80.h @@ -138,7 +138,7 @@ extern int target_flags; since there are no machine instructions for them. */ #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. @@ -169,9 +169,9 @@ extern int target_flags; /* No data type wants to be aligned rounder than this. */ #define BIGGEST_ALIGNMENT 16 -/* 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 1 /* Define number of bits in most basic integer type. (If undefined, default is BITS_PER_WORD). */ diff --git a/gcc/config/gmicro/gmicro.h b/gcc/config/gmicro/gmicro.h index 3d50048..8dcb6ab 100644 --- a/gcc/config/gmicro/gmicro.h +++ b/gcc/config/gmicro/gmicro.h @@ -136,7 +136,7 @@ extern int target_flags; since there are no machine instructions for them. ????? */ #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. */ @@ -167,11 +167,12 @@ extern int target_flags; /* This is not necessarily 32 on the Gmicro */ #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. */ -/* Unaligned data is allowed on Gmicro, though the access is slow. */ -/* But now STRICT is defined */ -#define STRICT_ALIGNMENT + Unaligned data is allowed on Gmicro, though the access is slow. */ + +#define STRICT_ALIGNMENT 1 +#define SLOW_UNALIGNED_ACCESS 1 /* Make strings word-aligned so strcpy from constants will be faster. */ #define CONSTANT_ALIGNMENT(EXP, ALIGN) \ @@ -369,7 +370,7 @@ extern enum reg_class regno_reg_class[]; We do a trick here to modify the effective constraints on the machine description; we zorch the constraint letters that aren't appropriate for a specific target. This allows us to guarantee - that a specific kind of register will not be used for a given taget + that a specific kind of register will not be used for a given target without fiddling with the register classes above. */ #define REG_CLASS_FROM_LETTER(C) \ @@ -384,7 +385,7 @@ extern enum reg_class regno_reg_class[]; Return 1 if VALUE is in the range specified by C. For the Gmicro, all immediate value optimizations are done - by assember, so no machine dependent definition is necessary ??? */ + by assembler, so no machine dependent definition is necessary ??? */ /* #define CONST_OK_FOR_LETTER_P(VALUE, C) ((C) == 'I') */ #define CONST_OK_FOR_LETTER_P(VALUE, C) 0 @@ -402,7 +403,7 @@ extern enum reg_class regno_reg_class[]; in class CLASS, return the class of reg to actually use. In general this is just CLASS; but on some machines in some cases it is preferable to use a more restrictive class. */ -/* On the Gmicro series, there is no restricton on GENERAL_REGS, +/* On the Gmicro series, there is no restriction on GENERAL_REGS, so CLASS is returned. I do not know whether I should treat FPU_REGS specially or not (at least, m68k does not). */ @@ -438,7 +439,7 @@ extern enum reg_class regno_reg_class[]; /* If we generate an insn to push BYTES bytes, this says how many the stack pointer really advances by. */ -/* On the Gmicro, sp is decrimented by the exact size of the operand */ +/* On the Gmicro, sp is decremented by the exact size of the operand */ #define PUSH_ROUNDING(BYTES) (BYTES) /* Offset of first parameter from the argument pointer register value. */ @@ -1215,7 +1216,7 @@ extern enum reg_class regno_reg_class[]; #define NOTICE_UPDATE_CC(EXP, INSN) {CC_STATUS_INIT;} -/* The skelton of the next macro is taken from "vax.h". +/* The skeleton of the next macro is taken from "vax.h". FPU-reg manipulation is added. M.Yuhara */ /* Now comment out. #define NOTICE_UPDATE_CC(EXP, INSN) { \ diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index e24cbd1..9878b50 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -19,7 +19,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* 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. @@ -91,7 +91,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 +129,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. */ @@ -439,10 +439,12 @@ extern enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; 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 @@ -992,7 +994,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) \ @@ -1000,9 +1002,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) @@ -1205,7 +1209,7 @@ to get gcc to use these, since they want the same but different 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 */ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index aa8fa53..f532bb7 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -252,30 +252,60 @@ ;; logical compare -;; ??? What if we are testing one byte of an offsettable memory reference? (define_insn "" [(set (cc0) - (and:SI (match_operand:SI 0 "general_operand" "%rm") + (and:SI (match_operand:SI 0 "general_operand" "%ro") (match_operand:SI 1 "general_operand" "ri")))] "" "* { /* For small integers, we may actually use testb. */ if (GET_CODE (operands[1]) == CONST_INT - && (INTVAL (operands[1]) & ~0xffff) == 0 - && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) + && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) + && ! NON_QI_REG_P (operands[0])) { /* We may set the sign bit spuriously. */ - cc_status.flags |= CC_NOT_NEGATIVE; - if (! NON_QI_REG_P (operands[0]) && (INTVAL (operands[1]) & ~0xff) == 0) - return AS2 (test%B0,%1,%b0); + if ((INTVAL (operands[1]) & ~0xff) == 0) + { + cc_status.flags |= CC_NOT_NEGATIVE; + return AS2 (test%B0,%1,%b0); + } - if (QI_REG_P (operands[0]) && (INTVAL (operands[1]) & ~0xff00) == 0) + if ((INTVAL (operands[1]) & ~0xff00) == 0) { + cc_status.flags |= CC_NOT_NEGATIVE; operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) >> 8); - return AS2 (test%B0,%1,%h0); + + if (QI_REG_P (operands[0])) + return AS2 (test%B0,%1,%h0); + else + { + operands[0] = adj_offsettable_operand (operands[0], 1); + return AS2 (test%B0,%1,%b0); + } + } + + if (GET_CODE (operands[0]) == MEM + && (INTVAL (operands[1]) & ~0xff0000) == 0) + { + cc_status.flags |= CC_NOT_NEGATIVE; + operands[1] = gen_rtx (CONST_INT, VOIDmode, + INTVAL (operands[1]) >> 16); + + operands[0] = adj_offsettable_operand (operands[0], 2); + return AS2 (test%B0,%1,%b0); + } + + if (GET_CODE (operands[0]) == MEM + && (INTVAL (operands[1]) & ~0xff000000) == 0) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, + (INTVAL (operands[1]) >> 24) & 0xff); + + operands[0] = adj_offsettable_operand (operands[0], 3); + return AS2 (test%B0,%1,%b0); } } @@ -287,18 +317,18 @@ (define_insn "" [(set (cc0) - (and:HI (match_operand:HI 0 "general_operand" "%rm") + (and:HI (match_operand:HI 0 "general_operand" "%ro") (match_operand:HI 1 "general_operand" "ri")))] "" "* { if (GET_CODE (operands[1]) == CONST_INT - && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) + && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) + && ! NON_QI_REG_P (operands[0])) { - /* Can we ignore the upper byte? */ - if (! NON_QI_REG_P (operands[0]) - && (INTVAL (operands[1]) & 0xff00) == 0) + if ((INTVAL (operands[1]) & 0xff00) == 0) { + /* ??? This might not be necessary. */ if (INTVAL (operands[1]) & 0xffff0000) operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) & 0xff); @@ -308,13 +338,18 @@ return AS2 (test%B0,%1,%b0); } - /* Can we ignore the lower byte? */ - /* ??? what about offsettable memory references? */ - if (QI_REG_P (operands[0]) && (INTVAL (operands[1]) & 0xff) == 0) + if ((INTVAL (operands[1]) & 0xff) == 0) { operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) >> 8) & 0xff); - return AS2 (test%B0,%1,%h0); + + if (QI_REG_P (operands[0])) + return AS2 (test%B0,%1,%h0); + else + { + operands[0] = adj_offsettable_operand (operands[0], 1); + return AS2 (test%B0,%1,%b0); + } } } @@ -747,47 +782,6 @@ ;;- conversion instructions ;;- NONE -;;- truncation instructions - -(define_insn "truncsiqi2" - [(set (match_operand:QI 0 "general_operand" "=q,qm") - (truncate:QI - (match_operand:SI 1 "general_operand" "qim,qn")))] - "" - "* -{ - if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT) - return AS2 (mov%L0,%1,%k0); - - return AS2 (mov%B0,%b1,%0); -}") - -(define_insn "trunchiqi2" - [(set (match_operand:QI 0 "general_operand" "=q,qm") - (truncate:QI - (match_operand:HI 1 "general_operand" "qim,qn")))] - "" - "* -{ - if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT) - return AS2 (mov%L0,%1,%k0); - - return AS2 (mov%B0,%b1,%0); -}") - -(define_insn "truncsihi2" - [(set (match_operand:HI 0 "general_operand" "=r,rm") - (truncate:HI - (match_operand:SI 1 "general_operand" "rim,rn")))] - "" - "* -{ - if (CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != CONST_INT) - return AS2 (mov%L0,%1,%k0); - - return AS2 (mov%W0,%w1,%0); -}") - ;;- zero extension instructions ;; See comments by `andsi' for when andl is faster than movzx. @@ -1060,7 +1054,7 @@ operands[1] = copy_to_mode_reg (SFmode, operands[1]); }") -;; These match a signed convertion of either DFmode or SFmode to DImode. +;; These match a signed conversion of either DFmode or SFmode to DImode. (define_insn "" [(set (match_operand:DI 0 "general_operand" "=m,!*r") @@ -1113,7 +1107,7 @@ ;; Conversion between fixed point and floating point. ;; The actual pattern that matches these is at the end of this file. -;; ??? Possibly repsent floatunssidf2 here in gcc2. +;; ??? Possibly represent floatunssidf2 here in gcc2. (define_expand "floatsisf2" [(set (match_operand:SF 0 "register_operand" "") @@ -1860,7 +1854,7 @@ CC_STATUS_INIT; if (INTVAL (operands[2]) == 0xff) - return AS1 (not%B0,%0); + return AS1 (not%B0,%b0); return AS2 (xor%B0,%2,%b0); } @@ -1901,7 +1895,7 @@ INTVAL (operands[2]) & 0xffff); if (INTVAL (operands[2]) == 0xff) - return AS1 (not%B0,%0); + return AS1 (not%B0,%b0); return AS2 (xor%B0,%2,%b0); } @@ -2622,6 +2616,10 @@ ;; i486, it is faster to copy a MEM to REG and then use bt, than to use ;; bt on the MEM directly. +;; ??? The first argument of a zero_extract must not be reloaded, so +;; don't allow a MEM in the operand predicate without allowing it in the +;; constraint. + (define_insn "" [(set (cc0) (zero_extract (match_operand:QI 0 "register_operand" "q") (const_int 1) @@ -2643,36 +2641,12 @@ RET; }") -(define_insn "" - [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m") - (const_int 1) - (match_operand:SI 1 "general_operand" "ri"))) - (clobber (match_scratch:SI 2 "=&r"))] - "" - "* -{ - /* Copy memory to scratch register; pretend it was there to start with. */ - if (GET_CODE (operands[0]) == MEM) - { - output_asm_insn (AS2 (mov%L2,%0,%2), operands); - operands[0] = operands[2]; - } - if (GET_CODE (operands[1]) == CONST_INT) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (operands[1])); - output_asm_insn (AS2 (test%L0,%1,%0), operands); - } - else - { - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0])); - cc_status.flags |= CC_Z_IN_NOT_C; - output_asm_insn (AS2 (bt%L0,%1,%0), operands); - } - RET; -}") +;; ??? The first argument of a zero_extract must not be reloaded, so +;; don't allow a MEM in the operand predicate without allowing it in the +;; constraint. (define_insn "" - [(set (cc0) (zero_extract (match_operand:HI 0 "nonimmediate_operand" "r") + [(set (cc0) (zero_extract (match_operand:HI 0 "register_operand" "r") (const_int 1) (match_operand:SI 1 "general_operand" "ri")))] "" @@ -2680,8 +2654,32 @@ { if (GET_CODE (operands[1]) == CONST_INT) { - operands[1] = gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (operands[1])); - output_asm_insn (AS2 (test%W0,%1,%0), operands); + if (QI_REG_P (operands[0]) && INTVAL (operands[1]) < 8) + { + cc_status.flags |= CC_NOT_NEGATIVE; + operands[1] = gen_rtx (CONST_INT, VOIDmode, + 1 << INTVAL (operands[1])); + + output_asm_insn (AS2 (test%B0,%1,%b0), operands); + } + else if (QI_REG_P (operands[0])) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, + 1 << (INTVAL (operands[1]) - 8)); + + output_asm_insn (AS2 (test%B0,%1,%h0), operands); + } + else + { + /* ??? This will never set CC to negative, even if we test + the sign bit of the HImode reg. But CC0 is only tested + for EQ and NE after this insn. */ + + operands[1] = gen_rtx (CONST_INT, VOIDmode, + 1 << INTVAL (operands[1])); + + output_asm_insn (AS2 (test%L0,%1,%k0), operands); + } } else { @@ -2691,8 +2689,12 @@ RET; }") +;; ??? The first argument of a zero_extract must not be reloaded, so +;; don't allow a MEM in the operand predicate without allowing it in the +;; constraint. + (define_insn "" - [(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "r") + [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") (const_int 1) (match_operand:SI 1 "general_operand" "ri")))] "" @@ -2700,8 +2702,29 @@ { if (GET_CODE (operands[1]) == CONST_INT) { - operands[1] = gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (operands[1])); - output_asm_insn (AS2 (test%L0,%1,%0), operands); + if (QI_REG_P (operands[0]) && INTVAL (operands[1]) < 8) + { + cc_status.flags |= CC_NOT_NEGATIVE; + operands[1] = gen_rtx (CONST_INT, VOIDmode, + 1 << INTVAL (operands[1])); + + output_asm_insn (AS2 (test%B0,%1,%b0), operands); + } + else if (QI_REG_P (operands[0]) && INTVAL (operands[1]) < 16) + { + cc_status.flags |= CC_NOT_NEGATIVE; + operands[1] = gen_rtx (CONST_INT, VOIDmode, + 1 << (INTVAL (operands[1]) - 8)); + + output_asm_insn (AS2 (test%B0,%1,%h0), operands); + } + else + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, + 1 << INTVAL (operands[1])); + + output_asm_insn (AS2 (test%L0,%1,%0), operands); + } } else { @@ -3079,31 +3102,29 @@ ;; Emit code here to do the range checking and make the index zero based. (define_expand "casesi" - [(parallel + [(set (match_dup 5) + (minus:SI (match_operand:SI 0 "general_operand" "") + (match_operand:SI 1 "general_operand" ""))) + (set (cc0) + (compare (match_dup 5) + (match_operand:SI 2 "general_operand" ""))) + (set (pc) + (if_then_else (gtu (cc0) + (const_int 0)) + (label_ref (match_operand 4 "" "")) + (pc))) + (parallel [(set (pc) - (if_then_else (leu (minus:SI - (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "const_int_operand" "")) - (match_operand:SI 2 "const_int_operand" "")) - (plus:SI (mem:SI (plus:SI (pc) - (minus:SI (match_dup 0) - (match_dup 1)))) - (label_ref (match_operand 3 "" ""))) - (pc))) - (use (label_ref (match_operand 4 "" ""))) - (clobber (match_scratch:SI 5 ""))])] + (minus:SI (reg:SI 3) + (mem:SI (plus:SI (mult:SI (match_dup 5) + (const_int 4)) + (label_ref (match_operand 3 "" "")))))) + (clobber (match_scratch:SI 6 ""))])] "flag_pic" " { - rtx reg = gen_reg_rtx (SImode); - + operands[5] = gen_reg_rtx (SImode); current_function_uses_pic_offset_table = 1; - - emit_insn (gen_subsi3 (reg, operands[0], operands[1])); - emit_insn (gen_cmpsi (reg, operands[2])); - emit_jump_insn (gen_bgtu (operands[4])); - operands[0] = reg; - operands[1] = CONST0_RTX (SImode); }") ;; Implement a casesi insn. @@ -3137,30 +3158,25 @@ (define_insn "" [(set (pc) - (if_then_else (leu (minus:SI - (match_operand:SI 0 "general_operand" "r") - (match_operand:SI 1 "const_int_operand" "i")) - (match_operand:SI 2 "const_int_operand" "i")) - (plus:SI (mem:SI (plus:SI (pc) - (minus:SI (match_dup 0) - (match_dup 1)))) - (label_ref (match_operand 3 "" ""))) - (pc))) - (use (label_ref (match_operand 4 "" ""))) - (clobber (match_scratch:SI 5 "=&r"))] + (minus:SI (reg:SI 3) + (mem:SI (plus:SI + (mult:SI (match_operand:SI 0 "register_operand" "r") + (const_int 4)) + (label_ref (match_operand 1 "" "")))))) + (clobber (match_scratch:SI 2 "=&r"))] "" "* { rtx xops[4]; - xops[0] = pic_offset_table_rtx; - xops[1] = operands[5]; - xops[2] = operands[3]; - xops[3] = operands[0]; + xops[0] = operands[0]; + xops[1] = operands[1]; + xops[2] = operands[2]; + xops[3] = pic_offset_table_rtx; - output_asm_insn (AS2 (mov%L1,%0,%1), xops); - output_asm_insn (\"sub%L1 %l2@GOTOFF(%0,%3,4),%1\", xops); - output_asm_insn (AS1 (jmp,%*%1), xops); + output_asm_insn (AS2 (mov%L2,%3,%2), xops); + output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops); + output_asm_insn (AS1 (jmp,%*%2), xops); ASM_OUTPUT_ALIGN_CODE (asm_out_file); RET; }") @@ -3451,8 +3467,8 @@ (define_insn "" [(set (match_operand:QI 0 "general_operand" "=q") - (compare (mem:BLK (match_operand:SI 1 "general_operand" "D")) - (mem:BLK (match_operand:SI 2 "general_operand" "S")))) + (compare (mem:BLK (match_operand:SI 1 "general_operand" "S")) + (mem:BLK (match_operand:SI 2 "general_operand" "D")))) (use (match_operand:SI 3 "general_operand" "c")) (use (match_operand:SI 4 "immediate_operand" "i")) (clobber (match_dup 1)) @@ -3478,8 +3494,8 @@ (define_insn "" [(set (cc0) - (compare (mem:BLK (match_operand:SI 0 "general_operand" "D")) - (mem:BLK (match_operand:SI 1 "general_operand" "S")))) + (compare (mem:BLK (match_operand:SI 0 "general_operand" "S")) + (mem:BLK (match_operand:SI 1 "general_operand" "D")))) (use (match_operand:SI 2 "general_operand" "c")) (use (match_operand:SI 3 "immediate_operand" "i")) (clobber (match_dup 0)) diff --git a/gcc/config/i386/sequent.h b/gcc/config/i386/sequent.h index 8d67b98..8bd3e69 100644 --- a/gcc/config/i386/sequent.h +++ b/gcc/config/i386/sequent.h @@ -88,5 +88,29 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define FUNCTION_PROFILER(FILE, LABELNO) \ fprintf (FILE, "\tmovl $LP%d,%%eax\n\tcall mcount\n", (LABELNO)); -/* Assember pseudo-op for shared data segment. */ +/* Assembler pseudo-op for shared data segment. */ #define SHARED_SECTION_ASM_OP ".shdata" + +/* A C statement or statements which output an assembler instruction + opcode to the stdio stream STREAM. The macro-operand PTR is a + variable of type `char *' which points to the opcode name in its + "internal" form--the form that is written in the machine description. + + The Sequent assembler (identified as "Balance 8000 Assembler + 07/17/85 3.90" by "as -v") does not understand the `movs[bwl]' string + move mnemonics - it uses `smov[bwl]' instead. Change "movs" into + "smov", carefully avoiding the sign-extend opcodes. */ + +#define ASM_OUTPUT_OPCODE(STREAM, PTR) \ +{ \ + if ((PTR)[0] == 'm' \ + && (PTR)[1] == 'o' \ + && (PTR)[2] == 'v' \ + && (PTR)[3] == 's' \ + && ((PTR)[4] == 'b' || (PTR)[4] == 'w' || (PTR)[4] == 'l') \ + && ((PTR)[5] == ' ' || (PTR)[5] == '\t'|| (PTR)[5] == '\0')) \ + { \ + fprintf (STREAM, "smov"); \ + (PTR) += 4; \ + } \ +} diff --git a/gcc/config/i860/i860.c b/gcc/config/i860/i860.c index c4c75ca..51175c7 100644 --- a/gcc/config/i860/i860.c +++ b/gcc/config/i860/i860.c @@ -1347,8 +1347,8 @@ output_block_move (operands) output_asm_insn ("adds %4,%?r0,%5", xoperands); /* Predecrement the loop counter. This happens again also in the `bla' - instruction which precceds the loop, but we need to have it done - two times before we enter the loop because of the bizzare semantics + instruction which precedes the loop, but we need to have it done + two times before we enter the loop because of the bizarre semantics of the bla instruction. */ output_asm_insn ("adds %5,%2,%2", xoperands); @@ -1522,7 +1522,7 @@ output_delayed_branch (template, operands, insn) output_asm_insn (template, operands); /* Now recognize the insn which we put in its delay slot. - We must do this after outputing the branch insn, + We must do this after outputting the branch insn, since operands may just be a pointer to `recog_operand'. */ INSN_CODE (delay_insn) = insn_code_number = recog (pat, delay_insn); if (insn_code_number == -1) @@ -1557,7 +1557,7 @@ output_delay_insn (delay_insn) int i; /* Now recognize the insn which we put in its delay slot. - We must do this after outputing the branch insn, + We must do this after outputting the branch insn, since operands may just be a pointer to `recog_operand'. */ insn_code_number = recog_memoized (delay_insn); if (insn_code_number == -1) @@ -1567,7 +1567,7 @@ output_delay_insn (delay_insn) INSN_CODE (delay_insn) = insn_code_number; insn_extract (delay_insn); - /* It is possible that this insn has not been properly scaned by final + /* It is possible that this insn has not been properly scanned by final yet. If this insn's operands don't appear in the peephole's actual operands, then they won't be fixed up by final, so we make sure they get fixed up here. -- This is a kludge. */ @@ -1623,7 +1623,7 @@ sfmode_constant_to_ulong (x) #if TARGET_FLOAT_FORMAT != HOST_FLOAT_FORMAT # error IEEE emulation needed #endif - REAL_VALUE_FROM_CONST_DOUBLE (u.d, x); + REAL_VALUE_FROM_CONST_DOUBLE (d, x); u2.f = d; return u2.i; } @@ -1663,7 +1663,7 @@ sfmode_constant_to_ulong (x) offsets from the frame pointer). Previous versions of GCC also saved the "preserved" registers in the - "nagative" part of the frame, but they saved them using positive + "negative" part of the frame, but they saved them using positive offsets from the (adjusted) stack pointer (after it had been adjusted to allocate space for the new frame). That's just plain wrong because if the current function calls alloca(), the stack pointer @@ -1702,7 +1702,7 @@ sfmode_constant_to_ulong (x) There are two somewhat different ways that you can generate prologues here... i.e. pedantically ABI-compliant, and the "other" way. The - "other" way is more consistant with what is currently generated by the + "other" way is more consistent with what is currently generated by the "native" svr4 C compiler for the i860. That's important if you want to use the current (as of 8/91) incarnation of svr4 SDB for the i860. The SVR4 SDB for the i860 insists on having function prologues be diff --git a/gcc/config/i860/i860.h b/gcc/config/i860/i860.h index 5bd9ed5..ac4b64b 100644 --- a/gcc/config/i860/i860.h +++ b/gcc/config/i860/i860.h @@ -77,7 +77,7 @@ extern int target_flags; /* For the i860 this goes with BYTES_BIG_ENDIAN. */ #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. @@ -117,9 +117,9 @@ extern int target_flags; boundaries. */ #define BIGGEST_ALIGNMENT 128 -/* Define this if move instructions will actually fail to work +/* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ -#define STRICT_ALIGNMENT +#define STRICT_ALIGNMENT 1 /* If bit field type is int, dont let it cross an int, and give entire struct the alignment of an int. */ @@ -1207,7 +1207,7 @@ struct cumulative_args { int ints, floats; }; `H' The operand is a numeric constant, a constant address, or a memory ref to a constant address. Print the correct notation to yield the high part of the given value or - address or the high part of the address of the refered + address or the high part of the address of the referred to memory object. `h' The operand is a numeric constant, a constant address, or @@ -1347,7 +1347,7 @@ extern unsigned long sfmode_constant_to_ulong (); libgcc1.c routines in such a way that they know the actual types of their formal arguments and the actual types of their return values. Otherwise, gcc will generate calls to the libgcc1.c - routines, passing argumenst in in the floating-point registers, + routines, passing arguments in the floating-point registers, but the libgcc1.c routines will expect their arguments on the stack (where the i860 calling conventions require structs & unions to be passed). */ @@ -1361,7 +1361,7 @@ extern unsigned long sfmode_constant_to_ulong (); /* Optionally define this if you have added predicates to `MACHINE.c'. This macro is called within an initializer of an array of structures. The first field in the structure is the - name of a predicate and the second field is an arrary of rtl + name of a predicate and the second field is an array of rtl codes. For each predicate, list all rtl codes that can be in expressions matched by the predicate. The list should have a trailing comma. Here is an example of two entries in the list diff --git a/gcc/config/i860/x-sysv4 b/gcc/config/i860/x-sysv4 index c766d9de..f480a57 100644 --- a/gcc/config/i860/x-sysv4 +++ b/gcc/config/i860/x-sysv4 @@ -9,9 +9,27 @@ INSTALL=cp # if we try to link programs with libucb.a before libc.a, those # programs tend to crash. -# More importantly, the alloca() routine supplied in early versions -# of svr4 for the i860 (in /usr/ucblib/libucb.a) is broken, so we -# should NOT try to use it anyway. +# Also, the alloca() routine supplied in early version of svr4 for +# the i860 is non-ABI compliant. It doesn't keep the stack aligned +# to a 16-byte boundary as the ABI requires. + +# More importantly however, even a fully ABI compliant alloca() routine +# would fail to work correctly with some versions of the native svr4 C +# compiler currently being distributed for the i860 (as of 1/29/92). +# The problem is that the native C compiler generates non-ABI-compliant +# function epilogues which cut back the stack (upon function exit) in +# an incorrect manner. Specifically, they cut back the stack by adding +# the nominal *static* frame size (determined statically at compile-time) +# to the stack pointer rather than setting the stack pointer based upon +# the current value of the frame pointer (as called for in the i860 ABI). +# This can cause serious trouble in cases where you repeatedly call a +# routine which itself calls alloca(). In such cases, the stack will +# grow continuously until you finally run out of swap space or exceed +# the system's process size limit. To avoid this problem (which can +# arise when a stage1 gcc is being used to build a stage2 gcc) you +# *must* link in the C language version of alloca() which is supplied +# with gcc to your stage1 version of gcc. The following definition +# forces that to happen. ALLOCA=alloca.o @@ -23,7 +41,7 @@ ALLOCA=alloca.o # i860 recognizes a special -gg option. Using that option causes *full* # Dwarf debugging information to be generated, whereas using only -g # causes only limited Dwarf debugging information to be generated. -# (This is an undocumented feature of that compiler.) +# (This is an undocumented feature of the native svr4 C compiler.) CCLIBFLAGS=-Bstatic -dn -gg GCC_CFLAGS=-static -g -O2 -B./ diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index 52dc753..2f0ed4e 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -82,7 +82,7 @@ extern int target_flags; #define TARGET_SKY (target_flags & 0200) /* Optimize for 68040. - The 68040 will execute all 68030 and 68881/2 instrcutions, but some + The 68040 will execute all 68030 and 68881/2 instructions, but some of them must be emulated in software by the OS. When TARGET_68040 is turned on, these instructions won't be used. This code will still run on a 68030 and 68881/2. */ @@ -158,7 +158,7 @@ extern int target_flags; So let's be consistent. */ #define WORDS_BIG_ENDIAN 1 -/* 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. @@ -189,9 +189,9 @@ extern int target_flags; /* No data type wants to be aligned rounder than this. */ #define BIGGEST_ALIGNMENT 16 -/* Define this if move instructions will actually fail to work +/* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ -#define STRICT_ALIGNMENT +#define STRICT_ALIGNMENT 1 #define SELECT_RTX_SECTION(MODE, X) \ { \ @@ -1254,11 +1254,6 @@ __transfer_from_trampoline () \ /* Nonzero if access to memory by bytes is slow and undesirable. */ #define SLOW_BYTE_ACCESS 0 -/* Define if shifts truncate the shift count - which implies one can omit a sign-extension or zero-extension - of a shift count. */ -#define SHIFT_COUNT_TRUNCATED - /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits is done just by pretending it is already truncated. */ #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 @@ -1328,6 +1323,9 @@ __transfer_from_trampoline () \ case LSHIFTRT: \ /* A shift by a big integer takes an extra instruction. */ \ if (GET_CODE (XEXP (X, 1)) == CONST_INT \ + && (INTVAL (XEXP (X, 1)) == 16)) \ + return COSTS_N_INSNS (2); /* clrw;swap */ \ + if (GET_CODE (XEXP (X, 1)) == CONST_INT \ && !(INTVAL (XEXP (X, 1)) > 0 \ && INTVAL (XEXP (X, 1)) <= 8)) \ return COSTS_N_INSNS (3); /* lsr #i,dn */ \ @@ -1335,7 +1333,17 @@ __transfer_from_trampoline () \ case MULT: \ if (GET_CODE (XEXP (x, 1)) == CONST_INT \ && exact_log2 (INTVAL (XEXP (x, 1))) >= 0) \ - total = 2; \ + { \ + /* A shift by a big integer takes an extra instruction. */ \ + if (GET_CODE (XEXP (X, 1)) == CONST_INT \ + && (INTVAL (XEXP (X, 1)) == (1 << 16))) \ + return COSTS_N_INSNS (2); /* clrw;swap */ \ + if (GET_CODE (XEXP (X, 1)) == CONST_INT \ + && !(INTVAL (XEXP (X, 1)) > 1 \ + && INTVAL (XEXP (X, 1)) <= 256)) \ + return COSTS_N_INSNS (3); /* lsr #i,dn */ \ + break; \ + } \ else if (GET_MODE (X) == QImode || GET_MODE (X) == HImode) \ return COSTS_N_INSNS (8); /* mul.w */ \ else \ @@ -1565,11 +1573,11 @@ do { union { float f; long l;} tem; \ that says to advance the location counter to a multiple of 2**LOG bytes. */ +/* We don't have a way to align to more than a two-byte boundary, so do the + best we can and don't complain. */ #define ASM_OUTPUT_ALIGN(FILE,LOG) \ - if ((LOG) == 1) \ - fprintf (FILE, "\t.even\n"); \ - else if ((LOG) != 0) \ - abort (); + if ((LOG) >= 1) \ + fprintf (FILE, "\t.even\n"); #define ASM_OUTPUT_SKIP(FILE,SIZE) \ fprintf (FILE, "\t.skip %u\n", (SIZE)) diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index df39ff2..7395126 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -221,7 +221,7 @@ ;;- "command register" mode means that no accessing of memory or the ;;- 68000 registers is being done. This can be expressed easily in ;;- constraints, so generally the mode of the instruction is -;;- determined by a branch off of which_alternative. In outputing +;;- determined by a branch off of which_alternative. In outputting ;;- instructions, a 'w' means to output an access to the constant ram ;;- (if the arg is CONST_DOUBLE and is one of the available ;;- constants), and 'x' means to output a register pair (if the arg is @@ -691,7 +691,7 @@ ;; ;; This is the main "hook" for PIC code. When generating ;; PIC, movsi is responsible for determining when the source address -;; needs PIC relocation and appropriatly calling legitimize_pic_address +;; needs PIC relocation and appropriately calling legitimize_pic_address ;; to perform the actual relocation. ;; ;; In both the PIC and non-PIC cases the patterns generated will @@ -1156,7 +1156,7 @@ { if (GET_CODE (operands[0]) == REG) { - /* Must clear condition codes, since the mov.l bases them on + /* Must clear condition codes, since the move.l bases them on the entire 32 bits, not just the desired 8 bits. */ CC_STATUS_INIT; return \"move%.l %1,%0\"; @@ -1177,14 +1177,14 @@ && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[1]) == CONST_INT)) { - /* Must clear condition codes, since the mov.w bases them on + /* Must clear condition codes, since the move.w bases them on the entire 16 bits, not just the desired 8 bits. */ CC_STATUS_INIT; return \"move%.w %1,%0\"; } if (GET_CODE (operands[0]) == REG) { - /* Must clear condition codes, since the mov.l bases them on + /* Must clear condition codes, since the move.l bases them on the entire 32 bits, not just the desired 8 bits. */ CC_STATUS_INIT; return \"move%.l %1,%0\"; @@ -1203,7 +1203,7 @@ { if (GET_CODE (operands[0]) == REG) { - /* Must clear condition codes, since the mov.l bases them on + /* Must clear condition codes, since the move.l bases them on the entire 32 bits, not just the desired 8 bits. */ CC_STATUS_INIT; return \"move%.l %1,%0\"; @@ -1747,7 +1747,7 @@ : \"subq%.l %2,%0\"); } /* On everything except the 68000 it is faster to use two - addqw instuctions to add a small integer (8 < N <= 16) + addqw instructions to add a small integer (8 < N <= 16) to an address register. Likewise for subqw.*/ if (INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16 @@ -1793,6 +1793,15 @@ #ifndef NO_ADDSUB_Q if (GET_CODE (operands[2]) == CONST_INT) { + /* If the constant would be a negative number when interpreted as + HImode, make it negative. This is usually, but not always, done + elsewhere in the compiler. First check for constants out of range, + which could confuse us. */ + + if (INTVAL (operands[2]) >= 32768) + operands[2] = gen_rtx (CONST_INT, VOIDmode, + INTVAL (operands[2]) - 65536); + if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 8) return \"addq%.w %2,%0\"; @@ -1804,7 +1813,7 @@ return \"subq%.w %2,%0\"; } /* On everything except the 68000 it is faster to use two - addqw instuctions to add a small integer (8 < N <= 16) + addqw insttuctions to add a small integer (8 < N <= 16) to an address register. Likewise for subqw. */ if (INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16 @@ -1839,14 +1848,108 @@ (plus:HI (match_dup 0) (match_operand:HI 1 "general_operand" "dn,rmn")))] "" - "add%.w %1,%0") + "* +{ +#ifndef NO_ADDSUB_Q + if (GET_CODE (operands[1]) == CONST_INT) + { + /* If the constant would be a negative number when interpreted as + HImode, make it negative. This is usually, but not always, done + elsewhere in the compiler. First check for constants out of range, + which could confuse us. */ + + if (INTVAL (operands[1]) >= 32768) + operands[1] = gen_rtx (CONST_INT, VOIDmode, + INTVAL (operands[1]) - 65536); + + if (INTVAL (operands[1]) > 0 + && INTVAL (operands[1]) <= 8) + return \"addq%.w %1,%0\"; + if (INTVAL (operands[1]) < 0 + && INTVAL (operands[1]) >= -8) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, + - INTVAL (operands[1])); + return \"subq%.w %1,%0\"; + } + /* On everything except the 68000 it is faster to use two + addqw instuctions to add a small integer (8 < N <= 16) + to an address register. Likewise for subqw. */ + if (INTVAL (operands[1]) > 8 + && INTVAL (operands[1]) <= 16 + && ADDRESS_REG_P (operands[0]) + && TARGET_68020) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); + return \"addq%.w %#8,%0; addq%.w %1,%0\"; + } + if (INTVAL (operands[1]) < -8 + && INTVAL (operands[1]) >= -16 + && ADDRESS_REG_P (operands[0]) + && TARGET_68020) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, + - INTVAL (operands[1]) - 8); + return \"subq%.w %#8,%0; subq%.w %1,%0\"; + } + } +#endif + return \"add%.w %1,%0\"; +}") (define_insn "" [(set (strict_low_part (match_operand:HI 0 "general_operand" "+m,d")) (plus:HI (match_operand:HI 1 "general_operand" "dn,rmn") (match_dup 0)))] "" - "add%.w %1,%0") + "* +{ +#ifndef NO_ADDSUB_Q + if (GET_CODE (operands[1]) == CONST_INT) + { + /* If the constant would be a negative number when interpreted as + HImode, make it negative. This is usually, but not always, done + elsewhere in the compiler. First check for constants out of range, + which could confuse us. */ + + if (INTVAL (operands[1]) >= 32768) + operands[1] = gen_rtx (CONST_INT, VOIDmode, + INTVAL (operands[1]) - 65536); + + if (INTVAL (operands[1]) > 0 + && INTVAL (operands[1]) <= 8) + return \"addq%.w %1,%0\"; + if (INTVAL (operands[1]) < 0 + && INTVAL (operands[1]) >= -8) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, + - INTVAL (operands[1])); + return \"subq%.w %1,%0\"; + } + /* On everything except the 68000 it is faster to use two + addqw instuctions to add a small integer (8 < N <= 16) + to an address register. Likewise for subqw. */ + if (INTVAL (operands[1]) > 8 + && INTVAL (operands[1]) <= 16 + && ADDRESS_REG_P (operands[0]) + && TARGET_68020) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) - 8); + return \"addq%.w %#8,%0; addq%.w %1,%0\"; + } + if (INTVAL (operands[1]) < -8 + && INTVAL (operands[1]) >= -16 + && ADDRESS_REG_P (operands[0]) + && TARGET_68020) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, + - INTVAL (operands[1]) - 8); + return \"subq%.w %#8,%0; subq%.w %1,%0\"; + } + } +#endif + return \"add%.w %1,%0\"; +}") (define_insn "addqi3" [(set (match_operand:QI 0 "general_operand" "=m,d") @@ -1858,12 +1961,13 @@ #ifndef NO_ADDSUB_Q if (GET_CODE (operands[2]) == CONST_INT) { + if (INTVAL (operands[2]) >= 128) + operands[2] = gen_rtx (CONST_INT, VOIDmode, + INTVAL (operands[2]) - 256); + if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 8) return \"addq%.b %2,%0\"; - } - if (GET_CODE (operands[2]) == CONST_INT) - { if (INTVAL (operands[2]) < 0 && INTVAL (operands[2]) >= -8) { operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2])); @@ -1879,14 +1983,54 @@ (plus:QI (match_dup 0) (match_operand:QI 1 "general_operand" "dn,dmn")))] "" - "add%.b %1,%0") + "* +{ +#ifndef NO_ADDSUB_Q + if (GET_CODE (operands[1]) == CONST_INT) + { + if (INTVAL (operands[1]) >= 128) + operands[1] = gen_rtx (CONST_INT, VOIDmode, + INTVAL (operands[1]) - 256); + + if (INTVAL (operands[1]) > 0 + && INTVAL (operands[1]) <= 8) + return \"addq%.b %1,%0\"; + if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); + return \"subq%.b %1,%0\"; + } + } +#endif + return \"add%.b %1,%0\"; +}") (define_insn "" [(set (strict_low_part (match_operand:QI 0 "general_operand" "+m,d")) (plus:QI (match_operand:QI 1 "general_operand" "dn,dmn") (match_dup 0)))] "" - "add%.b %1,%0") + "* +{ +#ifndef NO_ADDSUB_Q + if (GET_CODE (operands[1]) == CONST_INT) + { + if (INTVAL (operands[1]) >= 128) + operands[1] = gen_rtx (CONST_INT, VOIDmode, + INTVAL (operands[1]) - 256); + + if (INTVAL (operands[1]) > 0 + && INTVAL (operands[1]) <= 8) + return \"addq%.b %1,%0\"; + if (INTVAL (operands[1]) < 0 && INTVAL (operands[1]) >= -8) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[1])); + return \"subq%.b %1,%0\"; + } + } +#endif + return \"add%.b %1,%0\"; +}") (define_expand "adddf3" [(set (match_operand:DF 0 "general_operand" "") @@ -2542,11 +2686,7 @@ /* The swap insn produces cc's that don't correspond to the result. */ CC_STATUS_INIT; #ifdef MOTOROLA -#ifdef SGS_SWAP_W - return \"ext%.l %0\;divs%.w %2,%0\;swap%.w %0\"; -#else return \"ext%.l %0\;divs%.w %2,%0\;swap %0\"; -#endif #else return \"extl %0\;divs %2,%0\;swap %0\"; #endif @@ -2564,11 +2704,7 @@ /* The swap insn produces cc's that don't correspond to the result. */ CC_STATUS_INIT; #ifdef MOTOROLA -#ifdef SGS_SWAP_W - return \"divs%.w %2,%0\;swap%.w %0\"; -#else return \"divs%.w %2,%0\;swap %0\"; -#endif #else return \"divs %2,%0\;swap %0\"; #endif @@ -2584,11 +2720,7 @@ /* The swap insn produces cc's that don't correspond to the result. */ CC_STATUS_INIT; #ifdef MOTOROLA -#ifdef SGS_SWAP_W - return \"divs%.w %2,%0\;swap%.w %0\"; -#else return \"divs%.w %2,%0\;swap %0\"; -#endif #else return \"divs %2,%0\;swap %0\"; #endif @@ -2604,11 +2736,7 @@ /* The swap insn produces cc's that don't correspond to the result. */ CC_STATUS_INIT; #ifdef MOTOROLA -#ifdef SGS_SWAP_W - return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap%.w %0\"; -#else return \"and%.l %#0xFFFF,%0\;divu%.w %2,%0\;swap %0\"; -#endif #else return \"andl %#0xFFFF,%0\;divu %2,%0\;swap %0\"; #endif @@ -2626,11 +2754,7 @@ /* The swap insn produces cc's that don't correspond to the result. */ CC_STATUS_INIT; #ifdef MOTOROLA -#ifdef SGS_SWAP_W - return \"divu%.w %2,%0\;swap%.w %0\"; -#else return \"divu%.w %2,%0\;swap %0\"; -#endif #else return \"divu %2,%0\;swap %0\"; #endif @@ -2646,11 +2770,7 @@ /* The swap insn produces cc's that don't correspond to the result. */ CC_STATUS_INIT; #ifdef MOTOROLA -#ifdef SGS_SWAP_W - return \"divu%.w %2,%0\;swap%.w %0\"; -#else return \"divu%.w %2,%0\;swap %0\"; -#endif #else return \"divu %2,%0\;swap %0\"; #endif @@ -2690,7 +2810,7 @@ ;; Prevent AND from being made with sp. This doesn't exist in the machine ;; and reload will cause inefficient code. Since sp is a FIXED_REG, we -;; can't allocate psuedos into it. +;; can't allocate pseudos into it. (define_insn "andsi3" [(set (match_operand:SI 0 "not_sp_operand" "=m,d") (and:SI (match_operand:SI 1 "general_operand" "%0,0") @@ -3094,6 +3214,19 @@ ;; arithmetic shift instructions ;; We don't need the shift memory by 1 bit instruction +;; On all 68k models, this makes faster code in a special case. + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (ashift:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "immediate_operand" "i")))] + "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" + "* +{ + CC_STATUS_INIT; + return \"swap %0\;clr%.w %0\"; +}") + ;; On the 68000, this makes faster code in a special case. (define_insn "" @@ -3101,16 +3234,13 @@ (ashift:SI (match_operand:SI 1 "register_operand" "0") (match_operand:SI 2 "immediate_operand" "i")))] "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)" + && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" "* { CC_STATUS_INIT; - if (INTVAL (operands[2]) == 16) - return \"swap %0\;clrw %0\"; - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); - return \"asl%.w %2,%0\;swap %0\;clrw %0\"; + return \"asl%.w %2,%0\;swap %0\;clr%.w %0\"; }") (define_insn "ashlsi3" @@ -3153,6 +3283,15 @@ "" "asl%.b %1,%0") +;; On all 68k models, this makes faster code in a special case. + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "immediate_operand" "i")))] + "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" + "swap %0\;ext%.l %0") + ;; On the 68000, this makes faster code in a special case. (define_insn "" @@ -3160,12 +3299,9 @@ (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") (match_operand:SI 2 "immediate_operand" "i")))] "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)" + && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" "* { - if (INTVAL (operands[2]) == 16) - return \"swap %0\;ext%.l %0\"; - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); return \"swap %0\;asr%.w %2,%0\;ext%.l %0\"; }") @@ -3210,6 +3346,19 @@ ;; logical shift instructions +;; On all 68k models, this makes faster code in a special case. + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (lshift:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "immediate_operand" "i")))] + "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" + "* +{ + CC_STATUS_INIT; + return \"swap %0\;clr%.w %0\"; +}") + ;; On the 68000, this makes faster code in a special case. (define_insn "" @@ -3217,16 +3366,13 @@ (lshift:SI (match_operand:SI 1 "register_operand" "0") (match_operand:SI 2 "immediate_operand" "i")))] "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)" + && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" "* { CC_STATUS_INIT; - if (INTVAL (operands[2]) == 16) - return \"swap %0\;clrw %0\"; - operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); - return \"lsl%.w %2,%0\;swap %0\;clrw %0\"; + return \"lsl%.w %2,%0\;swap %0\;clr%.w %0\"; }") (define_insn "lshlsi3" @@ -3269,6 +3415,19 @@ "" "lsl%.b %1,%0") +;; On all 68k models, this makes faster code in a special case. + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "immediate_operand" "i")))] + "(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 16)" + "* +{ + CC_STATUS_INIT; + return \"clr%.w %0\;swap %0\"; +}") + ;; On the 68000, this makes faster code in a special case. (define_insn "" @@ -3276,18 +3435,12 @@ (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") (match_operand:SI 2 "immediate_operand" "i")))] "(! TARGET_68020 && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) >= 16 && INTVAL (operands[2]) <= 24)" + && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24)" "* { - if (INTVAL (operands[2]) == 16) - { - CC_STATUS_INIT; - return \"clrw %0\;swap %0\"; - } - /* I think lsr%.w sets the CC properly. */ operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 16); - return \"clrw %0\;swap %0\;lsr%.w %2,%0\"; + return \"clr%.w %0\;swap %0\;lsr%.w %2,%0\"; }") (define_insn "lshrsi3" @@ -4262,7 +4415,7 @@ } #ifdef MOTOROLA #ifdef SGS_CMP_ORDER -#ifndef NO_ADDSUB_Q +#ifdef NO_ADDSUB_Q return \"sub%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\"; #else return \"subq%.w %#1,%0\;cmp%.w %0,%#-1\;jbne %l1\"; @@ -4290,7 +4443,7 @@ { CC_STATUS_INIT; #ifdef MOTOROLA -#ifndef NO_ADDSUB_Q +#ifdef NO_ADDSUB_Q if (DATA_REG_P (operands[0])) return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\"; if (GET_CODE (operands[0]) == MEM) @@ -4300,9 +4453,9 @@ return \"dbra %0,%l1\;clr%.w %0\;subq%.l %#1,%0\;jbcc %l1\"; if (GET_CODE (operands[0]) == MEM) return \"subq%.l %#1,%0\;jbcc %l1\"; -#endif /* not NO_ADDSUB_Q */ +#endif /* NO_ADDSUB_Q */ #ifdef SGS_CMP_ORDER -#ifndef NO_ADDSUB_Q +#ifdef NO_ADDSUB_Q return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; #else return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; @@ -4312,19 +4465,65 @@ #endif /* not SGS_CMP_ORDER */ #else /* not MOTOROLA */ if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\"; + return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\"; if (GET_CODE (operands[0]) == MEM) return \"subql %#1,%0\;jcc %l1\"; return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\"; #endif /* not MOTOROLA */ }") -;; dbra patterns that use REG_NOTES info generated by strength_reduce. +;; Two dbra patterns that use REG_NOTES info generated by strength_reduce. + +(define_insn "" + [(set (pc) + (if_then_else + (ge (plus:HI (match_operand:HI 0 "general_operand" "+g") + (const_int -1)) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:HI (match_dup 0) + (const_int -1)))] + "find_reg_note (insn, REG_NONNEG, 0)" + "* +{ + CC_STATUS_INIT; +#ifdef MOTOROLA +#ifdef NO_ADDSUB_Q + if (DATA_REG_P (operands[0])) + return \"dbra %0,%l1\"; + if (GET_CODE (operands[0]) == MEM) + return \"sub%.w %#1,%0\;jbcc %l1\"; +#else + if (DATA_REG_P (operands[0])) + return \"dbra %0,%l1\"; + if (GET_CODE (operands[0]) == MEM) + return \"subq%.w %#1,%0\;jbcc %l1\"; +#endif +#ifdef SGS_CMP_ORDER +#ifdef NO_ADDSUB_Q + return \"sub.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\"; +#else + return \"subq.w %#1,%0\;cmp.w %0,%#-1\;jbne %l1\"; +#endif +#else /* not SGS_CMP_ORDER */ + return \"subq.w %#1,%0\;cmp.w %#-1,%0\;jbne %l1\"; +#endif /* not SGS_CMP_ORDER */ +#else /* not MOTOROLA */ + if (DATA_REG_P (operands[0])) + return \"dbra %0,%l1\"; + if (GET_CODE (operands[0]) == MEM) + return \"subqw %#1,%0\;jcc %l1\"; + return \"subqw %#1,%0\;cmpw %#-1,%0\;jne %l1\"; +#endif /* not MOTOROLA */ +}") (define_insn "decrement_and_branch_until_zero" [(set (pc) (if_then_else - (gt (match_operand:SI 0 "general_operand" "+g") + (ge (plus:SI (match_operand:SI 0 "general_operand" "+g") + (const_int -1)) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc))) @@ -4336,7 +4535,7 @@ { CC_STATUS_INIT; #ifdef MOTOROLA -#ifndef NO_ADDSUB_Q +#ifdef NO_ADDSUB_Q if (DATA_REG_P (operands[0])) return \"dbra %0,%l1\;clr%.w %0\;sub%.l %#1,%0\;jbcc %l1\"; if (GET_CODE (operands[0]) == MEM) @@ -4348,7 +4547,7 @@ return \"subq%.l %#1,%0\;jbcc %l1\"; #endif #ifdef SGS_CMP_ORDER -#ifndef NO_ADDSUB_Q +#ifdef NO_ADDSUB_Q return \"sub.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; #else return \"subq.l %#1,%0\;cmp.l %0,%#-1\;jbne %l1\"; @@ -4358,7 +4557,7 @@ #endif /* not SGS_CMP_ORDER */ #else /* not MOTOROLA */ if (DATA_REG_P (operands[0])) - return \"dbra %0,%l1\;clrw %0\;subql %#1,%0\;jcc %l1\"; + return \"dbra %0,%l1\;clr%.w %0\;subql %#1,%0\;jcc %l1\"; if (GET_CODE (operands[0]) == MEM) return \"subql %#1,%0\;jcc %l1\"; return \"subql %#1,%0\;cmpl %#-1,%0\;jne %l1\"; @@ -4476,7 +4675,7 @@ return \"tstl %0\"; }") -;; Used for framless functions which save no regs and allocate no locals. +;; Used for frameless functions which save no regs and allocate no locals. (define_insn "return" [(return)] "USE_RETURN_INSN" @@ -4626,6 +4825,71 @@ output_asm_insn (\"subq%.w %#4,%3\;move%.b %1,%2\", xoperands); return \"\"; }") + +;; dbCC peepholes +;; +;; Turns +;; loop: +;; [ ... ] +;; jCC label ; abnormal loop termination +;; dbra dN, loop ; normal loop termination +;; +;; Into +;; loop: +;; [ ... ] +;; dbCC dN, loop +;; jCC label +;; +;; Which moves the jCC condition outside the inner loop for free. +;; +(define_peephole + [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" + [(cc0) (const_int 0)]) + (label_ref (match_operand 2 "" "")) + (pc))) + (parallel + [(set (pc) + (if_then_else + (ge (plus:HI (match_operand:HI 0 "register_operand" "+d") + (const_int -1)) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:HI (match_dup 0) + (const_int -1)))])] + "DATA_REG_P (operands[0])" + "* +{ + CC_STATUS_INIT; + output_dbcc_and_branch (operands); + return \"\"; +}") + +(define_peephole + [(set (pc) (if_then_else (match_operator 3 "valid_dbcc_comparison_p" + [(cc0) (const_int 0)]) + (label_ref (match_operand 2 "" "")) + (pc))) + (parallel + [(set (pc) + (if_then_else + (ge (plus:SI (match_operand:SI 0 "register_operand" "+d") + (const_int -1)) + (const_int 0)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int -1)))])] + "DATA_REG_P (operands[0])" + "* +{ + CC_STATUS_INIT; + output_dbcc_and_branch (operands); + return \"\"; +}") + ;; FPA multiply and add. (define_insn "" diff --git a/gcc/config/m88k/m88k.c b/gcc/config/m88k/m88k.c index 8ba569c..ec11e20 100644 --- a/gcc/config/m88k/m88k.c +++ b/gcc/config/m88k/m88k.c @@ -47,7 +47,7 @@ extern char *ctime (); extern int flag_traditional; extern FILE *asm_out_file; -static char out_sccs_id[] = "@(#)m88k.c 2.0.2.1 28 Feb 1992 12:36:54"; +static char out_sccs_id[] = "@(#)m88k.c 2.0.2.2 02 Mar 1992 13:30:28"; static char tm_sccs_id [] = TM_SCCS_ID; char *m88k_pound_sign = ""; /* Either # for SVR4 or empty for SVR3 */ @@ -218,7 +218,7 @@ emit_move_sequence (operands, mode) emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); return 1; } - if (! reload_in_progress) + if (! reload_in_progress && ! reload_completed) { operands[0] = validize_mem (operand0); operands[1] = operand1 = force_reg (mode, operand1); @@ -231,7 +231,8 @@ emit_move_sequence (operands, mode) if (GET_CODE (operand1) != CONST_INT && GET_CODE (operand1) != CONST_DOUBLE) { - rtx temp = reload_in_progress ? operand0 : gen_reg_rtx (Pmode); + rtx temp = ((reload_in_progress || reload_completed) + ? operand0 : gen_reg_rtx (Pmode)); operands[1] = legitimize_address (flag_pic && symbolic_address_p (operand1), operand1, temp); @@ -696,7 +697,7 @@ output_xor (operands) /* Output a call. Normally this is just bsr or jsr, but this also deals with accomplishing a branch after the call by incrementing r1. This requires - that various assembler bugs be accomodated. The 4.30 DG/UX assembler + that various assembler bugs be accommodated. The 4.30 DG/UX assembler requires that forward references not occur when computing the difference of two labels. The [version?] Motorola assembler computes a word difference. No doubt there's more to come! @@ -819,7 +820,7 @@ output_short_branch_defs (stream) /* Report errors on floating point, if we are given NaN's, or such. Leave the number as is, though, since we output the number in hex, and the - assemble won't choak on it. */ + assembler won't choke on it. */ void check_float_value (mode, value) @@ -1884,7 +1885,7 @@ m88k_output_epilogue (stream, size) int size; { rtx insn = get_last_insn (); -#if (MONITOR_GCC & 0x4) /* What are interesting prologue/epiloge values? */ +#if (MONITOR_GCC & 0x4) /* What are interesting prologue/epilogue values? */ fprintf (stream, "; size = %d, m88k_fp_offset = %d, m88k_stack_size = %d\n", size, m88k_fp_offset, m88k_stack_size); #endif @@ -2727,7 +2728,7 @@ print_operand (file, x, code) fputs (reg_names[REGNO (x) + 1], file); return; - case 'r': /* an immediate 0 should be repesented as `r0' */ + case 'r': /* an immediate 0 should be represented as `r0' */ if (x == const0_rtx) { fputs (reg_names[0], file); diff --git a/gcc/config/ns32k/ns32k.h b/gcc/config/ns32k/ns32k.h index 897b1fb..92cda86 100644 --- a/gcc/config/ns32k/ns32k.h +++ b/gcc/config/ns32k/ns32k.h @@ -119,7 +119,7 @@ extern int target_flags; numbered. This is not true on the ns32k. */ #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. @@ -711,10 +711,8 @@ __transfer_from_trampoline () \ asm ("___trampoline:"); \ asm ("movd 16(r2),tos"); \ asm ("movd 12(r2),r2"); \ - asm ("ret"); \ + asm ("ret 0"); \ } - - /* Addressing modes, and classification of registers for them. */ diff --git a/gcc/config/ns32k/sequent.h b/gcc/config/ns32k/sequent.h index 2c06531..f03a0f6 100644 --- a/gcc/config/ns32k/sequent.h +++ b/gcc/config/ns32k/sequent.h @@ -18,10 +18,6 @@ You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* Two flags to control how addresses are printed in assembler insns. */ -#define SEQUENT_ADDRESS_BUG 1 -#define SEQUENT_BASE_REGS - #include "ns32k.h" /* This is BSD, so it wants DBX format. */ @@ -33,7 +29,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Don't split DBX symbols into continuations. */ #define DBX_CONTIN_LENGTH 0 -#define TARGET_DEFAULT 9 /* 32332 with 32081 (guessing) */ +#define TARGET_DEFAULT 9 /* 32332 with 32081 (guessing). */ /* Print subsidiary information on the compiler version in use. */ #undef TARGET_VERSION @@ -51,64 +47,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #undef ASM_OUTPUT_ALIGN_CODE -/* Assember pseudo-op for shared data segment. */ +/* Assembler pseudo-op for shared data segment. */ #define SHARED_SECTION_ASM_OP ".shdata" /* Control how stack adjust insns are output. */ #define SEQUENT_ADJUST_STACK -/* %$ means print the prefix for an immediate operand. - On the sequent, no prefix is used for such. */ - -#undef PRINT_OPERAND -#define PRINT_OPERAND(FILE, X, CODE) \ -{ if (CODE == '$') ; \ - else if (CODE == '?'); \ - else if (GET_CODE (X) == REG) \ - fprintf (FILE, "%s", reg_names[REGNO (X)]); \ - else if (GET_CODE (X) == MEM) \ - { \ - rtx xfoo; \ - xfoo = XEXP (X, 0); \ - switch (GET_CODE (xfoo)) \ - { \ - case MEM: \ - if (GET_CODE (XEXP (xfoo, 0)) == REG) \ - if (REGNO (XEXP (xfoo, 0)) == STACK_POINTER_REGNUM) \ - fprintf (FILE, "0(0(sp))"); \ - else fprintf (FILE, "0(0(%s))", \ - reg_names[REGNO (XEXP (xfoo, 0))]); \ - else \ - { \ - fprintf (FILE, "0("); \ - output_address (xfoo); \ - putc (')', FILE); \ - } \ - break; \ - case REG: \ - fprintf (FILE, "0(%s)", reg_names[REGNO (xfoo)]); \ - break; \ - case PRE_DEC: \ - case POST_INC: \ - fprintf (FILE, "tos"); \ - break; \ - case CONST_INT: \ - fprintf (FILE, "@%d", INTVAL (xfoo)); \ - break; \ - default: \ - output_address (xfoo); \ - break; \ - } \ - } \ - else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != DImode) \ - if (GET_MODE (X) == DFmode) \ - { union { double d; int i[2]; } u; \ - u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \ - fprintf (FILE, "0d%.20e", u.d); } \ - else { union { double d; int i[2]; } u; \ - u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X); \ - fprintf (FILE, "0f%.20e", u.d); } \ - else output_addr_const (FILE, X); } - -#undef PRINT_OPERAND_ADDRESS -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address(FILE, ADDR) +#define NO_ABSOLUTE_PREFIX_IF_SYMBOLIC + +#define IMMEDIATE_PREFIX 0 + +#define SEQUENT_ASM diff --git a/gcc/config/romp/romp.c b/gcc/config/romp/romp.c index 8b72b57..b9f8ad9 100644 --- a/gcc/config/romp/romp.c +++ b/gcc/config/romp/romp.c @@ -1,5 +1,5 @@ /* Subroutines used for code generation on ROMP. - Copyright (C) 1987-1991 Free Software Foundation, Inc. + Copyright (C) 1990, 1991 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) This file is part of GNU CC. @@ -613,7 +613,7 @@ float_unary (op, mode) && GET_MODE (XEXP (op, 0)) == GET_MODE (op); } -/* Return 1 if this is a valid floating-point converstion that can be done +/* Return 1 if this is a valid floating-point conversion that can be done as part of an operation by the RT floating-point routines. */ int @@ -929,7 +929,7 @@ print_operand (file, x, code) break; case '.': - /* Output nothing. Used as delimeter in, e.g., "mc%B1%.3 " */ + /* Output nothing. Used as delimiter in, e.g., "mc%B1%.3 " */ break; case '#': diff --git a/gcc/config/romp/romp.h b/gcc/config/romp/romp.h index 97531d0..8803728 100644 --- a/gcc/config/romp/romp.h +++ b/gcc/config/romp/romp.h @@ -70,7 +70,7 @@ extern int target_flags; #define TARGET_DEFAULT 3 -/* Define this to change the optimizations peformed by default. +/* Define this to change the optimizations performed by default. This used to depend on the value of write_symbols, but that is contrary to the general plan for GCC options. */ @@ -102,7 +102,7 @@ extern int target_flags; for them. Might as well be consistent with bits and bytes. */ #define WORDS_BIG_ENDIAN 1 -/* 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. @@ -150,9 +150,9 @@ extern int target_flags; && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) -/* Define this if move instructions will actually fail to work +/* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ -#define STRICT_ALIGNMENT +#define STRICT_ALIGNMENT 1 /* Standard register usage. */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 3d4683b..3d3dc12 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -37,13 +37,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define min(A,B) ((A) < (B) ? (A) : (B)) #define max(A,B) ((A) > (B) ? (A) : (B)) -/* Names of bss and data sections. These should be unique names for each - compilation unit. */ - -char *rs6000_bss_section_name; -char *rs6000_private_data_section_name; -char *rs6000_read_only_section_name; - /* Set to non-zero by "fix" operation to indicate that itrunc and uitrunc must be defined. */ @@ -591,7 +584,7 @@ secondary_reload_class (class, mode, in) SCC_P is 1 if this is for an scc. That means that %D will have been used instead of %C, so the bits will be in different places. - Return -1 if OP isn't a valid compaison for some reason. */ + Return -1 if OP isn't a valid comparison for some reason. */ int ccr_bit (op, scc_p) @@ -835,7 +828,7 @@ print_operand (file, x, code) return; case 'U': - /* Print `u' is this has an auto-increment or auto-decremement. */ + /* Print `u' is this has an auto-increment or auto-decrement. */ if (GET_CODE (x) == MEM && (GET_CODE (XEXP (x, 0)) == PRE_INC || GET_CODE (XEXP (x, 0)) == PRE_DEC)) @@ -1008,8 +1001,8 @@ print_operand (file, x, code) return; case 'z': - /* X is a SYMBOL_REF. Write out the name preceeded by a - period and without any trailing data in backets. Used for function + /* X is a SYMBOL_REF. Write out the name preceded by a + period and without any trailing data in brackets. Used for function names. */ if (GET_CODE (x) != SYMBOL_REF) abort (); @@ -1287,19 +1280,18 @@ output_epilog (file, size) else if (must_push) fprintf (file, "\tai 1,1,%d\n", total_size); - /* Get the old lr if we saved it. To speed things up, copy it into - lr here if we don't have to save more than 2 fp regs. */ + /* Get the old lr if we saved it. */ if (regs_ever_live[65]) - { - fprintf (file, "\tl 0,8(1)\n"); - if (first_fp_reg >= 62) - fprintf (file, "\tmtlr 0\n"); - } + fprintf (file, "\tl 0,8(1)\n"); /* Get the old cr if we saved it. */ if (must_save_cr ()) fprintf (file, "\tl 12,4(1)\n"); + /* Set LR here to try to overlap restores below. */ + if (regs_ever_live[65]) + fprintf (file, "\tmtlr 0\n"); + /* Restore gpr's. */ if (first_reg == 31) fprintf (file, "\tl 31,%d(1)\n", -4 - (64 - first_fp_reg) * 8); @@ -1307,25 +1299,26 @@ output_epilog (file, size) fprintf (file, "\tlm %d,%d(1)\n", first_reg, - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8); - /* Restore fpr's. */ + /* Restore fpr's if we can do it without calling a function. */ if (first_fp_reg == 62) fprintf (file, "\tlfd 30,-16(1)\n\tlfd 31,-8(1)\n"); else if (first_fp_reg == 63) fprintf (file, "\tlfd 31,-8(1)\n"); - else if (first_fp_reg != 64) - fprintf (file, "\tbl ._restf%d\n\tcror 15,15,15\n", first_fp_reg - 32); - - /* If we used the link register, get it from r0 if we haven't - already. */ - if (regs_ever_live[65] && first_fp_reg < 62) - fprintf (file, "\tmtlr 0\n"); /* If we saved cr, restore it here. Just set cr2, cr3, and cr4. */ if (must_save_cr ()) fprintf (file, "\tmtcrf 0x38,12\n"); - fprintf (file, "\tbr\n"); + /* If we have to restore more than two FP registers, branch to the + restore function. It will return to our caller. */ + if (first_fp_reg < 62) + fprintf (file, "\tb ._restf%d\n\tcror 15,15,15\n", first_fp_reg - 32); + else + fprintf (file, "\tbr\n"); } + + /* ??? Need to output a traceback table here when -g was given for complete + debugging output. */ } /* Output a TOC entry. We derive the entry name from what is diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 38fdad0..c2803ab 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -406,17 +406,6 @@ arith_operand (op, mode) || (GET_CODE (op) == CONST_INT && SMALL_INT (op))); } -/* Return truth value of whether OP can be used as an operand in a two - address arithmetic insn (such as set 123456,%o4) of mode MODE. */ - -int -arith32_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - return (register_operand (op, mode) || GET_CODE (op) == CONST_INT); -} - /* Return truth value of whether OP is a register or a CONST_DOUBLE. */ int @@ -634,10 +623,20 @@ legitimize_pic_address (orig, mode, reg, scratch) rtx temp_reg = ((reload_in_progress || reload_completed) ? reg : gen_reg_rtx (Pmode)); + /* Must put the SYMBOL_REF inside an UNSPEC here so that cse + won't get confused into thinking that these two instructions + are loading in the true address of the symbol. If in the + future a PIC rtx exists, that should be used instead. */ emit_insn (gen_rtx (SET, VOIDmode, temp_reg, - gen_rtx (HIGH, Pmode, orig))); + gen_rtx (HIGH, Pmode, + gen_rtx (UNSPEC, Pmode, + gen_rtvec (1, orig), + 0)))); emit_insn (gen_rtx (SET, VOIDmode, temp_reg, - gen_rtx (LO_SUM, Pmode, temp_reg, orig))); + gen_rtx (LO_SUM, Pmode, temp_reg, + gen_rtx (UNSPEC, Pmode, + gen_rtvec (1, orig), + 0)))); address = temp_reg; } else @@ -1548,7 +1547,7 @@ output_block_move (operands) here. The SUN assembler complains about labels in branch delay slots, so we - do this before outputing the load address, so that there will always + do this before outputting the load address, so that there will always be a harmless insn between the branch here and the next label emitted below. */ @@ -2048,7 +2047,7 @@ output_cbranch (op, label, reversed, annul, noop) enum machine_mode mode = GET_MODE (XEXP (op, 0)); static char labelno[] = " %lX"; - /* ??? FP branches can not be preceeded by another floating point insn. + /* ??? FP branches can not be preceded by another floating point insn. Because there is currently no concept of pre-delay slots, we can fix this only by always emitting a nop before a floating point branch. */ @@ -2284,22 +2283,29 @@ output_arc_profiler (arcno, insert_after) gen_rtx (PLUS, Pmode, profiler_label, gen_rtx (CONST_INT, VOIDmode, 4 * arcno))); register rtx profiler_reg = gen_reg_rtx (SImode); - register rtx temp = gen_reg_rtx (Pmode); - register rtx profiler_target = gen_rtx (MEM, SImode, - gen_rtx (LO_SUM, Pmode, temp, - profiler_target_addr)); - /* The insns are emitted from last to first after the insn insert_after. - Emit_insn_after is used because sometimes we want to put the - instrumentation code after the last insn of the function. */ - emit_insn_after (gen_rtx (SET, VOIDmode, profiler_target, profiler_reg), - insert_after); - emit_insn_after (gen_rtx (SET, VOIDmode, profiler_reg, - gen_rtx (PLUS, SImode, profiler_reg, const1_rtx)), - insert_after); - emit_insn_after (gen_rtx (SET, VOIDmode, profiler_reg, profiler_target), - insert_after); - emit_insn_after (gen_rtx (SET, VOIDmode, temp, - gen_rtx (HIGH, Pmode, profiler_target_addr)), + register rtx address_reg = gen_reg_rtx (Pmode); + rtx mem_ref; + + insert_after = emit_insn_after (gen_rtx (SET, VOIDmode, address_reg, + gen_rtx (HIGH, Pmode, + profiler_target_addr)), + insert_after); + + mem_ref = gen_rtx (MEM, SImode, gen_rtx (LO_SUM, Pmode, address_reg, + profiler_target_addr)); + insert_after = emit_insn_after (gen_rtx (SET, VOIDmode, profiler_reg, + mem_ref), + insert_after); + + insert_after = emit_insn_after (gen_rtx (SET, VOIDmode, profiler_reg, + gen_rtx (PLUS, SImode, profiler_reg, + const1_rtx)), + insert_after); + + /* This is the same rtx as above, but it is not legal to share this rtx. */ + mem_ref = gen_rtx (MEM, SImode, gen_rtx (LO_SUM, Pmode, address_reg, + profiler_target_addr)); + emit_insn_after (gen_rtx (SET, VOIDmode, mem_ref, profiler_reg), insert_after); } diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 61bd204..3451083 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -122,7 +122,7 @@ extern int target_flags; matters when cross-compiling. */ #define WORDS_BIG_ENDIAN 1 -/* 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. @@ -171,9 +171,9 @@ extern int target_flags; && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) -/* Define this if move instructions will actually fail to work +/* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ -#define STRICT_ALIGNMENT +#define STRICT_ALIGNMENT 1 /* Things that must be doubleword aligned cannot go in the text section, because the linker fails to align the text section enough! @@ -422,9 +422,9 @@ enum reg_class { NO_REGS, GENERAL_REGS, FP_REGS, ALL_REGS, LIM_REG_CLASSES }; /* This is the order in which to allocate registers normally. */ #define REG_ALLOC_ORDER \ -{ 8, 9, 10, 11, 12, 13, 2, 15, \ - 16, 17, 18, 19, 20, 21, 22, 23, \ - 24, 25, 26, 27, 28, 29, 3, 31, \ +{ 8, 9, 10, 11, 12, 13, 2, 3, \ + 15, 16, 17, 18, 19, 20, 21, 22, \ + 23, 24, 25, 26, 27, 28, 29, 31, \ 32, 33, 34, 35, 36, 37, 38, 39, \ 40, 41, 42, 43, 44, 45, 46, 47, \ 48, 49, 50, 51, 52, 53, 54, 55, \ @@ -571,7 +571,7 @@ extern char leaf_reg_backmap[]; #define REG_PARM_STACK_SPACE(DECL) (NPARM_REGS * UNITS_PER_WORD) /* Keep the stack pointer constant throughout the function. - This is both an optimization and a neccessity: longjmp + This is both an optimization and a necessity: longjmp doesn't behave itself when the stack pointer moves within the function! */ #define ACCUMULATE_OUTGOING_ARGS @@ -1187,6 +1187,9 @@ extern struct rtx_def *legitimize_pic_address (); between pointers and any other objects of this machine mode. */ #define Pmode SImode +/* Generate calls to memcpy, memcmp and memset. */ +#define TARGET_MEM_FUNCTIONS + /* Add any extra modes needed to represent the condition code. On the Sparc, we have a "no-overflow" mode which is used when an add or diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index f8f5495..20cfca8 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -56,6 +56,8 @@ (match_operand 2 "arith_double_operand" "")) (const_int 1) (const_int 3)) + (eq_attr "type" "multi") (const_int 2) + (eq_attr "type" "move,unary") (if_then_else (ior (match_operand 1 "arith_operand" "") (match_operand 1 "arith_double_operand" "")) @@ -451,8 +453,7 @@ (clobber (reg:CC 0))] "" "subcc %%g0,%1,%%g0\;addx %2,-1,%0" - [(set_attr "type" "unary") - (set_attr "length" "2")]) + [(set_attr "length" "2")]) ;; We can also do GEU and LTU directly, but these operate after a ;; compare. @@ -518,8 +519,7 @@ (plus:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI"))))] "" - "addx %1,%2,%0" - [(set_attr "type" "binary")]) + "addx %1,%2,%0") (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") @@ -536,8 +536,7 @@ (match_operand:SI 2 "arith_operand" "rI")) (ltu:SI (reg:CC 0) (const_int 0))))] "" - "subx %1,%2,%0" - [(set_attr "type" "binary")]) + "subx %1,%2,%0") (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") @@ -545,8 +544,7 @@ (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) (match_operand:SI 2 "arith_operand" "rI"))))] "" - "subx %1,%2,%0" - [(set_attr "type" "binary")]) + "subx %1,%2,%0") (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") @@ -572,7 +570,8 @@ (match_operator:SI 1 "normal_comp_operator" [(reg 0) (const_int 0)]))] "" "* return output_scc_insn (operands, insn); " - [(set_attr "type" "multi")]) + [(set_attr "type" "multi") + (set_attr "length" "3")]) ;; These control RTL generation for conditional jump insns @@ -734,7 +733,7 @@ ;; subreg sets. ;; We cannot combine the similar 'r' and 'f' constraints, because it causes -;; problems with register allocation. Reload might try to put an interger +;; problems with register allocation. Reload might try to put an integer ;; in an fp register, or an fp number is an integer register. (define_insn "" @@ -751,8 +750,8 @@ st %r1,%0 st %r1,%0 st %r1,[%%fp-4]\;ld [%%fp-4],%0" - [(set_attr "type" "move,move,load,load,store,store,misc") - (set_attr "length" "*,1,*,*,*,*,2")]) + [(set_attr "type" "move,move,load,load,store,store,multi") + (set_attr "length" "*,1,*,*,*,*,*")]) ;; Special pic pattern, for loading the address of a label into a register. ;; It clobbers o7 because the call puts the return address (i.e. pc value) @@ -803,6 +802,16 @@ [(set_attr "type" "move") (set_attr "length" "2")]) +;; For PIC, symbol_refs are put inside unspec so that the optimizer won't +;; confuse them with real addresses. +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))] + "check_pic (1)" + "sethi %%hi(%a1),%0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (match_operand 1 "" "")))] @@ -836,6 +845,18 @@ ;; is not an "arith_operand". [(set_attr "length" "1")]) +;; For PIC, symbol_refs are put inside unspec so that the optimizer won't +;; confuse them with real addresses. +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (lo_sum:SI (match_operand:SI 1 "register_operand" "r") + (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))] + "" + "or %1,%%lo(%a2),%0" + ;; Need to set length for this arith insn because operand2 + ;; is not an "arith_operand". + [(set_attr "length" "1")]) + (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") @@ -944,7 +965,7 @@ (define_expand "movstrsi" [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) (mem:BLK (match_operand:BLK 1 "general_operand" ""))) - (use (match_operand:SI 2 "arith32_operand" "")) + (use (match_operand:SI 2 "nonmemory_operand" "")) (use (match_operand:SI 3 "immediate_operand" "")) (clobber (match_dup 0)) (clobber (match_dup 1)) @@ -967,7 +988,7 @@ (define_insn "" [(set (mem:BLK (match_operand:SI 0 "register_operand" "r")) (mem:BLK (match_operand:SI 1 "register_operand" "r"))) - (use (match_operand:SI 2 "arith32_operand" "rn")) + (use (match_operand:SI 2 "nonmemory_operand" "rn")) (use (match_operand:SI 3 "immediate_operand" "i")) (clobber (match_dup 0)) (clobber (match_dup 1)) @@ -976,7 +997,8 @@ (clobber (reg:SI 1))] "" "* return output_block_move (operands);" - [(set_attr "type" "multi")]) + [(set_attr "type" "multi") + (set_attr "length" "6")]) ;; Floating point move insns @@ -1071,7 +1093,7 @@ return output_fp_move_double (operands); return output_move_double (operands); }" - [(set_attr "type" "move,store,load,misc,multi,fp,fpload,multi,fpstore") + [(set_attr "type" "move,store,load,multi,multi,fp,fpload,multi,fpstore") (set_attr "length" "2,3,3,3,3,2,3,3,3")]) ;; Floating-point move insns. @@ -1099,8 +1121,7 @@ ld %1,%0 st %r1,%0 st %r1,%0" - [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store") - (set_attr "length" "*,*,2,*,*,*,*")]) + [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store")]) (define_insn "" [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i")) @@ -1277,6 +1298,27 @@ "ldsb %1,%0" [(set_attr "type" "load")]) +;; Special pattern for optimizing bit-field compares. This is needed +;; because combine uses this as a canonical form. + +(define_insn "" + [(set (reg:CC 0) + (compare:CC + (zero_extract:SI (match_operand:SI 0 "register_operand" "r") + (match_operand:SI 1 "small_int" "n") + (match_operand:SI 2 "small_int" "n")) + (const_int 0)))] + "INTVAL (operands[2]) > 19" + "* +{ + int len = INTVAL (operands[1]); + int pos = 32 - INTVAL (operands[2]) - len; + unsigned mask = ((1 << len) - 1) << pos; + + operands[1] = gen_rtx (CONST_INT, VOIDmode, mask); + return \"andcc %0,%1,%%g0\"; +}") + ;; Conversions between float and double. (define_insn "extendsfdf2" @@ -1372,7 +1414,7 @@ { rtx op2 = operands[2]; - /* If constant is postive, upper bits zeroed, otherwise unchanged + /* If constant is positive, upper bits zeroed, otherwise unchanged * give the assembler a chance to pick the move instruction. */ if (GET_CODE (op2) == CONST_INT) { @@ -1430,8 +1472,8 @@ { rtx op2 = operands[2]; - /* If constant is postive, upper bits zeroed, otherwise unchanged - * give the assembler a chance to pick the move instruction. */ + /* If constant is positive, upper bits zeroed, otherwise unchanged + /* If constant is positive, upper bits zeroed, otherwise unchanged if (GET_CODE (op2) == CONST_INT) { int sign = INTVAL (op2); @@ -1498,7 +1540,7 @@ { rtx op2 = operands[2]; - /* If constant is postive, upper bits zeroed, otherwise unchanged + /* If constant is positive, upper bits zeroed, otherwise unchanged * give the assembler a chance to pick the move instruction. */ if (GET_CODE (op2) == CONST_INT) { @@ -1558,7 +1600,7 @@ { rtx op2 = operands[2]; - /* If constant is postive, upper bits zeroed, otherwise unchanged + /* If constant is positive, upper bits zeroed, otherwise unchanged * give the assembler a chance to pick the move instruction. */ if (GET_CODE (op2) == CONST_INT) { @@ -2004,7 +2046,7 @@ ;; Unconditional and other jump instructions ;; Note that for the Sparc, by setting the annul bit on an unconditional ;; branch, the following insn is never executed. This saves us a nop, -;; but requires a debugger which can handle annuled branches. +;; but requires a debugger which can handle annulled branches. (define_insn "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] "" @@ -2263,12 +2305,15 @@ (define_insn "" [(unspec_volatile [(const_int 0)] 0)] "" - "ta 3") + "ta 3" + [(set_attr "type" "misc")]) (define_insn "" [(unspec_volatile [(const_int 0)] 1)] "" - "jmp %%o0+0\;restore") + "jmp %%o0+0\;restore" + [(set_attr "type" "misc") + (set_attr "length" "2")]) ;(define_insn "tail_call" ;; tail call ; [(set (pc) (match_operand 0 "memory_operand" "m"))] @@ -2469,8 +2514,7 @@ (const_int 0)))] "rtx_equal_p (operands[2], operands[0]) || rtx_equal_p (operands[2], operands[1])" - "orcc %1,%%g0,%0" - [(set_attr "type" "move")]) + "orcc %1,%%g0,%0") ;; Do {sign,zero}-extended compares somewhat more efficiently. ;; ??? Is this now the Right Way to do this? Or will SCRATCH @@ -2604,7 +2648,8 @@ (match_operand:SF 0 "register_operand" "f")) (return)] "! TARGET_EPILOGUE" - "ret\;fmovs %0,%%f0") + "ret\;fmovs %0,%%f0" + [(set_attr "type" "multi")]) ;; Now peepholes to go a call followed by a jump. @@ -2638,8 +2683,7 @@ (clobber (reg:CC 0))]) (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))] "" - "subxcc %r1,0,%0" - [(set_attr "type" "compare")]) + "subxcc %r1,0,%0") ;;- Local variables: ;;- mode:emacs-lisp diff --git a/gcc/config/spur/spur.h b/gcc/config/spur/spur.h index b8cb806..bf6d347 100644 --- a/gcc/config/spur/spur.h +++ b/gcc/config/spur/spur.h @@ -83,7 +83,7 @@ extern int target_flags; since there are no machine instructions for them. */ #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. @@ -117,9 +117,9 @@ extern int target_flags; /* No data type wants to be aligned rounder than this. */ #define BIGGEST_ALIGNMENT 64 -/* Define this if move instructions will actually fail to work +/* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ -#define STRICT_ALIGNMENT +#define STRICT_ALIGNMENT 1 /* Standard register usage. */ diff --git a/gcc/config/svr4.h b/gcc/config/svr4.h index 7db294c..f49fa69 100644 --- a/gcc/config/svr4.h +++ b/gcc/config/svr4.h @@ -117,7 +117,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. #undef MD_STARTFILE_PREFIX #define MD_STARTFILE_PREFIX "/usr/ccs/lib/" -/* Provide a LIB_SPEC appropropriate for svr4. Here we tack on the default +/* Provide a LIB_SPEC appropriate for svr4. Here we tack on the default standard C library (unless we are building a shared library) followed by our own magical crtend.o file (see crtstuff.c) which provides part of the support for getting C++ file-scope static object constructed before @@ -154,11 +154,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. not being done. */ #undef LINK_SPEC -#define LINK_SPEC "%{z*} %{h*} %{V} %{v:%{!V:-V}} \ - %{b} %{t} %{Wl,*:%*} \ +#define LINK_SPEC "%{h*} %{V} %{v:%{!V:-V}} \ + %{b} %{Wl,*:%*} \ %{static:-dn -Bstatic} \ %{shared:-G -dy} \ %{symbolic:-Bsymbolic -G -dy} \ + %{G:-G} \ %{YP,*} \ %{!YP,*:%{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ %{!p:-Y P,/usr/ccs/lib:/usr/lib}} \ @@ -173,7 +174,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. The SVR4 library routines query the value of `_lib_version' at run to decide how they should behave. Specifically, they decide (based upon the value of `_lib_version') if they will act in a strictly ANSI - conformant manner or not. + conforming manner or not. */ #undef STARTFILE_SPEC @@ -186,9 +187,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. %{traditional:values-Xt.o%s} \ %{!traditional:values-Xa.o%s}}}} crtbegin.o%s" -/* Attach a sepcial .ident directive to the end of the file to identify +/* Attach a special .ident directive to the end of the file to identify the version of GCC which compiled this code. The format of the - .ident string is patterened after the ones produced by native svr4 + .ident string is patterned after the ones produced by native svr4 C compilers. */ #define ASM_FILE_END(FILE) \ @@ -558,7 +559,7 @@ dtors_section () \ has such a limitation, you should define STRING_LIMIT to reflect that limit. Note that at least some svr4 assemblers have a limit on the actual number of bytes in the double-quoted string, and that they - count each chanacter in an escape sequence as one byte. Thus, an + count each character in an escape sequence as one byte. Thus, an escape sequence like \377 would count as four bytes. If your target assembler doesn't support the .string directive, you diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index b059a3a..37176c9 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -29,35 +29,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "output.h" #include "insn-attr.h" -/* Return 1 if the operand is a REG, a SUBREG, or a MEM that is does not - have an index. This is used when we are using an operand in a different - mode than the hardware expects. See jlbc/jlbs. - - This is nonimmedate_operand with a restriction on the type of MEM. */ - -int -reg_or_nxmem_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (! nonimmediate_operand (op, mode)) - return 0; - - if (GET_CODE (op) != MEM) - return 1; - - GO_IF_NONINDEXED_ADDRESS (XEXP (op, 0), nonidx); - - return 0; - - nonidx: - return 1; -} void split_quadword_operands (operands, low, n) rtx *operands, *low; - int n; + This is nonimmediate_operand with a restriction on the type of MEM. */ { int i; /* Split operands. */ diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h index d9abb28..459eb55 100644 --- a/gcc/config/vax/vax.h +++ b/gcc/config/vax/vax.h @@ -93,7 +93,7 @@ extern int target_flags; /* This is not true on the vax. */ #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. @@ -133,6 +133,9 @@ extern int target_flags; /* Set this nonzero if move instructions will actually fail to work when given unaligned data. */ #define STRICT_ALIGNMENT 0 + +/* Let's keep the stack somewhat aligned. */ +#define STACK_BOUNDARY 32 /* Standard register usage. */ @@ -877,7 +880,7 @@ gen_rtx (PLUS, Pmode, frame, gen_rtx (CONST_INT, VOIDmode, 12)) /* Check a `double' value for validity for a particular machine mode. */ -/* note that it is very hard to accidently create a number that fits in a +/* note that it is very hard to accidentally create a number that fits in a double but not in a float, since their ranges are almost the same */ #define CHECK_FLOAT_VALUE(mode, d) \ if ((mode) == SFmode) \ diff --git a/gcc/config/vax/vms.h b/gcc/config/vax/vms.h index 8f55e13..13873bd 100644 --- a/gcc/config/vax/vms.h +++ b/gcc/config/vax/vms.h @@ -38,6 +38,15 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ??? __GNU__ is probably obsolete; delete it for 2.1. */ #define CPP_PREDEFINES "-Dvax -Dvms -DVMS -D__GNU__ -D__GNUC__=2" +/* These match the definitions used in VAXCRTL, the VMS C run-time library */ + +#define SIZE_TYPE "unsigned int" +#define PTRDIFF_TYPE "int" +#define WCHAR_TYPE "unsigned int" + +/* Use memcpy for structure copying, and so forth. */ +#define TARGET_MEM_FUNCTIONS + /* Strictly speaking, VMS does not use DBX at all, but the interpreter built into gas only speaks straight DBX. */ @@ -172,7 +181,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define NO_DOLLAR_IN_LABEL -/* Add a "const" section. This is viewed by the assember as being nearly +/* Add a "const" section. This is viewed by the assembler as being nearly the same as the "data" section, with the only difference being that a flag is set for variables declared while in the const section. This flag is used to determine whether or not the read/write bit should be diff --git a/gcc/ginclude/va-pyr.h b/gcc/ginclude/va-pyr.h index edc1710..be4b3f5 100644 --- a/gcc/ginclude/va-pyr.h +++ b/gcc/ginclude/va-pyr.h @@ -9,7 +9,7 @@ * C compiler. * As such, it depends strongly on the Pyramid conventions for * parameter passing.ct and indepenent implementation. - * These (somewhat bizarre) paramter-passing conventions are described + * These (somewhat bizarre) parameter-passing conventions are described * in the ``OSx Operating System Porting Guide''. * * A quick summary is useful: @@ -89,9 +89,12 @@ typedef __va_buf va_list; &(_AP.__pr0), (void*)&__builtin_va_alist, (void*)0, \ __va0,__va1,__va2,__va3,__va4,__va5, \ __va6,__va7,__va8,__va9,__va10,__va11}) - - - + + +/* Avoid errors if compiling GCC v2 with GCC v1. */ +#if __GNUC__ == 1 +#define __extension__ +#endif #define va_arg(_AP, _MODE) \ __extension__ \ diff --git a/gcc/sched.c b/gcc/sched.c index a804fbe..4d43693 100644 --- a/gcc/sched.c +++ b/gcc/sched.c @@ -144,7 +144,7 @@ static int *insn_priority; #define DONE_PRIORITY_P(INSN) (INSN_PRIORITY (INSN) < 0) #define LOW_PRIORITY_P(INSN) ((INSN_PRIORITY (INSN) & 0x7f000000) == 0) -/* Vector indexed by INSN_UID giving number of insns refering to this insn. */ +/* Vector indexed by INSN_UID giving number of insns referring to this insn. */ static int *insn_ref_count; #define INSN_REF_COUNT(INSN) (insn_ref_count[INSN_UID (INSN)]) @@ -2324,13 +2324,20 @@ schedule_block (b, file) && GET_CODE (PATTERN (tail)) == USE && next_nonnote_insn (tail) == 0) { - /* If this was the only insn in the block, then there are no insns to - schedule. */ - if (head == tail) - return; + /* Don't try to reorder any USE insns at the end of a function. + They must be last to ensure proper register allocation. + Exclude them all from scheduling. */ + do + { + /* If we are down to one USE insn, then there are no insns to + schedule. */ + if (head == tail) + return; - /* We don't try to reorder the USE at the end of a function. */ - tail = prev_nonnote_insn (tail); + tail = prev_nonnote_insn (tail); + } + while (GET_CODE (tail) == INSN + && GET_CODE (PATTERN (tail)) == USE); #if 0 /* This short-cut does not work. See comment above. */ @@ -3944,7 +3951,10 @@ schedule_insns (dump_file) fprintf (dump_file, ";; register %d now crosses calls\n", regno); } - reg_live_length[regno] = sched_reg_live_length[regno]; + /* Negative values are special; don't overwrite the current + reg_live_length value if it is negative. */ + if (reg_live_length[regno] >= 0) + reg_live_length[regno] = sched_reg_live_length[regno]; reg_n_calls_crossed[regno] = sched_reg_n_calls_crossed[regno]; } } @@ -1150,14 +1150,10 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) for (tail = clobbers; tail; tail = TREE_CHAIN (tail), i++) { - int j; char *regname = TREE_STRING_POINTER (TREE_VALUE (tail)); + int j = decode_reg_name (regname); - for (j = 0; j < FIRST_PSEUDO_REGISTER; j++) - if (!strcmp (regname, reg_names[j])) - break; - - if (j == FIRST_PSEUDO_REGISTER) + if (j < 0) { error ("unknown register name `%s' in `asm'", regname); return; @@ -1270,6 +1266,7 @@ warn_if_unused_value (exp) case NOP_EXPR: case CONVERT_EXPR: + case NON_LVALUE_EXPR: /* Don't warn about values cast to void. */ if (TREE_TYPE (exp) == void_type_node) return 0; @@ -1885,7 +1882,7 @@ expand_end_loop () register rtx newstart_label = gen_label_rtx (); register rtx start_move = start_label; - /* If the start label is preceeded by a NOTE_INSN_LOOP_CONT note, + /* If the start label is preceded by a NOTE_INSN_LOOP_CONT note, then we want to move this note also. */ if (GET_CODE (PREV_INSN (start_move)) == NOTE && (NOTE_LINE_NUMBER (PREV_INSN (start_move)) @@ -2498,7 +2495,10 @@ expand_end_bindings (vars, mark_ends, dont_jump_in) if (arg_pointer_save_area == 0) arg_pointer_save_area = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0); - emit_move_insn (virtual_incoming_args_rtx, arg_pointer_save_area); + emit_move_insn (virtual_incoming_args_rtx, + /* We need a pseudo here, + or else instantiate_virtual_regs_1 complains. */ + copy_to_reg (arg_pointer_save_area)); } #endif @@ -2779,6 +2779,8 @@ void expand_decl_init (decl) tree decl; { + int was_used = TREE_USED (decl); + if (TREE_STATIC (decl)) return; @@ -2800,6 +2802,9 @@ expand_decl_init (decl) emit_queue (); } + /* Don't let the initialization count as "using" the variable. */ + TREE_USED (decl) = was_used; + /* Free any temporaries we made while initializing the decl. */ free_temp_slots (); } @@ -3546,11 +3551,13 @@ expand_end_case (orig_index) #endif || (unsigned) (TREE_INT_CST_LOW (range)) > 10 * count || TREE_CODE (index_expr) == INTEGER_CST - /* This will reduce to a constant. */ + /* These will reduce to a constant. */ || (TREE_CODE (index_expr) == CALL_EXPR && TREE_CODE (TREE_OPERAND (index_expr, 0)) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == FUNCTION_DECL - && DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == BUILT_IN_CLASSIFY_TYPE)) + && DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == BUILT_IN_CLASSIFY_TYPE) + || (TREE_CODE (index_expr) == COMPOUND_EXPR + && TREE_CODE (TREE_OPERAND (index_expr, 1)) == INTEGER_CST)) { index = expand_expr (index_expr, 0, VOIDmode, 0); @@ -3668,14 +3675,16 @@ expand_end_case (orig_index) if (! win && HAVE_tablejump) { index_expr = convert (thiscase->data.case_stmt.nominal_type, - build (MINUS_EXPR, TREE_TYPE (index_expr), - index_expr, minval)); + fold (build (MINUS_EXPR, + TREE_TYPE (index_expr), + index_expr, minval))); index = expand_expr (index_expr, 0, VOIDmode, 0); emit_queue (); index = protect_from_queue (index, 0); do_pending_stack_adjust (); do_tablejump (index, + TYPE_MODE (thiscase->data.case_stmt.nominal_type), gen_rtx (CONST_INT, VOIDmode, TREE_INT_CST_LOW (range)), table_label, default_label); @@ -2168,7 +2168,7 @@ build_type_variant (type, constp, volatilep) constp = !!constp; volatilep = !!volatilep; - /* If not generating auxilliary info, search the chain of variants to see + /* If not generating auxiliary info, search the chain of variants to see if there is already one there just like the one we need to have. If so, use that existing one. @@ -2199,6 +2199,31 @@ build_type_variant (type, constp, volatilep) current_obstack = ambient_obstack; return t; } + +/* Create a new variant of TYPE, equivalent but distinct. + This is so the caller can modify it. */ + +tree +build_type_copy (type) + tree type; +{ + register tree t, m = TYPE_MAIN_VARIANT (type); + register struct obstack *ambient_obstack = current_obstack; + + current_obstack + = TREE_PERMANENT (type) ? &permanent_obstack : saveable_obstack; + + t = copy_node (type); + TYPE_POINTER_TO (t) = 0; + TYPE_REFERENCE_TO (t) = 0; + + /* Add this type to the chain of variants of TYPE. */ + TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); + TYPE_NEXT_VARIANT (m) = t; + + current_obstack = ambient_obstack; + return t; +} /* Hashing of types so that we don't make duplicates. The entry point is `type_hash_canon'. */ diff --git a/gcc/unroll.c b/gcc/unroll.c index ccc6f47..577f47c 100644 --- a/gcc/unroll.c +++ b/gcc/unroll.c @@ -324,12 +324,12 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, else if (GET_CODE (last_loop_insn) == JUMP_INSN) { #ifdef HAVE_cc0 - /* The immediately preceeding insn is a compare which must be + /* The immediately preceding insn is a compare which must be deleted. */ delete_insn (last_loop_insn); delete_insn (PREV_INSN (last_loop_insn)); #else - /* The immediately preceeding insn may not be the compare, so don't + /* The immediately preceding insn may not be the compare, so don't delete it. */ delete_insn (last_loop_insn); #endif @@ -883,11 +883,11 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, else if (GET_CODE (last_loop_insn) == JUMP_INSN) { #ifdef HAVE_cc0 - /* The immediately preceeding insn is a compare which we do not + /* The immediately preceding insn is a compare which we do not want to copy. */ copy_end = PREV_INSN (PREV_INSN (last_loop_insn)); #else - /* The immediately preceeding insn may not be a compare, so we + /* The immediately preceding insn may not be a compare, so we must copy it. */ copy_end = PREV_INSN (last_loop_insn); #endif @@ -937,12 +937,12 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before, else { #ifdef HAVE_cc0 - /* The immediately preceeding insn is a compare which we do not + /* The immediately preceding insn is a compare which we do not want to copy. */ insert_before = PREV_INSN (last_loop_insn); copy_end = PREV_INSN (insert_before); #else - /* The immediately preceeding insn may not be a compare, so we + /* The immediately preceding insn may not be a compare, so we must copy it. */ insert_before = last_loop_insn; copy_end = PREV_INSN (last_loop_insn); @@ -2053,7 +2053,7 @@ iteration_info (iteration_var, initial_value, increment, loop_start, loop_end) { if (loop_dump_stream) fprintf (loop_dump_stream, - "Loop unrolling: Iteration var not an interger.\n"); + "Loop unrolling: Iteration var not an integer.\n"); return; } else if (reg_iv_type[REGNO (iteration_var)] == BASIC_INDUCT) @@ -2240,7 +2240,7 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before, { /* If the initial value of the biv is itself (i.e. it is too complicated for strength_reduce to compute), or is a hard - register, then we must create a new psuedo reg to hold the + register, then we must create a new pseudo reg to hold the initial value of the biv. */ if (GET_CODE (bl->initial_value) == REG @@ -2733,6 +2733,11 @@ final_biv_value (bl, loop_start, loop_end) { rtx increment, tem; + /* ??? This only works for MODE_INT biv's. Reject all others for now. */ + + if (GET_MODE_CLASS (bl->biv->mode) != MODE_INT) + return 0; + /* The final value for reversed bivs must be calculated differently than for ordinary bivs. In this case, there is already an insn after the loop which sets this biv's final value (if necessary), and there are diff --git a/gcc/varasm.c b/gcc/varasm.c index 890c969..12afb28 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -38,6 +38,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "obstack.h" +#ifdef XCOFF_DEBUGGING_INFO +#include "xcoff.h" +#endif + #ifndef ASM_STABS_OP #define ASM_STABS_OP ".stabs" #endif @@ -189,10 +193,25 @@ make_function_rtl (decl) function_defined = 1; } +/* Given NAME, a putative register name, discard any customary prefixes. */ + +static char * +strip_reg_name (name) + char *name; +{ +#ifdef REGISTER_PREFIX + if (!strncmp (name, REGISTER_PREFIX, strlen (REGISTER_PREFIX))) + name += strlen (REGISTER_PREFIX); +#endif + if (name[0] == '%' || name[0] == '#') + name++; + return name; +} + /* Decode an `asm' spec for a declaration as a register name. Return the register number, or -1 if nothing specified, - or -2 if the name is not a register. Accept an exact spelling, - a decimal number, or an optional prefix of '%' or '#'. */ + or -2 if the name is not a register. Accept an exact spelling or + a decimal number. Prefixes such as % are optional. */ int decode_reg_name (asmspec) @@ -202,6 +221,9 @@ decode_reg_name (asmspec) { int i; + /* Get rid of confusing prefixes. */ + asmspec = strip_reg_name (asmspec); + /* Allow a decimal number as a "register name". */ for (i = strlen (asmspec) - 1; i >= 0; i--) if (! (asmspec[i] >= '0' && asmspec[i] <= '9')) @@ -216,14 +238,10 @@ decode_reg_name (asmspec) } for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (reg_names[i][0] && ! strcmp (asmspec, reg_names[i])) + if (reg_names[i][0] + && ! strcmp (asmspec, strip_reg_name (reg_names[i]))) return i; - if (asmspec[0] == '%' || asmspec[0] == '#') - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (reg_names[i][0] && ! strcmp (asmspec + 1, reg_names[i])) - return i; - #ifdef ADDITIONAL_REGISTER_NAMES { static struct { char *name; int number; } table[] @@ -232,11 +250,6 @@ decode_reg_name (asmspec) for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) if (! strcmp (asmspec, table[i].name)) return table[i].number; - - if (asmspec[0] == '%' || asmspec[0] == '#') - for (i = 0; i < sizeof (table) / sizeof (table[0]); i++) - if (! strcmp (asmspec + 1, table[i].name)) - return table[i].number; } #endif /* ADDITIONAL_REGISTER_NAMES */ @@ -657,9 +670,10 @@ assemble_variable (decl, top_level, at_end) return; TREE_ASM_WRITTEN (decl) = 1; -#ifdef DBX_DEBUGGING_INFO +#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) /* File-scope global variables are output here. */ - if (write_symbols == DBX_DEBUG && top_level) + if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG) + && top_level) dbxout_symbol (decl, 0); #endif #ifdef SDB_DEBUGGING_INFO @@ -746,7 +760,7 @@ assemble_variable (decl, top_level, at_end) Error message was already made. */ if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) - return; + goto finish; app_disable (); @@ -757,7 +771,7 @@ assemble_variable (decl, top_level, at_end) if (TREE_INT_CST_HIGH (size_tree) != 0) { error_with_decl (decl, "size of variable `%s' is too large"); - return; + goto finish; } name = XSTR (XEXP (DECL_RTL (decl), 0), 0); @@ -816,7 +830,7 @@ assemble_variable (decl, top_level, at_end) ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded); #endif } - return; + goto finish; } /* Handle initialized definitions. */ @@ -907,6 +921,22 @@ assemble_variable (decl, top_level, at_end) else /* Leave space for it. */ assemble_zeros (int_size_in_bytes (TREE_TYPE (decl))); + + finish: +#ifdef XCOFF_DEBUGGING_INFO + /* Unfortunately, the IBM assembler cannot handle stabx before the actual + declaration. When something like ".stabx "aa:S-2",aa,133,0" is emitted + and `aa' hasn't been output yet, the assembler generates a stab entry with + a value of zero, in addition to creating an unnecessary external entry + for `aa'. Hence, we must pospone dbxout_symbol to here at the end. */ + + /* File-scope global variables are output here. */ + if (write_symbols == XCOFF_DEBUG && top_level) + dbxout_symbol (decl, 0); +#else + /* There must be a statement after a label. */ + ; +#endif } /* Output something to declare an external symbol to the assembler. @@ -2703,7 +2733,7 @@ output_constructor (exp, size) separate bytes, and combine each byte with previous or following bit-fields. */ - /* next_offset is the offset n fbits from the begining of + /* next_offset is the offset n fbits from the beginning of the structure to the next bit of this element to be processed. end_offset is the offset of the first bit past the end of this element. */ |