Commit 6eb791fc by Jan Hubicka Committed by Jan Hubicka

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
parent 5b66fcf9
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> 2001-09-19 Alan Modra <amodra@bigpond.net.au>
David Edelsohn <edelsohn@gnu.org> David Edelsohn <edelsohn@gnu.org>
......
...@@ -1495,8 +1495,9 @@ symbolic_operand (op, mode) ...@@ -1495,8 +1495,9 @@ symbolic_operand (op, mode)
if (GET_CODE (op) == SYMBOL_REF if (GET_CODE (op) == SYMBOL_REF
|| GET_CODE (op) == LABEL_REF || GET_CODE (op) == LABEL_REF
|| (GET_CODE (op) == UNSPEC || (GET_CODE (op) == UNSPEC
&& XINT (op, 1) >= 6 && (XINT (op, 1) == 6
&& XINT (op, 1) <= 7)) || XINT (op, 1) == 7
|| XINT (op, 1) == 15)))
return 1; return 1;
if (GET_CODE (op) != PLUS if (GET_CODE (op) != PLUS
|| GET_CODE (XEXP (op, 1)) != CONST_INT) || GET_CODE (XEXP (op, 1)) != CONST_INT)
...@@ -1529,9 +1530,16 @@ pic_symbolic_operand (op, mode) ...@@ -1529,9 +1530,16 @@ pic_symbolic_operand (op, mode)
register rtx op; register rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED; 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) if (GET_CODE (op) == UNSPEC)
return 1; return 1;
if (GET_CODE (op) != PLUS if (GET_CODE (op) != PLUS
...@@ -3220,6 +3228,29 @@ ix86_find_base_term (x) ...@@ -3220,6 +3228,29 @@ ix86_find_base_term (x)
{ {
rtx term; 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 if (GET_CODE (x) != PLUS
|| XEXP (x, 0) != pic_offset_table_rtx || XEXP (x, 0) != pic_offset_table_rtx
|| GET_CODE (XEXP (x, 1)) != CONST) || GET_CODE (XEXP (x, 1)) != CONST)
...@@ -3251,10 +3282,42 @@ int ...@@ -3251,10 +3282,42 @@ int
legitimate_pic_address_disp_p (disp) legitimate_pic_address_disp_p (disp)
register rtx 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) if (GET_CODE (disp) != CONST)
return 0; return 0;
disp = XEXP (disp, 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 (disp) == PLUS)
{ {
if (GET_CODE (XEXP (disp, 1)) != CONST_INT) if (GET_CODE (XEXP (disp, 1)) != CONST_INT)
...@@ -3576,16 +3639,23 @@ legitimize_pic_address (orig, reg) ...@@ -3576,16 +3639,23 @@ legitimize_pic_address (orig, reg)
if (local_symbolic_operand (op0, Pmode) if (local_symbolic_operand (op0, Pmode)
&& GET_CODE (op1) == CONST_INT) && GET_CODE (op1) == CONST_INT)
{ {
current_function_uses_pic_offset_table = 1; if (!TARGET_64BIT)
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 7); {
new = gen_rtx_PLUS (Pmode, new, op1); current_function_uses_pic_offset_table = 1;
new = gen_rtx_CONST (Pmode, new); new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 7);
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new); 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); /* ??? We need to limit offsets here. */
new = reg;
} }
} }
else else
...@@ -3900,6 +3970,9 @@ output_pic_addr_const (file, x, code) ...@@ -3900,6 +3970,9 @@ output_pic_addr_const (file, x, code)
case 8: case 8:
fputs ("@PLT", file); fputs ("@PLT", file);
break; break;
case 15:
fputs ("@GOTPCREL(%RIP)", file);
break;
default: default:
output_operand_lossage ("invalid UNSPEC as operand"); output_operand_lossage ("invalid UNSPEC as operand");
break; break;
...@@ -3937,6 +4010,15 @@ i386_simplify_dwarf_addr (orig_x) ...@@ -3937,6 +4010,15 @@ i386_simplify_dwarf_addr (orig_x)
{ {
rtx x = 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 if (GET_CODE (x) != PLUS
|| GET_CODE (XEXP (x, 0)) != REG || GET_CODE (XEXP (x, 0)) != REG
|| GET_CODE (XEXP (x, 1)) != CONST) || GET_CODE (XEXP (x, 1)) != CONST)
......
...@@ -2244,7 +2244,7 @@ while (0) ...@@ -2244,7 +2244,7 @@ while (0)
/* Specify the machine mode that this machine uses /* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */ 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 /* Define as C expression which evaluates to nonzero if the tablejump
instruction expects the table to contain offsets from the address of the instruction expects the table to contain offsets from the address of the
......
...@@ -12948,14 +12948,14 @@ ...@@ -12948,14 +12948,14 @@
[(set_attr "type" "ibr")]) [(set_attr "type" "ibr")])
(define_insn "indirect_jump" (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" "jmp\t%A0"
[(set_attr "type" "ibr") [(set_attr "type" "ibr")
(set_attr "length_immediate" "0")]) (set_attr "length_immediate" "0")])
(define_expand "tablejump" (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 "" "")))])] (use (label_ref (match_operand 1 "" "")))])]
"" ""
{ {
...@@ -12963,10 +12963,17 @@ ...@@ -12963,10 +12963,17 @@
the relative address to an absolute address. */ the relative address to an absolute address. */
if (flag_pic) if (flag_pic)
{ {
operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx, if (TARGET_64BIT)
operands[0], NULL_RTX, 1, operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
OPTAB_DIRECT); operands[1], NULL_RTX, 0,
current_function_uses_pic_offset_table = 1; 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;
}
} }
}) })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment