From: Jan Hubicka Date: Thu, 20 Sep 2001 10:21:40 +0000 (+0200) Subject: i386.md (indirect_jump): Allow Pmode operand. X-Git-Tag: prereleases/libstdc++-3.0.95~2029 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6eb791fc977474c35eed05b27836328e110460ad;p=thirdparty%2Fgcc.git i386.md (indirect_jump): Allow Pmode operand. * i386.md (indirect_jump): Allow Pmode operand. (tablejump): LIkewise; perform expansion to 64bit mode. * i386.c (symbolic_operand): Allow 64bit PIC references. (pic_symbolic_operand): Likewise. (ix86_find_base_term): Strip the 64bit PIC references. (legitimate_pic_address_disp_p): Handle 64bit PIC. (legitimize_pic_address): Likewise. (i386_simplify_dwarf_addr): Strip down the 64bit PIC references. * i386.h (CASE_VECTOR_MODE): Set to SImode for 64bit PIC compilation. From-SVN: r45705 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0d6f11fb25e3..6f039c6fd8e7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +Thu Sep 20 12:19:36 CEST 2001 Jan Hubicka + + * i386.md (indirect_jump): Allow Pmode operand. + (tablejump): LIkewise; perform expansion to 64bit mode. + * i386.c (symbolic_operand): Allow 64bit PIC references. + (pic_symbolic_operand): Likewise. + (ix86_find_base_term): Strip the 64bit PIC references. + (legitimate_pic_address_disp_p): Handle 64bit PIC. + (legitimize_pic_address): Likewise. + (i386_simplify_dwarf_addr): Strip down the 64bit PIC references. + * i386.h (CASE_VECTOR_MODE): Set to SImode for 64bit PIC compilation. + 2001-09-19 Alan Modra David Edelsohn diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 35c9dcfea1c5..c89a0ab591d7 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1495,8 +1495,9 @@ symbolic_operand (op, mode) if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF || (GET_CODE (op) == UNSPEC - && XINT (op, 1) >= 6 - && XINT (op, 1) <= 7)) + && (XINT (op, 1) == 6 + || XINT (op, 1) == 7 + || XINT (op, 1) == 15))) return 1; if (GET_CODE (op) != PLUS || GET_CODE (XEXP (op, 1)) != CONST_INT) @@ -1529,9 +1530,16 @@ pic_symbolic_operand (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED; { - if (GET_CODE (op) == CONST) + if (GET_CODE (op) != CONST) + return 0; + op = XEXP (op, 0); + if (TARGET_64BIT) + { + if (GET_CODE (XEXP (op, 0)) == UNSPEC) + return 1; + } + else { - op = XEXP (op, 0); if (GET_CODE (op) == UNSPEC) return 1; if (GET_CODE (op) != PLUS @@ -3220,6 +3228,29 @@ ix86_find_base_term (x) { rtx term; + if (TARGET_64BIT) + { + if (GET_CODE (x) != CONST) + return x; + term = XEXP (x, 0); + if (GET_CODE (term) == PLUS + && (GET_CODE (XEXP (term, 1)) == CONST_INT + || GET_CODE (XEXP (term, 1)) == CONST_DOUBLE)) + term = XEXP (term, 0); + if (GET_CODE (term) != UNSPEC + || XVECLEN (term, 0) != 1 + || XINT (term, 1) != 15) + return x; + + term = XVECEXP (term, 0, 0); + + if (GET_CODE (term) != SYMBOL_REF + && GET_CODE (term) != LABEL_REF) + return x; + + return term; + } + if (GET_CODE (x) != PLUS || XEXP (x, 0) != pic_offset_table_rtx || GET_CODE (XEXP (x, 1)) != CONST) @@ -3251,10 +3282,42 @@ int legitimate_pic_address_disp_p (disp) register rtx disp; { + /* In 64bit mode we can allow direct addresses of symbols and labels + when they are not dynamic symbols. */ + if (TARGET_64BIT) + { + rtx x = disp; + if (GET_CODE (disp) == CONST) + x = XEXP (disp, 0); + /* ??? Handle PIC code models */ + if (GET_CODE (x) == PLUS + && (GET_CODE (XEXP (x, 1)) == CONST_INT + && ix86_cmodel == CM_SMALL_PIC + && INTVAL (XEXP (x, 1)) < 1024*1024*1024 + && INTVAL (XEXP (x, 1)) > -1024*1024*1024)) + x = XEXP (x, 0); + if (local_symbolic_operand (x, Pmode)) + return 1; + } if (GET_CODE (disp) != CONST) return 0; disp = XEXP (disp, 0); + if (TARGET_64BIT) + { + /* We are unsafe to allow PLUS expressions. This limit allowed distance + of GOT tables. We should not need these anyway. */ + if (GET_CODE (disp) != UNSPEC + || XVECLEN (disp, 0) != 1 + || XINT (disp, 1) != 15) + return 0; + + if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF + && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF) + return 0; + return 1; + } + if (GET_CODE (disp) == PLUS) { if (GET_CODE (XEXP (disp, 1)) != CONST_INT) @@ -3576,16 +3639,23 @@ legitimize_pic_address (orig, reg) if (local_symbolic_operand (op0, Pmode) && GET_CODE (op1) == CONST_INT) { - current_function_uses_pic_offset_table = 1; - new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 7); - new = gen_rtx_PLUS (Pmode, new, op1); - new = gen_rtx_CONST (Pmode, new); - new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new); + if (!TARGET_64BIT) + { + current_function_uses_pic_offset_table = 1; + new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 7); + new = gen_rtx_PLUS (Pmode, new, op1); + new = gen_rtx_CONST (Pmode, new); + new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new); - if (reg != 0) + if (reg != 0) + { + emit_move_insn (reg, new); + new = reg; + } + } + else { - emit_move_insn (reg, new); - new = reg; + /* ??? We need to limit offsets here. */ } } else @@ -3900,6 +3970,9 @@ output_pic_addr_const (file, x, code) case 8: fputs ("@PLT", file); break; + case 15: + fputs ("@GOTPCREL(%RIP)", file); + break; default: output_operand_lossage ("invalid UNSPEC as operand"); break; @@ -3937,6 +4010,15 @@ i386_simplify_dwarf_addr (orig_x) { rtx x = orig_x; + if (TARGET_64BIT) + { + if (GET_CODE (x) != CONST + || GET_CODE (XEXP (x, 0)) != UNSPEC + || XINT (XEXP (x, 0), 1) != 15) + return orig_x; + return XVECEXP (XEXP (x, 0), 0, 0); + } + if (GET_CODE (x) != PLUS || GET_CODE (XEXP (x, 0)) != REG || GET_CODE (XEXP (x, 1)) != CONST) diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 1a1715e8f8e4..86e83dfbbab7 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2244,7 +2244,7 @@ while (0) /* Specify the machine mode that this machine uses for the index in the tablejump instruction. */ -#define CASE_VECTOR_MODE Pmode +#define CASE_VECTOR_MODE (!TARGET_64BIT || flag_pic ? SImode : DImode) /* Define as C expression which evaluates to nonzero if the tablejump instruction expects the table to contain offsets from the address of the diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 797431f19ad4..ef5d0fc86de9 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -12948,14 +12948,14 @@ [(set_attr "type" "ibr")]) (define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] + [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))] "" "jmp\t%A0" [(set_attr "type" "ibr") (set_attr "length_immediate" "0")]) (define_expand "tablejump" - [(parallel [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm")) + [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm")) (use (label_ref (match_operand 1 "" "")))])] "" { @@ -12963,10 +12963,17 @@ the relative address to an absolute address. */ if (flag_pic) { - operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx, - operands[0], NULL_RTX, 1, - OPTAB_DIRECT); - current_function_uses_pic_offset_table = 1; + if (TARGET_64BIT) + operands[0] = expand_simple_binop (Pmode, PLUS, operands[0], + operands[1], NULL_RTX, 0, + OPTAB_DIRECT); + else + { + operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx, + operands[0], NULL_RTX, 1, + OPTAB_DIRECT); + current_function_uses_pic_offset_table = 1; + } } })