mirror of
https://github.com/autc04/Retro68.git
synced 2025-01-11 18:30:58 +00:00
m68k: uppercase pascal functions for linking
This commit is contained in:
parent
fe6f08fd7f
commit
4d0f9e202c
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user