diff options
author | Doug Evans <dje@gnu.org> | 1996-03-08 00:12:21 +0000 |
---|---|---|
committer | Doug Evans <dje@gnu.org> | 1996-03-08 00:12:21 +0000 |
commit | c4ce68534a192e1b452b70dee5a4bab71f6729e4 (patch) | |
tree | 3a3d48d7e2df5b02343b034e24da534243bb5496 /gcc/config | |
parent | 05066d29ea8d6debe362cd48b1921a78078dd185 (diff) | |
download | gcc-c4ce68534a192e1b452b70dee5a4bab71f6729e4.zip gcc-c4ce68534a192e1b452b70dee5a4bab71f6729e4.tar.gz gcc-c4ce68534a192e1b452b70dee5a4bab71f6729e4.tar.bz2 |
sparc.h (MASK_LIVE_G0,TARGET_LIVE_G0): Define.
* sparc/sparc.h (MASK_LIVE_G0,TARGET_LIVE_G0): Define.
(TARGET_SWITCHES): Add live-g0.
(FIRST_PSEUDO_REGISTER): Add 1 for %icc (now 101).
(FIXED_REGISTERS,CALL_USED_REGISTERS): Update.
(FIXED_REGISTERS): %g0 is fixed by default.
(SPARC_{FIRST,LAST}_V9_FCC_REG): Define.
(SPARC_{ICC,FCC}_REG): Define.
(CONDITIONAL_REGISTER_USAGE): Don't fix %fcc0 if v8.
(REG_CLASS_CONTENTS): Reg 0 is an int reg, reg 100 is %icc.
(REGNO_REG_CLASS): Rewrite to use global `sparc_regno_reg_class'.
(REG_ALLOC_ORDER,REG_LEAF_ALLOC_ORDER,LEAF_REGISTERS): Add %icc.
(REG_CLASS_FROM_LETTER): Handle 'c' for FPCC_REGS in non-v9 case.
(REGNO_OK_FOR_{BASE,INDEX}_P): Treat %g0 as a normal reg.
(REG_OK_FOR_{BASE,INDEX}_P,EXTRA_CONSTRAINT): Likewise.
(REGISTER_NAMES): Add %icc.
(ADDITIONAL_REGISTER_NAMES): Use SPARC_ICC_REG.
* sparc/sparc.c (leaf_reg_remap): Add %icc=100.
(reg_or_0_operand): Don't allow 0 if TARGET_LIVE_G0.
(fcc_reg_operand): Renamed from ccfp_reg_operand.
Use SPARC_FCC_REG. Don't treat reg 0 as an fcc reg. Don't match
modes if `mode' argument is VOIDmode.
(icc_or_fcc_reg_operand): New function.
(gen_compare_reg): Use SPARC_FCC_REG for v8 fp compares.
Use SPARC_ICC_REG for int compares.
(eligible_for_epilogue_delay): Don't allow anything if TARGET_LIVE_G0.
Delete unnecessary test for %g0.
(emit_move_sequence): Don't emit (set (mem) (const_int 0)) if
TARGET_LIVE_G0.
(output_scc_insn): Label moved to operand 3. Condition code reg
moved to operand 2.
(sparc_mode_class): Enum C_MODE renamed to CC_MODE.
(hard_32bit_mode_classes): Set reg 0 to S_MODES. Add entry for %icc.
(hard_64bit_mode_classes): Set reg 0 to D_MODES. Add entry for %icc.
(sparc_regno_reg_class): New global.
(sparc_init_modes): Initialize it.
(output_cbranch): Delete fp_cond_reg argument.
(print_operand, MEM op): Don't print "%g0+" if TARGET_SPARCLET.
(sparc_flat_eligible_for_epilogue_delay): Don't allow anything if
TARGET_LIVE_G0.
* sparc/sparc.md (live_g0): New attribute.
(*): Integer condition code register is now reg 100.
Use SPARC_ICC_REG instead of hardcoding reg 100 where possible.
Non-v9 floating point condition code register is now reg 96.
(*cmp{sf,df,tf}_{fpe,fp}_sp{32,64}): Combine v9/non-v9 cases.
(*{normal,inverted}_{,fp,fpe}_branch): Update call to output_cbranch.
(*mov{qi,hi,si}_insn): Don't use if TARGET_LIVE_G0.
(*mov{qi,hi,si}_insn_liveg0): New patterns.
(*mov{si,di,sf,df,tf}_ccfp{,e}_sp64): ccfp_reg_operand renamed to
fcc_reg_operand.
(*negdi2_sp32,negsi2,one_cmplsi2,ffssi2): Ensure %%g0 is 0 if
TARGET_LIVE_G0.
(*one_cmpldi2_sp32): Move operand 1 to rs1 and use 0 as rs2.
(patterns that use %g0 in rs2): Use 0 immediate value instead.
(patterns that read %g0): Don't use if TARGET_LIVE_G0.
From-SVN: r11494
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/sparc/sparc.c | 163 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 104 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 747 |
3 files changed, 595 insertions, 419 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 8bf67aa..dc6bcbf 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -99,7 +99,7 @@ char leaf_reg_remap[] = 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99}; + 96, 97, 98, 99, 100}; #endif @@ -268,13 +268,19 @@ v9_regcmp_p (code) /* Operand constraints. */ /* Return non-zero only if OP is a register of mode MODE, - or const0_rtx. */ + or const0_rtx. Don't allow const0_rtx if TARGET_LIVE_G0 because + %g0 may contain anything. */ + int reg_or_0_operand (op, mode) rtx op; enum machine_mode mode; { - if (op == const0_rtx || register_operand (op, mode)) + if (register_operand (op, mode)) + return 1; + if (TARGET_LIVE_G0) + return 0; + if (op == const0_rtx) return 1; if (GET_MODE (op) == VOIDmode && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0 @@ -288,6 +294,7 @@ reg_or_0_operand (op, mode) } /* Nonzero if OP is a floating point value with value 0.0. */ + int fp_zero_operand (op) rtx op; @@ -312,26 +319,38 @@ intreg_operand (op, mode) /* Nonzero if OP is a floating point condition code register. */ int -ccfp_reg_operand (op, mode) +fcc_reg_operand (op, mode) rtx op; enum machine_mode mode; { /* This can happen when recog is called from combine. Op may be a MEM. Fail instead of calling abort in this case. */ - if (GET_CODE (op) != REG || REGNO (op) == 0) + if (GET_CODE (op) != REG) return 0; - if (GET_MODE (op) != mode) + if (mode != VOIDmode && mode != GET_MODE (op)) return 0; -#if 0 /* ??? ==> 1 when %fcc1-3 are pseudos first. See gen_compare_reg(). */ +#if 0 /* ??? ==> 1 when %fcc0-3 are pseudos first. See gen_compare_reg(). */ if (reg_renumber == 0) return REGNO (op) >= FIRST_PSEUDO_REGISTER; return REGNO_OK_FOR_CCFP_P (REGNO (op)); #else - return (unsigned) REGNO (op) - 96 < 4; + return (unsigned) REGNO (op) - SPARC_FIRST_V9_FCC_REG < 4; #endif } +/* Nonzero if OP is an integer or floating point condition code register. */ + +int +icc_or_fcc_reg_operand (op, mode) + rtx op; + enum machine_mode mode; +{ + if (GET_CODE (op) == REG && REGNO (op) == SPARC_ICC_REG) + return 1; + return fcc_reg_operand (op, mode); +} + /* Nonzero if OP can appear as the dest of a RESTORE insn. */ int restore_operand (op, mode) @@ -855,7 +874,7 @@ gen_compare_reg (code, x, y) rtx cc_reg; /* ??? We don't have movcc patterns so we cannot generate pseudo regs for the - fpcc regs (cse can't tell they're really call clobbered regs and will + fcc regs (cse can't tell they're really call clobbered regs and will remove a duplicate comparison even if there is an intervening function call - it will then try to reload the cc reg via an int reg which is why we need the movcc patterns). It is possible to provide the movcc @@ -875,8 +894,8 @@ gen_compare_reg (code, x, y) { int reg; /* We cycle through the registers to ensure they're all exercised. */ - static int next_fpcc_reg = 0; - /* Previous x,y for each fpcc reg. */ + static int next_fcc_reg = 0; + /* Previous x,y for each fcc reg. */ static rtx prev_args[4][2]; /* Scan prev_args for x,y. */ @@ -885,18 +904,20 @@ gen_compare_reg (code, x, y) break; if (reg == 4) { - reg = next_fpcc_reg; + reg = next_fcc_reg; prev_args[reg][0] = x; prev_args[reg][1] = y; - next_fpcc_reg = (next_fpcc_reg + 1) & 3; + next_fcc_reg = (next_fcc_reg + 1) & 3; } - cc_reg = gen_rtx (REG, mode, reg + 96); + cc_reg = gen_rtx (REG, mode, reg + SPARC_FIRST_V9_FCC_REG); } #else cc_reg = gen_reg_rtx (mode); #endif /* ! experiment */ + else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) + cc_reg = gen_rtx (REG, mode, SPARC_FCC_REG); else - cc_reg = gen_rtx (REG, mode, 0); + cc_reg = gen_rtx (REG, mode, SPARC_ICC_REG); emit_insn (gen_rtx (SET, VOIDmode, cc_reg, gen_rtx (COMPARE, mode, x, y))); @@ -1062,6 +1083,14 @@ eligible_for_epilogue_delay (trial, slot) if (get_attr_length (trial) != 1) return 0; + pat = PATTERN (trial); + + /* If %g0 is live, there are lots of things we can't handle. + Rather than trying to find them all now, let's punt and only + optimize things as necessary. */ + if (TARGET_LIVE_G0) + return 0; + /* In the case of a true leaf function, anything can go into the delay slot. A delay slot only exists however if the frame size is zero, otherwise we will put an insn to adjust the stack after the return. */ @@ -1074,9 +1103,7 @@ eligible_for_epilogue_delay (trial, slot) /* Otherwise, only operations which can be done in tandem with a `restore' insn can go into the delay slot. */ - pat = PATTERN (trial); if (GET_CODE (SET_DEST (pat)) != REG - || REGNO (SET_DEST (pat)) == 0 || REGNO (SET_DEST (pat)) >= 32 || REGNO (SET_DEST (pat)) < 24) return 0; @@ -1442,7 +1469,8 @@ emit_move_sequence (operands, mode) } else if (GET_CODE (operand0) == MEM) { - if (register_operand (operand1, mode) || operand1 == const0_rtx) + if (register_operand (operand1, mode) + || (operand1 == const0_rtx && ! TARGET_LIVE_G0)) { /* Run this case quickly. */ emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); @@ -2575,7 +2603,8 @@ output_scc_insn (operands, insn) LABEL_NUSES (label) += 1; - operands[2] = label; + /* operands[3] is an unused slot. */ + operands[3] = label; /* If we are in a delay slot, assume it is the delay slot of an fpcc insn since our type isn't allowed anywhere else. */ @@ -2598,17 +2627,17 @@ output_scc_insn (operands, insn) if (final_sequence) { strcpy (string, "mov 0,%0\n\t"); - strcat (string, output_cbranch (operands[1], 0, 2, 0, 1, 0)); + strcat (string, output_cbranch (operands[2], 3, 0, 1, 0)); strcat (string, "\n\tmov 1,%0"); } else { - strcpy (string, output_cbranch (operands[1], 0, 2, 0, 1, 0)); + strcpy (string, output_cbranch (operands[2], 3, 0, 1, 0)); strcat (string, "\n\tmov 1,%0\n\tmov 0,%0"); } if (need_label) - strcat (string, "\n%l2:"); + strcat (string, "\n%l3:"); return string; } @@ -2623,15 +2652,11 @@ output_scc_insn (operands, insn) mapped into one sparc_mode_class mode. */ enum sparc_mode_class { - C_MODE, CCFP_MODE, S_MODE, D_MODE, T_MODE, O_MODE, - SF_MODE, DF_MODE, TF_MODE, OF_MODE + SF_MODE, DF_MODE, TF_MODE, OF_MODE, + CC_MODE, CCFP_MODE }; -/* Modes for condition codes. */ -#define C_MODES ((1 << (int) C_MODE) | (1 << (int) CCFP_MODE)) -#define CCFP_MODES (1 << (int) CCFP_MODE) - /* Modes for single-word and smaller quantities. */ #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE)) @@ -2653,7 +2678,8 @@ enum sparc_mode_class { #define DF_MODES64 (SF_MODES | DF_MODE /* | D_MODE*/) /* Modes for double-float only quantities. */ -/* ??? Sparc64 fp regs cannot hold DImode values. */ +/* ??? Sparc64 fp regs cannot hold DImode values. + See fix_truncsfdi2. */ #define DF_ONLY_MODES ((1 << (int) DF_MODE) /*| (1 << (int) D_MODE)*/) /* Modes for double-float and larger quantities. */ @@ -2665,20 +2691,25 @@ enum sparc_mode_class { /* Modes for quad-float and smaller quantities. */ #define TF_MODES (DF_MODES | TF_ONLY_MODES) -/* ??? Sparc64 fp regs cannot hold DImode values. */ +/* ??? Sparc64 fp regs cannot hold DImode values. + See fix_truncsfdi2. */ #define TF_MODES64 (DF_MODES64 | TF_ONLY_MODES) +/* Modes for condition codes. */ +#define CC_MODES (1 << (int) CC_MODE) +#define CCFP_MODES (1 << (int) CCFP_MODE) + /* Value is 1 if register/mode pair is acceptable on sparc. The funny mixture of D and T modes is because integer operations do not specially operate on tetra quantities, so non-quad-aligned registers can hold quadword quantities (except %o4 and %i4 because - they cross fixed registers. */ + they cross fixed registers). */ /* This points to either the 32 bit or the 64 bit version. */ int *hard_regno_mode_classes; static int hard_32bit_mode_classes[] = { - C_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, + S_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES, @@ -2696,11 +2727,14 @@ static int hard_32bit_mode_classes[] = { DF_UP_MODES, 0, DF_ONLY_MODES, 0, DF_UP_MODES, 0, DF_ONLY_MODES, 0, /* %fcc[0123] */ - CCFP_MODE, CCFP_MODE, CCFP_MODE, CCFP_MODE + CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES, + + /* %icc */ + CC_MODES }; static int hard_64bit_mode_classes[] = { - C_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, + D_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, @@ -2718,11 +2752,16 @@ static int hard_64bit_mode_classes[] = { DF_UP_MODES, 0, DF_ONLY_MODES, 0, DF_UP_MODES, 0, DF_ONLY_MODES, 0, /* %fcc[0123] */ - CCFP_MODE, CCFP_MODE, CCFP_MODE, CCFP_MODE + CCFP_MODES, CCFP_MODES, CCFP_MODES, CCFP_MODES, + + /* %icc */ + CC_MODES }; int sparc_mode_class [NUM_MACHINE_MODES]; +enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER]; + static void sparc_init_modes () { @@ -2767,7 +2806,7 @@ sparc_init_modes () sparc_mode_class[i] = 1 << (int) CCFP_MODE; else if (i == (int) CCmode || i == (int) CC_NOOVmode || i == (int) CCXmode || i == (int) CCX_NOOVmode) - sparc_mode_class[i] = 1 << (int) C_MODE; + sparc_mode_class[i] = 1 << (int) CC_MODE; else sparc_mode_class[i] = 0; break; @@ -2778,6 +2817,21 @@ sparc_init_modes () hard_regno_mode_classes = hard_64bit_mode_classes; else hard_regno_mode_classes = hard_32bit_mode_classes; + + /* Initialize the array used by REGNO_REG_CLASS. */ + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + { + if (i < 32) + sparc_regno_reg_class[i] = GENERAL_REGS; + else if (i < 64) + sparc_regno_reg_class[i] = FP_REGS; + else if (i < 96) + sparc_regno_reg_class[i] = EXTRA_FP_REGS; + else if (i < 100) + sparc_regno_reg_class[i] = FPCC_REGS; + else + sparc_regno_reg_class[i] = NO_REGS; + } } /* Save non call used registers from LOW to HIGH at BASE+OFFSET. @@ -3320,11 +3374,9 @@ sparc_builtin_saveregs (arglist) #endif /* ! SPARC_ARCH64 */ /* Return the string to output a conditional branch to LABEL, which is - the operand number of the label. OP is the conditional expression. The - mode of register 0 says what kind of comparison we made. - - FP_COND_REG indicates which fp condition code register to use if this is - a floating point branch. + the operand number of the label. OP is the conditional expression. + XEXP (OP, 0) is assumed to be a condition code register (integer or + floating point) and its mode specifies what kind of comparison we made. REVERSED is non-zero if we should reverse the sense of the comparison. @@ -3333,14 +3385,15 @@ sparc_builtin_saveregs (arglist) NOOP is non-zero if we have to follow this branch by a noop. */ char * -output_cbranch (op, fp_cond_reg, label, reversed, annul, noop) - rtx op, fp_cond_reg; +output_cbranch (op, label, reversed, annul, noop) + rtx op; int label; int reversed, annul, noop; { static char string[20]; enum rtx_code code = GET_CODE (op); - enum machine_mode mode = GET_MODE (XEXP (op, 0)); + rtx cc_reg = XEXP (op, 0); + enum machine_mode mode = GET_MODE (cc_reg); static char v8_labelno[] = " %lX"; static char v9_icc_labelno[] = " %%icc,%lX"; static char v9_xcc_labelno[] = " %%xcc,%lX"; @@ -3467,7 +3520,7 @@ output_cbranch (op, fp_cond_reg, label, reversed, annul, noop) labeloff = 10; labelno = v9_fcc_labelno; /* Set the char indicating the number of the fcc reg to use. */ - labelno[6] = REGNO (fp_cond_reg) - 96 + '0'; + labelno[6] = REGNO (cc_reg) - SPARC_FIRST_V9_FCC_REG + '0'; } else if (mode == CCXmode || mode == CCX_NOOVmode) labelno = v9_xcc_labelno; @@ -3930,8 +3983,9 @@ print_operand (file, x, code) else if (GET_CODE (x) == MEM) { fputc ('[', file); - if (CONSTANT_P (XEXP (x, 0))) /* Poor Sun assembler doesn't understand absolute addressing. */ + if (CONSTANT_P (XEXP (x, 0)) + && ! TARGET_LIVE_G0) fputs ("%g0+", file); output_address (XEXP (x, 0)); fputc (']', file); @@ -4847,10 +4901,21 @@ sparc_flat_eligible_for_epilogue_delay (trial, slot) rtx trial; int slot; { - if (get_attr_length (trial) == 1 - && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial)) - && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial))) + rtx pat = PATTERN (trial); + + if (get_attr_length (trial) != 1) + return 0; + + /* If %g0 is live, there are lots of things we can't handle. + Rather than trying to find them all now, let's punt and only + optimize things as necessary. */ + if (TARGET_LIVE_G0) + return 0; + + if (! reg_mentioned_p (stack_pointer_rtx, pat) + && ! reg_mentioned_p (frame_pointer_rtx, pat)) return 1; + return 0; } diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 0b54f24..b634957 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -369,6 +369,13 @@ extern int target_flags; #define MASK_STACK_BIAS 0x80000 #define TARGET_STACK_BIAS (target_flags & MASK_STACK_BIAS) +/* Non-zero means %g0 is a normal register. + We still clobber it as necessary, but we can't rely on it always having + a zero value. + We don't bother to support this in true 64 bit mode. */ +#define MASK_LIVE_G0 0x100000 +#define TARGET_LIVE_G0 (target_flags & MASK_LIVE_G0) + /* Macro to define tables used to set the flags. This is a list in braces of pairs in braces, each pair being { "NAME", VALUE } @@ -392,6 +399,7 @@ extern int target_flags; {"no-app-regs", -MASK_APP_REGS}, \ {"hard-quad-float", MASK_HARD_QUAD}, \ {"soft-quad-float", -MASK_HARD_QUAD}, \ + {"live-g0", MASK_LIVE_G0}, \ /* ??? These are coerced to -mcpu=. Delete in 2.9. */ \ {"cypress", 0}, \ {"sparclite", 0}, \ @@ -673,18 +681,23 @@ extern struct sparc_cpu_select sparc_select[]; accessible. We still account for them to simplify register computations (eg: in CLASS_MAX_NREGS). There are also 4 fp condition code registers, so 32+32+32+4 == 100. - Register 0 is used as the integer condition code register. */ + Register 100 is used as the integer condition code register. */ -#define FIRST_PSEUDO_REGISTER 100 +#define FIRST_PSEUDO_REGISTER 101 /* Additional V9 fp regs. */ #define SPARC_FIRST_V9_FP_REG 64 -#define SPARC_LAST_V9_FP_REG 99 +#define SPARC_LAST_V9_FP_REG 95 +/* V9 %fcc[0123]. V8 uses (figuratively) %fcc0. */ +#define SPARC_FIRST_V9_FCC_REG 96 +#define SPARC_LAST_V9_FCC_REG 99 +/* V8 fcc reg. */ +#define SPARC_FCC_REG 96 +/* Integer CC reg. We don't distinguish %icc from %xcc. */ +#define SPARC_ICC_REG 100 /* 1 for registers that have pervasive standard uses and are not available for the register allocator. - g0 is used for the condition code and not to represent %g0, which is - hardwired to 0, so reg 0 is *not* fixed. On non-v9 systems: g1 is free to use as temporary. g2-g4 are reserved for applications. Gcc normally uses them as @@ -705,7 +718,7 @@ extern struct sparc_cpu_select sparc_select[]; */ #define FIXED_REGISTERS \ - {0, 0, 0, 0, 0, 0, 1, 1, \ + {1, 0, 0, 0, 0, 0, 1, 1, \ 0, 0, 0, 0, 0, 0, 1, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 1, 1, \ @@ -720,7 +733,7 @@ extern struct sparc_cpu_select sparc_select[]; 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ \ - 0, 0, 0, 0} + 0, 0, 0, 0, 0} /* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any @@ -745,10 +758,10 @@ extern struct sparc_cpu_select sparc_select[]; 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ \ - 1, 1, 1, 1} + 1, 1, 1, 1, 1} -/* If !TARGET_FPU, then make the fp registers fixed so that they won't - be allocated. On v9, also make the fp cc regs fixed. */ +/* If !TARGET_FPU, then make the fp registers and fp cc regs fixed so that + they won't be allocated. */ #define CONDITIONAL_REGISTER_USAGE \ do \ @@ -772,11 +785,16 @@ do \ regno <= SPARC_LAST_V9_FP_REG; \ regno++) \ fixed_regs[regno] = 1; \ + /* %fcc0 is used by v8 and v9. */ \ + for (regno = SPARC_FIRST_V9_FCC_REG + 1; \ + regno <= SPARC_LAST_V9_FCC_REG; \ + regno++) \ + fixed_regs[regno] = 1; \ } \ if (! TARGET_FPU) \ { \ int regno; \ - for (regno = 32; regno < FIRST_PSEUDO_REGISTER; regno++) \ + for (regno = 32; regno < SPARC_LAST_V9_FCC_REG; regno++) \ fixed_regs[regno] = 1; \ } \ /* Don't unfix g2-g4 if they were fixed with -ffixed-. */ \ @@ -982,7 +1000,12 @@ extern int sparc_mode_class[]; have a class that is the union of FPCC_REGS with either of the others, it is important that it appear first. Otherwise the compiler will die trying to compile _fixunsdfsi because fix_truncdfsi2 won't match its - constraints. */ + constraints. + + It is important that SPARC_ICC_REG have class NO_REGS. Otherwise combine + may try to use it to hold an SImode value. See register_operand. + ??? Should %fcc[0123] be handled similarily? +*/ enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS, GENERAL_OR_FP_REGS, GENERAL_OR_EXTRA_FP_REGS, @@ -1001,21 +1024,18 @@ enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS, of length N_REG_CLASSES. */ #define REG_CLASS_CONTENTS \ - {{0, 0, 0, 0}, {0, 0, 0, 0xf}, {-2, 0, 0, 0}, \ - {0, -1, 0, 0}, {0, -1, -1, 0}, {-2, -1, 0, 0}, {-2, -1, -1, 0}, \ - {-2, -1, -1, 0xf}} + {{0, 0, 0, 0}, {0, 0, 0, 0xf}, \ + {-1, 0, 0, 0}, {0, -1, 0, 0}, {0, -1, -1, 0}, \ + {-1, -1, 0, 0}, {-1, -1, -1, 0}, {-1, -1, -1, 0x1f}} /* The same information, inverted: Return the class number of the smallest class containing reg number REGNO. This could be a conditional expression or could index an array. */ -#define REGNO_REG_CLASS(REGNO) \ - ((REGNO) == 0 ? NO_REGS \ - : (REGNO) < 32 ? GENERAL_REGS \ - : (REGNO) < 64 ? FP_REGS \ - : (REGNO) < 96 ? EXTRA_FP_REGS \ - : FPCC_REGS) +extern enum reg_class sparc_regno_reg_class[]; + +#define REGNO_REG_CLASS(REGNO) sparc_regno_reg_class[(REGNO)] /* This is the order in which to allocate registers normally. @@ -1040,7 +1060,7 @@ enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS, 64, 65, 66, 67, 68, 69, 70, 71, /* %f32-%f39 */ \ 72, 73, 74, 75, 76, 77, 78, 79, /* %f40-%f47 */ \ 32, 33, /* %f0,%f1 */ \ - 96, 97, 98, 99, /* %fcc0-3 */ \ + 96, 97, 98, 99, 100, /* %fcc0-3, %icc */ \ 1, 4, 5, 6, 7, 0, 14, 30} /* This is the order in which to allocate registers for @@ -1062,7 +1082,7 @@ enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS, 64, 65, 66, 67, 68, 69, 70, 71, \ 72, 73, 74, 75, 76, 77, 78, 79, \ 32, 33, \ - 96, 97, 98, 99, \ + 96, 97, 98, 99, 100, \ 1, 4, 5, 6, 7, 0, 14, 30, 31} #define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc () @@ -1086,7 +1106,7 @@ enum reg_class { NO_REGS, FPCC_REGS, GENERAL_REGS, FP_REGS, EXTRA_FP_REGS, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ - 1, 1, 1, 1} + 1, 1, 1, 1, 1} extern char leaf_reg_remap[]; #define LEAF_REG_REMAP(REGNO) (leaf_reg_remap[REGNO]) @@ -1110,6 +1130,7 @@ extern char leaf_reg_remap[]; : NO_REGS) \ : ((C) == 'f' ? FP_REGS \ : (C) == 'e' ? FP_REGS \ + : (C) == 'c' ? FPCC_REGS \ : NO_REGS)) /* The letters I, J, K, L and M in a register constraint string @@ -1624,7 +1645,7 @@ extern int leaf_function; #define FUNCTION_PROLOGUE(FILE, SIZE) \ (TARGET_FLAT ? sparc_flat_output_function_prologue (FILE, SIZE) \ : output_function_prologue (FILE, SIZE, leaf_function)) - + /* Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry. */ @@ -1981,7 +2002,7 @@ while(0) asm ("LSFLGNZVC" ID ":");\ asm (" unimp");\ asm ("LFLGRET" ID ":"); - + /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, the stack pointer does not matter. The value is tested only in functions that have frame pointers. @@ -2136,15 +2157,16 @@ extern struct rtx_def *sparc_builtin_saveregs (); has been allocated, which happens in local-alloc.c. */ #define REGNO_OK_FOR_INDEX_P(REGNO) \ -(((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) && (REGNO) != 0) +((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) #define REGNO_OK_FOR_BASE_P(REGNO) \ -(((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) && (REGNO) != 0) +((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32) #define REGNO_OK_FOR_FP_P(REGNO) \ (((unsigned) (REGNO) - 32 < (TARGET_V9 ? 64 : 32)) \ || ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? 64 : 32))) #define REGNO_OK_FOR_CCFP_P(REGNO) \ (TARGET_V9 \ - && ((unsigned) (REGNO) - 96 < 4) || ((unsigned) reg_renumber[REGNO] - 96 < 4)) + && (((unsigned) (REGNO) - 96 < 4) \ + || ((unsigned) reg_renumber[REGNO] - 96 < 4))) /* Now macros that check whether X is a register and also, strictly, whether it is in a specified class. @@ -2210,11 +2232,11 @@ extern struct rtx_def *sparc_builtin_saveregs (); /* Nonzero if X is a hard reg that can be used as an index or if it is a pseudo reg. */ #define REG_OK_FOR_INDEX_P(X) \ - (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32) && REGNO (X) != 0) + (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32)) /* Nonzero if X is a hard reg that can be used as a base reg or if it is a pseudo reg. */ #define REG_OK_FOR_BASE_P(X) \ - (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32) && REGNO (X) != 0) + (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32)) /* 'T', 'U' are for aligned memory loads which aren't needed for v9. */ @@ -2249,8 +2271,9 @@ extern struct rtx_def *sparc_builtin_saveregs (); : (! TARGET_ARCH64 && (C) == 'U') \ ? (GET_CODE (OP) == REG \ && (REGNO (OP) < FIRST_PSEUDO_REGISTER \ - || reg_renumber[REGNO (OP)] > 0) \ - && register_ok_for_ldd (OP)) : 0) + || reg_renumber[REGNO (OP)] >= 0) \ + && register_ok_for_ldd (OP)) \ + : 0) #endif /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression @@ -2468,8 +2491,7 @@ extern struct rtx_def *legitimize_pic_address (); We also have two modes to indicate that the relevant condition code is in the floating-point condition code register. One for comparisons which will generate an exception if the result is unordered (CCFPEmode) and - one for comparisons which will never trap (CCFPmode). This really should - be a separate register, but we don't want to go to 65 registers. + one for comparisons which will never trap (CCFPmode). CCXmode and CCX_NOOVmode are only used by v9. */ @@ -2703,16 +2725,12 @@ extern struct rtx_def *legitimize_pic_address (); "%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47", \ "%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55", \ "%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63", \ - "%fcc0", "%fcc1", "%fcc2", "%fcc3"} - -/* Define additional names for use in asm clobbers and asm declarations. + "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc"} - We define the fake Condition Code register as an alias for reg 0 (which - is our `condition code' register), so that condition codes can easily - be clobbered by an asm. No such register actually exists. Condition - codes are partly stored in the PSR and partly in the FSR. */ +/* Define additional names for use in asm clobbers and asm declarations. */ -#define ADDITIONAL_REGISTER_NAMES {"ccr", 0, "cc", 0} +#define ADDITIONAL_REGISTER_NAMES \ +{{"ccr", SPARC_ICC_REG}, {"cc", SPARC_ICC_REG}} /* How to renumber registers for dbx and gdb. */ diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 4598922..fc5279b 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -28,6 +28,9 @@ ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of ;; 'f' for all DF/TFmode values, including those that are specific to the v8. +;; +;; -mlive-g0 is *not* supported for TARGET_ARCH64, so we don't bother to +;; test TARGET_LIVE_G0 if we have TARGET_ARCH64. ;; Attribute for cpu type. ;; These must match the values for enum processor_type in sparc.h. @@ -49,6 +52,12 @@ (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")] (const_string "arch32bit")))) +;; Whether -mlive-g0 is in effect. +(define_attr "live_g0" "no,yes" + (const + (cond [(symbol_ref "TARGET_LIVE_G0") (const_string "yes")] + (const_string "no")))) + ;; Insn type. Used to default other attribute values. ;; type "unary" insns have one input operand (1) and one output operand (0) @@ -282,7 +291,7 @@ ;; Put cmpsi first among compare insns so it matches two CONST_INT operands. (define_expand "cmpsi" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "arith_operand" "")))] "" @@ -294,7 +303,7 @@ }") (define_expand "cmpdi" - [(set (reg:CCX 0) + [(set (reg:CCX 100) (compare:CCX (match_operand:DI 0 "register_operand" "") (match_operand:DI 1 "arith_double_operand" "")))] "TARGET_ARCH64" @@ -306,7 +315,8 @@ }") (define_expand "cmpsf" - [(set (reg:CCFP 0) + ;; The 96 here isn't ever used by anyone. + [(set (reg:CCFP 96) (compare:CCFP (match_operand:SF 0 "register_operand" "") (match_operand:SF 1 "register_operand" "")))] "TARGET_FPU" @@ -318,7 +328,8 @@ }") (define_expand "cmpdf" - [(set (reg:CCFP 0) + ;; The 96 here isn't ever used by anyone. + [(set (reg:CCFP 96) (compare:CCFP (match_operand:DF 0 "register_operand" "") (match_operand:DF 1 "register_operand" "")))] "TARGET_FPU" @@ -330,7 +341,8 @@ }") (define_expand "cmptf" - [(set (reg:CCFP 0) + ;; The 96 here isn't ever used by anyone. + [(set (reg:CCFP 96) (compare:CCFP (match_operand:TF 0 "register_operand" "") (match_operand:TF 1 "register_operand" "")))] "TARGET_FPU" @@ -344,115 +356,97 @@ ;; Now the compare DEFINE_INSNs. (define_insn "*cmpsi_insn" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "arith_operand" "rI")))] "" "cmp %0,%1" [(set_attr "type" "compare")]) -(define_insn "*cmpsf_fpe_sp32" - [(set (reg:CCFPE 0) - (compare:CCFPE (match_operand:SF 0 "register_operand" "f") - (match_operand:SF 1 "register_operand" "f")))] - "! TARGET_V9 && TARGET_FPU" - "fcmpes %0,%1" - [(set_attr "type" "fpcmp")]) - -(define_insn "*cmpdf_fpe_sp32" - [(set (reg:CCFPE 0) - (compare:CCFPE (match_operand:DF 0 "register_operand" "e") - (match_operand:DF 1 "register_operand" "e")))] - "! TARGET_V9 && TARGET_FPU" - "fcmped %0,%1" - [(set_attr "type" "fpcmp")]) - -(define_insn "*cmptf_fpe_sp32" - [(set (reg:CCFPE 0) - (compare:CCFPE (match_operand:TF 0 "register_operand" "e") - (match_operand:TF 1 "register_operand" "e")))] - "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" - "fcmpeq %0,%1" - [(set_attr "type" "fpcmp")]) - -(define_insn "*cmpsf_fp_sp32" - [(set (reg:CCFP 0) - (compare:CCFP (match_operand:SF 0 "register_operand" "f") - (match_operand:SF 1 "register_operand" "f")))] - "! TARGET_V9 && TARGET_FPU" - "fcmps %0,%1" - [(set_attr "type" "fpcmp")]) - -(define_insn "*cmpdf_fp_sp32" - [(set (reg:CCFP 0) - (compare:CCFP (match_operand:DF 0 "register_operand" "e") - (match_operand:DF 1 "register_operand" "e")))] - "! TARGET_V9 && TARGET_FPU" - "fcmpd %0,%1" - [(set_attr "type" "fpcmp")]) - -(define_insn "*cmptf_fp_sp32" - [(set (reg:CCFP 0) - (compare:CCFP (match_operand:TF 0 "register_operand" "e") - (match_operand:TF 1 "register_operand" "e")))] - "! TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" - "fcmpq %0,%1" - [(set_attr "type" "fpcmp")]) - (define_insn "*cmpdi_sp64" - [(set (reg:CCX 0) + [(set (reg:CCX 100) (compare:CCX (match_operand:DI 0 "register_operand" "r") (match_operand:DI 1 "arith_double_operand" "rHI")))] "TARGET_ARCH64" "cmp %0,%1" [(set_attr "type" "compare")]) -(define_insn "*cmpsf_fpe_sp64" - [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c") +(define_insn "*cmpsf_fpe" + [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c") (compare:CCFPE (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f")))] - "TARGET_V9 && TARGET_FPU" - "fcmpes %0,%1,%2" + "TARGET_FPU" + "* +{ + if (TARGET_V9) + return \"fcmpes %0,%1,%2\"; + return \"fcmpes %1,%2\"; +}" [(set_attr "type" "fpcmp")]) -(define_insn "*cmpdf_fpe_sp64" - [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c") +(define_insn "*cmpdf_fpe" + [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c") (compare:CCFPE (match_operand:DF 1 "register_operand" "e") (match_operand:DF 2 "register_operand" "e")))] - "TARGET_V9 && TARGET_FPU" - "fcmped %0,%1,%2" + "TARGET_FPU" + "* +{ + if (TARGET_V9) + return \"fcmped %0,%1,%2\"; + return \"fcmped %1,%2\"; +}" [(set_attr "type" "fpcmp")]) -(define_insn "*cmptf_fpe_sp64" - [(set (match_operand:CCFPE 0 "ccfp_reg_operand" "=c") +(define_insn "*cmptf_fpe" + [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c") (compare:CCFPE (match_operand:TF 1 "register_operand" "e") (match_operand:TF 2 "register_operand" "e")))] - "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" - "fcmpeq %0,%1,%2" + "TARGET_FPU && TARGET_HARD_QUAD" + "* +{ + if (TARGET_V9) + return \"fcmpeq %0,%1,%2\"; + return \"fcmpeq %1,%2\"; +}" [(set_attr "type" "fpcmp")]) -(define_insn "*cmpsf_fp_sp64" - [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c") +(define_insn "*cmpsf_fp" + [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c") (compare:CCFP (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f")))] - "TARGET_V9 && TARGET_FPU" - "fcmps %0,%1,%2" + "TARGET_FPU" + "* +{ + if (TARGET_V9) + return \"fcmps %0,%1,%2\"; + return \"fcmps %1,%2\"; +}" [(set_attr "type" "fpcmp")]) -(define_insn "*cmpdf_fp_sp64" - [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c") +(define_insn "*cmpdf_fp" + [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c") (compare:CCFP (match_operand:DF 1 "register_operand" "e") (match_operand:DF 2 "register_operand" "e")))] - "TARGET_V9 && TARGET_FPU" - "fcmpd %0,%1,%2" + "TARGET_FPU" + "* +{ + if (TARGET_V9) + return \"fcmpd %0,%1,%2\"; + return \"fcmpd %1,%2\"; +}" [(set_attr "type" "fpcmp")]) -(define_insn "*cmptf_fp_sp64" - [(set (match_operand:CCFP 0 "ccfp_reg_operand" "=c") +(define_insn "*cmptf_fp" + [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c") (compare:CCFP (match_operand:TF 1 "register_operand" "e") (match_operand:TF 2 "register_operand" "e")))] - "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" - "fcmpq %0,%1,%2" + "TARGET_FPU && TARGET_HARD_QUAD" + "* +{ + if (TARGET_V9) + return \"fcmpq %0,%1,%2\"; + return \"fcmpq %1,%2\"; +}" [(set_attr "type" "fpcmp")]) ;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this @@ -471,8 +465,8 @@ (match_operand:SI 2 "register_operand" ""))) (parallel [(set (match_operand:SI 0 "register_operand" "") (eq:SI (match_dup 3) (const_int 0))) - (clobber (reg:CC 0))])] - "" + (clobber (reg:CC 100))])] + "! TARGET_LIVE_G0" "{ operands[3] = gen_reg_rtx (SImode); }") (define_expand "seqdi_special" @@ -481,7 +475,7 @@ (match_operand:DI 2 "register_operand" ""))) (parallel [(set (match_operand:DI 0 "register_operand" "") (eq:DI (match_dup 3) (const_int 0))) - (clobber (reg:CCX 0))])] + (clobber (reg:CCX 100))])] "TARGET_ARCH64" "{ operands[3] = gen_reg_rtx (DImode); }") @@ -491,8 +485,8 @@ (match_operand:SI 2 "register_operand" ""))) (parallel [(set (match_operand:SI 0 "register_operand" "") (ne:SI (match_dup 3) (const_int 0))) - (clobber (reg:CC 0))])] - "" + (clobber (reg:CC 100))])] + "! TARGET_LIVE_G0" "{ operands[3] = gen_reg_rtx (SImode); }") (define_expand "snedi_special" @@ -501,7 +495,7 @@ (match_operand:DI 2 "register_operand" ""))) (parallel [(set (match_operand:DI 0 "register_operand" "") (ne:DI (match_dup 3) (const_int 0))) - (clobber (reg:CCX 0))])] + (clobber (reg:CCX 100))])] "TARGET_ARCH64" "{ operands[3] = gen_reg_rtx (DImode); }") @@ -511,7 +505,7 @@ (match_operand:DI 2 "register_operand" ""))) (parallel [(set (match_operand:SI 0 "register_operand" "") (eq:DI (match_dup 3) (const_int 0))) - (clobber (reg:CCX 0))])] + (clobber (reg:CCX 100))])] "TARGET_ARCH64" "{ operands[3] = gen_reg_rtx (DImode); }") @@ -521,7 +515,7 @@ (match_operand:DI 2 "register_operand" ""))) (parallel [(set (match_operand:SI 0 "register_operand" "") (ne:DI (match_dup 3) (const_int 0))) - (clobber (reg:CCX 0))])] + (clobber (reg:CCX 100))])] "TARGET_ARCH64" "{ operands[3] = gen_reg_rtx (DImode); }") @@ -531,7 +525,7 @@ (match_operand:SI 2 "register_operand" ""))) (parallel [(set (match_operand:DI 0 "register_operand" "") (eq:SI (match_dup 3) (const_int 0))) - (clobber (reg:CC 0))])] + (clobber (reg:CC 100))])] "TARGET_ARCH64" "{ operands[3] = gen_reg_rtx (SImode); }") @@ -541,7 +535,7 @@ (match_operand:SI 2 "register_operand" ""))) (parallel [(set (match_operand:DI 0 "register_operand" "") (ne:SI (match_dup 3) (const_int 0))) - (clobber (reg:CC 0))])] + (clobber (reg:CC 100))])] "TARGET_ARCH64" "{ operands[3] = gen_reg_rtx (SImode); }") @@ -550,7 +544,7 @@ (define_expand "seq" [(set (match_operand:SI 0 "intreg_operand" "") (eq:SI (match_dup 1) (const_int 0)))] - "" + "! TARGET_LIVE_G0" " { if (GET_MODE (sparc_compare_op0) == SImode) @@ -603,7 +597,7 @@ (define_expand "sne" [(set (match_operand:SI 0 "intreg_operand" "") (ne:SI (match_dup 1) (const_int 0)))] - "" + "! TARGET_LIVE_G0" " { if (GET_MODE (sparc_compare_op0) == SImode) @@ -654,7 +648,7 @@ (define_expand "sgt" [(set (match_operand:SI 0 "intreg_operand" "") (gt:SI (match_dup 1) (const_int 0)))] - "" + "! TARGET_LIVE_G0" " { if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) @@ -675,7 +669,7 @@ (define_expand "slt" [(set (match_operand:SI 0 "intreg_operand" "") (lt:SI (match_dup 1) (const_int 0)))] - "" + "! TARGET_LIVE_G0" " { if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) @@ -696,7 +690,7 @@ (define_expand "sge" [(set (match_operand:SI 0 "intreg_operand" "") (ge:SI (match_dup 1) (const_int 0)))] - "" + "! TARGET_LIVE_G0" " { if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) @@ -717,7 +711,7 @@ (define_expand "sle" [(set (match_operand:SI 0 "intreg_operand" "") (le:SI (match_dup 1) (const_int 0)))] - "" + "! TARGET_LIVE_G0" " { if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD) @@ -738,7 +732,7 @@ (define_expand "sgtu" [(set (match_operand:SI 0 "intreg_operand" "") (gtu:SI (match_dup 1) (const_int 0)))] - "" + "! TARGET_LIVE_G0" " { if (! TARGET_V9) @@ -770,7 +764,7 @@ (define_expand "sltu" [(set (match_operand:SI 0 "intreg_operand" "") (ltu:SI (match_dup 1) (const_int 0)))] - "" + "! TARGET_LIVE_G0" " { if (TARGET_V9) @@ -784,7 +778,7 @@ (define_expand "sgeu" [(set (match_operand:SI 0 "intreg_operand" "") (geu:SI (match_dup 1) (const_int 0)))] - "" + "! TARGET_LIVE_G0" " { if (TARGET_V9) @@ -798,7 +792,7 @@ (define_expand "sleu" [(set (match_operand:SI 0 "intreg_operand" "") (leu:SI (match_dup 1) (const_int 0)))] - "" + "! TARGET_LIVE_G0" " { if (! TARGET_V9) @@ -836,8 +830,8 @@ [(set (match_operand:SI 0 "register_operand" "=r") (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CC 0))] - "" + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" "subcc %%g0,%1,%%g0\;addx %%g0,0,%0" [(set_attr "type" "unary") (set_attr "length" "2")]) @@ -846,8 +840,8 @@ [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))) - (clobber (reg:CC 0))] - "" + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" "subcc %%g0,%1,%%g0\;subx %%g0,0,%0" [(set_attr "type" "unary") (set_attr "length" "2")]) @@ -856,7 +850,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CC 0))] + (clobber (reg:CC 100))] "TARGET_ARCH64" "subcc %%g0,%1,%%g0\;addx %%g0,0,%0" [(set_attr "type" "unary") @@ -866,7 +860,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (ne:DI (match_operand:DI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CCX 0))] + (clobber (reg:CCX 100))] "TARGET_ARCH64" "mov 0,%0\;movrnz %1,1,%0" [(set_attr "type" "unary") @@ -876,7 +870,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r") (const_int 0)))) - (clobber (reg:CCX 0))] + (clobber (reg:CCX 100))] "TARGET_ARCH64" "mov 0,%0\;movrnz %1,-1,%0" [(set_attr "type" "unary") @@ -886,8 +880,8 @@ [(set (match_operand:SI 0 "register_operand" "=r") (ne:DI (match_operand:DI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CCX 0))] - "! TARGET_ARCH64" + (clobber (reg:CCX 100))] + "! TARGET_ARCH64 && ! TARGET_LIVE_G0" "xor %1,%R1,%0\;subcc %%g0,%0,%%g0\;addx %%g0,0,%0" [(set_attr "type" "unary") (set_attr "length" "3")]) @@ -896,7 +890,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (ne:DI (match_operand:DI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CCX 0))] + (clobber (reg:CCX 100))] "TARGET_ARCH64" "mov 0,%0\;movrnz %1,1,%0" [(set_attr "type" "unary") @@ -906,8 +900,8 @@ [(set (match_operand:SI 0 "register_operand" "=r") (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CC 0))] - "" + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0" [(set_attr "type" "unary") (set_attr "length" "2")]) @@ -916,8 +910,8 @@ [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))) - (clobber (reg:CC 0))] - "" + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0" [(set_attr "type" "unary") (set_attr "length" "2")]) @@ -926,7 +920,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CC 0))] + (clobber (reg:CC 100))] "TARGET_ARCH64" "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0" [(set_attr "type" "unary") @@ -936,7 +930,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (eq:DI (match_operand:DI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CCX 0))] + (clobber (reg:CCX 100))] "TARGET_ARCH64" "mov 0,%0\;movrz %1,1,%0" [(set_attr "type" "unary") @@ -946,7 +940,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r") (const_int 0)))) - (clobber (reg:CCX 0))] + (clobber (reg:CCX 100))] "TARGET_ARCH64" "mov 0,%0\;movrz %1,-1,%0" [(set_attr "type" "unary") @@ -956,8 +950,8 @@ [(set (match_operand:SI 0 "register_operand" "=r") (eq:DI (match_operand:DI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CCX 0))] - "! TARGET_ARCH64" + (clobber (reg:CCX 100))] + "! TARGET_ARCH64 && ! TARGET_LIVE_G0" "xor %1,%R1,%0\;subcc %%g0,%0,%%g0\;subx %%g0,-1,%0" [(set_attr "type" "unary") (set_attr "length" "3")]) @@ -966,7 +960,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (eq:DI (match_operand:DI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CCX 0))] + (clobber (reg:CCX 100))] "TARGET_ARCH64" "mov 0,%0\;movrz %1,1,%0" [(set_attr "type" "unary") @@ -981,8 +975,8 @@ (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)) (match_operand:SI 2 "register_operand" "r"))) - (clobber (reg:CC 0))] - "" + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" "subcc %%g0,%1,%%g0\;addx %2,0,%0" [(set_attr "length" "2")]) @@ -991,8 +985,8 @@ (minus:SI (match_operand:SI 2 "register_operand" "r") (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))) - (clobber (reg:CC 0))] - "" + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" "subcc %%g0,%1,%%g0\;subx %2,0,%0" [(set_attr "length" "2")]) @@ -1001,8 +995,8 @@ (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)) (match_operand:SI 2 "register_operand" "r"))) - (clobber (reg:CC 0))] - "" + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" "subcc %%g0,%1,%%g0\;subx %2,-1,%0" [(set_attr "length" "2")]) @@ -1011,8 +1005,8 @@ (minus:SI (match_operand:SI 2 "register_operand" "r") (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))) - (clobber (reg:CC 0))] - "" + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" "subcc %%g0,%1,%%g0\;addx %2,-1,%0" [(set_attr "length" "2")]) @@ -1022,46 +1016,46 @@ (define_insn "*sltu_insn" [(set (match_operand:SI 0 "register_operand" "=r") - (ltu:SI (reg:CC 0) (const_int 0)))] - "" + (ltu:SI (reg:CC 100) (const_int 0)))] + "! TARGET_LIVE_G0" "addx %%g0,0,%0" [(set_attr "type" "misc")]) (define_insn "*neg_sltu_insn" [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))] - "" + (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))] + "! TARGET_LIVE_G0" "subx %%g0,0,%0" [(set_attr "type" "misc")]) ;; ??? Combine should canonicalize these next two to the same pattern. (define_insn "*neg_sltu_minus_x" [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (neg:SI (ltu:SI (reg:CC 0) (const_int 0))) + (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0))) (match_operand:SI 1 "arith_operand" "rI")))] - "" + "! TARGET_LIVE_G0" "subx %%g0,%1,%0" [(set_attr "type" "unary")]) (define_insn "*neg_sltu_plus_x" [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) + (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) (match_operand:SI 1 "arith_operand" "rI"))))] - "" + "! TARGET_LIVE_G0" "subx %%g0,%1,%0" [(set_attr "type" "unary")]) (define_insn "*sgeu_insn" [(set (match_operand:SI 0 "register_operand" "=r") - (geu:SI (reg:CC 0) (const_int 0)))] - "" + (geu:SI (reg:CC 100) (const_int 0)))] + "! TARGET_LIVE_G0" "subx %%g0,-1,%0" [(set_attr "type" "misc")]) (define_insn "*neg_sgeu_insn" [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (geu:SI (reg:CC 0) (const_int 0))))] - "" + (neg:SI (geu:SI (reg:CC 100) (const_int 0))))] + "! TARGET_LIVE_G0" "addx %%g0,-1,%0" [(set_attr "type" "misc")]) @@ -1071,15 +1065,15 @@ (define_insn "*sltu_plus_x" [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) + (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) (match_operand:SI 1 "arith_operand" "rI")))] - "" + "! TARGET_LIVE_G0" "addx %%g0,%1,%0" [(set_attr "type" "unary")]) (define_insn "*sltu_plus_x_plus_y" [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) + (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) (plus:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI"))))] "" @@ -1088,7 +1082,7 @@ (define_insn "*x_minus_sltu" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "r") - (ltu:SI (reg:CC 0) (const_int 0))))] + (ltu:SI (reg:CC 100) (const_int 0))))] "" "subx %1,0,%0" [(set_attr "type" "unary")]) @@ -1098,21 +1092,21 @@ [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI")) - (ltu:SI (reg:CC 0) (const_int 0))))] + (ltu:SI (reg:CC 100) (const_int 0))))] "" "subx %1,%2,%0") (define_insn "*x_minus_sltu_plus_y" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "r") - (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) + (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) (match_operand:SI 2 "arith_operand" "rI"))))] "" "subx %1,%2,%0") (define_insn "*sgeu_plus_x" [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (geu:SI (reg:CC 0) (const_int 0)) + (plus:SI (geu:SI (reg:CC 100) (const_int 0)) (match_operand:SI 1 "register_operand" "r")))] "" "subx %1,-1,%0" @@ -1121,7 +1115,7 @@ (define_insn "*x_minus_sgeu" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "r") - (geu:SI (reg:CC 0) (const_int 0))))] + (geu:SI (reg:CC 100) (const_int 0))))] "" "addx %1,-1,%0" [(set_attr "type" "unary")]) @@ -1134,7 +1128,9 @@ (define_insn "*scc_si" [(set (match_operand:SI 0 "register_operand" "=r") - (match_operator:SI 1 "noov_compare_op" [(reg 0) (const_int 0)]))] + (match_operator:SI 2 "noov_compare_op" + [(match_operand 1 "icc_or_fcc_reg_operand" "") + (const_int 0)]))] "" "* return output_scc_insn (operands, insn); " [(set_attr "type" "multi") @@ -1142,7 +1138,9 @@ (define_insn "*scc_di" [(set (match_operand:DI 0 "register_operand" "=r") - (match_operator:DI 1 "noov_compare_op" [(reg 0) (const_int 0)]))] + (match_operator:DI 2 "noov_compare_op" + [(match_operand 1 "icc_or_fcc_reg_operand" "") + (const_int 0)]))] "TARGET_ARCH64" "* return output_scc_insn (operands, insn); " [(set_attr "type" "multi") @@ -1343,13 +1341,13 @@ (define_insn "*normal_branch" [(set (pc) (if_then_else (match_operator 0 "noov_compare_op" - [(reg 0) (const_int 0)]) + [(reg 100) (const_int 0)]) (label_ref (match_operand 1 "" "")) (pc)))] "" "* { - return output_cbranch (operands[0], 0, 1, 0, + return output_cbranch (operands[0], 1, 0, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence); }" @@ -1358,77 +1356,77 @@ (define_insn "*inverted_branch" [(set (pc) (if_then_else (match_operator 0 "noov_compare_op" - [(reg 0) (const_int 0)]) + [(reg 100) (const_int 0)]) (pc) (label_ref (match_operand 1 "" ""))))] "" "* { - return output_cbranch (operands[0], 0, 1, 1, + return output_cbranch (operands[0], 1, 1, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence); }" [(set_attr "type" "branch")]) -(define_insn "*normal_fp_branch_sp64" +(define_insn "*normal_fp_branch" [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(match_operand:CCFP 1 "ccfp_reg_operand" "c") + (if_then_else (match_operator 1 "comparison_operator" + [(match_operand:CCFP 0 "fcc_reg_operand" "c") (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] - "TARGET_V9" + "" "* { - return output_cbranch (operands[0], operands[1], 2, 0, + return output_cbranch (operands[1], 2, 0, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence); }" [(set_attr "type" "branch")]) -(define_insn "*inverted_fp_branch_sp64" +(define_insn "*inverted_fp_branch" [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(match_operand:CCFP 1 "ccfp_reg_operand" "c") + (if_then_else (match_operator 1 "comparison_operator" + [(match_operand:CCFP 0 "fcc_reg_operand" "c") (const_int 0)]) (pc) (label_ref (match_operand 2 "" ""))))] - "TARGET_V9" + "" "* { - return output_cbranch (operands[0], operands[1], 2, 1, + return output_cbranch (operands[1], 2, 1, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence); }" [(set_attr "type" "branch")]) -(define_insn "*normal_fpe_branch_sp64" +(define_insn "*normal_fpe_branch" [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(match_operand:CCFPE 1 "ccfp_reg_operand" "c") + (if_then_else (match_operator 1 "comparison_operator" + [(match_operand:CCFPE 0 "fcc_reg_operand" "c") (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] - "TARGET_V9" + "" "* { - return output_cbranch (operands[0], operands[1], 2, 0, + return output_cbranch (operands[1], 2, 0, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence); }" [(set_attr "type" "branch")]) -(define_insn "*inverted_fpe_branch_sp64" +(define_insn "*inverted_fpe_branch" [(set (pc) - (if_then_else (match_operator 0 "comparison_operator" - [(match_operand:CCFPE 1 "ccfp_reg_operand" "c") + (if_then_else (match_operator 1 "comparison_operator" + [(match_operand:CCFPE 0 "fcc_reg_operand" "c") (const_int 0)]) (pc) (label_ref (match_operand 2 "" ""))))] - "TARGET_V9" + "" "* { - return output_cbranch (operands[0], operands[1], 2, 1, + return output_cbranch (operands[1], 2, 1, final_sequence && INSN_ANNULLED_BRANCH_P (insn), ! final_sequence); }" @@ -1792,9 +1790,10 @@ (define_insn "*movqi_insn" [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))] - "register_operand (operands[0], QImode) - || register_operand (operands[1], QImode) - || operands[1] == const0_rtx" + "! TARGET_LIVE_G0 + && (register_operand (operands[0], QImode) + || register_operand (operands[1], QImode) + || operands[1] == const0_rtx)" "@ mov %1,%0 sethi %%hi(%a1),%0 @@ -1803,6 +1802,22 @@ [(set_attr "type" "move,move,load,store") (set_attr "length" "1")]) +(define_insn "*movqi_insn_liveg0" + [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q") + (match_operand:QI 1 "move_operand" "r,J,I,K,Q,r"))] + "TARGET_LIVE_G0 + && (register_operand (operands[0], QImode) + || register_operand (operands[1], QImode))" + "@ + mov %1,%0 + and %0,0,%0 + and %0,0,%0\;or %0,%1,%0 + sethi %%hi(%a1),%0 + ldub %1,%0 + stb %1,%0" + [(set_attr "type" "move,move,move,move,load,store") + (set_attr "length" "1,1,2,1,1,1")]) + (define_insn "*lo_sum_qi" [(set (match_operand:QI 0 "register_operand" "=r") (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r") @@ -1815,7 +1830,8 @@ [(set (mem:QI (match_operand:SI 0 "symbolic_operand" "")) (match_operand:QI 1 "reg_or_0_operand" "rJ")) (clobber (match_scratch:SI 2 "=&r"))] - "(reload_completed || reload_in_progress) && ! TARGET_PTR64" + "(reload_completed || reload_in_progress) + && ! TARGET_PTR64" "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]" [(set_attr "type" "store") (set_attr "length" "2")]) @@ -1833,9 +1849,10 @@ (define_insn "*movhi_insn" [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))] - "register_operand (operands[0], HImode) - || register_operand (operands[1], HImode) - || operands[1] == const0_rtx" + "! TARGET_LIVE_G0 + && (register_operand (operands[0], HImode) + || register_operand (operands[1], HImode) + || operands[1] == const0_rtx)" "@ mov %1,%0 sethi %%hi(%a1),%0 @@ -1844,6 +1861,22 @@ [(set_attr "type" "move,move,load,store") (set_attr "length" "1")]) +(define_insn "*movhi_insn_liveg0" + [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q") + (match_operand:HI 1 "move_operand" "r,J,I,K,Q,r"))] + "TARGET_LIVE_G0 + && (register_operand (operands[0], HImode) + || register_operand (operands[1], HImode))" + "@ + mov %1,%0 + and %0,0,%0 + and %0,0,%0\;or %0,%1,%0 + sethi %%hi(%a1),%0 + lduh %1,%0 + sth %1,%0" + [(set_attr "type" "move,move,move,move,load,store") + (set_attr "length" "1,1,2,1,1,1")]) + (define_insn "*lo_sum_hi" [(set (match_operand:HI 0 "register_operand" "=r") (lo_sum:HI (match_operand:HI 1 "register_operand" "r") @@ -1856,7 +1889,8 @@ [(set (mem:HI (match_operand:SI 0 "symbolic_operand" "")) (match_operand:HI 1 "reg_or_0_operand" "rJ")) (clobber (match_scratch:SI 2 "=&r"))] - "(reload_completed || reload_in_progress) && ! TARGET_PTR64" + "(reload_completed || reload_in_progress) + && ! TARGET_PTR64" "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]" [(set_attr "type" "store") (set_attr "length" "2")]) @@ -1882,9 +1916,10 @@ (define_insn "*movsi_insn" [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q") (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f"))] - "register_operand (operands[0], SImode) - || register_operand (operands[1], SImode) - || operands[1] == const0_rtx" + "! TARGET_LIVE_G0 + && (register_operand (operands[0], SImode) + || register_operand (operands[1], SImode) + || operands[1] == const0_rtx)" "@ mov %1,%0 fmovs %1,%0 @@ -1896,11 +1931,31 @@ [(set_attr "type" "move,fp,move,load,fpload,store,fpstore") (set_attr "length" "1")]) +(define_insn "*movsi_insn_liveg0" + [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,f,r,r,f,Q,Q") + (match_operand:SI 1 "move_operand" "r,J,I,!f,K,Q,!Q,r,!f"))] + "TARGET_LIVE_G0 + && (register_operand (operands[0], SImode) + || register_operand (operands[1], SImode))" + "@ + mov %1,%0 + and %0,0,%0 + and %0,0,%0\;or %0,%1,%0 + fmovs %1,%0 + sethi %%hi(%a1),%0 + ld %1,%0 + ld %1,%0 + st %1,%0 + st %1,%0" + [(set_attr "type" "move,move,move,fp,move,load,fpload,store,fpstore") + (set_attr "length" "1,1,2,1,1,1,1,1,1")]) + (define_insn "*store_si" [(set (mem:SI (match_operand:SI 0 "symbolic_operand" "")) (match_operand:SI 1 "reg_or_0_operand" "rJ")) (clobber (match_scratch:SI 2 "=&r"))] - "(reload_completed || reload_in_progress) && ! TARGET_PTR64" + "(reload_completed || reload_in_progress) + && ! TARGET_PTR64" "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" [(set_attr "type" "store") (set_attr "length" "2")]) @@ -2004,7 +2059,7 @@ ; (clobber (match_dup 0)) ; (clobber (match_dup 1)) ; (clobber (match_scratch:SI 4 "")) -; (clobber (reg:SI 0)) +; (clobber (reg:SI 100)) ; (clobber (reg:SI 1))])] ; "" ; " @@ -2030,7 +2085,7 @@ ; (clobber (match_dup 0)) ; (clobber (match_dup 1)) ; (clobber (match_scratch:SI 4 "=&r")) -; (clobber (reg:SI 0)) +; (clobber (reg:SI 100)) ; (clobber (reg:SI 1))] ; "" ; "* return output_block_move (operands);" @@ -2106,7 +2161,8 @@ [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i")) (match_operand:SF 1 "reg_or_0_operand" "rfG")) (clobber (match_scratch:SI 2 "=&r"))] - "(reload_completed || reload_in_progress) && ! TARGET_PTR64" + "(reload_completed || reload_in_progress) + && ! TARGET_PTR64" "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" [(set_attr "type" "store") (set_attr "length" "2")]) @@ -2217,7 +2273,8 @@ [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i")) (match_operand:DF 1 "reg_or_0_operand" "re,G")) (clobber (match_scratch:SI 2 "=&r,&r"))] - "(reload_completed || reload_in_progress) && ! TARGET_PTR64" + "(reload_completed || reload_in_progress) + && ! TARGET_PTR64" "* { output_asm_insn (\"sethi %%hi(%a0),%2\", operands); @@ -2314,7 +2371,8 @@ [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i")) (match_operand:TF 1 "reg_or_0_operand" "re,G")) (clobber (match_scratch:SI 2 "=&r,&r"))] - "0 && (reload_completed || reload_in_progress) && ! TARGET_PTR64" + "0 && (reload_completed || reload_in_progress) + && ! TARGET_PTR64" "* { output_asm_insn (\"sethi %%hi(%a0),%2\", operands); @@ -2466,7 +2524,7 @@ (define_insn "*movsi_cc_sp64" [(set (match_operand:SI 0 "register_operand" "=r") (if_then_else (match_operator 1 "comparison_operator" - [(reg:CC 0) (const_int 0)]) + [(reg:CC 100) (const_int 0)]) (match_operand:SI 2 "arith11_operand" "ri") (match_operand:SI 3 "register_operand" "0")))] "TARGET_V9" @@ -2476,7 +2534,7 @@ (define_insn "*movdi_cc_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (if_then_else (match_operator 1 "comparison_operator" - [(reg:CC 0) (const_int 0)]) + [(reg:CC 100) (const_int 0)]) (match_operand:DI 2 "arith11_double_operand" "rHI") (match_operand:DI 3 "register_operand" "0")))] "TARGET_ARCH64" @@ -2486,7 +2544,7 @@ (define_insn "*movsi_ccx_sp64" [(set (match_operand:SI 0 "register_operand" "=r") (if_then_else (match_operator 1 "comparison_operator" - [(reg:CCX 0) (const_int 0)]) + [(reg:CCX 100) (const_int 0)]) (match_operand:SI 2 "arith11_operand" "ri") (match_operand:SI 3 "register_operand" "0")))] "TARGET_ARCH64" @@ -2496,7 +2554,7 @@ (define_insn "*movdi_ccx_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (if_then_else (match_operator 1 "comparison_operator" - [(reg:CCX 0) (const_int 0)]) + [(reg:CCX 100) (const_int 0)]) (match_operand:DI 2 "arith11_double_operand" "rHI") (match_operand:DI 3 "register_operand" "0")))] "TARGET_ARCH64" @@ -2506,7 +2564,7 @@ (define_insn "*movsi_ccfp_sp64" [(set (match_operand:SI 0 "register_operand" "=r") (if_then_else (match_operator 1 "comparison_operator" - [(match_operand:CCFP 2 "ccfp_reg_operand" "c") + [(match_operand:CCFP 2 "fcc_reg_operand" "c") (const_int 0)]) (match_operand:SI 3 "arith11_operand" "ri") (match_operand:SI 4 "register_operand" "0")))] @@ -2517,7 +2575,7 @@ (define_insn "*movsi_ccfpe_sp64" [(set (match_operand:SI 0 "register_operand" "=r") (if_then_else (match_operator 1 "comparison_operator" - [(match_operand:CCFPE 2 "ccfp_reg_operand" "c") + [(match_operand:CCFPE 2 "fcc_reg_operand" "c") (const_int 0)]) (match_operand:SI 3 "arith11_operand" "ri") (match_operand:SI 4 "register_operand" "0")))] @@ -2528,7 +2586,7 @@ (define_insn "*movdi_ccfp_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (if_then_else (match_operator 1 "comparison_operator" - [(match_operand:CCFP 2 "ccfp_reg_operand" "c") + [(match_operand:CCFP 2 "fcc_reg_operand" "c") (const_int 0)]) (match_operand:DI 3 "arith11_double_operand" "rHI") (match_operand:DI 4 "register_operand" "0")))] @@ -2539,7 +2597,7 @@ (define_insn "*movdi_ccfpe_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (if_then_else (match_operator 1 "comparison_operator" - [(match_operand:CCFPE 2 "ccfp_reg_operand" "c") + [(match_operand:CCFPE 2 "fcc_reg_operand" "c") (const_int 0)]) (match_operand:DI 3 "arith11_double_operand" "rHI") (match_operand:DI 4 "register_operand" "0")))] @@ -2605,7 +2663,7 @@ (define_insn "*movsf_ccfp_sp64" [(set (match_operand:SF 0 "register_operand" "=f") (if_then_else (match_operator 1 "comparison_operator" - [(match_operand:CCFP 2 "ccfp_reg_operand" "c") + [(match_operand:CCFP 2 "fcc_reg_operand" "c") (const_int 0)]) (match_operand:SF 3 "register_operand" "f") (match_operand:SF 4 "register_operand" "0")))] @@ -2616,7 +2674,7 @@ (define_insn "*movsf_ccfpe_sp64" [(set (match_operand:SF 0 "register_operand" "=f") (if_then_else (match_operator 1 "comparison_operator" - [(match_operand:CCFPE 2 "ccfp_reg_operand" "c") + [(match_operand:CCFPE 2 "fcc_reg_operand" "c") (const_int 0)]) (match_operand:SF 3 "register_operand" "f") (match_operand:SF 4 "register_operand" "0")))] @@ -2627,7 +2685,7 @@ (define_insn "*movdf_ccfp_sp64" [(set (match_operand:DF 0 "register_operand" "=e") (if_then_else (match_operator 1 "comparison_operator" - [(match_operand:CCFP 2 "ccfp_reg_operand" "c") + [(match_operand:CCFP 2 "fcc_reg_operand" "c") (const_int 0)]) (match_operand:DF 3 "register_operand" "e") (match_operand:DF 4 "register_operand" "0")))] @@ -2638,7 +2696,7 @@ (define_insn "*movdf_ccfpe_sp64" [(set (match_operand:DF 0 "register_operand" "=e") (if_then_else (match_operator 1 "comparison_operator" - [(match_operand:CCFPE 2 "ccfp_reg_operand" "c") + [(match_operand:CCFPE 2 "fcc_reg_operand" "c") (const_int 0)]) (match_operand:DF 3 "register_operand" "e") (match_operand:DF 4 "register_operand" "0")))] @@ -2649,7 +2707,7 @@ (define_insn "*movtf_ccfp_sp64" [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else (match_operator 1 "comparison_operator" - [(match_operand:CCFP 2 "ccfp_reg_operand" "c") + [(match_operand:CCFP 2 "fcc_reg_operand" "c") (const_int 0)]) (match_operand:TF 3 "register_operand" "e") (match_operand:TF 4 "register_operand" "0")))] @@ -2660,7 +2718,7 @@ (define_insn "*movtf_ccfpe_sp64" [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else (match_operator 1 "comparison_operator" - [(match_operand:CCFPE 2 "ccfp_reg_operand" "c") + [(match_operand:CCFPE 2 "fcc_reg_operand" "c") (const_int 0)]) (match_operand:TF 3 "register_operand" "e") (match_operand:TF 4 "register_operand" "0")))] @@ -2671,7 +2729,7 @@ (define_insn "*movsf_cc_sp64" [(set (match_operand:SF 0 "register_operand" "=f") (if_then_else (match_operator 1 "comparison_operator" - [(reg:CC 0) (const_int 0)]) + [(reg:CC 100) (const_int 0)]) (match_operand:SF 2 "register_operand" "f") (match_operand:SF 3 "register_operand" "0")))] "TARGET_V9 && TARGET_FPU" @@ -2681,7 +2739,7 @@ (define_insn "*movdf_cc_sp64" [(set (match_operand:DF 0 "register_operand" "=e") (if_then_else (match_operator 1 "comparison_operator" - [(reg:CC 0) (const_int 0)]) + [(reg:CC 100) (const_int 0)]) (match_operand:DF 2 "register_operand" "e") (match_operand:DF 3 "register_operand" "0")))] "TARGET_V9 && TARGET_FPU" @@ -2691,7 +2749,7 @@ (define_insn "*movtf_cc_sp64" [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else (match_operator 1 "comparison_operator" - [(reg:CC 0) (const_int 0)]) + [(reg:CC 100) (const_int 0)]) (match_operand:TF 2 "register_operand" "e") (match_operand:TF 3 "register_operand" "0")))] "TARGET_V9 && TARGET_FPU" @@ -2701,7 +2759,7 @@ (define_insn "*movsf_ccx_sp64" [(set (match_operand:SF 0 "register_operand" "=f") (if_then_else (match_operator 1 "comparison_operator" - [(reg:CCX 0) (const_int 0)]) + [(reg:CCX 100) (const_int 0)]) (match_operand:SF 2 "register_operand" "f") (match_operand:SF 3 "register_operand" "0")))] "TARGET_ARCH64 && TARGET_FPU" @@ -2711,7 +2769,7 @@ (define_insn "*movdf_ccx_sp64" [(set (match_operand:DF 0 "register_operand" "=e") (if_then_else (match_operator 1 "comparison_operator" - [(reg:CCX 0) (const_int 0)]) + [(reg:CCX 100) (const_int 0)]) (match_operand:DF 2 "register_operand" "e") (match_operand:DF 3 "register_operand" "0")))] "TARGET_ARCH64 && TARGET_FPU" @@ -2721,7 +2779,7 @@ (define_insn "*movtf_ccx_sp64" [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else (match_operator 1 "comparison_operator" - [(reg:CCX 0) (const_int 0)]) + [(reg:CCX 100) (const_int 0)]) (match_operand:TF 2 "register_operand" "e") (match_operand:TF 3 "register_operand" "0")))] "TARGET_ARCH64 && TARGET_FPU" @@ -2863,7 +2921,7 @@ ;; Simplify comparisons of extended values. (define_insn "*cmp_zero_extendqisi2" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r")) (const_int 0)))] "" @@ -2871,7 +2929,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_zero_extendqisi2_set" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=r") @@ -2883,7 +2941,7 @@ ;; Similarly, handle SI->QI mode truncation followed by a compare. (define_insn "*cmp_siqi_trunc" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0) (const_int 0)))] "" @@ -2891,7 +2949,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_siqi_trunc_set" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0) (const_int 0))) (set (match_operand:QI 0 "register_operand" "=r") @@ -3083,7 +3141,7 @@ ;; because combine uses this as a canonical form. (define_insn "*cmp_zero_extract" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (zero_extract:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "small_int" "n") @@ -3101,7 +3159,7 @@ }") (define_insn "*cmp_zero_extract_sp64" - [(set (reg:CCX 0) + [(set (reg:CCX 100) (compare:CCX (zero_extract:DI (match_operand:DI 0 "register_operand" "r") (match_operand:SI 1 "small_int" "n") @@ -3461,7 +3519,8 @@ gen_rtx (SET, VOIDmode, operands[0], gen_rtx (PLUS, DImode, operands[1], operands[2])), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0))))); + gen_rtx (CLOBBER, VOIDmode, + gen_rtx (REG, SImode, SPARC_ICC_REG))))); DONE; } }") @@ -3470,7 +3529,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") (match_operand:DI 2 "arith_double_operand" "rHI"))) - (clobber (reg:SI 0))] + (clobber (reg:SI 100))] "! TARGET_ARCH64" "* { @@ -3518,7 +3577,7 @@ [(set_attr "type" "ialu")]) (define_insn "*cmp_cc_plus" - [(set (reg:CC_NOOV 0) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r") (match_operand:SI 1 "arith_operand" "rI")) (const_int 0)))] @@ -3527,7 +3586,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_plus" - [(set (reg:CCX_NOOV 0) + [(set (reg:CCX_NOOV 100) (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r") (match_operand:DI 1 "arith_double_operand" "rHI")) (const_int 0)))] @@ -3536,7 +3595,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_plus_set" - [(set (reg:CC_NOOV 0) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI")) (const_int 0))) @@ -3546,7 +3605,7 @@ "addcc %1,%2,%0") (define_insn "*cmp_ccx_plus_set" - [(set (reg:CCX_NOOV 0) + [(set (reg:CCX_NOOV 100) (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") (match_operand:DI 2 "arith_double_operand" "rHI")) (const_int 0))) @@ -3568,7 +3627,8 @@ gen_rtx (SET, VOIDmode, operands[0], gen_rtx (MINUS, DImode, operands[1], operands[2])), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0))))); + gen_rtx (CLOBBER, VOIDmode, + gen_rtx (REG, SImode, SPARC_ICC_REG))))); DONE; } }") @@ -3577,7 +3637,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (match_operand:DI 1 "register_operand" "r") (match_operand:DI 2 "arith_double_operand" "rHI"))) - (clobber (reg:SI 0))] + (clobber (reg:SI 100))] "! TARGET_ARCH64" "* { @@ -3625,7 +3685,7 @@ [(set_attr "type" "ialu")]) (define_insn "*cmp_minus_cc" - [(set (reg:CC_NOOV 0) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "arith_operand" "rI")) (const_int 0)))] @@ -3634,7 +3694,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_minus_ccx" - [(set (reg:CCX_NOOV 0) + [(set (reg:CCX_NOOV 100) (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r") (match_operand:DI 1 "arith_double_operand" "rHI")) (const_int 0)))] @@ -3643,7 +3703,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_minus_cc_set" - [(set (reg:CC_NOOV 0) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI")) (const_int 0))) @@ -3653,7 +3713,7 @@ "subcc %1,%2,%0") (define_insn "*cmp_minus_ccx_set" - [(set (reg:CCX_NOOV 0) + [(set (reg:CCX_NOOV 100) (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r") (match_operand:DI 2 "arith_double_operand" "rHI")) (const_int 0))) @@ -3689,7 +3749,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI"))) - (set (reg:CC_NOOV 0) + (set (reg:CC_NOOV 100) (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2)) (const_int 0)))] "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" @@ -3865,7 +3925,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (div:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI"))) - (set (reg:CC 0) + (set (reg:CC 100) (compare:CC (div:SI (match_dup 1) (match_dup 2)) (const_int 0))) (clobber (match_scratch:SI 3 "=&r"))] @@ -3910,7 +3970,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (udiv:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI"))) - (set (reg:CC 0) + (set (reg:CC 100) (compare:CC (udiv:SI (match_dup 1) (match_dup 2)) (const_int 0)))] "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" @@ -4078,7 +4138,12 @@ { int sign = INTVAL (op2); if (sign < 0) - return \"mov -1,%0\;or %R1,%2,%R0\"; + { + if (TARGET_LIVE_G0) + return \"and %0,0,%0\;add %0,-1,%0\;or %R1,%2,%R0\"; + else + return \"mov -1,%0\;or %R1,%2,%R0\"; + } return \"mov %1,%0\;or %R1,%2,%R0\"; } else if (GET_CODE (op2) == CONST_DOUBLE) @@ -4265,7 +4330,7 @@ ;; want to set the condition code. (define_insn "*cmp_cc_arith_op" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (match_operator:SI 2 "cc_arithop" [(match_operand:SI 0 "arith_operand" "%r") @@ -4276,7 +4341,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_arith_op" - [(set (reg:CCX 0) + [(set (reg:CCX 100) (compare:CCX (match_operator:DI 2 "cc_arithop" [(match_operand:DI 0 "arith_double_operand" "%r") @@ -4287,7 +4352,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_arith_op_set" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (match_operator:SI 3 "cc_arithop" [(match_operand:SI 1 "arith_operand" "%r") @@ -4299,7 +4364,7 @@ "%A3cc %1,%2,%0") (define_insn "*cmp_ccx_arith_op_set" - [(set (reg:CCX 0) + [(set (reg:CCX 100) (compare:CCX (match_operator:DI 3 "cc_arithop" [(match_operand:DI 1 "arith_double_operand" "%r") @@ -4311,7 +4376,7 @@ "%A3cc %1,%2,%0") (define_insn "*cmp_cc_xor_not" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ") (match_operand:SI 1 "arith_operand" "rI"))) @@ -4321,7 +4386,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_xor_not" - [(set (reg:CCX 0) + [(set (reg:CCX 100) (compare:CCX (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ") (match_operand:DI 1 "arith_double_operand" "rHI"))) @@ -4331,7 +4396,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_xor_not_set" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") (match_operand:SI 2 "arith_operand" "rI"))) @@ -4342,7 +4407,7 @@ "xnorcc %r1,%2,%0") (define_insn "*cmp_ccx_xor_not_set" - [(set (reg:CCX 0) + [(set (reg:CCX 100) (compare:CCX (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") (match_operand:DI 2 "arith_double_operand" "rHI"))) @@ -4353,7 +4418,7 @@ "xnorcc %r1,%2,%0") (define_insn "*cmp_cc_arith_op_not" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (match_operator:SI 2 "cc_arithopn" [(not:SI (match_operand:SI 0 "arith_operand" "rI")) @@ -4364,7 +4429,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_arith_op_not" - [(set (reg:CCX 0) + [(set (reg:CCX 100) (compare:CCX (match_operator:DI 2 "cc_arithopn" [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI")) @@ -4375,7 +4440,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_arith_op_not_set" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (match_operator:SI 3 "cc_arithopn" [(not:SI (match_operand:SI 1 "arith_operand" "rI")) @@ -4387,7 +4452,7 @@ "%B3cc %r2,%1,%0") (define_insn "*cmp_ccx_arith_op_not_set" - [(set (reg:CCX 0) + [(set (reg:CCX 100) (compare:CCX (match_operator:DI 3 "cc_arithopn" [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI")) @@ -4412,7 +4477,8 @@ emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2, gen_rtx (SET, VOIDmode, operand0, gen_rtx (NEG, DImode, operand1)), - gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 0))))); + gen_rtx (CLOBBER, VOIDmode, + gen_rtx (REG, SImode, SPARC_ICC_REG))))); DONE; } }") @@ -4420,10 +4486,16 @@ (define_insn "*negdi2_sp32" [(set (match_operand:DI 0 "register_operand" "=r") (neg:DI (match_operand:DI 1 "register_operand" "r"))) - (clobber (reg:SI 0))] + (clobber (reg:SI 100))] "! TARGET_ARCH64" - "subcc %%g0,%R1,%R0\;subx %%g0,%1,%0" + "* +{ + if (TARGET_LIVE_G0) + output_asm_insn (\"and %%g0,0,%%g0\", operands); + return \"subcc %%g0,%R1,%R0\;subx %%g0,%1,%0\"; +}" [(set_attr "type" "unary") + ;; ??? This is wrong for TARGET_LIVE_G0 but it's not critical. (set_attr "length" "2")]) (define_insn "*negdi2_sp64" @@ -4438,19 +4510,26 @@ [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] "" - "sub %%g0,%1,%0" - [(set_attr "type" "unary")]) + "* +{ + if (TARGET_LIVE_G0) + return \"and %%g0,0,%%g0\;sub %%g0,%1,%0\"; + return \"sub %%g0,%1,%0\"; +}" + [(set_attr "type" "unary") + (set (attr "length") + (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1)))]) (define_insn "*cmp_cc_neg" - [(set (reg:CC_NOOV 0) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI")) (const_int 0)))] - "" + "! TARGET_LIVE_G0" "subcc %%g0,%0,%%g0" [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_neg" - [(set (reg:CCX_NOOV 0) + [(set (reg:CCX_NOOV 100) (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI")) (const_int 0)))] "TARGET_ARCH64" @@ -4458,17 +4537,17 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_set_neg" - [(set (reg:CC_NOOV 0) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=r") (neg:SI (match_dup 1)))] - "" + "! TARGET_LIVE_G0" "subcc %%g0,%1,%0" [(set_attr "type" "unary")]) (define_insn "*cmp_ccx_set_neg" - [(set (reg:CCX_NOOV 0) + [(set (reg:CCX_NOOV 100) (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") @@ -4489,7 +4568,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (not:DI (match_operand:DI 1 "register_operand" "r")))] "! TARGET_ARCH64" - "xnor %%g0,%1,%0\;xnor %%g0,%R1,%R0" + "xnor %1,0,%0\;xnor %R1,0,%R0" [(set_attr "type" "unary") (set_attr "length" "2")]) @@ -4497,26 +4576,36 @@ [(set (match_operand:DI 0 "register_operand" "=r") (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))] "TARGET_ARCH64" - "xnor %%g0,%1,%0" + "xnor %1,0,%0" [(set_attr "type" "unary")]) (define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (not:SI (match_operand:SI 1 "arith_operand" "rI")))] + [(set (match_operand:SI 0 "register_operand" "=r,r") + (not:SI (match_operand:SI 1 "arith_operand" "r,I")))] "" - "xnor %%g0,%1,%0" - [(set_attr "type" "unary")]) + "* +{ + if (which_alternative == 0) + return \"xnor %1,0,%0\"; + if (TARGET_LIVE_G0) + output_asm_insn (\"and %%g0,0,%%g0\", operands); + return \"xnor %%g0,%1,%0\"; +}" + [(set_attr "type" "unary") + (set_attr_alternative "length" + [(const_int 1) + (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1))])]) (define_insn "*cmp_cc_not" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI")) (const_int 0)))] - "" + "! TARGET_LIVE_G0" "xnorcc %%g0,%0,%%g0" [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_not" - [(set (reg:CCX 0) + [(set (reg:CCX 100) (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI")) (const_int 0)))] "TARGET_ARCH64" @@ -4524,17 +4613,17 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_set_not" - [(set (reg:CC 0) + [(set (reg:CC 100) (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=r") (not:SI (match_dup 1)))] - "" + "! TARGET_LIVE_G0" "xnorcc %%g0,%1,%0" [(set_attr "type" "unary")]) (define_insn "*cmp_ccx_set_not" - [(set (reg:CCX 0) + [(set (reg:CCX 100) (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") @@ -4797,7 +4886,7 @@ }") (define_insn "*cmp_cc_ashift_1" - [(set (reg:CC_NOOV 0) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r") (const_int 1)) (const_int 0)))] @@ -4806,7 +4895,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_set_ashift_1" - [(set (reg:CC_NOOV 0) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r") (const_int 1)) (const_int 0))) @@ -5379,7 +5468,12 @@ (ffs:SI (match_operand:SI 1 "register_operand" "r"))) (clobber (match_scratch:SI 2 "=&r"))] "TARGET_SPARCLITE || TARGET_SPARCLET" - "sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0" + "* +{ + if (TARGET_LIVE_G0) + output_asm_insn (\"and %%g0,0,%%g0\", operands); + return \"sub %%g0,%1,%0\;and %0,%1,%0\;scan %0,0,%0\;mov 32,%2\;sub %2,%0,%0\;sra %0,31,%2\;and %2,31,%2\;add %2,%0,%0\"; +}" [(set_attr "type" "multi") (set_attr "length" "8")]) @@ -5391,7 +5485,7 @@ (ffs:DI (match_operand:DI 1 "register_operand" "r"))) (clobber (match_scratch:DI 2 "=&r"))] "TARGET_ARCH64" - "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,%%g0,%0" + "neg %1,%2\;not %2,%2\;xor %1,%2,%2\;popc %2,%0\;movrz %1,0,%0" [(set_attr "type" "multi") (set_attr "length" "5")]) @@ -5502,44 +5596,44 @@ [(set (match_operand:SI 0 "register_operand" "") (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0))) - (clobber (reg:CC 0))] + (clobber (reg:CC 100))] "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (ltu:SI (reg:CC 0) (const_int 0)))] + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))] "") (define_split [(set (match_operand:SI 0 "register_operand" "") (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))) - (clobber (reg:CC 0))] + (clobber (reg:CC 100))] "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 0) (const_int 0))))] + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))] "") (define_split [(set (match_operand:SI 0 "register_operand" "") (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0))) - (clobber (reg:CC 0))] + (clobber (reg:CC 100))] "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (geu:SI (reg:CC 0) (const_int 0)))] + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))] "") (define_split [(set (match_operand:SI 0 "register_operand" "") (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))) - (clobber (reg:CC 0))] + (clobber (reg:CC 100))] "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (neg:SI (geu:SI (reg:CC 0) (const_int 0))))] + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))] "") (define_split @@ -5547,11 +5641,11 @@ (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)) (match_operand:SI 2 "register_operand" ""))) - (clobber (reg:CC 0))] + (clobber (reg:CC 100))] "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 0) (const_int 0)) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) (match_dup 2)))] "") @@ -5560,12 +5654,12 @@ (minus:SI (match_operand:SI 2 "register_operand" "") (ne:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))) - (clobber (reg:CC 0))] + (clobber (reg:CC 100))] "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) (set (match_dup 0) (minus:SI (match_dup 2) - (ltu:SI (reg:CC 0) (const_int 0))))] + (ltu:SI (reg:CC 100) (const_int 0))))] "") (define_split @@ -5573,11 +5667,11 @@ (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)) (match_operand:SI 2 "register_operand" ""))) - (clobber (reg:CC 0))] + (clobber (reg:CC 100))] "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (plus:SI (geu:SI (reg:CC 0) (const_int 0)) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0)) (match_dup 2)))] "") @@ -5586,12 +5680,12 @@ (minus:SI (match_operand:SI 2 "register_operand" "") (eq:SI (match_operand:SI 1 "register_operand" "") (const_int 0)))) - (clobber (reg:CC 0))] + (clobber (reg:CC 100))] "" - [(set (reg:CC_NOOV 0) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) (set (match_dup 0) (minus:SI (match_dup 2) - (geu:SI (reg:CC 0) (const_int 0))))] + (geu:SI (reg:CC 100) (const_int 0))))] "") ;; Peepholes go at the end. @@ -5695,25 +5789,25 @@ (define_peephole [(set (match_operand:SI 0 "register_operand" "=r") (match_operand:SI 1 "register_operand" "r")) - (set (reg:CC 0) + (set (reg:CC 100) (compare:CC (match_operand:SI 2 "register_operand" "r") (const_int 0)))] "(rtx_equal_p (operands[2], operands[0]) || rtx_equal_p (operands[2], operands[1])) && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" - "orcc %1,%%g0,%0") + "orcc %1,0,%0") (define_peephole [(set (match_operand:DI 0 "register_operand" "=r") (match_operand:DI 1 "register_operand" "r")) - (set (reg:CCX 0) + (set (reg:CCX 100) (compare:CCX (match_operand:DI 2 "register_operand" "r") (const_int 0)))] "TARGET_ARCH64 && (rtx_equal_p (operands[2], operands[0]) || rtx_equal_p (operands[2], operands[1])) && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" - "orcc %1,%%g0,%0") + "orcc %1,0,%0") ;; Do {sign,zero}-extended compares somewhat more efficiently. ;; ??? Is this now the Right Way to do this? Or will SCRATCH @@ -5724,44 +5818,44 @@ (match_operand:HI 1 "memory_operand" "")) (set (match_operand:SI 2 "register_operand" "") (sign_extend:SI (match_dup 0))) - (set (reg:CC 0) + (set (reg:CC 100) (compare:CC (match_dup 2) (const_int 0)))] "" - "ldsh %1,%0\;orcc %0,%%g0,%2") + "ldsh %1,%0\;orcc %0,0,%2") (define_peephole [(set (match_operand:HI 0 "register_operand" "") (match_operand:HI 1 "memory_operand" "")) (set (match_operand:DI 2 "register_operand" "") (sign_extend:DI (match_dup 0))) - (set (reg:CCX 0) + (set (reg:CCX 100) (compare:CCX (match_dup 2) (const_int 0)))] "TARGET_ARCH64" - "ldsh %1,%0\;orcc %0,%%g0,%2") + "ldsh %1,%0\;orcc %0,0,%2") (define_peephole [(set (match_operand:QI 0 "register_operand" "") (match_operand:QI 1 "memory_operand" "")) (set (match_operand:SI 2 "register_operand" "") (sign_extend:SI (match_dup 0))) - (set (reg:CC 0) + (set (reg:CC 100) (compare:CC (match_dup 2) (const_int 0)))] "" - "ldsb %1,%0\;orcc %0,%%g0,%2") + "ldsb %1,%0\;orcc %0,0,%2") (define_peephole [(set (match_operand:QI 0 "register_operand" "") (match_operand:QI 1 "memory_operand" "")) (set (match_operand:DI 2 "register_operand" "") (sign_extend:DI (match_dup 0))) - (set (reg:CCX 0) + (set (reg:CCX 100) (compare:CCX (match_dup 2) (const_int 0)))] "TARGET_ARCH64" - "ldsb %1,%0\;orcc %0,%%g0,%2") + "ldsb %1,%0\;orcc %0,0,%2") ;; Floating-point move peepholes ;; ??? v9: Do we want similar ones? @@ -5792,16 +5886,14 @@ "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)" "ld [%0+%%lo(%a1)],%2") -;; Return peepholes. First the "normal" ones - -;; ??? There are QImode, HImode, and SImode versions of this pattern. -;; It might be possible to write one more general pattern instead of three. +;; Return peepholes. First the "normal" ones. +;; These are necessary to catch insns ending up in the epilogue delay list. (define_insn "*return_qi" [(set (match_operand:QI 0 "restore_operand" "") (match_operand:QI 1 "arith_operand" "rI")) (return)] - "! TARGET_EPILOGUE" + "! TARGET_EPILOGUE && ! TARGET_LIVE_G0" "* { if (! TARGET_ARCH64 && current_function_returns_struct) @@ -5815,7 +5907,7 @@ [(set (match_operand:HI 0 "restore_operand" "") (match_operand:HI 1 "arith_operand" "rI")) (return)] - "! TARGET_EPILOGUE" + "! TARGET_EPILOGUE && ! TARGET_LIVE_G0" "* { if (! TARGET_ARCH64 && current_function_returns_struct) @@ -5829,7 +5921,7 @@ [(set (match_operand:SI 0 "restore_operand" "") (match_operand:SI 1 "arith_operand" "rI")) (return)] - "! TARGET_EPILOGUE" + "! TARGET_EPILOGUE && ! TARGET_LIVE_G0" "* { if (! TARGET_ARCH64 && current_function_returns_struct) @@ -5846,7 +5938,7 @@ [(set (match_operand:SF 0 "restore_operand" "r") (match_operand:SF 1 "register_operand" "r")) (return)] - "! TARGET_FPU && ! TARGET_EPILOGUE" + "! TARGET_FPU && ! TARGET_EPILOGUE && ! TARGET_LIVE_G0" "* { if (! TARGET_ARCH64 && current_function_returns_struct) @@ -5861,7 +5953,7 @@ (plus:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI"))) (return)] - "! TARGET_EPILOGUE" + "! TARGET_EPILOGUE && ! TARGET_LIVE_G0" "* { if (! TARGET_ARCH64 && current_function_returns_struct) @@ -5951,11 +6043,12 @@ ;; Other miscellaneous peepholes. +;; (reg:SI 100) is created by the {add,neg,sub}di patterns. (define_peephole [(parallel [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") - (reg:SI 0))) - (clobber (reg:CC 0))]) - (set (reg:CC 0) (compare (match_dup 0) (const_int 0)))] + (reg:SI 100))) + (clobber (reg:CC 100))]) + (set (reg:CC 100) (compare (match_dup 0) (const_int 0)))] "" "subxcc %r1,0,%0") |