diff options
author | Doug Evans <dje@gnu.org> | 1996-01-26 22:22:32 +0000 |
---|---|---|
committer | Doug Evans <dje@gnu.org> | 1996-01-26 22:22:32 +0000 |
commit | eb582c5d18a8fcddc4ee9f2ca76f13e99c49d174 (patch) | |
tree | 66d651f73bbac94607fb51f27d7a1d0864253752 | |
parent | 2f3e5814284494e67d761eb0e68e8b7f1a130966 (diff) | |
download | gcc-eb582c5d18a8fcddc4ee9f2ca76f13e99c49d174.zip gcc-eb582c5d18a8fcddc4ee9f2ca76f13e99c49d174.tar.gz gcc-eb582c5d18a8fcddc4ee9f2ca76f13e99c49d174.tar.bz2 |
sparc.h (sparc_arch_type): Delete.
* sparc/sparc.h (sparc_arch_type): Delete.
({,TARGET_}MASK_DEPRECATED_V8_INSNS): Define.
(ARCH64_SWITCHES): Renamed from V9_SWITCHES.
* sparc/sparc.c (sparc_arch_type): Delete.
(sparc_init_modes): Likewise.
(output_move_quad): Don't use ldq/stq unless TARGET_HARD_QUAD.
* sparc/sp64-sol2.h (TARGET_DEFAULT): Add MASK_DEPRECATED_V8_INSNS.
(SUBTARGET_SWITCHES): Add -m{no,}deprecated-v8-insns
* sparc/sparc.md (arch attribute): Rewrite.
(isa): New attribute.
(32 bit multiply/divide patterns): Use if TARGET_DEPRECATED_V8_INSNS.
(32 bit divide patterns): V9 doesn't require delay after y reg write.
From-SVN: r11110
-rw-r--r-- | gcc/config/sparc/sparc.c | 8 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 39 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 113 |
3 files changed, 97 insertions, 63 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index b79b6a1..244cd93 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -45,9 +45,6 @@ Boston, MA 02111-1307, USA. */ /* Global variables for machine-dependent things. */ -/* Says what architecture we're compiling for. */ -enum arch_type sparc_arch_type; - /* Size of frame. Need to know this to emit return insns from leaf procedures. ACTUAL_FSIZE is set by compute_frame_size() which is called during the reload pass. This is important as the value is later used in insn @@ -1913,13 +1910,14 @@ output_move_quad (operands) the register number. */ || (TARGET_V9 && REGNO (reg) >= 64)) { - if (TARGET_V9 && FP_REG_P (reg)) + if (TARGET_V9 && FP_REG_P (reg) && TARGET_HARD_QUAD) { if ((REGNO (reg) & 3) != 0) abort (); return (mem == op1 ? "ldq %1,%0" : "stq %1,%0"); } operands[2] = adj_offsettable_operand (mem, 8); + /* ??? In arch64 case, shouldn't we use ldd/std for fp regs. */ if (mem == op1) return TARGET_ARCH64 ? "ldx %1,%0;ldx %2,%R0" : "ldd %1,%0;ldd %2,%S0"; else @@ -2641,8 +2639,6 @@ sparc_init_modes () { int i; - sparc_arch_type = TARGET_ARCH64 ? ARCH_64BIT : ARCH_32BIT; - for (i = 0; i < NUM_MACHINE_MODES; i++) { switch (GET_MODE_CLASS (i)) diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 0ee0112..ca432ff 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -55,12 +55,6 @@ Boston, MA 02111-1307, USA. */ #define SPARC_ARCH64 0 #endif -/* ??? Delete and use `TARGET_ARCH64' instead. */ -/* What architecture we're compiling for. This must coincide with the - `arch_type' attribute in the .md file. */ -enum arch_type { ARCH_32BIT, ARCH_64BIT }; -extern enum arch_type sparc_arch_type; - /* Names to predefine in the preprocessor for this target machine. */ /* ??? The GCC_NEW_VARARGS macro is now obsolete, because gcc always uses @@ -204,7 +198,7 @@ extern int target_flags; /* Nonzero if we're compiling for v9 sparc. Note that v9's can run in 32 bit mode so this doesn't necessarily mean the word size is 64. It does mean that the extra fp regs are available - as are the new instructions. */ + as are the new instructions that don't require 64 bit words. */ #define MASK_V9 0x40 #define TARGET_V9 (target_flags & MASK_V9) @@ -238,13 +232,16 @@ extern int target_flags; #define MASK_APP_REGS 0x400 #define TARGET_APP_REGS (target_flags & MASK_APP_REGS) -/* Option to select how quad word floating point is implemented. - When TARGET_HARD_QUAD is true, we use the hardware quad instructions. - Otherwise, we use the SPARC ABI quad library functions. */ +/* Option to select how quad word floating point is implemented. + When TARGET_HARD_QUAD is true, we use the hardware quad instructions. + Otherwise, we use the SPARC ABI quad library functions. */ #define MASK_HARD_QUAD 0x800 #define TARGET_HARD_QUAD (target_flags & MASK_HARD_QUAD) -/* Bit 0x1000 is unused. */ +/* Non-zero to generate code that uses the instructions deprecated in + the v9 architecture. This option only applies to v9 systems. */ +#define MASK_DEPRECATED_V8_INSNS 0x1000 +#define TARGET_DEPRECATED_V8_INSNS (target_flags & MASK_DEPRECATED_V8_INSNS) /* Nonzero if ints are 64 bits. This automatically implies longs are 64 bits too. @@ -266,16 +263,12 @@ extern int target_flags; /* Nonzero if generating code to run in a 64 bit environment. */ #define MASK_ARCH64 0x10000 #define TARGET_ARCH64 (target_flags & MASK_ARCH64) - -/* Nonzero if generating code to run in a 32 bit environment. - Hence, we assume the upper 32 bits of symbolic addresses are zero, and - avoid generating %uhi and %ulo terms. - Pointers are still 64 bits though! This option is for v9 only. */ #define TARGET_ARCH32 (! TARGET_ARCH64) /* SPARC64 memory models. - TARGET_MEDLOW: 32 bit address space, top 32 bits = 0 - (pointers still 64 bits) + TARGET_MEDLOW: 32 bit address space, top 32 bits = 0, + avoid generating %uhi and %ulo terms. + (pointers can be 32 or 64 bits) TARGET_MEDANY: 64 bit address space, data segment restricted to 4G, but can be loaded anywhere (use %g4 as offset). TARGET_FULLANY: 64 bit address space, no restrictions. @@ -338,7 +331,7 @@ extern int target_flags; {"hard-quad-float", MASK_HARD_QUAD}, \ {"soft-quad-float", -MASK_HARD_QUAD}, \ SUBTARGET_SWITCHES \ - V9_SWITCHES \ + ARCH64_SWITCHES \ { "", TARGET_DEFAULT}} #define TARGET_DEFAULT (MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU) @@ -346,10 +339,10 @@ extern int target_flags; /* This is meant to be redefined in the host dependent files */ #define SUBTARGET_SWITCHES -/* ??? Until we support a combination v8/v9 compiler, the v9 specific options - are only defined for the v9 compiler (in a true 64 bit environment). */ +/* ??? Until we support a combination 32/64 bit compiler, these options + are only defined for the v9 compiler in a true 64 bit environment. */ #if SPARC_ARCH64 -#define V9_SWITCHES \ +#define ARCH64_SWITCHES \ /* {"arch32", -MASK_ARCH64}, */ \ /* {"arch64", MASK_ARCH64}, */ \ {"int64", MASK_INT64+MASK_LONG64}, \ @@ -369,7 +362,7 @@ extern int target_flags; {"fullany", -MASK_CODE_MODEL}, \ {"fullany", MASK_FULLANY}, #else -#define V9_SWITCHES +#define ARCH64_SWITCHES #endif /* target machine storage layout */ diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 7094749..85dae7c 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -29,12 +29,22 @@ ;; 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. -;; Architecture type. Arch32bit includes v7, sparclite, v8. -;; ??? Delete and use `TARGET_ARCH64' instead. +;; Attribute for the instruction set. +;; At present we only need to distinguish v9/!v9, but for clarity we +;; test TARGET_V8 too. +(define_attr "isa" "v6,v8,v9" + (const + (cond [(symbol_ref "TARGET_V9") (const_string "v9") + (symbol_ref "TARGET_V8") (const_string "v8")] + (const_string "v6")))) + +;; Architecture size. (define_attr "arch" "arch32bit,arch64bit" - (const (symbol_ref "sparc_arch_type"))) + (const + (cond [(symbol_ref "TARGET_ARCH64") (const_string "arch64bit")] + (const_string "arch32bit")))) -;; CPU type. This is only used for instruction scheduling +;; CPU type. This is only used for instruction scheduling. (define_attr "cpu" "cypress,supersparc" (const (cond [(symbol_ref "TARGET_SUPERSPARC") (const_string "supersparc")] @@ -3580,15 +3590,18 @@ (minus:DI (match_dup 1) (match_dup 2)))] "TARGET_ARCH64" "subcc %1,%2,%0") + +;; Integer Multiply/Divide. -;; This is anachronistic, and should not be used in v9 software. -;; The v9 compiler will widen the args and use muldi3. +;; The 32 bit multiply/divide instructions are deprecated on v9 and shouldn't +;; we used. We still use them in 32 bit v9 compilers. +;; The 64 bit v9 compiler will (/should) widen the args and use muldi3. (define_insn "mulsi3" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI")))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" "smul %1,%2,%0" [(set_attr "type" "imul")]) @@ -3608,7 +3621,7 @@ (set (reg:CC_NOOV 0) (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2)) (const_int 0)))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" "smulcc %1,%2,%0" [(set_attr "type" "imul")]) @@ -3616,7 +3629,7 @@ [(set (match_operand:DI 0 "register_operand" "") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" " { if (CONSTANT_P (operands[2])) @@ -3630,7 +3643,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" "smul %1,%2,%R0\;rd %%y,%0" [(set_attr "length" "2")]) @@ -3640,7 +3653,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "small_int" "I")))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" "smul %1,%2,%R0\;rd %%y,%0" [(set_attr "length" "2")]) @@ -3650,7 +3663,7 @@ (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" " { if (CONSTANT_P (operands[2])) @@ -3666,7 +3679,7 @@ (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" "smul %1,%2,%%g0\;rd %%y,%0" [(set_attr "length" "2")]) @@ -3676,7 +3689,7 @@ (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "register_operand" "r")) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" "smul %1,%2,%%g0\;rd %%y,%0" [(set_attr "length" "2")]) @@ -3684,7 +3697,7 @@ [(set (match_operand:DI 0 "register_operand" "") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" " { if (CONSTANT_P (operands[2])) @@ -3698,7 +3711,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" "umul %1,%2,%R0\;rd %%y,%0" [(set_attr "length" "2")]) @@ -3708,7 +3721,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "uns_small_int" "")))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" "umul %1,%2,%R0\;rd %%y,%0" [(set_attr "length" "2")]) @@ -3718,7 +3731,7 @@ (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" " { if (CONSTANT_P (operands[2])) @@ -3734,7 +3747,7 @@ (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" "umul %1,%2,%%g0\;rd %%y,%0" [(set_attr "length" "2")]) @@ -3744,11 +3757,11 @@ (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "uns_small_int" "")) (const_int 32))))] - "TARGET_V8 || TARGET_SPARCLITE" + "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" "umul %1,%2,%%g0\;rd %%y,%0" [(set_attr "length" "2")]) -;; The architecture specifies that there must be 3 instructions between +;; The v8 architecture specifies that there must be 3 instructions between ;; a y register write and a use of it for correct results. (define_insn "divsi3" @@ -3756,9 +3769,17 @@ (div:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI"))) (clobber (match_scratch:SI 3 "=&r"))] - "TARGET_V8" - "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0" - [(set_attr "length" "6")]) + "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" + "* +{ + if (TARGET_V9) + return \"sra %1,31,%3\;wr %%g0,%3,%%y\;sdiv %1,%2,%0\"; + else + return \"sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0\"; +}" + [(set (attr "length") + (if_then_else (eq_attr "isa" "v9") + (const_int 3) (const_int 6)))]) (define_insn "divdi3" [(set (match_operand:DI 0 "register_operand" "=r") @@ -3777,17 +3798,33 @@ (compare:CC (div:SI (match_dup 1) (match_dup 2)) (const_int 0))) (clobber (match_scratch:SI 3 "=&r"))] - "TARGET_V8" - "sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0" - [(set_attr "length" "6")]) + "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" + "* +{ + if (TARGET_V9) + return \"sra %1,31,%3\;wr %%g0,%3,%%y\;sdivcc %1,%2,%0\"; + else + return \"sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0\"; +}" + [(set (attr "length") + (if_then_else (eq_attr "isa" "v9") + (const_int 3) (const_int 6)))]) (define_insn "udivsi3" [(set (match_operand:SI 0 "register_operand" "=r") (udiv:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "arith_operand" "rI")))] - "TARGET_V8" - "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0" - [(set_attr "length" "5")]) + (match_operand:SI 2 "arith_operand" "rI")))] + "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" + "* +{ + if (TARGET_V9) + return \"wr %%g0,%%g0,%%y\;udiv %1,%2,%0\"; + else + return \"wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udiv %1,%2,%0\"; +}" + [(set (attr "length") + (if_then_else (eq_attr "isa" "v9") + (const_int 2) (const_int 5)))]) (define_insn "udivdi3" [(set (match_operand:DI 0 "register_operand" "=r") @@ -3805,9 +3842,17 @@ (set (reg:CC 0) (compare:CC (udiv:SI (match_dup 1) (match_dup 2)) (const_int 0)))] - "TARGET_V8" - "wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0" - [(set_attr "length" "5")]) + "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" + "* +{ + if (TARGET_V9) + return \"wr %%g0,%%g0,%%y\;udivcc %1,%2,%0\"; + else + return \"wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0\"; +}" + [(set (attr "length") + (if_then_else (eq_attr "isa" "v9") + (const_int 2) (const_int 5)))]) ;;- Boolean instructions ;; We define DImode `and` so with DImode `not` we can get |