Add support for the -mcmodel=MODEL flag on TILE-Gx.
Add support for the -mcmodel=MODEL flag on TILE-Gx. The models supported are small and large. In the small model (default), distance for direct calls is limited to 500M in either direction. PC-relative addresses are 32 bits. Absolute addresses support the full address range. In the large model, there is no limiation on call distance, pc-relative addresses, or absolute addresses. * doc/invoke.texi: Document -mcmodel=small, -mcmodel=large. * config/tilegx/tilegx.h: Include config/tilegx/tilegx-opts.h. (CRT_CALL_STATIC_FUNCTION): Define. * config/tilegx/predicates.md (const_last_symbolic_operand): Handle UNSPEC_HW2_LAST_PCREL, UNSPEC_HW1_LAST_PLT_PCREL, and UNSPEC_HW2_LAST_PLT_PCREL. (const_symbolic_operand): Handle UNSPEC_HW1_PCREL, UNSPEC_HW0_PLT_PCREL, and UNSPEC_HW1_PLT_PCREL. * config/tilegx/tilegx.md (UNSPEC_MOV_LARGE_PCREL_STEP4): Define, and renumber the constants that follow. (UNSPEC_HW1_PCREL): Define, and renumber the constants that follow. (UNSPEC_HW0_PLT_PCREL): Define. (UNSPEC_HW1_PLT_PCREL): Define. (UNSPEC_HW1_LAST_PLT_PCREL): Define. (UNSPEC_HW2_LAST_PLT_PCREL): Define. (mov_large_pcrel_step1): Define. (mov_large_pcrel_step2): Define. (mov_large_pcrel_step3): Define. (mov_large_pcrel_step4): Define. (mov_plt_pcrel_step1): Define. (mov_plt_pcrel_step2): Define. (mov_plt_pcrel_step3): Define. (mov_plt_pcrel_step1_32bit): Define. (mov_plt_pcrel_step2_32bit): Define. (call): Handle tilegx_cmodel == CM_LARGE, CM_LARGE_PIC. (call_value): Ditto. * config/tilegx/tilegx.opt: Include config/tilegx/tilegx-opts.h. (mcmodel): New option. (enum cmodel): Define. (CM_SMALL): Define. (CM_LARGE): Define. * config/tilegx/tilegx-protos.h (tilegx_compute_pcrel_address): Declare. (tilegx_compute_pcrel_plt_address): Declare. * config/tilegx/tilegx.c (tilegx_option_override): Handle tilegx_cmodel. (tilegx_function_ok_for_sibcall): Ditto. (compute_pcrel_address): Rename to tilegx_compute_pcrel_address, and don't declare static. Handle tilegx_cmodel. (tilegx_compute_pcrel_plt_address): Define. (tilegx_legitimize_pic_address): Rename calls to compute_pcrel_address. (tilegx_delegitimize_address): Handle UNSPEC_HW1_PCREL, UNSPEC_HW2_LAST_PCREL, UNSPEC_HW0_PLT_PCREL, UNSPEC_HW1_PLT_PCREL, UNSPEC_HW1_LAST_PLT_PCREL, UNSPEC_HW2_LAST_PLT_PCREL. (load_pic_register): Rename call to compute_pcrel_address. (tilegx_print_operand): Handle UNSPEC_HW1_PCREL, UNSPEC_HW2_LAST_PCREL, UNSPEC_HW0_PLT_PCREL, UNSPEC_HW1_PLT_PCREL, UNSPEC_HW1_LAST_PLT_PCREL, UNSPEC_HW2_LAST_PLT_PCREL. From-SVN: r190737
This commit is contained in:
parent
bebfb71bf4
commit
1773cd776a
@ -1,3 +1,57 @@
|
||||
2012-08-28 Walter Lee <walt@tilera.com>
|
||||
|
||||
* doc/invoke.texi: Document -mcmodel=small, -mcmodel=large.
|
||||
* config/tilegx/tilegx.h: Include config/tilegx/tilegx-opts.h.
|
||||
(CRT_CALL_STATIC_FUNCTION): Define.
|
||||
* config/tilegx/predicates.md (const_last_symbolic_operand):
|
||||
Handle UNSPEC_HW2_LAST_PCREL, UNSPEC_HW1_LAST_PLT_PCREL, and
|
||||
UNSPEC_HW2_LAST_PLT_PCREL.
|
||||
(const_symbolic_operand): Handle UNSPEC_HW1_PCREL,
|
||||
UNSPEC_HW0_PLT_PCREL, and UNSPEC_HW1_PLT_PCREL.
|
||||
* config/tilegx/tilegx.md (UNSPEC_MOV_LARGE_PCREL_STEP4): Define,
|
||||
and renumber the constants that follow.
|
||||
(UNSPEC_HW1_PCREL): Ditto.
|
||||
(UNSPEC_HW2_LAST_PCREL): Ditto.
|
||||
(UNSPEC_HW0_PLT_PCREL): Define.
|
||||
(UNSPEC_HW1_PLT_PCREL): Define.
|
||||
(UNSPEC_HW1_LAST_PLT_PCREL): Define.
|
||||
(UNSPEC_HW2_LAST_PLT_PCREL): Define.
|
||||
(mov_large_pcrel_step1): Define.
|
||||
(mov_large_pcrel_step2): Define.
|
||||
(mov_large_pcrel_step3): Define.
|
||||
(mov_large_pcrel_step4): Define.
|
||||
(mov_plt_pcrel_step1): Define.
|
||||
(mov_plt_pcrel_step2): Define.
|
||||
(mov_plt_pcrel_step3): Define.
|
||||
(mov_plt_pcrel_step1_32bit): Define.
|
||||
(mov_plt_pcrel_step2_32bit): Define.
|
||||
(call): Handle tilegx_cmodel == CM_LARGE, CM_LARGE_PIC.
|
||||
(call_value): Ditto.
|
||||
* config/tilegx/tilegx.opt: Include config/tilegx/tilegx-opts.h.
|
||||
(mcmodel): New option.
|
||||
(enum cmodel): Define.
|
||||
(CM_SMALL): Define.
|
||||
(CM_LARGE): Define.
|
||||
* config/tilegx/tilegx-opts.h: New file.
|
||||
* config/tilegx/tilegx-protos.h (tilegx_compute_pcrel_address):
|
||||
Declare.
|
||||
(tilegx_compute_pcrel_plt_address): Declare.
|
||||
* config/tilegx/tilegx.c (tilegx_option_override): Handle
|
||||
tilegx_cmodel.
|
||||
(tilegx_function_ok_for_sibcall): Ditto.
|
||||
(compute_pcrel_address): Rename to tilegx_compute_pcrel_address,
|
||||
and don't declare static. Handle tilegx_cmodel.
|
||||
(tilegx_compute_pcrel_plt_address): Define.
|
||||
(tilegx_legitimize_pic_address): Rename calls to
|
||||
compute_pcrel_address.
|
||||
(tilegx_delegitimize_address): Handle UNSPEC_HW1_PCREL,
|
||||
UNSPEC_HW2_LAST_PCREL, UNSPEC_HW0_PLT_PCREL, UNSPEC_HW1_PLT_PCREL,
|
||||
UNSPEC_HW1_LAST_PLT_PCREL, UNSPEC_HW2_LAST_PLT_PCREL.
|
||||
(load_pic_register): Rename call to compute_pcrel_address.
|
||||
(tilegx_print_operand): Handle UNSPEC_HW1_PCREL,
|
||||
UNSPEC_HW2_LAST_PCREL, UNSPEC_HW0_PLT_PCREL, UNSPEC_HW1_PLT_PCREL,
|
||||
UNSPEC_HW1_LAST_PLT_PCREL, UNSPEC_HW2_LAST_PLT_PCREL.
|
||||
|
||||
2012-08-27 Maxim Kuvyrkov <maxim@codesourcery.com>
|
||||
|
||||
* sched-deps.c (add_dependence_list_and_free): Simplify.
|
||||
|
@ -80,11 +80,14 @@
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW2_LAST")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_PCREL")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW2_LAST_PCREL")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_LAST_GOT")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_GOT")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_TLS_GD")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_TLS_IE")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_TLS_LE"))))
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_TLS_LE")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_PLT_PCREL")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW2_LAST_PLT_PCREL"))))
|
||||
|
||||
;; Returns 1 if OP is an unspec wrapper for a symbol, got, or tls
|
||||
;; reference.
|
||||
@ -96,10 +99,13 @@
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW2")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW3")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_PCREL")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_PCREL")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_GOT")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_TLS_GD")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_TLS_IE")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_TLS_LE"))))
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_TLS_LE")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_PLT_PCREL")
|
||||
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_PLT_PCREL"))))
|
||||
|
||||
;; Return 1 if OP is a 8-element vector constant with identical signed
|
||||
;; 8-bit elements or any register.
|
||||
|
34
gcc/config/tilegx/tilegx-opts.h
Normal file
34
gcc/config/tilegx/tilegx-opts.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* Definitions for option handling for TILE-Gx.
|
||||
Copyright (C) 2012
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Walter Lee (walt@tilera.com)
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your
|
||||
option) any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef TILEGX_OPTS_H
|
||||
#define TILEGX_OPTS_H
|
||||
|
||||
enum cmodel {
|
||||
CM_SMALL, /* Makes various assumpation about sizes of code and
|
||||
data fits. */
|
||||
CM_LARGE, /* No assumptions. */
|
||||
CM_SMALL_PIC, /* Makes various assumpation about sizes of code and
|
||||
data fits. */
|
||||
CM_LARGE_PIC /* No assumptions. */
|
||||
};
|
||||
|
||||
#endif
|
@ -23,6 +23,8 @@
|
||||
#define GCC_TILEGX_PROTOS_H
|
||||
|
||||
extern void tilegx_init_expanders (void);
|
||||
extern void tilegx_compute_pcrel_address (rtx, rtx);
|
||||
extern void tilegx_compute_pcrel_plt_address (rtx, rtx);
|
||||
extern bool tilegx_legitimate_pic_operand_p (rtx);
|
||||
extern rtx tilegx_simd_int (rtx, enum machine_mode);
|
||||
|
||||
|
@ -67,6 +67,29 @@ static bool output_memory_autoinc_first;
|
||||
static void
|
||||
tilegx_option_override (void)
|
||||
{
|
||||
if (global_options_set.x_tilegx_cmodel)
|
||||
{
|
||||
switch (tilegx_cmodel)
|
||||
{
|
||||
case CM_SMALL:
|
||||
case CM_SMALL_PIC:
|
||||
if (flag_pic)
|
||||
tilegx_cmodel = CM_SMALL_PIC;
|
||||
break;
|
||||
|
||||
case CM_LARGE:
|
||||
case CM_LARGE_PIC:
|
||||
if (flag_pic)
|
||||
tilegx_cmodel = CM_LARGE_PIC;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
else
|
||||
tilegx_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
|
||||
|
||||
/* When modulo scheduling is enabled, we still rely on regular
|
||||
scheduler for bundling. */
|
||||
if (flag_modulo_sched)
|
||||
@ -119,7 +142,8 @@ tilegx_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
static bool
|
||||
tilegx_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return decl != NULL;
|
||||
return (tilegx_cmodel != CM_LARGE && tilegx_cmodel != CM_LARGE_PIC
|
||||
&& (decl != NULL));
|
||||
}
|
||||
|
||||
|
||||
@ -1024,12 +1048,12 @@ tilegx_legitimize_tls_address (rtx addr)
|
||||
|
||||
/* Returns a register that points to ADDR, a symbolic address, by
|
||||
computing its address relative to tilegx_text_label_symbol. */
|
||||
static void
|
||||
compute_pcrel_address (rtx result, rtx addr)
|
||||
void
|
||||
tilegx_compute_pcrel_address (rtx result, rtx addr)
|
||||
{
|
||||
rtx text_label_symbol = tilegx_text_label_symbol ();
|
||||
rtx text_label_rtx = tilegx_text_label_rtx ();
|
||||
rtx temp, temp2;
|
||||
rtx temp, temp2, temp3;
|
||||
|
||||
temp = create_temp_reg_if_possible (Pmode, result);
|
||||
temp2 = create_temp_reg_if_possible (Pmode, result);
|
||||
@ -1043,6 +1067,18 @@ compute_pcrel_address (rtx result, rtx addr)
|
||||
text_label_rtx,
|
||||
addr, text_label_symbol));
|
||||
}
|
||||
else if (tilegx_cmodel == CM_LARGE_PIC)
|
||||
{
|
||||
temp3 = create_temp_reg_if_possible (Pmode, result);
|
||||
emit_insn (gen_mov_large_pcrel_step1 (temp, addr, text_label_symbol));
|
||||
emit_insn (gen_mov_large_pcrel_step2 (temp2, temp, addr,
|
||||
text_label_symbol));
|
||||
emit_insn (gen_mov_large_pcrel_step3 (temp3, temp2, addr,
|
||||
text_label_symbol));
|
||||
emit_insn (gen_mov_large_pcrel_step4 (result, temp3,
|
||||
text_label_rtx,
|
||||
addr, text_label_symbol));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_insn (gen_mov_pcrel_step1 (temp, addr, text_label_symbol));
|
||||
@ -1054,6 +1090,41 @@ compute_pcrel_address (rtx result, rtx addr)
|
||||
}
|
||||
|
||||
|
||||
/* Returns a register that points to the plt entry of ADDR, a symbolic
|
||||
address, by computing its address relative to
|
||||
tilegx_text_label_symbol. */
|
||||
void
|
||||
tilegx_compute_pcrel_plt_address (rtx result, rtx addr)
|
||||
{
|
||||
rtx text_label_symbol = tilegx_text_label_symbol ();
|
||||
rtx text_label_rtx = tilegx_text_label_rtx ();
|
||||
rtx temp, temp2, temp3;
|
||||
|
||||
temp = create_temp_reg_if_possible (Pmode, result);
|
||||
temp2 = create_temp_reg_if_possible (Pmode, result);
|
||||
|
||||
if (TARGET_32BIT)
|
||||
{
|
||||
emit_insn (gen_mov_plt_pcrel_step1_32bit (temp, addr,
|
||||
text_label_symbol));
|
||||
emit_insn (gen_mov_plt_pcrel_step2_32bit (temp2, temp, addr,
|
||||
text_label_symbol));
|
||||
emit_move_insn (result, gen_rtx_PLUS (Pmode, temp2, text_label_rtx));
|
||||
}
|
||||
else
|
||||
{
|
||||
temp3 = create_temp_reg_if_possible (Pmode, result);
|
||||
|
||||
emit_insn (gen_mov_plt_pcrel_step1 (temp, addr, text_label_symbol));
|
||||
emit_insn (gen_mov_plt_pcrel_step2 (temp2, temp, addr,
|
||||
text_label_symbol));
|
||||
emit_insn (gen_mov_plt_pcrel_step3 (temp3, temp2, addr,
|
||||
text_label_symbol));
|
||||
emit_move_insn (result, gen_rtx_PLUS (Pmode, temp3, text_label_rtx));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Legitimize PIC addresses. If the address is already
|
||||
position-independent, we return ORIG. Newly generated
|
||||
position-independent addresses go into a reg. This is REG if
|
||||
@ -1079,7 +1150,7 @@ tilegx_legitimize_pic_address (rtx orig,
|
||||
loading in the address, so that these instructions can be
|
||||
optimized properly. */
|
||||
rtx temp_reg = create_temp_reg_if_possible (Pmode, reg);
|
||||
compute_pcrel_address (temp_reg, orig);
|
||||
tilegx_compute_pcrel_address (temp_reg, orig);
|
||||
|
||||
/* Note: this is conservative. We use the text_label but we
|
||||
don't use the pic_offset_table. However, in some cases
|
||||
@ -1196,7 +1267,7 @@ tilegx_legitimize_pic_address (rtx orig,
|
||||
loading in the address, so that these instructions can be
|
||||
optimized properly. */
|
||||
temp_reg = create_temp_reg_if_possible (Pmode, reg);
|
||||
compute_pcrel_address (temp_reg, orig);
|
||||
tilegx_compute_pcrel_address (temp_reg, orig);
|
||||
|
||||
/* Note: this is conservative. We use the text_label but we
|
||||
don't use the pic_offset_table. */
|
||||
@ -1250,7 +1321,13 @@ tilegx_delegitimize_address (rtx x)
|
||||
case UNSPEC_HW1_LAST:
|
||||
case UNSPEC_HW2_LAST:
|
||||
case UNSPEC_HW0_PCREL:
|
||||
case UNSPEC_HW1_PCREL:
|
||||
case UNSPEC_HW1_LAST_PCREL:
|
||||
case UNSPEC_HW2_LAST_PCREL:
|
||||
case UNSPEC_HW0_PLT_PCREL:
|
||||
case UNSPEC_HW1_PLT_PCREL:
|
||||
case UNSPEC_HW1_LAST_PLT_PCREL:
|
||||
case UNSPEC_HW2_LAST_PLT_PCREL:
|
||||
case UNSPEC_HW0_GOT:
|
||||
case UNSPEC_HW0_LAST_GOT:
|
||||
case UNSPEC_HW1_LAST_GOT:
|
||||
@ -1290,7 +1367,7 @@ load_pic_register (bool delay_pic_helper ATTRIBUTE_UNUSED)
|
||||
emit_insn (gen_insn_lnk_and_label (text_label_rtx, text_label_symbol));
|
||||
}
|
||||
|
||||
compute_pcrel_address (tilegx_got_rtx (), got_symbol);
|
||||
tilegx_compute_pcrel_address (tilegx_got_rtx (), got_symbol);
|
||||
|
||||
flag_pic = orig_flag_pic;
|
||||
|
||||
@ -2577,7 +2654,7 @@ tilegx_expand_tablejump (rtx op0, rtx op1)
|
||||
rtx temp = gen_reg_rtx (Pmode);
|
||||
rtx temp2 = gen_reg_rtx (Pmode);
|
||||
|
||||
compute_pcrel_address (temp, gen_rtx_LABEL_REF (Pmode, op1));
|
||||
tilegx_compute_pcrel_address (temp, gen_rtx_LABEL_REF (Pmode, op1));
|
||||
emit_move_insn (temp2,
|
||||
gen_rtx_PLUS (Pmode,
|
||||
convert_to_mode (Pmode, op0, false),
|
||||
@ -4961,6 +5038,7 @@ tilegx_print_operand (FILE *file, rtx x, int code)
|
||||
opstr = "hw0";
|
||||
break;
|
||||
case UNSPEC_HW1:
|
||||
case UNSPEC_HW1_PCREL:
|
||||
opstr = "hw1";
|
||||
break;
|
||||
case UNSPEC_HW2:
|
||||
@ -4977,6 +5055,7 @@ tilegx_print_operand (FILE *file, rtx x, int code)
|
||||
opstr = "hw1_last";
|
||||
break;
|
||||
case UNSPEC_HW2_LAST:
|
||||
case UNSPEC_HW2_LAST_PCREL:
|
||||
opstr = "hw2_last";
|
||||
break;
|
||||
case UNSPEC_HW0_GOT:
|
||||
@ -5006,6 +5085,18 @@ tilegx_print_operand (FILE *file, rtx x, int code)
|
||||
case UNSPEC_HW1_LAST_TLS_LE:
|
||||
opstr = "hw1_last_tls_le";
|
||||
break;
|
||||
case UNSPEC_HW0_PLT_PCREL:
|
||||
opstr = "hw0_plt";
|
||||
break;
|
||||
case UNSPEC_HW1_PLT_PCREL:
|
||||
opstr = "hw1_plt";
|
||||
break;
|
||||
case UNSPEC_HW1_LAST_PLT_PCREL:
|
||||
opstr = "hw1_last_plt";
|
||||
break;
|
||||
case UNSPEC_HW2_LAST_PLT_PCREL:
|
||||
opstr = "hw2_last_plt";
|
||||
break;
|
||||
default:
|
||||
output_operand_lossage ("invalid %%H specifier");
|
||||
}
|
||||
@ -5015,7 +5106,13 @@ tilegx_print_operand (FILE *file, rtx x, int code)
|
||||
output_addr_const (file, addr);
|
||||
|
||||
if (unspec == UNSPEC_HW0_PCREL
|
||||
|| unspec == UNSPEC_HW1_LAST_PCREL)
|
||||
|| unspec == UNSPEC_HW1_PCREL
|
||||
|| unspec == UNSPEC_HW1_LAST_PCREL
|
||||
|| unspec == UNSPEC_HW2_LAST_PCREL
|
||||
|| unspec == UNSPEC_HW0_PLT_PCREL
|
||||
|| unspec == UNSPEC_HW1_PLT_PCREL
|
||||
|| unspec == UNSPEC_HW1_LAST_PLT_PCREL
|
||||
|| unspec == UNSPEC_HW2_LAST_PLT_PCREL)
|
||||
{
|
||||
rtx addr2 = XVECEXP (XEXP (x, 0), 0, 1);
|
||||
fputs (" - " , file);
|
||||
|
@ -31,6 +31,8 @@
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#include "config/tilegx/tilegx-opts.h"
|
||||
|
||||
|
||||
/* Target CPU builtins. */
|
||||
#define TARGET_CPU_CPP_BUILTINS() \
|
||||
@ -480,6 +482,19 @@ enum reg_class
|
||||
assemble_name ((FILE), (NAME)), \
|
||||
fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED)))
|
||||
|
||||
#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
|
||||
static void __attribute__((__used__)) \
|
||||
call_ ## FUNC (void) \
|
||||
{ \
|
||||
asm (SECTION_OP); \
|
||||
asm ("{ moveli r0, hw2_last(" #FUNC " - . - 8); lnk r1 }\n"); \
|
||||
asm ("shl16insli r0, r0, hw1(" #FUNC " - .)\n"); \
|
||||
asm ("shl16insli r0, r0, hw0(" #FUNC " - . + 8)\n"); \
|
||||
asm ("add r0, r1, r0\n"); \
|
||||
asm ("jalr r0\n"); \
|
||||
asm (TEXT_SECTION_ASM_OP); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define INIT_EXPANDERS tilegx_init_expanders ()
|
||||
|
@ -150,42 +150,43 @@
|
||||
|
||||
;; Insns generating difference of two labels
|
||||
(UNSPEC_MOV_PCREL_STEP3 204)
|
||||
(UNSPEC_MOV_LARGE_PCREL_STEP4 205)
|
||||
|
||||
;; Latency specifying loads.
|
||||
(UNSPEC_LATENCY_L2 205)
|
||||
(UNSPEC_LATENCY_MISS 206)
|
||||
(UNSPEC_LATENCY_L2 206)
|
||||
(UNSPEC_LATENCY_MISS 207)
|
||||
|
||||
;; A pseudo-op that prevents network operations from being ordered.
|
||||
(UNSPEC_NETWORK_BARRIER 207)
|
||||
(UNSPEC_NETWORK_BARRIER 208)
|
||||
|
||||
;; Operations that access network registers.
|
||||
(UNSPEC_NETWORK_RECEIVE 208)
|
||||
(UNSPEC_NETWORK_SEND 209)
|
||||
(UNSPEC_NETWORK_RECEIVE 209)
|
||||
(UNSPEC_NETWORK_SEND 210)
|
||||
|
||||
;; Stack protector operations
|
||||
(UNSPEC_SP_SET 210)
|
||||
(UNSPEC_SP_TEST 211)
|
||||
(UNSPEC_SP_SET 211)
|
||||
(UNSPEC_SP_TEST 212)
|
||||
|
||||
;; This is used to move a value to a SPR.
|
||||
(UNSPEC_SPR_MOVE 212)
|
||||
(UNSPEC_SPR_MOVE 213)
|
||||
|
||||
;; A call to __tls_get_addr
|
||||
(UNSPEC_TLS_GD_CALL 213)
|
||||
(UNSPEC_TLS_GD_CALL 214)
|
||||
|
||||
;; An opaque TLS "add" operation for TLS general dynamic model
|
||||
;; access.
|
||||
(UNSPEC_TLS_GD_ADD 214)
|
||||
(UNSPEC_TLS_GD_ADD 215)
|
||||
|
||||
;; An opaque TLS "load" operation for TLS initial exec model access.
|
||||
(UNSPEC_TLS_IE_LOAD 215)
|
||||
(UNSPEC_TLS_IE_LOAD 216)
|
||||
|
||||
;; An opaque TLS "add" operation for TLS access.
|
||||
(UNSPEC_TLS_ADD 216)
|
||||
(UNSPEC_TLS_ADD 217)
|
||||
|
||||
;; Atomics
|
||||
(UNSPEC_ATOMIC 217)
|
||||
(UNSPEC_CMPXCHG 218)
|
||||
(UNSPEC_XCHG 219)
|
||||
(UNSPEC_ATOMIC 218)
|
||||
(UNSPEC_CMPXCHG 219)
|
||||
(UNSPEC_XCHG 220)
|
||||
|
||||
;;
|
||||
;; The following are operands.
|
||||
@ -199,24 +200,32 @@
|
||||
(UNSPEC_HW2_LAST 306)
|
||||
|
||||
(UNSPEC_HW0_PCREL 307)
|
||||
(UNSPEC_HW1_LAST_PCREL 308)
|
||||
(UNSPEC_HW1_PCREL 308)
|
||||
(UNSPEC_HW1_LAST_PCREL 309)
|
||||
(UNSPEC_HW2_LAST_PCREL 310)
|
||||
|
||||
(UNSPEC_HW0_GOT 309)
|
||||
(UNSPEC_HW0_LAST_GOT 310)
|
||||
(UNSPEC_HW1_LAST_GOT 311)
|
||||
(UNSPEC_HW0_GOT 311)
|
||||
(UNSPEC_HW0_LAST_GOT 312)
|
||||
(UNSPEC_HW1_LAST_GOT 313)
|
||||
|
||||
(UNSPEC_HW0_TLS_GD 312)
|
||||
(UNSPEC_HW1_LAST_TLS_GD 313)
|
||||
(UNSPEC_HW0_TLS_GD 314)
|
||||
(UNSPEC_HW1_LAST_TLS_GD 315)
|
||||
|
||||
(UNSPEC_HW0_TLS_IE 314)
|
||||
(UNSPEC_HW1_LAST_TLS_IE 315)
|
||||
(UNSPEC_HW0_TLS_IE 316)
|
||||
(UNSPEC_HW1_LAST_TLS_IE 317)
|
||||
|
||||
(UNSPEC_HW0_TLS_LE 316)
|
||||
(UNSPEC_HW1_LAST_TLS_LE 317)
|
||||
(UNSPEC_HW0_TLS_LE 318)
|
||||
(UNSPEC_HW1_LAST_TLS_LE 319)
|
||||
|
||||
(UNSPEC_HW0_PLT_PCREL 320)
|
||||
(UNSPEC_HW1_PLT_PCREL 321)
|
||||
|
||||
(UNSPEC_HW1_LAST_PLT_PCREL 322)
|
||||
(UNSPEC_HW2_LAST_PLT_PCREL 323)
|
||||
|
||||
;; This is used to wrap around the addresses of non-temporal load/store
|
||||
;; intrinsics.
|
||||
(UNSPEC_NON_TEMPORAL 318)
|
||||
(UNSPEC_NON_TEMPORAL 324)
|
||||
])
|
||||
|
||||
;; Mark the last instruction of various latencies, used to
|
||||
@ -885,15 +894,15 @@
|
||||
;; Addresses
|
||||
;;
|
||||
|
||||
;; First step of the 3-insn sequence to materialize a symbolic
|
||||
;; address.
|
||||
;; The next three patterns are used to to materialize a position
|
||||
;; independent address by adding the difference of two labels to a base
|
||||
;; label in the text segment, assuming that the difference fits in 32
|
||||
;; signed bits.
|
||||
(define_expand "mov_address_step1"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(const:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
|
||||
UNSPEC_HW2_LAST)))])
|
||||
|
||||
;; Second step of the 3-insn sequence to materialize a symbolic
|
||||
;; address.
|
||||
(define_expand "mov_address_step2"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(unspec:DI
|
||||
@ -902,8 +911,6 @@
|
||||
UNSPEC_HW1))]
|
||||
UNSPEC_INSN_ADDR_SHL16INSLI))])
|
||||
|
||||
;; Third step of the 3-insn sequence to materialize a symbolic
|
||||
;; address.
|
||||
(define_expand "mov_address_step3"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(unspec:DI
|
||||
@ -988,6 +995,106 @@
|
||||
"flag_pic"
|
||||
"add<x>\t%0, %r1, %r2")
|
||||
|
||||
;; The next three patterns are used to to materialize a position
|
||||
;; independent 64-bit address by adding the difference of two labels to
|
||||
;; a base label in the text segment, without any limitation on the size
|
||||
;; of the difference.
|
||||
(define_expand "mov_large_pcrel_step1"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(const:DI (unspec:DI
|
||||
[(match_operand:DI 1 "symbolic_operand" "")
|
||||
(match_operand:DI 2 "symbolic_operand" "")]
|
||||
UNSPEC_HW2_LAST_PCREL)))]
|
||||
"flag_pic")
|
||||
|
||||
(define_expand "mov_large_pcrel_step2"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(unspec:DI
|
||||
[(match_operand:DI 1 "reg_or_0_operand" "")
|
||||
(const:DI
|
||||
(unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
|
||||
(match_operand:DI 3 "symbolic_operand" "")]
|
||||
UNSPEC_HW1_PCREL))]
|
||||
UNSPEC_INSN_ADDR_SHL16INSLI))]
|
||||
"flag_pic")
|
||||
|
||||
;; Note: step 3 is same as move_pcrel_step2.
|
||||
(define_expand "mov_large_pcrel_step3"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(unspec:DI
|
||||
[(match_operand:DI 1 "reg_or_0_operand" "")
|
||||
(const:DI
|
||||
(unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
|
||||
(match_operand:DI 3 "symbolic_operand" "")]
|
||||
UNSPEC_HW0_PCREL))]
|
||||
UNSPEC_INSN_ADDR_SHL16INSLI))]
|
||||
"flag_pic")
|
||||
|
||||
(define_insn "mov_large_pcrel_step4"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rO")
|
||||
(match_operand:DI 2 "reg_or_0_operand" "rO")
|
||||
(match_operand:DI 3 "symbolic_operand" "in")
|
||||
(match_operand:DI 4 "symbolic_operand" "in")]
|
||||
UNSPEC_MOV_LARGE_PCREL_STEP4))]
|
||||
"flag_pic"
|
||||
"add\t%0, %r1, %r2")
|
||||
|
||||
;; The next three patterns are used to materialize a position
|
||||
;; independent 64-bit plt address by adding the difference of two
|
||||
;; labels to a base label in the text segment.
|
||||
(define_expand "mov_plt_pcrel_step1"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(const:DI (unspec:DI
|
||||
[(match_operand:DI 1 "symbolic_operand" "")
|
||||
(match_operand:DI 2 "symbolic_operand" "")]
|
||||
UNSPEC_HW2_LAST_PLT_PCREL)))]
|
||||
"flag_pic")
|
||||
|
||||
(define_expand "mov_plt_pcrel_step2"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(unspec:DI
|
||||
[(match_operand:DI 1 "reg_or_0_operand" "")
|
||||
(const:DI
|
||||
(unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
|
||||
(match_operand:DI 3 "symbolic_operand" "")]
|
||||
UNSPEC_HW1_PLT_PCREL))]
|
||||
UNSPEC_INSN_ADDR_SHL16INSLI))]
|
||||
"flag_pic")
|
||||
|
||||
(define_expand "mov_plt_pcrel_step3"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(unspec:DI
|
||||
[(match_operand:DI 1 "reg_or_0_operand" "")
|
||||
(const:DI
|
||||
(unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
|
||||
(match_operand:DI 3 "symbolic_operand" "")]
|
||||
UNSPEC_HW0_PLT_PCREL))]
|
||||
UNSPEC_INSN_ADDR_SHL16INSLI))]
|
||||
"flag_pic")
|
||||
|
||||
;; The next two patterns are used to materialize a position independent
|
||||
;; 32-bit plt address by adding the difference of two labels to a base
|
||||
;; label in the text segment.
|
||||
(define_expand "mov_plt_pcrel_step1_32bit"
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(const:SI (unspec:SI
|
||||
[(match_operand:SI 1 "symbolic_operand" "")
|
||||
(match_operand:SI 2 "symbolic_operand" "")]
|
||||
UNSPEC_HW1_LAST_PLT_PCREL)))]
|
||||
"flag_pic")
|
||||
|
||||
(define_expand "mov_plt_pcrel_step2_32bit"
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(unspec:SI
|
||||
[(match_operand:SI 1 "reg_or_0_operand" "")
|
||||
(const:SI
|
||||
(unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
|
||||
(match_operand:SI 3 "symbolic_operand" "")]
|
||||
UNSPEC_HW0_PLT_PCREL))]
|
||||
UNSPEC_INSN_ADDR_SHL16INSLI))]
|
||||
"flag_pic")
|
||||
|
||||
(define_expand "add_got16<bitsuffix>"
|
||||
[(set (match_operand:I48MODE 0 "register_operand" "")
|
||||
(plus:I48MODE
|
||||
@ -2300,7 +2407,29 @@
|
||||
(use (reg:DI 54))
|
||||
(clobber (reg:DI 55))])]
|
||||
""
|
||||
"")
|
||||
{
|
||||
rtx orig_addr = XEXP (operands[0], 0);
|
||||
rtx addr;
|
||||
if (GET_CODE (orig_addr) == SYMBOL_REF)
|
||||
{
|
||||
if (tilegx_cmodel == CM_LARGE)
|
||||
{
|
||||
addr = gen_reg_rtx (Pmode);
|
||||
tilegx_expand_set_const64 (addr, orig_addr);
|
||||
operands[0] = gen_rtx_MEM (DImode, addr);
|
||||
}
|
||||
else if (tilegx_cmodel == CM_LARGE_PIC)
|
||||
{
|
||||
crtl->uses_pic_offset_table = 1;
|
||||
addr = gen_reg_rtx (Pmode);
|
||||
if (SYMBOL_REF_LOCAL_P (orig_addr))
|
||||
tilegx_compute_pcrel_address (addr, orig_addr);
|
||||
else
|
||||
tilegx_compute_pcrel_plt_address (addr, orig_addr);
|
||||
operands[0] = gen_rtx_MEM (DImode, addr);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
(define_insn "*call_insn"
|
||||
[(call (mem:DI (match_operand:I48MODE 0 "call_address_operand" "rO,i"))
|
||||
@ -2319,7 +2448,30 @@
|
||||
(match_operand 2 "" "")))
|
||||
(use (reg:DI 54))
|
||||
(clobber (reg:DI 55))])]
|
||||
"")
|
||||
""
|
||||
{
|
||||
rtx orig_addr = XEXP (operands[1], 0);
|
||||
rtx addr;
|
||||
if (GET_CODE (orig_addr) == SYMBOL_REF)
|
||||
{
|
||||
if (tilegx_cmodel == CM_LARGE)
|
||||
{
|
||||
addr = gen_reg_rtx (Pmode);
|
||||
tilegx_expand_set_const64 (addr, orig_addr);
|
||||
operands[1] = gen_rtx_MEM (DImode, addr);
|
||||
}
|
||||
else if (tilegx_cmodel == CM_LARGE_PIC)
|
||||
{
|
||||
crtl->uses_pic_offset_table = 1;
|
||||
addr = gen_reg_rtx (Pmode);
|
||||
if (SYMBOL_REF_LOCAL_P (orig_addr))
|
||||
tilegx_compute_pcrel_address (addr, orig_addr);
|
||||
else
|
||||
tilegx_compute_pcrel_plt_address (addr, orig_addr);
|
||||
operands[1] = gen_rtx_MEM (DImode, addr);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
(define_insn "*call_value_insn"
|
||||
[(set (match_operand 0 "register_operand" "=r,r")
|
||||
|
@ -19,6 +19,9 @@
|
||||
; along with GCC; see the file COPYING3. If not see
|
||||
; <http://www.gnu.org/licenses/>.
|
||||
|
||||
HeaderInclude
|
||||
config/tilegx/tilegx-opts.h
|
||||
|
||||
mcpu=
|
||||
Target RejectNegative Joined Enum(tilegx_cpu) Var(tilegx_cpu) Init(0)
|
||||
-mcpu=CPU Use features of and schedule code for given CPU
|
||||
@ -38,3 +41,16 @@ m64
|
||||
Target Report RejectNegative Negative(m32) InverseMask(32BIT, 64BIT)
|
||||
Compile with 64 bit longs and pointers.
|
||||
|
||||
mcmodel=
|
||||
Target RejectNegative Joined Enum(cmodel) Var(tilegx_cmodel) Init(CM_SMALL)
|
||||
Use given TILE-Gx code model
|
||||
|
||||
Enum
|
||||
Name(cmodel) Type(enum cmodel)
|
||||
Known code models (for use with the -mcmodel= option):
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(small) Value(CM_SMALL)
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(large) Value(CM_LARGE)
|
||||
|
@ -929,7 +929,7 @@ See RS/6000 and PowerPC Options.
|
||||
@gccoptlist{-Qy -Qn -YP,@var{paths} -Ym,@var{dir}}
|
||||
|
||||
@emph{TILE-Gx Options}
|
||||
@gccoptlist{-mcpu=CPU -m32 -m64}
|
||||
@gccoptlist{-mcpu=CPU -m32 -m64 -mcmodel=@var{code-model}}
|
||||
|
||||
@emph{TILEPro Options}
|
||||
@gccoptlist{-mcpu=CPU -m32}
|
||||
@ -18937,6 +18937,17 @@ The assembler uses this option.
|
||||
These @samp{-m} options are supported on the TILE-Gx:
|
||||
|
||||
@table @gcctabopt
|
||||
@item -mcmodel=small
|
||||
@opindex mcmodel=small
|
||||
Generate code for the small model. Distance for direct calls is
|
||||
limited to 500M in either direction. PC-relative addresses are 32
|
||||
bits. Absolute addresses support the full address range.
|
||||
|
||||
@item -mcmodel=large
|
||||
@opindex mcmodel=large
|
||||
Generate code for the large model. There is no limiation on call
|
||||
distance, pc-relative addresses, or absolute addresses.
|
||||
|
||||
@item -mcpu=@var{name}
|
||||
@opindex mcpu
|
||||
Selects the type of CPU to be targeted. Currently the only supported
|
||||
|
Loading…
Reference in New Issue
Block a user