rtx addr = x;
rtx reg = gen_reg_rtx (Pmode);
rtx pat;
+ int relax_group_id = nds32_alloc_relax_group_id ();
if (GET_CODE (x) == LABEL_REF
|| (GET_CODE (x) == SYMBOL_REF
{
addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOTOFF);
addr = gen_rtx_CONST (SImode, addr);
- emit_insn (gen_sethi (reg, addr));
- emit_insn (gen_lo_sum (reg, reg, addr));
+ emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx);
}
else if (GET_CODE (x) == SYMBOL_REF)
{
addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOT);
addr = gen_rtx_CONST (SImode, addr);
- emit_insn (gen_sethi (reg, addr));
- emit_insn (gen_lo_sum (reg, reg, addr));
+ emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
x = gen_const_mem (SImode, gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
reg));
pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), UNSPEC_GOTOFF);
pat = gen_rtx_PLUS (Pmode, pat, op1);
pat = gen_rtx_CONST (Pmode, pat);
- emit_insn (gen_sethi (reg, pat));
- emit_insn (gen_lo_sum (reg, reg, pat));
+ emit_insn (gen_sym_got (reg, pat, GEN_INT (relax_group_id)));
x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx);
}
else if (GET_CODE (op0) == SYMBOL_REF
/* This is a constant offset from a @GOT symbol reference. */
addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, op0), UNSPEC_GOT);
addr = gen_rtx_CONST (SImode, addr);
- emit_insn (gen_sethi (reg, addr));
- emit_insn (gen_lo_sum (reg, reg, addr));
+ emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
+
addr = gen_const_mem (SImode, gen_rtx_PLUS (Pmode,
pic_offset_table_rtx,
reg));
rtx tmp_reg;
rtx tp_reg = gen_rtx_REG (Pmode, TP_REGNUM);
rtx pat, insns, reg0;
+ int relax_group_id = nds32_alloc_relax_group_id ();
if (GET_CODE (x) == SYMBOL_REF)
switch (SYMBOL_REF_TLS_MODEL (x))
reg0 = gen_rtx_REG (Pmode, 0);
/* If we can confirm all clobber reigsters, it doesn't have to use call
instruction. */
- insns = emit_call_insn (gen_tls_desc (pat, GEN_INT (0)));
+ insns = emit_call_insn (gen_tls_desc (pat, GEN_INT (relax_group_id)));
use_reg (&CALL_INSN_FUNCTION_USAGE (insns), pic_offset_table_rtx);
RTL_CONST_CALL_P (insns) = 1;
tmp_reg = gen_reg_rtx (SImode);
pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSIE);
tmp_reg = gen_reg_rtx (SImode);
pat = gen_rtx_CONST (SImode, pat);
- emit_insn (gen_tls_ie (tmp_reg, pat, GEN_INT (0)));
+ emit_insn (gen_tls_ie (tmp_reg, pat, GEN_INT (relax_group_id)));
if (flag_pic)
emit_use (pic_offset_table_rtx);
x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
tmp_reg = gen_reg_rtx (SImode);
pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSLE);
pat = gen_rtx_CONST (SImode, pat);
- emit_insn (gen_sethi (tmp_reg, pat));
- emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat));
+ emit_insn (gen_tls_le (tmp_reg, pat, GEN_INT (relax_group_id)));
x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
break;
pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, base), UNSPEC_TLSLE);
pat = gen_rtx_PLUS (SImode, pat, addend);
pat = gen_rtx_CONST (SImode, pat);
- emit_insn (gen_sethi (tmp_reg, pat));
- emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat));
+ emit_insn (gen_tls_le (tmp_reg, pat, GEN_INT (relax_group_id)));
x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
}
}
output_asm_insn (pattern, operands);
return "";
}
+
+const char *
+nds32_output_symrel (rtx *operands)
+{
+ char pattern[1000];
+
+ if (TARGET_RELAX_HINT)
+ snprintf (pattern, sizeof (pattern),
+ ".relax_hint %%2\n\tsethi %%0, hi20(%%1)\n\t"
+ ".relax_hint %%2\n\tori %%0, %%0, lo12(%%1)");
+ else
+ snprintf (pattern, sizeof (pattern),
+ "sethi %%0, hi20(%%1)\n\t"
+ "ori %%0, %%0, lo12(%%1)");
+
+ output_asm_insn (pattern, operands);
+ return "";
+}
lwi37 $rb, [(sym)]
swi37 $rc, [(sym)] */
+int
+nds32_alloc_relax_group_id ()
+{
+ return relax_group_id++;
+}
+
/* Return true if is load/store with REG addressing mode
and memory mode is SImode. */
static bool
return;
}
- group_id = GEN_INT (relax_group_id);
+ group_id = GEN_INT (nds32_alloc_relax_group_id ());
/* Insert .relax_* directive for sethi. */
emit_insn_before (gen_relax_group (group_id), sethi);
}
}
}
-
- relax_group_id++;
}
/* Convert relax group id in rtl. */
{
rtx pat = PATTERN (insn);
rtx unspec_relax_group = XEXP (XVECEXP (pat, 0, 1), 0);
+ int group_id = nds32_alloc_relax_group_id ();
while (GET_CODE (pat) != SET && GET_CODE (pat) == PARALLEL)
{
if (GET_CODE (unspec_relax_group) == UNSPEC
&& XINT (unspec_relax_group, 1) == UNSPEC_VOLATILE_RELAX_GROUP)
{
- XVECEXP (unspec_relax_group, 0, 0) = GEN_INT (relax_group_id);
+ XVECEXP (unspec_relax_group, 0, 0) = GEN_INT (group_id);
}
-
- relax_group_id++;
}
static bool
return;
}
- group_id = GEN_INT (relax_group_id);
+ group_id = GEN_INT (nds32_alloc_relax_group_id ());
/* Insert .relax_* directive for insn. */
emit_insn_before (gen_relax_group (group_id), insn);
/* Insert .relax_* directive. */
emit_insn_before (gen_relax_group (group_id), use_insn);
}
-
- relax_group_id++;
}
/* Group the relax candidate instructions for linker. */