diff options
author | Jan Hubicka <jh@suse.cz> | 2001-03-30 00:25:16 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2001-03-29 22:25:16 +0000 |
commit | 885a70fdff53beb587e130d48162eba8ff2a7480 (patch) | |
tree | 63c02f76cdfb52fa55591056a699c6270da03368 /gcc | |
parent | e4b776a6d013ba9ec635f30f09021f050d844fdd (diff) | |
download | gcc-885a70fdff53beb587e130d48162eba8ff2a7480.zip gcc-885a70fdff53beb587e130d48162eba8ff2a7480.tar.gz gcc-885a70fdff53beb587e130d48162eba8ff2a7480.tar.bz2 |
i386.c (ix86_expand_setcc): Support 64bit.
* i386.c (ix86_expand_setcc): Support 64bit.
(ix86_expand_int_movcc): Likewise.
* i386.md (movdicc_rex64, x86_movsicc_0_m1_rex64, movdicc_c_rex64):
New patterns.
* i386.md (allocate_stack_worker): Turn to expander.
(allocate_stack_worker_1, allocate_stack_worker_rex64): New insns.
* i386.c (print_reg): Do not print x86_64 style regs on IA-32
From-SVN: r40958
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 42 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 65 |
3 files changed, 107 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 332d6df..826b875 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +Fri Mar 30 00:21:41 CEST 2001 Jan Hubicka <jh@suse.cz> + + * i386.c (ix86_expand_setcc): Support 64bit. + (ix86_expand_int_movcc): Likewise. + * i386.md (movdicc_rex64, x86_movsicc_0_m1_rex64, movdicc_c_rex64): + New patterns. + + * i386.md (allocate_stack_worker): Turn to expander. + (allocate_stack_worker_1, allocate_stack_worker_rex64): New insns. + + * i386.c (print_reg): Do not print x86_64 style regs on IA-32 + 2001-03-29 Richard Henderson <rth@redhat.com> * libgcc2.c [L__main]: Include unwind-dw2-fde.h instead of frame.h. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 57db899..5dc9fa9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -3798,6 +3798,8 @@ print_reg (x, code, file) from the normal registers. */ if (REX_INT_REG_P (x)) { + if (!TARGET_64BIT) + abort (); switch (code) { case 5: @@ -3837,7 +3839,7 @@ print_reg (x, code, file) case 4: case 12: if (! ANY_FP_REG_P (x)) - putc (code == 8 ? 'r' : 'e', file); + putc (code == 8 && TARGET_64BIT ? 'r' : 'e', file); /* FALLTHRU */ case 16: case 2: @@ -6112,7 +6114,8 @@ ix86_expand_setcc (code, dest) rtx second_test, bypass_test; int type; - if (GET_MODE (ix86_compare_op0) == DImode) + if (GET_MODE (ix86_compare_op0) == DImode + && !TARGET_64BIT) return 0; /* FAIL */ /* Three modes of generation: @@ -6229,6 +6232,7 @@ ix86_expand_int_movcc (operands) HImode insns, we'd be swallowed in word prefix ops. */ if (GET_MODE (operands[0]) != HImode + && GET_MODE (operands[0]) != DImode && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT) { @@ -6362,28 +6366,46 @@ ix86_expand_int_movcc (operands) ix86_compare_op1, VOIDmode, 0, 1); nops = 0; + /* On x86_64 the lea instruction operates on Pmode, so we need to get arithmetics + done in proper mode to match. */ if (diff == 1) - tmp = out; + { + if (Pmode != SImode) + tmp = gen_lowpart (Pmode, out); + else + tmp = out; + } else { - tmp = gen_rtx_MULT (SImode, out, GEN_INT (diff & ~1)); + rtx out1; + if (Pmode != SImode) + out1 = gen_lowpart (Pmode, out); + else + out1 = out; + tmp = gen_rtx_MULT (Pmode, out1, GEN_INT (diff & ~1)); nops++; if (diff & 1) { - tmp = gen_rtx_PLUS (SImode, tmp, out); + tmp = gen_rtx_PLUS (Pmode, tmp, out1); nops++; } } if (cf != 0) { - tmp = gen_rtx_PLUS (SImode, tmp, GEN_INT (cf)); + tmp = gen_rtx_PLUS (Pmode, tmp, GEN_INT (cf)); nops++; } - if (tmp != out) + if (tmp != out + && (GET_CODE (tmp) != SUBREG || SUBREG_REG (tmp) != out)) { - if (nops == 0) - emit_move_insn (out, tmp); - else if (nops == 1) + if (Pmode != SImode) + tmp = gen_rtx_SUBREG (SImode, tmp, 0); + + /* ??? We should to take care for outputing non-lea arithmetics + for Pmode != SImode case too, but it is quite tricky and not + too important, since all TARGET_64BIT machines support real + conditional moves. */ + if (nops == 1 && Pmode == SImode) { rtx clob; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 0d61b8e..695d488 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -14919,6 +14919,45 @@ ;; Conditional move instructions. +(define_expand "movdicc_rex64" + [(set (match_operand:DI 0 "register_operand" "") + (if_then_else:DI (match_operand 1 "comparison_operator" "") + (match_operand:DI 2 "x86_64_general_operand" "") + (match_operand:DI 3 "x86_64_general_operand" "")))] + "TARGET_64BIT" + "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") + +(define_insn "x86_movsicc_0_m1_rex64" + [(set (match_operand:DI 0 "register_operand" "=r") + (if_then_else:DI (ltu (reg:CC 17) (const_int 0)) + (const_int -1) + (const_int 0))) + (clobber (reg:CC 17))] + "TARGET_64BIT" + "sbb{l}\\t%0, %0" + ; Since we don't have the proper number of operands for an alu insn, + ; fill in all the blanks. + [(set_attr "type" "alu") + (set_attr "memory" "none") + (set_attr "imm_disp" "false") + (set_attr "mode" "DI") + (set_attr "length_immediate" "0")]) + +(define_insn "*movdicc_c_rex64" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (if_then_else:DI (match_operator 1 "ix86_comparison_operator" + [(reg 17) (const_int 0)]) + (match_operand:DI 2 "nonimmediate_operand" "rm,0") + (match_operand:DI 3 "nonimmediate_operand" "0,rm")))] + "TARGET_64BIT && TARGET_CMOVE + && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" + "@ + cmov%C1\\t{%2, %0|%0, %2} + cmov%c1\\t{%3, %0|%0, %3}" + [(set_attr "type" "icmov") + (set_attr "mode" "DI")]) + + (define_expand "movsicc" [(set (match_operand:SI 0 "register_operand" "") (if_then_else:SI (match_operand 1 "comparison_operator" "") @@ -15749,12 +15788,34 @@ } }") -(define_insn "allocate_stack_worker" +(define_expand "allocate_stack_worker" + [(match_operand:SI 0 "register_operand" "")] + "TARGET_STACK_PROBE" + " +{ + if (TARGET_64BIT) + emit_insn (gen_allocate_stack_worker_rex64 (operands[0])); + else + emit_insn (gen_allocate_stack_worker_1 (operands[0])); + DONE; +}") + +(define_insn "allocate_stack_worker_1" [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3) (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0))) (clobber (match_dup 0)) (clobber (reg:CC 17))] - "TARGET_STACK_PROBE" + "TARGET_STACK_PROBE && !TARGET_64BIT" + "call\\t__alloca" + [(set_attr "type" "multi") + (set_attr "length" "5")]) + +(define_insn "allocate_stack_worker_rex64" + [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] 3) + (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0))) + (clobber (match_dup 0)) + (clobber (reg:CC 17))] + "TARGET_STACK_PROBE && TARGET_64BIT" "call\\t__alloca" [(set_attr "type" "multi") (set_attr "length" "5")]) |