m68k: uppercase pascal functions for linking

This commit is contained in:
Wolfgang Thaller 2017-04-15 23:31:48 +02:00
parent fe6f08fd7f
commit 4d0f9e202c
1 changed files with 69 additions and 36 deletions

View File

@ -65,6 +65,7 @@ along with GCC; see the file COPYING3. If not see
#include "optabs.h"
#include "builtins.h"
#include "rtl-iter.h"
#include "stringpool.h"
/* This file should be included last. */
#include "target-def.h"
@ -191,6 +192,7 @@ static bool m68k_cannot_force_const_mem (machine_mode mode, rtx x);
static bool m68k_output_addr_const_extra (FILE *, rtx);
static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
static tree m68k_mangle_decl_assembler_name (tree decl, tree id);
/* Initialize the GCC target structure. */
@ -335,6 +337,9 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
#undef TARGET_FUNCTION_VALUE
#define TARGET_FUNCTION_VALUE m68k_function_value
#undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
#define TARGET_MANGLE_DECL_ASSEMBLER_NAME m68k_mangle_decl_assembler_name
static const struct attribute_spec m68k_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
@ -344,11 +349,11 @@ static const struct attribute_spec m68k_attribute_table[] =
/* Stdcall attribute says callee is responsible for popping arguments
if they are not variable. */
{ "pascal", 0, 0, false, true, true, m68k_handle_fndecl_attribute,
true },
true },
{ "regparam", 1, 1, false, true, true, m68k_handle_fndecl_attribute,
true },
{ "raw_inline", 1, 32, false, true, true, m68k_handle_fndecl_attribute,
false },
false },
{ "interrupt_handler", 0, 0, true, false, false,
m68k_handle_fndecl_attribute, false },
{ "interrupt_thread", 0, 0, true, false, false,
@ -746,7 +751,7 @@ m68k_get_function_kind (tree func)
tree a;
gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
if (a != NULL_TREE)
return m68k_fk_interrupt_handler;
@ -1348,14 +1353,14 @@ m68k_expand_epilogue (bool sibcall_p)
emit_jump_insn (ret_rtx);
}
/* Return true if X is a valid comparison operator for the dbcc
instruction.
/* Return true if X is a valid comparison operator for the dbcc
instruction.
Note it rejects floating point comparison operators.
(In the future we could use Fdbcc).
It also rejects some comparisons when CC_NO_OVERFLOW is set. */
int
valid_dbcc_comparison_p_2 (rtx x, machine_mode mode ATTRIBUTE_UNUSED)
{
@ -1412,7 +1417,7 @@ static bool
m68k_ok_for_sibcall_p (tree decl, tree exp)
{
enum m68k_function_kind kind;
/* We cannot use sibcalls for nested functions because we use the
static chain register for indirect calls. */
if (CALL_EXPR_STATIC_CHAIN (exp))
@ -1451,14 +1456,14 @@ m68k_ok_for_sibcall_p (tree decl, tree exp)
the same. */
if (decl && m68k_get_function_kind (decl) == kind)
return true;
return false;
}
/* On the m68k all args are always pushed - NOT. */
void m68k_init_cumulative_args (CUMULATIVE_ARGS *cum,
const_tree fntype,
void m68k_init_cumulative_args (CUMULATIVE_ARGS *cum,
const_tree fntype,
rtx libname ATTRIBUTE_UNUSED,
const_tree fndecl,
int n_named_args)
@ -1679,8 +1684,8 @@ m68k_legitimize_address (rtx x, rtx oldx, machine_mode mode)
return x;
}
/* Output a dbCC; jCC sequence. Note we do not handle the
/* Output a dbCC; jCC sequence. Note we do not handle the
floating point version of this sequence (Fdbcc). We also
do not handle alternative conditions when CC_NO_OVERFLOW is
set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
@ -2529,19 +2534,19 @@ m68k_wrap_symbol_into_got_ref (rtx x, enum m68k_reloc reloc, rtx temp_reg)
/* Legitimize PIC addresses. If the address is already
position-independent, we return ORIG. Newly generated
position-independent addresses go to REG. If we need more
than one register, we lose.
than one register, we lose.
An address is legitimized by making an indirect reference
through the Global Offset Table with the name of the symbol
used as an offset.
used as an offset.
The assembler and linker are responsible for placing the
The assembler and linker are responsible for placing the
address of the symbol in the GOT. The function prologue
is responsible for initializing a5 to the starting address
of the GOT.
The assembler is also responsible for translating a symbol name
into a constant displacement from the start of the GOT.
into a constant displacement from the start of the GOT.
A quick example may make things a little clearer:
@ -2561,9 +2566,9 @@ m68k_wrap_symbol_into_got_ref (rtx x, enum m68k_reloc reloc, rtx temp_reg)
movel a5@(_foo:w), a0
movel #12345, a0@
That (in a nutshell) is how *all* symbol and label references are
That (in a nutshell) is how *all* symbol and label references are
handled. */
rtx
@ -2592,7 +2597,7 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
/* legitimize both operands of the PLUS */
gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
base == reg ? 0 : reg);
@ -2654,13 +2659,13 @@ m68k_call_tls_get_addr (rtx x, rtx eqv, enum m68k_reloc reloc)
is the simpliest way of generating a call. The difference between
__tls_get_addr() and libcall is that the result is returned in D0
instead of A0. To workaround this, we use m68k_libcall_value_in_a0_p
which temporarily switches returning the result to A0. */
which temporarily switches returning the result to A0. */
m68k_libcall_value_in_a0_p = true;
a0 = emit_library_call_value (m68k_get_tls_get_addr (), NULL_RTX, LCT_PURE,
Pmode, 1, x, Pmode);
m68k_libcall_value_in_a0_p = false;
insns = get_insns ();
end_sequence ();
@ -2688,7 +2693,7 @@ m68k_get_m68k_read_tp (void)
/* Emit instruction sequence that calls __m68k_read_tp.
A pseudo register with result of __m68k_read_tp call is returned. */
static rtx
static rtx
m68k_call_m68k_read_tp (void)
{
rtx a0;
@ -2702,7 +2707,7 @@ m68k_call_m68k_read_tp (void)
is the simpliest way of generating a call. The difference between
__m68k_read_tp() and libcall is that the result is returned in D0
instead of A0. To workaround this, we use m68k_libcall_value_in_a0_p
which temporarily switches returning the result to A0. */
which temporarily switches returning the result to A0. */
/* Emit the call sequence. */
m68k_libcall_value_in_a0_p = true;
@ -2741,7 +2746,7 @@ m68k_legitimize_tls_address (rtx orig)
rtx eqv;
rtx a0;
rtx x;
/* Attach a unique REG_EQUIV, to allow the RTL optimizers to
share the LDM result with other LD model accesses. */
eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
@ -3211,7 +3216,7 @@ output_move_qimode (rtx *operands)
{
/* 68k family always modifies the stack pointer by at least 2, even for
byte pushes. The 5200 (ColdFire) does not do this. */
/* This case is generated by pushqi1 pattern now. */
gcc_assert (!(GET_CODE (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
@ -4265,13 +4270,13 @@ notice_update_cc (rtx exp, rtx insn)
if (GET_CODE (exp) == SET)
{
if (GET_CODE (SET_SRC (exp)) == CALL)
CC_STATUS_INIT;
CC_STATUS_INIT;
else if (ADDRESS_REG_P (SET_DEST (exp)))
{
if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
cc_status.value1 = 0;
if (cc_status.value2 && modified_in_p (cc_status.value2, insn))
cc_status.value2 = 0;
cc_status.value2 = 0;
}
/* fmoves to memory or data registers do not set the condition
codes. Normal moves _do_ set the condition codes, but not in
@ -4285,7 +4290,7 @@ notice_update_cc (rtx exp, rtx insn)
&& (FP_REG_P (SET_SRC (exp))
|| GET_CODE (SET_SRC (exp)) == FIX
|| FLOAT_MODE_P (GET_MODE (SET_DEST (exp)))))
CC_STATUS_INIT;
CC_STATUS_INIT;
/* A pair of move insns doesn't produce a useful overall cc. */
else if (!FP_REG_P (SET_DEST (exp))
&& !FP_REG_P (SET_SRC (exp))
@ -4293,7 +4298,7 @@ notice_update_cc (rtx exp, rtx insn)
&& (GET_CODE (SET_SRC (exp)) == REG
|| GET_CODE (SET_SRC (exp)) == MEM
|| GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
CC_STATUS_INIT;
CC_STATUS_INIT;
else if (SET_DEST (exp) != pc_rtx)
{
cc_status.flags = 0;
@ -4342,7 +4347,7 @@ notice_update_cc (rtx exp, rtx insn)
ends with a move insn moving r2 in r2's mode.
Thus, the cc's are set for r2.
This can set N bit spuriously. */
cc_status.flags |= CC_NOT_NEGATIVE;
cc_status.flags |= CC_NOT_NEGATIVE;
default:
break;
@ -4407,7 +4412,7 @@ output_move_const_single (rtx *operands)
to get the desired constant. */
/* This code has been fixed for cross-compilation. */
static int inited_68881_table = 0;
static const char *const strings_68881[7] = {
@ -4475,7 +4480,7 @@ standard_68881_constant_p (rtx x)
if (real_identical (r, &values_68881[i]))
return (codes_68881[i]);
}
if (GET_MODE (x) == SFmode)
return 0;
@ -4760,7 +4765,7 @@ m68k_delegitimize_address (rtx orig_x)
unspec = XEXP (addr.offset, 0);
if (GET_CODE (unspec) == PLUS && CONST_INT_P (XEXP (unspec, 1)))
unspec = XEXP (unspec, 0);
if (GET_CODE (unspec) != UNSPEC
if (GET_CODE (unspec) != UNSPEC
|| (XINT (unspec, 1) != UNSPEC_RELOC16
&& XINT (unspec, 1) != UNSPEC_RELOC32))
return orig_x;
@ -4781,7 +4786,7 @@ m68k_delegitimize_address (rtx orig_x)
x = replace_equiv_address_nv (orig_x, x);
return x;
}
/* A C compound statement to output to stdio stream STREAM the
assembler syntax for an instruction operand that is a memory
@ -4795,7 +4800,7 @@ m68k_delegitimize_address (rtx orig_x)
It is possible for PIC to generate a (plus (label_ref...) (reg...))
and we handle that just like we would a (plus (symbol_ref...) (reg...)).
This routine is responsible for distinguishing between -fpic and -fPIC
This routine is responsible for distinguishing between -fpic and -fPIC
style relocations in an address. When generating -fpic code the
offset is output in word mode (e.g. movel a5@(_foo:w), a0). When generating
-fPIC code the offset is output in long mode (e.g. movel a5@(_foo:l), a0) */
@ -6228,7 +6233,7 @@ m68k_sched_variable_issue (FILE *sched_dump ATTRIBUTE_UNUSED,
case CPU_CFV3:
insn_size = sched_get_attr_size_int (insn);
/* ColdFire V3 and V4 cores have instruction buffers that can
accumulate up to 8 instructions regardless of instructions'
sizes. So we should take care not to "prefetch" 24 one-word
@ -6732,6 +6737,34 @@ m68k_write_macsbug_name(FILE *file, const char *name)
fprintf(file, "\t.align 2,0\n\t.short 0\n");
}
static tree
m68k_mangle_decl_assembler_name (tree decl, tree id)
{
tree new_id = NULL_TREE;
if (TREE_CODE (decl) == FUNCTION_DECL)
{
tree attrs = TYPE_ATTRIBUTES ( TREE_TYPE(decl) );
if (attrs != NULL_TREE)
{
if (lookup_attribute ("pascal", attrs))
{
const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl));
char *new_str, *p;
int len = strlen(old_str);
new_str = XALLOCAVEC (char, 1 + len);
for(int i = 0; i < len; i++)
new_str[i] = TOUPPER(old_str[i]);
new_str[len] = 0;
return get_identifier (new_str);
}
}
}
return id;
}