LoongArch: Add support code model extreme.
Use five instructions to calculate a signed 64-bit offset relative to the pc. gcc/ChangeLog: * config/loongarch/loongarch-opts.cc: Allow cmodel to be extreme. * config/loongarch/loongarch.cc (loongarch_call_tls_get_addr): Add extreme support for TLS GD and LD types. (loongarch_legitimize_tls_address): Add extreme support for TLS LE and IE. (loongarch_split_symbol): When compiling with -mcmodel=extreme, the symbol address will be obtained through five instructions. (loongarch_print_operand_reloc): Add support. (loongarch_print_operand): Add support. (loongarch_print_operand_address): Add support. (loongarch_option_override_internal): Set '-mcmodel=extreme' option incompatible with '-mno-explicit-relocs'. * config/loongarch/loongarch.md (@lui_l_hi20<mode>): Loads bits 12-31 of data into registers. (lui_h_lo20): Load bits 32-51 of the data and spell bits 0-31 of the source register. (lui_h_hi12): Load bits 52-63 of the data and spell bits 0-51 of the source register. * config/loongarch/predicates.md: Symbols need to be decomposed when defining the macro TARGET_CMODEL_EXTREME * doc/invoke.texi: Modify the description information of cmodel in the document. Document -W[no-]extreme-plt. gcc/testsuite/ChangeLog: * gcc.target/loongarch/func-call-1.c: Add option '-mcmodel=normal'. * gcc.target/loongarch/func-call-2.c: Likewise. * gcc.target/loongarch/func-call-3.c: Likewise. * gcc.target/loongarch/func-call-4.c: Likewise. * gcc.target/loongarch/func-call-5.c: Likewise. * gcc.target/loongarch/func-call-6.c: Likewise. * gcc.target/loongarch/func-call-7.c: Likewise. * gcc.target/loongarch/func-call-8.c: Likewise. * gcc.target/loongarch/relocs-symbol-noaddend.c: Likewise. * gcc.target/loongarch/func-call-extreme-1.c: New test. * gcc.target/loongarch/func-call-extreme-2.c: New test.
This commit is contained in:
parent
e9dd050e0c
commit
6945814526
16 changed files with 318 additions and 82 deletions
|
@ -376,14 +376,13 @@ fallback:
|
|||
|
||||
/* 5. Target code model */
|
||||
t.cmodel = constrained.cmodel ? opt_cmodel : CMODEL_NORMAL;
|
||||
if (t.cmodel != CMODEL_NORMAL)
|
||||
if (t.cmodel != CMODEL_NORMAL && t.cmodel != CMODEL_EXTREME)
|
||||
{
|
||||
warning (0, "%qs is not supported, now cmodel is set to %qs",
|
||||
loongarch_cmodel_strings[t.cmodel], "normal");
|
||||
t.cmodel = CMODEL_NORMAL;
|
||||
}
|
||||
|
||||
|
||||
/* Cleanup and return. */
|
||||
obstack_free (&msg_obstack, NULL);
|
||||
*target = t;
|
||||
|
|
|
@ -2436,7 +2436,19 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0)
|
|||
/* Split tls symbol to high and low. */
|
||||
rtx high = gen_rtx_HIGH (Pmode, copy_rtx (loc));
|
||||
high = loongarch_force_temporary (tmp, high);
|
||||
emit_insn (gen_tls_low (Pmode, a0, high, loc));
|
||||
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
{
|
||||
gcc_assert (TARGET_EXPLICIT_RELOCS);
|
||||
|
||||
rtx tmp1 = gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_tls_low (Pmode, tmp1, gen_rtx_REG (Pmode, 0), loc));
|
||||
emit_insn (gen_lui_h_lo20 (tmp1, tmp1, loc));
|
||||
emit_insn (gen_lui_h_hi12 (tmp1, tmp1, loc));
|
||||
emit_move_insn (a0, gen_rtx_PLUS (Pmode, high, tmp1));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_tls_low (Pmode, a0, high, loc));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2449,14 +2461,44 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0)
|
|||
}
|
||||
|
||||
if (flag_plt)
|
||||
insn = emit_call_insn (gen_call_value_internal (v0, loongarch_tls_symbol,
|
||||
insn = emit_call_insn (gen_call_value_internal (v0,
|
||||
loongarch_tls_symbol,
|
||||
const0_rtx));
|
||||
else
|
||||
{
|
||||
rtx dest = gen_reg_rtx (Pmode);
|
||||
rtx high = gen_reg_rtx (Pmode);
|
||||
loongarch_emit_move (high, gen_rtx_HIGH (Pmode, loongarch_tls_symbol));
|
||||
emit_insn (gen_ld_from_got (Pmode, dest, high, loongarch_tls_symbol));
|
||||
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
{
|
||||
gcc_assert (TARGET_EXPLICIT_RELOCS);
|
||||
|
||||
rtx tmp1 = gen_reg_rtx (Pmode);
|
||||
rtx high = gen_reg_rtx (Pmode);
|
||||
|
||||
loongarch_emit_move (high,
|
||||
gen_rtx_HIGH (Pmode, loongarch_tls_symbol));
|
||||
loongarch_emit_move (tmp1, gen_rtx_LO_SUM (Pmode,
|
||||
gen_rtx_REG (Pmode, 0),
|
||||
loongarch_tls_symbol));
|
||||
emit_insn (gen_lui_h_lo20 (tmp1, tmp1, loongarch_tls_symbol));
|
||||
emit_insn (gen_lui_h_hi12 (tmp1, tmp1, loongarch_tls_symbol));
|
||||
loongarch_emit_move (dest,
|
||||
gen_rtx_MEM (Pmode,
|
||||
gen_rtx_PLUS (Pmode, high, tmp1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TARGET_EXPLICIT_RELOCS)
|
||||
{
|
||||
rtx high = gen_reg_rtx (Pmode);
|
||||
loongarch_emit_move (high,
|
||||
gen_rtx_HIGH (Pmode, loongarch_tls_symbol));
|
||||
emit_insn (gen_ld_from_got (Pmode, dest, high,
|
||||
loongarch_tls_symbol));
|
||||
}
|
||||
else
|
||||
loongarch_emit_move (dest, loongarch_tls_symbol);
|
||||
}
|
||||
insn = emit_call_insn (gen_call_value_internal (v0, dest, const0_rtx));
|
||||
}
|
||||
|
||||
|
@ -2508,7 +2550,23 @@ loongarch_legitimize_tls_address (rtx loc)
|
|||
tmp3 = gen_reg_rtx (Pmode);
|
||||
rtx high = gen_rtx_HIGH (Pmode, copy_rtx (tmp2));
|
||||
high = loongarch_force_temporary (tmp3, high);
|
||||
emit_insn (gen_ld_from_got (Pmode, tmp1, high, tmp2));
|
||||
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
{
|
||||
gcc_assert (TARGET_EXPLICIT_RELOCS);
|
||||
|
||||
rtx tmp3 = gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_tls_low (Pmode, tmp3,
|
||||
gen_rtx_REG (Pmode, 0), tmp2));
|
||||
emit_insn (gen_lui_h_lo20 (tmp3, tmp3, tmp2));
|
||||
emit_insn (gen_lui_h_hi12 (tmp3, tmp3, tmp2));
|
||||
emit_move_insn (tmp1,
|
||||
gen_rtx_MEM (Pmode,
|
||||
gen_rtx_PLUS (Pmode,
|
||||
high, tmp3)));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_ld_from_got (Pmode, tmp1, high, tmp2));
|
||||
}
|
||||
else
|
||||
emit_insn (loongarch_got_load_tls_ie (tmp1, loc));
|
||||
|
@ -2530,11 +2588,18 @@ loongarch_legitimize_tls_address (rtx loc)
|
|||
rtx high = gen_rtx_HIGH (Pmode, copy_rtx (tmp2));
|
||||
high = loongarch_force_temporary (tmp3, high);
|
||||
emit_insn (gen_ori_l_lo12 (Pmode, tmp1, high, tmp2));
|
||||
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
{
|
||||
gcc_assert (TARGET_EXPLICIT_RELOCS);
|
||||
|
||||
emit_insn (gen_lui_h_lo20 (tmp1, tmp1, tmp2));
|
||||
emit_insn (gen_lui_h_hi12 (tmp1, tmp1, tmp2));
|
||||
}
|
||||
}
|
||||
else
|
||||
emit_insn (loongarch_got_load_tls_le (tmp1, loc));
|
||||
emit_insn (gen_add3_insn (dest, tmp1, tp));
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2603,7 +2668,6 @@ bool
|
|||
loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out)
|
||||
{
|
||||
enum loongarch_symbol_type symbol_type;
|
||||
rtx high;
|
||||
|
||||
/* If build with '-mno-explicit-relocs', don't split symbol. */
|
||||
if (!TARGET_EXPLICIT_RELOCS)
|
||||
|
@ -2615,6 +2679,8 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out)
|
|||
|| !loongarch_split_symbol_type (symbol_type))
|
||||
return false;
|
||||
|
||||
rtx high, temp1 = NULL;
|
||||
|
||||
if (temp == NULL)
|
||||
temp = gen_reg_rtx (Pmode);
|
||||
|
||||
|
@ -2622,20 +2688,42 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out)
|
|||
high = gen_rtx_HIGH (Pmode, copy_rtx (addr));
|
||||
high = loongarch_force_temporary (temp, high);
|
||||
|
||||
if (TARGET_CMODEL_EXTREME && can_create_pseudo_p ())
|
||||
{
|
||||
gcc_assert (TARGET_EXPLICIT_RELOCS);
|
||||
|
||||
temp1 = gen_reg_rtx (Pmode);
|
||||
emit_move_insn (temp1, gen_rtx_LO_SUM (Pmode, gen_rtx_REG (Pmode, 0),
|
||||
addr));
|
||||
emit_insn (gen_lui_h_lo20 (temp1, temp1, addr));
|
||||
emit_insn (gen_lui_h_hi12 (temp1, temp1, addr));
|
||||
}
|
||||
|
||||
if (low_out)
|
||||
switch (symbol_type)
|
||||
{
|
||||
case SYMBOL_PCREL:
|
||||
*low_out = gen_rtx_LO_SUM (Pmode, high, addr);
|
||||
break;
|
||||
{
|
||||
if (TARGET_CMODEL_EXTREME && can_create_pseudo_p ())
|
||||
*low_out = gen_rtx_PLUS (Pmode, high, temp1);
|
||||
else
|
||||
*low_out = gen_rtx_LO_SUM (Pmode, high, addr);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYMBOL_GOT_DISP:
|
||||
/* SYMBOL_GOT_DISP symbols are loaded from the GOT. */
|
||||
{
|
||||
rtx low = gen_rtx_LO_SUM (Pmode, high, addr);
|
||||
rtx mem = gen_rtx_MEM (Pmode, low);
|
||||
*low_out = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, mem),
|
||||
UNSPEC_LOAD_FROM_GOT);
|
||||
if (TARGET_CMODEL_EXTREME && can_create_pseudo_p ())
|
||||
*low_out = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, high, temp1));
|
||||
else
|
||||
{
|
||||
rtx low = gen_rtx_LO_SUM (Pmode, high, addr);
|
||||
rtx mem = gen_rtx_MEM (Pmode, low);
|
||||
*low_out = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, mem),
|
||||
UNSPEC_LOAD_FROM_GOT);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4584,34 +4672,86 @@ loongarch_memmodel_needs_release_fence (enum memmodel model)
|
|||
in context CONTEXT. HI_RELOC indicates a high-part reloc. */
|
||||
|
||||
static void
|
||||
loongarch_print_operand_reloc (FILE *file, rtx op, bool hi_reloc)
|
||||
loongarch_print_operand_reloc (FILE *file, rtx op, bool hi64_part,
|
||||
bool hi_reloc)
|
||||
{
|
||||
const char *reloc;
|
||||
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
gcc_assert (TARGET_EXPLICIT_RELOCS);
|
||||
|
||||
switch (loongarch_classify_symbolic_expression (op))
|
||||
{
|
||||
case SYMBOL_PCREL:
|
||||
reloc = hi_reloc ? "%pc_hi20" : "%pc_lo12";
|
||||
if (hi64_part)
|
||||
{
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
reloc = hi_reloc ? "%pc64_hi12" : "%pc64_lo20";
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else
|
||||
reloc = hi_reloc ? "%pc_hi20" : "%pc_lo12";
|
||||
break;
|
||||
|
||||
case SYMBOL_GOT_DISP:
|
||||
reloc = hi_reloc ? "%got_pc_hi20" : "%got_pc_lo12";
|
||||
if (hi64_part)
|
||||
{
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
reloc = hi_reloc ? "%got64_pc_hi12" : "%got64_pc_lo20";
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else
|
||||
reloc = hi_reloc ? "%got_pc_hi20" : "%got_pc_lo12";
|
||||
break;
|
||||
|
||||
case SYMBOL_TLS_IE:
|
||||
reloc = hi_reloc ? "%ie_pc_hi20" : "%ie_pc_lo12";
|
||||
if (hi64_part)
|
||||
{
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
reloc = hi_reloc ? "%ie64_pc_hi12" : "%ie64_pc_lo20";
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else
|
||||
reloc = hi_reloc ? "%ie_pc_hi20" : "%ie_pc_lo12";
|
||||
break;
|
||||
|
||||
case SYMBOL_TLS_LE:
|
||||
reloc = hi_reloc ? "%le_hi20" : "%le_lo12";
|
||||
if (hi64_part)
|
||||
{
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
reloc = hi_reloc ? "%le64_hi12" : "%le64_lo20";
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else
|
||||
reloc = hi_reloc ? "%le_hi20" : "%le_lo12";
|
||||
break;
|
||||
|
||||
case SYMBOL_TLSGD:
|
||||
reloc = hi_reloc ? "%gd_pc_hi20" : "%got_pc_lo12";
|
||||
if (hi64_part)
|
||||
{
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
reloc = hi_reloc ? "%got64_pc_hi12" : "%got64_pc_lo20";
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else
|
||||
reloc = hi_reloc ? "%gd_pc_hi20" : "%got_pc_lo12";
|
||||
break;
|
||||
|
||||
case SYMBOL_TLSLDM:
|
||||
reloc = hi_reloc ? "%ld_pc_hi20" : "%got_pc_lo12";
|
||||
if (hi64_part)
|
||||
{
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
reloc = hi_reloc ? "%got64_pc_hi12" : "%got64_pc_lo20";
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else
|
||||
reloc = hi_reloc ? "%ld_pc_hi20" : "%got_pc_lo12";
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -4637,6 +4777,8 @@ loongarch_print_operand_reloc (FILE *file, rtx op, bool hi_reloc)
|
|||
'L' Print the low-part relocation associated with OP.
|
||||
'm' Print one less than CONST_INT OP in decimal.
|
||||
'N' Print the inverse of the integer branch condition for comparison OP.
|
||||
'r' Print address 12-31bit relocation associated with OP.
|
||||
'R' Print address 32-51bit relocation associated with OP.
|
||||
'T' Print 'f' for (eq:CC ...), 't' for (ne:CC ...),
|
||||
'z' for (eq:?I ...), 'n' for (ne:?I ...).
|
||||
't' Like 'T', but with the EQ/NE cases reversed
|
||||
|
@ -4694,7 +4836,13 @@ loongarch_print_operand (FILE *file, rtx op, int letter)
|
|||
case 'h':
|
||||
if (code == HIGH)
|
||||
op = XEXP (op, 0);
|
||||
loongarch_print_operand_reloc (file, op, true /* hi_reloc */);
|
||||
loongarch_print_operand_reloc (file, op, false /* hi64_part */,
|
||||
true /* hi_reloc */);
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
loongarch_print_operand_reloc (file, op, true /* hi64_part */,
|
||||
true /* hi_reloc */);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
|
@ -4703,7 +4851,8 @@ loongarch_print_operand (FILE *file, rtx op, int letter)
|
|||
break;
|
||||
|
||||
case 'L':
|
||||
loongarch_print_operand_reloc (file, op, false /* lo_reloc */);
|
||||
loongarch_print_operand_reloc (file, op, false /* hi64_part*/,
|
||||
false /* lo_reloc */);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
|
@ -4718,6 +4867,16 @@ loongarch_print_operand (FILE *file, rtx op, int letter)
|
|||
letter);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
loongarch_print_operand_reloc (file, op, false /* hi64_part */,
|
||||
true /* lo_reloc */);
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
loongarch_print_operand_reloc (file, op, true /* hi64_part */,
|
||||
false /* lo_reloc */);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
{
|
||||
|
@ -4848,7 +5007,8 @@ loongarch_print_operand_address (FILE *file, machine_mode /* mode */, rtx x)
|
|||
|
||||
case ADDRESS_LO_SUM:
|
||||
fprintf (file, "%s,", reg_names[REGNO (addr.reg)]);
|
||||
loongarch_print_operand_reloc (file, addr.offset, false /* hi_reloc */);
|
||||
loongarch_print_operand_reloc (file, addr.offset, false /* hi64_part */,
|
||||
false /* hi_reloc */);
|
||||
return;
|
||||
|
||||
case ADDRESS_CONST_INT:
|
||||
|
@ -5821,13 +5981,21 @@ loongarch_option_override_internal (struct gcc_options *opts)
|
|||
|
||||
switch (la_target.cmodel)
|
||||
{
|
||||
case CMODEL_TINY_STATIC:
|
||||
case CMODEL_EXTREME:
|
||||
if (!TARGET_EXPLICIT_RELOCS)
|
||||
error ("code model %qs needs %s",
|
||||
"extreme", "-mexplicit-relocs");
|
||||
|
||||
if (opts->x_flag_plt)
|
||||
error ("code model %qs and %qs not support %s mode",
|
||||
"tiny-static", "extreme", "plt");
|
||||
{
|
||||
if (global_options_set.x_flag_plt)
|
||||
error ("code model %qs is not compatible with %s",
|
||||
"extreme", "-fplt");
|
||||
opts->x_flag_plt = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMODEL_TINY_STATIC:
|
||||
case CMODEL_NORMAL:
|
||||
case CMODEL_TINY:
|
||||
case CMODEL_LARGE:
|
||||
|
|
|
@ -60,6 +60,9 @@
|
|||
|
||||
UNSPEC_LOAD_FROM_GOT
|
||||
UNSPEC_ORI_L_LO12
|
||||
UNSPEC_LUI_L_HI20
|
||||
UNSPEC_LUI_H_LO20
|
||||
UNSPEC_LUI_H_HI12
|
||||
UNSPEC_TLS_LOW
|
||||
])
|
||||
|
||||
|
@ -1934,16 +1937,45 @@
|
|||
[(set_attr "type" "move")]
|
||||
)
|
||||
|
||||
(define_insn "@lui_l_hi20<mode>"
|
||||
[(set (match_operand:P 0 "register_operand" "=r")
|
||||
(unspec:P [(match_operand:P 1 "symbolic_operand")]
|
||||
UNSPEC_LUI_L_HI20))]
|
||||
""
|
||||
"lu12i.w\t%0,%r1"
|
||||
[(set_attr "type" "move")]
|
||||
)
|
||||
|
||||
(define_insn "@ori_l_lo12<mode>"
|
||||
[(set (match_operand:P 0 "register_operand" "=r")
|
||||
(unspec:P [(match_operand:P 1 "register_operand" "r")
|
||||
(match_operand:P 2 "symbolic_operand")]
|
||||
(match_operand:P 2 "symbolic_operand")]
|
||||
UNSPEC_ORI_L_LO12))]
|
||||
""
|
||||
"ori\t%0,%1,%L2"
|
||||
[(set_attr "type" "move")]
|
||||
)
|
||||
|
||||
(define_insn "lui_h_lo20"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(unspec:DI [(match_operand:DI 1 "register_operand" "0")
|
||||
(match_operand:DI 2 "symbolic_operand")]
|
||||
UNSPEC_LUI_H_LO20))]
|
||||
"TARGET_64BIT"
|
||||
"lu32i.d\t%0,%R2"
|
||||
[(set_attr "type" "move")]
|
||||
)
|
||||
|
||||
(define_insn "lui_h_hi12"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
|
||||
(match_operand:DI 2 "symbolic_operand")]
|
||||
UNSPEC_LUI_H_HI12))]
|
||||
"TARGET_64BIT"
|
||||
"lu52i.d\t%0,%1,%H2"
|
||||
[(set_attr "type" "move")]
|
||||
)
|
||||
|
||||
;; Convert floating-point numbers to integers
|
||||
(define_insn "frint_<fmt>"
|
||||
[(set (match_operand:ANYF 0 "register_operand" "=f")
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
(match_code "const,symbol_ref,label_ref")
|
||||
{
|
||||
/* Split symbol to high and low if return false.
|
||||
If defined TARGET_CMODEL_LARGE, all symbol would be splited,
|
||||
If defined TARGET_CMODEL_EXTREME, all symbol would be splited,
|
||||
else if offset is not zero, the symbol would be splited. */
|
||||
|
||||
enum loongarch_symbol_type symbol_type;
|
||||
|
@ -126,10 +126,13 @@
|
|||
switch (symbol_type)
|
||||
{
|
||||
case SYMBOL_PCREL:
|
||||
return 1;
|
||||
if (TARGET_CMODEL_EXTREME)
|
||||
return false;
|
||||
else
|
||||
return 1;
|
||||
|
||||
case SYMBOL_GOT_DISP:
|
||||
if (TARGET_CMODEL_LARGE || !flag_plt)
|
||||
if (TARGET_CMODEL_EXTREME || !flag_plt)
|
||||
return false;
|
||||
else
|
||||
return 1;
|
||||
|
|
|
@ -1021,6 +1021,7 @@ Objective-C and Objective-C++ Dialects}.
|
|||
-mcond-move-float -mno-cond-move-float @gol
|
||||
-memcpy -mno-memcpy -mstrict-align -mno-strict-align @gol
|
||||
-mmax-inline-memcpy-size=@var{n} @gol
|
||||
-mexplicit-relocs -mno-explicit-relocs @gol
|
||||
-mcmodel=@var{code-model}}
|
||||
|
||||
@emph{M32R/D Options}
|
||||
|
@ -25090,50 +25091,19 @@ less than or equal to @var{n} bytes. The default value of @var{n} is 1024.
|
|||
@item -mcmodel=@var{code-model}
|
||||
Set the code model to one of:
|
||||
@table @samp
|
||||
@item tiny-static
|
||||
@itemize @bullet
|
||||
@item
|
||||
local symbol and global strong symbol: The data section must be within +/-2MiB addressing space.
|
||||
The text section must be within +/-128MiB addressing space.
|
||||
@item
|
||||
global weak symbol: The got table must be within +/-2GiB addressing space.
|
||||
@end itemize
|
||||
|
||||
@item tiny
|
||||
@itemize @bullet
|
||||
@item
|
||||
local symbol: The data section must be within +/-2MiB addressing space.
|
||||
The text section must be within +/-128MiB
|
||||
addressing space.
|
||||
@item
|
||||
global symbol: The got table must be within +/-2GiB addressing space.
|
||||
@end itemize
|
||||
@item tiny-static (Not implemented yet)
|
||||
@item tiny (Not implemented yet)
|
||||
|
||||
@item normal
|
||||
@itemize @bullet
|
||||
@item
|
||||
local symbol: The data section must be within +/-2GiB addressing space.
|
||||
The text section must be within +/-128MiB addressing space.
|
||||
@item
|
||||
global symbol: The got table must be within +/-2GiB addressing space.
|
||||
@end itemize
|
||||
The text segment must be within 128MB addressing space. The data segment must
|
||||
be within 2GB addressing space.
|
||||
|
||||
@item large
|
||||
@itemize @bullet
|
||||
@item
|
||||
local symbol: The data section must be within +/-2GiB addressing space.
|
||||
The text section must be within +/-128GiB addressing space.
|
||||
@item
|
||||
global symbol: The got table must be within +/-2GiB addressing space.
|
||||
@end itemize
|
||||
@item large (Not implemented yet)
|
||||
|
||||
@item extreme(Not implemented yet)
|
||||
@itemize @bullet
|
||||
@item
|
||||
local symbol: The data and text section must be within +/-8EiB addressing space.
|
||||
@item
|
||||
global symbol: The data got table must be within +/-8EiB addressing space.
|
||||
@end itemize
|
||||
@item extreme
|
||||
This mode does not limit the size of the code segment and data segment.
|
||||
The @option{-mcmodel=extreme} option is incompatible with @option{-fplt} and
|
||||
@option{-mno-explicit-relocs}.
|
||||
@end table
|
||||
The default code model is @code{normal}.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mno-explicit-relocs" } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mno-explicit-relocs -mcmodel=normal" } */
|
||||
/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "test1:.*bl\t%plt\\(f\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mno-explicit-relocs" } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mno-explicit-relocs -mcmodel=normal" } */
|
||||
/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */
|
||||
/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mno-explicit-relocs" } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mno-explicit-relocs -mcmodel=normal" } */
|
||||
/* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */
|
||||
/* { dg-final { scan-assembler "test1:.*la\.global\t.*f\n\tjirl" } } */
|
||||
/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mno-explicit-relocs" } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mno-explicit-relocs -mcmodel=normal" } */
|
||||
/* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */
|
||||
/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */
|
||||
/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mexplicit-relocs" } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mexplicit-relocs -mcmodel=normal" } */
|
||||
/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "test1:.*bl\t%plt\\(f\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mexplicit-relocs" } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mexplicit-relocs -mcmodel=normal" } */
|
||||
/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */
|
||||
/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs" } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs -mcmodel=normal" } */
|
||||
/* { dg-final { scan-assembler "test:.*pcalau12i\t.*%got_pc_hi20\\(g\\)\n\tld\.d\t.*%got_pc_lo12\\(g\\)\n\tjirl" } } */
|
||||
/* { dg-final { scan-assembler "test1:.*pcalau12i\t.*%got_pc_hi20\\(f\\)\n\tld\.d\t.*%got_pc_lo12\\(f\\)\n\tjirl" } } */
|
||||
/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs" } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs -mcmodel=normal" } */
|
||||
/* { dg-final { scan-assembler "test:.*pcalau12i\t.*%got_pc_hi20\\(g\\)\n\tld\.d\t.*%got_pc_lo12\\(g\\)\n\tjirl" } } */
|
||||
/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */
|
||||
/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */
|
||||
|
|
32
gcc/testsuite/gcc.target/loongarch/func-call-extreme-1.c
Normal file
32
gcc/testsuite/gcc.target/loongarch/func-call-extreme-1.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs -mcmodel=extreme" } */
|
||||
/* { dg-final { scan-assembler "test:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */
|
||||
/* { dg-final { scan-assembler "test1:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */
|
||||
/* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */
|
||||
|
||||
extern void g (void);
|
||||
void
|
||||
f (void)
|
||||
{}
|
||||
|
||||
static void
|
||||
l (void)
|
||||
{}
|
||||
|
||||
void
|
||||
test (void)
|
||||
{
|
||||
g ();
|
||||
}
|
||||
|
||||
void
|
||||
test1 (void)
|
||||
{
|
||||
f ();
|
||||
}
|
||||
|
||||
void
|
||||
test2 (void)
|
||||
{
|
||||
l ();
|
||||
}
|
32
gcc/testsuite/gcc.target/loongarch/func-call-extreme-2.c
Normal file
32
gcc/testsuite/gcc.target/loongarch/func-call-extreme-2.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs -mcmodel=extreme" } */
|
||||
/* { dg-final { scan-assembler "test:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */
|
||||
/* { dg-final { scan-assembler "test1:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */
|
||||
/* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */
|
||||
|
||||
extern void g (void);
|
||||
void
|
||||
f (void)
|
||||
{}
|
||||
|
||||
static void
|
||||
l (void)
|
||||
{}
|
||||
|
||||
void
|
||||
test (void)
|
||||
{
|
||||
g ();
|
||||
}
|
||||
|
||||
void
|
||||
test1 (void)
|
||||
{
|
||||
f ();
|
||||
}
|
||||
|
||||
void
|
||||
test2 (void)
|
||||
{
|
||||
l ();
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mabi=lp64d -mexplicit-relocs -fno-pic -O2" } */
|
||||
/* { dg-options "-mabi=lp64d -mexplicit-relocs -fno-pic -O2 -mcmodel=normal" } */
|
||||
/* { dg-final { scan-assembler "pcalau12i.*%pc_hi20\\(\.LANCHOR0\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "addi\.d.*%pc_lo12\\(\.LANCHOR0\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "ldptr.d\t\\\$r4,.*,0\n" } } */
|
||||
|
|
Loading…
Add table
Reference in a new issue