diff options
author | Jan Hubicka <jh@suse.cz> | 2001-09-20 12:21:40 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2001-09-20 10:21:40 +0000 |
commit | 6eb791fc977474c35eed05b27836328e110460ad (patch) | |
tree | 171c0dd8ab08b64284d3fef0e676571a789213be /gcc | |
parent | 5b66fcf9a9448d80ca43d721eaaad0c8b3ace0f4 (diff) | |
download | gcc-6eb791fc977474c35eed05b27836328e110460ad.zip gcc-6eb791fc977474c35eed05b27836328e110460ad.tar.gz gcc-6eb791fc977474c35eed05b27836328e110460ad.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 106 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 19 |
4 files changed, 120 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0d6f11f..6f039c6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +Thu Sep 20 12:19:36 CEST 2001 Jan Hubicka <jh@suse.cz> + + * 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 <amodra@bigpond.net.au> David Edelsohn <edelsohn@gnu.org> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 35c9dcf..c89a0ab 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 1a1715e..86e83df 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 797431f..ef5d0fc 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; + } } }) |