#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
/* 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)
#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.
/* 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.
{"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)
/* 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}, \
{"fullany", -MASK_CODE_MODEL}, \
{"fullany", MASK_FULLANY},
#else
-#define V9_SWITCHES
+#define ARCH64_SWITCHES
#endif
\f
/* target machine storage layout */
;; 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")]
(minus:DI (match_dup 1) (match_dup 2)))]
"TARGET_ARCH64"
"subcc %1,%2,%0")
+\f
+;; 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")])
(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")])
[(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]))
[(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")])
[(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")])
(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]))
(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")])
(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")])
[(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]))
[(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")])
[(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")])
(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]))
(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")])
(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"
(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")
(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")
(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)))])
\f
;;- Boolean instructions
;; We define DImode `and` so with DImode `not` we can get