+2012-03-11 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/predicates.md (call_insn_operand): Allow
+ constant_call_address_operand in Pmode only.
+ (sibcall_insn_operand): Ditto.
+ * config/i386/i386.md (*call): Use W mode iterator instead of P mode.
+ (*call_vzeroupper): Ditto.
+ (*sibcall): Ditto.
+ (*sibcall_vzeroupper): Ditto.
+ (*call_value): Ditto.
+ (*call_value_vzeroupper): Ditto.
+ (*sibcall_value): Ditto.
+ (*sibcall_value_vzeroupper): Ditto.
+ (*indirect_jump): Ditto.
+ (*tablejump_1): Ditto.
+ (indirect_jump): Convert memory address to word mode for TARGET_X32.
+ (tablejump): Ditto.
+ * config/i386/i386.c (ix86_expand_call): Convert indirect operands
+ to word mode.
+
2012-03-11 Oleg Endo <olegendo@gcc.gnu.org>
PR target/51244
* config/i386/i386.c (ix86_decompose_address): Disallow fs:(reg)
if Pmode != word_mode.
(legitimize_tls_address): Call gen_tls_initial_exec_x32 if
- Pmode == SImode for x32.
+ Pmode == SImode for TARGET_X32.
* config/i386/i386.md (UNSPEC_TLS_IE_X32): New.
(tls_initial_exec_x32): Likewise.
PR target/52146
* config/i386/i386.c (ix86_legitimate_address_p): Disallow
- negative constant address for x32.
+ negative constant address for TARGET_X32.
2012-02-10 Richard Henderson <rth@redhat.com>
&& !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode))
fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, 0)));
else if (sibcall
- ? !sibcall_insn_operand (XEXP (fnaddr, 0), Pmode)
- : !call_insn_operand (XEXP (fnaddr, 0), Pmode))
+ ? !sibcall_insn_operand (XEXP (fnaddr, 0), word_mode)
+ : !call_insn_operand (XEXP (fnaddr, 0), word_mode))
{
fnaddr = XEXP (fnaddr, 0);
- if (GET_MODE (fnaddr) != Pmode)
- fnaddr = convert_to_mode (Pmode, fnaddr, 1);
- fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (Pmode, fnaddr));
+ if (GET_MODE (fnaddr) != word_mode)
+ fnaddr = convert_to_mode (word_mode, fnaddr, 1);
+ fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (word_mode, fnaddr));
}
vec_len = 0;
(set_attr "modrm" "0")])
(define_expand "indirect_jump"
- [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
+ [(set (pc) (match_operand 0 "indirect_branch_operand" ""))]
+ ""
+{
+ if (TARGET_X32)
+ operands[0] = convert_memory_address (word_mode, operands[0]);
+})
(define_insn "*indirect_jump"
- [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
""
"jmp\t%A0"
[(set_attr "type" "ibr")
operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
OPTAB_DIRECT);
}
- else if (TARGET_X32)
- operands[0] = convert_memory_address (Pmode, operands[0]);
+
+ if (TARGET_X32)
+ operands[0] = convert_memory_address (word_mode, operands[0]);
})
(define_insn "*tablejump_1"
- [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
+ [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
(use (label_ref (match_operand 1 "" "")))]
""
"jmp\t%A0"
})
(define_insn_and_split "*call_vzeroupper"
- [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
+ [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
(match_operand 1 "" ""))
(unspec [(match_operand 2 "const_int_operand" "")]
UNSPEC_CALL_NEEDS_VZEROUPPER)]
[(set_attr "type" "call")])
(define_insn "*call"
- [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
+ [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
(match_operand 1 "" ""))]
"!SIBLING_CALL_P (insn)"
"* return ix86_output_call_insn (insn, operands[0]);"
[(set_attr "type" "call")])
(define_insn_and_split "*sibcall_vzeroupper"
- [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
+ [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
(match_operand 1 "" ""))
(unspec [(match_operand 2 "const_int_operand" "")]
UNSPEC_CALL_NEEDS_VZEROUPPER)]
[(set_attr "type" "call")])
(define_insn "*sibcall"
- [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
+ [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
(match_operand 1 "" ""))]
"SIBLING_CALL_P (insn)"
"* return ix86_output_call_insn (insn, operands[0]);"
(define_insn_and_split "*call_value_vzeroupper"
[(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
+ (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
(match_operand 2 "" "")))
(unspec [(match_operand 3 "const_int_operand" "")]
UNSPEC_CALL_NEEDS_VZEROUPPER)]
(define_insn "*call_value"
[(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
+ (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
(match_operand 2 "" "")))]
"!SIBLING_CALL_P (insn)"
"* return ix86_output_call_insn (insn, operands[1]);"
(define_insn_and_split "*sibcall_value_vzeroupper"
[(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
+ (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
(match_operand 2 "" "")))
(unspec [(match_operand 3 "const_int_operand" "")]
UNSPEC_CALL_NEEDS_VZEROUPPER)]
(define_insn "*sibcall_value"
[(set (match_operand 0 "" "")
- (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
+ (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
(match_operand 2 "" "")))]
"SIBLING_CALL_P (insn)"
"* return ix86_output_call_insn (insn, operands[1]);"
;; Predicate definitions for IA-32 and x86-64.
-;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
;; Free Software Foundation, Inc.
;;
;; This file is part of GCC.
(match_operand 0 "memory_operand"))))
;; Test for a valid operand for a call instruction.
-(define_predicate "call_insn_operand"
- (ior (match_operand 0 "constant_call_address_operand")
+;; Allow constant call address operands in Pmode only.
+(define_special_predicate "call_insn_operand"
+ (ior (match_test "constant_call_address_operand
+ (op, mode == VOIDmode ? mode : Pmode)")
(match_operand 0 "call_register_no_elim_operand")
(and (not (match_test "TARGET_X32"))
(match_operand 0 "memory_operand"))))
;; Similarly, but for tail calls, in which we cannot allow memory references.
-(define_predicate "sibcall_insn_operand"
- (ior (match_operand 0 "constant_call_address_operand")
+(define_special_predicate "sibcall_insn_operand"
+ (ior (match_test "constant_call_address_operand
+ (op, mode == VOIDmode ? mode : Pmode)")
(match_operand 0 "register_no_elim_operand")))
;; Match exactly zero.