#define VALID_FP_MODE_P(mode) \
((mode) == SFmode || (mode) == DFmode || (mode) == TFmode \
- || (mode) == XFmode \
+ || (!TARGET_64BIT && (mode) == XFmode) \
|| (mode) == SCmode || (mode) == DCmode || (mode) == TCmode\
- || (mode) == XCmode)
+ || (!TARGET_64BIT && (mode) == XCmode))
#define VALID_INT_MODE_P(mode) \
((mode) == QImode || (mode) == HImode || (mode) == SImode \
#define MODES_TIEABLE_P(MODE1, MODE2) \
((MODE1) == (MODE2) \
- || ((MODE1) == SImode && (MODE2) == HImode) \
- || ((MODE1) == HImode && (MODE2) == SImode))
+ || (((MODE1) == HImode || (MODE1) == SImode \
+ || ((MODE1) == QImode \
+ && (TARGET_64BIT || !TARGET_PARTIAL_REG_STALL)) \
+ || ((MODE1) == DImode && TARGET_64BIT)) \
+ && ((MODE2) == HImode || (MODE2) == SImode \
+ || ((MODE1) == QImode \
+ && (TARGET_64BIT || !TARGET_PARTIAL_REG_STALL)) \
+ || ((MODE2) == DImode && TARGET_64BIT))))
+
/* Specify the modes required to caller save a given hard regno.
We do this on i386 to prevent flags from being saved at all.
: (MODE) == VOIDmode && (NREGS) != 1 ? VOIDmode \
: (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS)) \
: (MODE) == HImode && !TARGET_PARTIAL_REG_STALL ? SImode \
- : (MODE) == QImode && (REGNO) >= 4 ? SImode : (MODE))
-
+ : (MODE) == QImode && (REGNO) >= 4 && !TARGET_64BIT ? SImode \
+ : (MODE))
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
/* Base register for access to arguments of the function. */
#define ARG_POINTER_REGNUM 16
-/* Register in which static-chain is passed to a function. */
-#define STATIC_CHAIN_REGNUM 2
+/* Register in which static-chain is passed to a function.
+ We do use ECX as static chain register for 32 bit ABI. On the
+ 64bit ABI, ECX is an argument register, so we use R10 instead. */
+#define STATIC_CHAIN_REGNUM (TARGET_64BIT ? FIRST_REX_INT_REG + 10 - 8 : 2)
/* Register to hold the addressing base for position independent
- code access to data items. */
-#define PIC_OFFSET_TABLE_REGNUM 3
+ code access to data items.
+ We don't use PIC pointer for 64bit mode. Define the regnum to
+ dummy value to prevent gcc from pesimizing code dealing with EBX.
+ */
+#define PIC_OFFSET_TABLE_REGNUM (TARGET_64BIT ? INVALID_REGNUM : 3)
/* Register in which address to store a structure value
arrives in the function. On the 386, the prologue
is necessary to be able to hold a value of mode MODE in a reload
register for which class CLASS would ordinarily be used. */
-#define LIMIT_RELOAD_CLASS(MODE, CLASS) \
- ((MODE) == QImode && ((CLASS) == ALL_REGS || (CLASS) == GENERAL_REGS) \
+#define LIMIT_RELOAD_CLASS(MODE, CLASS) \
+ ((MODE) == QImode && !TARGET_64BIT \
+ && ((CLASS) == ALL_REGS || (CLASS) == GENERAL_REGS) \
? Q_REGS : (CLASS))
/* Given an rtx X being reloaded into a reg required to be
pseudo. */
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS,MODE,OUT) \
- ((CLASS) == GENERAL_REGS && (MODE) == QImode ? Q_REGS : NO_REGS)
+ ((CLASS) == GENERAL_REGS && !TARGET_64BIT && (MODE) == QImode \
+ ? Q_REGS : NO_REGS)
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */
this says how many the stack pointer really advances by.
On 386 pushw decrements by exactly 2 no matter what the position was.
On the 386 there is no pushb; we use pushw instead, and this
- has the effect of rounding up to 2. */
+ has the effect of rounding up to 2.
+
+ For 64bit ABI we round up to 8 bytes.
+ */
-#define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & (-2))
+#define PUSH_ROUNDING(BYTES) \
+ (TARGET_64BIT \
+ ? (((BYTES) + 7) & (-8)) \
+ : (((BYTES) + 1) & (-2)))
/* If defined, the maximum amount of space required for outgoing arguments will
be computed and placed into the variable
#define CONSTANT_ADDRESS_P(X) \
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
- || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST)
+ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
+ || GET_CODE (X) == CONST_DOUBLE)
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
is also used as the pic register in ELF. So for now, don't allow more than
3 registers to be passed in registers. */
-#define REGPARM_MAX 3
+#define REGPARM_MAX (TARGET_64BIT ? 6 : 3)
+
+#define SSE_REGPARM_MAX (TARGET_64BIT ? 16 : 0)
\f
/* Specify the machine mode that this machine uses
-;; GCC machine description for IA-32.
+;; GCC machine description for IA-32 and x86-64.
;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
;; Free Software Foundation, Inc.
;; Mostly by William Schelter.
+;; x86_64 support added by Jan Hubicka
;;
;; This file is part of GNU CC.
;;
(define_insn "*cmpqi_ext_1"
[(set (reg 17)
(compare
- (match_operand:QI 0 "general_operand" "qm")
+ (match_operand:QI 0 "general_operand" "Qm")
(subreg:QI
(zero_extract:SI
- (match_operand 1 "ext_register_operand" "q")
+ (match_operand 1 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)) 0)))]
- "ix86_match_ccmode (insn, CCmode)"
+ "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
+ "cmp{b}\\t{%h1, %0|%0, %h1}"
+ [(set_attr "type" "icmp")
+ (set_attr "mode" "QI")])
+
+(define_insn "*cmpqi_ext_1_rex64"
+ [(set (reg 17)
+ (compare
+ (match_operand:QI 0 "ext_register_operand" "Q")
+ (subreg:QI
+ (zero_extract:SI
+ (match_operand 1 "ext_register_operand" "Q")
+ (const_int 8)
+ (const_int 8)) 0)))]
+ "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
"cmp{b}\\t{%h1, %0|%0, %h1}"
[(set_attr "type" "icmp")
(set_attr "mode" "QI")])
(compare
(subreg:QI
(zero_extract:SI
- (match_operand 0 "ext_register_operand" "q")
+ (match_operand 0 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 1 "const0_operand" "n")))]
(compare:CC
(subreg:QI
(zero_extract:SI
- (match_operand 0 "ext_register_operand" "q")
+ (match_operand 0 "ext_register_operand" "")
(const_int 8)
(const_int 8)) 0)
- (match_operand:QI 1 "general_operand" "qmn")))]
+ (match_operand:QI 1 "general_operand" "")))]
""
"")
(compare
(subreg:QI
(zero_extract:SI
- (match_operand 0 "ext_register_operand" "q")
+ (match_operand 0 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)) 0)
- (match_operand:QI 1 "general_operand" "qmn")))]
- "ix86_match_ccmode (insn, CCmode)"
+ (match_operand:QI 1 "general_operand" "Qmn")))]
+ "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
+ "cmp{b}\\t{%1, %h0|%h0, %1}"
+ [(set_attr "type" "icmp")
+ (set_attr "mode" "QI")])
+
+(define_insn "cmpqi_ext_3_insn_rex64"
+ [(set (reg 17)
+ (compare
+ (subreg:QI
+ (zero_extract:SI
+ (match_operand 0 "ext_register_operand" "Q")
+ (const_int 8)
+ (const_int 8)) 0)
+ (match_operand:QI 1 "nonmemory_operand" "Qn")))]
+ "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
"cmp{b}\\t{%1, %h0|%h0, %1}"
[(set_attr "type" "icmp")
(set_attr "mode" "QI")])
(compare
(subreg:QI
(zero_extract:SI
- (match_operand 0 "ext_register_operand" "q")
+ (match_operand 0 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)) 0)
(subreg:QI
(zero_extract:SI
- (match_operand 1 "ext_register_operand" "q")
+ (match_operand 1 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)) 0)))]
"ix86_match_ccmode (insn, CCmode)"
(set_attr "length_immediate" "0")])
(define_insn "*movsi_extv_1"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (sign_extract:SI (match_operand:SI 1 "register_operand" "q")
+ [(set (match_operand:SI 0 "register_operand" "=R")
+ (sign_extract:SI (match_operand:SI 1 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)))]
""
(set_attr "mode" "SI")])
(define_insn "*movhi_extv_1"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (sign_extract:HI (match_operand:SI 1 "register_operand" "q")
+ [(set (match_operand:HI 0 "register_operand" "=R")
+ (sign_extract:HI (match_operand:SI 1 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)))]
""
(const_string "QI")))])
(define_insn "*movsi_extzv_1"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extract:SI (match_operand 1 "ext_register_operand" "q")
+ [(set (match_operand:SI 0 "register_operand" "=R")
+ (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)))]
""
[(set_attr "type" "imovx")
(set_attr "mode" "SI")])
-(define_insn "*movqi_extzv_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?r")
- (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "q,q")
+(define_insn "*movqi_extzv_2"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
+ (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
(const_int 8)
(const_int 8)) 0))]
- ""
+ "!TARGET_64BIT"
"*
{
switch (get_attr_type (insn))
(const_string "SI")
(const_string "QI")))])
+(define_insn "*movqi_extzv_2_rex64"
+ [(set (match_operand:QI 0 "register_operand" "=Q,?R")
+ (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
+ (const_int 8)
+ (const_int 8)) 0))]
+ "TARGET_64BIT"
+ "*
+{
+ switch (get_attr_type (insn))
+ {
+ case TYPE_IMOVX:
+ return \"movz{bl|x}\\t{%h1, %k0|%k0, %h1}\";
+ default:
+ return \"mov{b}\\t{%h1, %0|%0, %h1}\";
+ }
+}"
+ [(set (attr "type")
+ (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
+ (ne (symbol_ref "TARGET_MOVX")
+ (const_int 0)))
+ (const_string "imovx")
+ (const_string "imov")))
+ (set (attr "mode")
+ (if_then_else (eq_attr "type" "imovx")
+ (const_string "SI")
+ (const_string "QI")))])
+
(define_insn "*movsi_insv_1"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
+ [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
(const_int 8)
(const_int 8))
- (match_operand:SI 1 "nonimmediate_operand" "qm"))]
- ""
+ (match_operand:SI 1 "nonimmediate_operand" "Qm"))]
+ "!TARGET_64BIT"
+ "mov{b}\\t{%b1, %h0|%h0, %b1}"
+ [(set_attr "type" "imov")
+ (set_attr "mode" "QI")])
+
+(define_insn "*movsi_insv_1_rex64"
+ [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
+ (const_int 8)
+ (const_int 8))
+ (match_operand:SI 1 "ext_register_operand" "Q"))]
+ "TARGET_64BIT"
"mov{b}\\t{%b1, %h0|%h0, %b1}"
[(set_attr "type" "imov")
(set_attr "mode" "QI")])
(define_insn "*movqi_insv_2"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+q")
+ [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
(const_int 8)
(const_int 8))
- (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "q")
+ (and:SI (lshiftrt:SI (match_operand:SI 1 "ext_register_operand" "Q")
(const_int 8))
(const_int 255)))]
""
(const_int 8))
(match_operand:QI 2 "general_operand" "qmn")))
(clobber (reg:CC 17))]
- ""
+ "!TARGET_64BIT"
+ "*
+{
+ switch (get_attr_type (insn))
+ {
+ case TYPE_INCDEC:
+ if (operands[2] == const1_rtx)
+ return \"inc{b}\\t%h0\";
+ else if (operands[2] == constm1_rtx
+ || (GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) == 255))
+ return \"dec{b}\\t%h0\";
+ abort();
+
+ default:
+ return \"add{b}\\t{%2, %h0|%h0, %2}\";
+ }
+}"
+ [(set (attr "type")
+ (if_then_else (match_operand:QI 2 "incdec_operand" "")
+ (const_string "incdec")
+ (const_string "alu")))
+ (set_attr "mode" "QI")])
+
+(define_insn "*addqi_ext_1_rex64"
+ [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
+ (const_int 8)
+ (const_int 8))
+ (plus:SI
+ (zero_extract:SI
+ (match_operand 1 "ext_register_operand" "0")
+ (const_int 8)
+ (const_int 8))
+ (match_operand:QI 2 "nonmemory_operand" "Qn")))
+ (clobber (reg:CC 17))]
+ "TARGET_64BIT"
"*
{
switch (get_attr_type (insn))
(set_attr "mode" "QI")])
(define_insn "*addqi_ext_2"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
+ [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
(const_int 8)
(const_int 8))
(plus:SI
(const_int 8)
(const_int 8))
(zero_extract:SI
- (match_operand 2 "ext_register_operand" "q")
+ (match_operand 2 "ext_register_operand" "Q")
(const_int 8)
(const_int 8))))
(clobber (reg:CC 17))]
(compare
(and:SI
(zero_extract:SI
- (match_operand 0 "ext_register_operand" "q")
+ (match_operand 0 "ext_register_operand" "Q")
(const_int 8)
(const_int 8))
(match_operand 1 "const_int_operand" "n"))
(compare
(and:SI
(zero_extract:SI
- (match_operand 0 "ext_register_operand" "q")
+ (match_operand 0 "ext_register_operand" "Q")
(const_int 8)
(const_int 8))
(zero_extend:SI
- (match_operand:QI 1 "nonimmediate_operand" "qm")))
+ (match_operand:QI 1 "nonimmediate_operand" "Qm")))
(const_int 0)))]
- "ix86_match_ccmode (insn, CCNOmode)"
+ "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
+ "test{b}\\t{%1, %h0|%h0, %1}"
+ [(set_attr "type" "test")
+ (set_attr "mode" "QI")])
+
+(define_insn "*testqi_ext_1_rex64"
+ [(set (reg 17)
+ (compare
+ (and:SI
+ (zero_extract:SI
+ (match_operand 0 "ext_register_operand" "Q")
+ (const_int 8)
+ (const_int 8))
+ (zero_extend:SI
+ (match_operand:QI 1 "ext_register_operand" "Q")))
+ (const_int 0)))]
+ "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
"test{b}\\t{%1, %h0|%h0, %1}"
[(set_attr "type" "test")
(set_attr "mode" "QI")])
(compare
(and:SI
(zero_extract:SI
- (match_operand 0 "ext_register_operand" "q")
+ (match_operand 0 "ext_register_operand" "Q")
(const_int 8)
(const_int 8))
(zero_extract:SI
- (match_operand 1 "ext_register_operand" "q")
+ (match_operand 1 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)))
(const_int 0)))]
;; for a QImode operand, which of course failed.
(define_insn "andqi_ext_0"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
+ [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
(const_int 8)
(const_int 8))
(and:SI
(and:SI
(zero_extract:SI
(match_operand 1 "ext_register_operand" "0")
- (const_int 8)
+ (const_int 8)
(const_int 8))
(match_operand 2 "const_int_operand" "n"))
(const_int 0)))
- (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
+ (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
(const_int 8)
(const_int 8))
(and:SI
(set_attr "mode" "QI")])
(define_insn "*andqi_ext_1"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
+ [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
(const_int 8)
(const_int 8))
(and:SI
(const_int 8)
(const_int 8))
(zero_extend:SI
- (match_operand:QI 2 "general_operand" "qm"))))
+ (match_operand:QI 2 "general_operand" "Qm"))))
(clobber (reg:CC 17))]
- ""
+ "!TARGET_64BIT"
+ "and{b}\\t{%2, %h0|%h0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
+
+(define_insn "*andqi_ext_1_rex64"
+ [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
+ (const_int 8)
+ (const_int 8))
+ (and:SI
+ (zero_extract:SI
+ (match_operand 1 "ext_register_operand" "0")
+ (const_int 8)
+ (const_int 8))
+ (zero_extend:SI
+ (match_operand:QI 2 "ext_register_operand" "Q"))))
+ (clobber (reg:CC 17))]
+ "TARGET_64BIT"
"and{b}\\t{%2, %h0|%h0, %2}"
[(set_attr "type" "alu")
(set_attr "length_immediate" "0")
(set_attr "mode" "QI")])
(define_insn "*andqi_ext_2"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
+ [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
(const_int 8)
(const_int 8))
(and:SI
(const_int 8)
(const_int 8))
(zero_extract:SI
- (match_operand 2 "ext_register_operand" "q")
+ (match_operand 2 "ext_register_operand" "Q")
(const_int 8)
(const_int 8))))
(clobber (reg:CC 17))]
(set_attr "mode" "QI,QI,SI")])
(define_insn "*xorqi_ext_1"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
+ [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
(const_int 8)
(const_int 8))
(xor:SI
(zero_extract:SI (match_operand 1 "ext_register_operand" "0")
(const_int 8)
(const_int 8))
- (zero_extract:SI (match_operand 2 "ext_register_operand" "q")
+ (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
(const_int 8)
(const_int 8))))
(clobber (reg:CC 17))]
(xor:SI
(zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
(match_dup 2)))]
- "ix86_match_ccmode (insn, CCNOmode)"
+ "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
+ "xor{b}\\t{%2, %h0|%h0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "QI")])
+
+(define_insn "*xorqi_cc_ext_1_rex64"
+ [(set (reg 17)
+ (compare
+ (xor:SI
+ (zero_extract:SI
+ (match_operand 1 "ext_register_operand" "0")
+ (const_int 8)
+ (const_int 8))
+ (match_operand:QI 2 "nonmemory_operand" "Qn"))
+ (const_int 0)))
+ (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
+ (const_int 8)
+ (const_int 8))
+ (xor:SI
+ (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
+ (match_dup 2)))]
+ "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
"xor{b}\\t{%2, %h0|%h0, %2}"
[(set_attr "type" "alu")
(set_attr "mode" "QI")])
[(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
(neg:DI (match_operand:DI 1 "general_operand" "0")))
(clobber (reg:CC 17))]
- "ix86_unary_operator_ok (NEG, DImode, operands)"
+ "!TARGET_64BIT
+ && ix86_unary_operator_ok (NEG, DImode, operands)"
"#")
(define_split
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(neg:DI (match_operand:DI 1 "general_operand" "")))
(clobber (reg:CC 17))]
- "reload_completed"
+ "reload_completed
+ && !TARGET_64BIT"
[(parallel
[(set (reg:CCZ 17)
(compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))