mirror of
https://github.com/autc04/Retro68.git
synced 2025-08-15 16:27:55 +00:00
m68k: uppercase pascal functions for linking
This commit is contained in:
@@ -65,6 +65,7 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
#include "optabs.h"
|
#include "optabs.h"
|
||||||
#include "builtins.h"
|
#include "builtins.h"
|
||||||
#include "rtl-iter.h"
|
#include "rtl-iter.h"
|
||||||
|
#include "stringpool.h"
|
||||||
|
|
||||||
/* This file should be included last. */
|
/* This file should be included last. */
|
||||||
#include "target-def.h"
|
#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 bool m68k_output_addr_const_extra (FILE *, rtx);
|
||||||
static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
|
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. */
|
/* Initialize the GCC target structure. */
|
||||||
|
|
||||||
@@ -335,6 +337,9 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
|
|||||||
#undef TARGET_FUNCTION_VALUE
|
#undef TARGET_FUNCTION_VALUE
|
||||||
#define TARGET_FUNCTION_VALUE m68k_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[] =
|
static const struct attribute_spec m68k_attribute_table[] =
|
||||||
{
|
{
|
||||||
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
|
/* { 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
|
/* Stdcall attribute says callee is responsible for popping arguments
|
||||||
if they are not variable. */
|
if they are not variable. */
|
||||||
{ "pascal", 0, 0, false, true, true, m68k_handle_fndecl_attribute,
|
{ "pascal", 0, 0, false, true, true, m68k_handle_fndecl_attribute,
|
||||||
true },
|
true },
|
||||||
{ "regparam", 1, 1, false, true, true, m68k_handle_fndecl_attribute,
|
{ "regparam", 1, 1, false, true, true, m68k_handle_fndecl_attribute,
|
||||||
true },
|
true },
|
||||||
{ "raw_inline", 1, 32, false, true, true, m68k_handle_fndecl_attribute,
|
{ "raw_inline", 1, 32, false, true, true, m68k_handle_fndecl_attribute,
|
||||||
false },
|
false },
|
||||||
{ "interrupt_handler", 0, 0, true, false, false,
|
{ "interrupt_handler", 0, 0, true, false, false,
|
||||||
m68k_handle_fndecl_attribute, false },
|
m68k_handle_fndecl_attribute, false },
|
||||||
{ "interrupt_thread", 0, 0, true, false, false,
|
{ "interrupt_thread", 0, 0, true, false, false,
|
||||||
@@ -746,7 +751,7 @@ m68k_get_function_kind (tree func)
|
|||||||
tree a;
|
tree a;
|
||||||
|
|
||||||
gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
|
gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
|
||||||
|
|
||||||
a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
|
a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
|
||||||
if (a != NULL_TREE)
|
if (a != NULL_TREE)
|
||||||
return m68k_fk_interrupt_handler;
|
return m68k_fk_interrupt_handler;
|
||||||
@@ -1348,14 +1353,14 @@ m68k_expand_epilogue (bool sibcall_p)
|
|||||||
emit_jump_insn (ret_rtx);
|
emit_jump_insn (ret_rtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if X is a valid comparison operator for the dbcc
|
/* Return true if X is a valid comparison operator for the dbcc
|
||||||
instruction.
|
instruction.
|
||||||
|
|
||||||
Note it rejects floating point comparison operators.
|
Note it rejects floating point comparison operators.
|
||||||
(In the future we could use Fdbcc).
|
(In the future we could use Fdbcc).
|
||||||
|
|
||||||
It also rejects some comparisons when CC_NO_OVERFLOW is set. */
|
It also rejects some comparisons when CC_NO_OVERFLOW is set. */
|
||||||
|
|
||||||
int
|
int
|
||||||
valid_dbcc_comparison_p_2 (rtx x, machine_mode mode ATTRIBUTE_UNUSED)
|
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)
|
m68k_ok_for_sibcall_p (tree decl, tree exp)
|
||||||
{
|
{
|
||||||
enum m68k_function_kind kind;
|
enum m68k_function_kind kind;
|
||||||
|
|
||||||
/* We cannot use sibcalls for nested functions because we use the
|
/* We cannot use sibcalls for nested functions because we use the
|
||||||
static chain register for indirect calls. */
|
static chain register for indirect calls. */
|
||||||
if (CALL_EXPR_STATIC_CHAIN (exp))
|
if (CALL_EXPR_STATIC_CHAIN (exp))
|
||||||
@@ -1451,14 +1456,14 @@ m68k_ok_for_sibcall_p (tree decl, tree exp)
|
|||||||
the same. */
|
the same. */
|
||||||
if (decl && m68k_get_function_kind (decl) == kind)
|
if (decl && m68k_get_function_kind (decl) == kind)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* On the m68k all args are always pushed - NOT. */
|
/* On the m68k all args are always pushed - NOT. */
|
||||||
|
|
||||||
void m68k_init_cumulative_args (CUMULATIVE_ARGS *cum,
|
void m68k_init_cumulative_args (CUMULATIVE_ARGS *cum,
|
||||||
const_tree fntype,
|
const_tree fntype,
|
||||||
rtx libname ATTRIBUTE_UNUSED,
|
rtx libname ATTRIBUTE_UNUSED,
|
||||||
const_tree fndecl,
|
const_tree fndecl,
|
||||||
int n_named_args)
|
int n_named_args)
|
||||||
@@ -1679,8 +1684,8 @@ m68k_legitimize_address (rtx x, rtx oldx, machine_mode mode)
|
|||||||
return x;
|
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
|
floating point version of this sequence (Fdbcc). We also
|
||||||
do not handle alternative conditions when CC_NO_OVERFLOW is
|
do not handle alternative conditions when CC_NO_OVERFLOW is
|
||||||
set. It is assumed that valid_dbcc_comparison_p and flags_in_68881 will
|
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
|
/* Legitimize PIC addresses. If the address is already
|
||||||
position-independent, we return ORIG. Newly generated
|
position-independent, we return ORIG. Newly generated
|
||||||
position-independent addresses go to REG. If we need more
|
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
|
An address is legitimized by making an indirect reference
|
||||||
through the Global Offset Table with the name of the symbol
|
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
|
address of the symbol in the GOT. The function prologue
|
||||||
is responsible for initializing a5 to the starting address
|
is responsible for initializing a5 to the starting address
|
||||||
of the GOT.
|
of the GOT.
|
||||||
|
|
||||||
The assembler is also responsible for translating a symbol name
|
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:
|
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 a5@(_foo:w), a0
|
||||||
movel #12345, 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. */
|
handled. */
|
||||||
|
|
||||||
rtx
|
rtx
|
||||||
@@ -2592,7 +2597,7 @@ legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
/* legitimize both operands of the PLUS */
|
/* legitimize both operands of the PLUS */
|
||||||
gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
|
gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
|
||||||
|
|
||||||
base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
|
base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
|
||||||
orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
|
orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
|
||||||
base == reg ? 0 : reg);
|
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
|
is the simpliest way of generating a call. The difference between
|
||||||
__tls_get_addr() and libcall is that the result is returned in D0
|
__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
|
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;
|
m68k_libcall_value_in_a0_p = true;
|
||||||
a0 = emit_library_call_value (m68k_get_tls_get_addr (), NULL_RTX, LCT_PURE,
|
a0 = emit_library_call_value (m68k_get_tls_get_addr (), NULL_RTX, LCT_PURE,
|
||||||
Pmode, 1, x, Pmode);
|
Pmode, 1, x, Pmode);
|
||||||
m68k_libcall_value_in_a0_p = false;
|
m68k_libcall_value_in_a0_p = false;
|
||||||
|
|
||||||
insns = get_insns ();
|
insns = get_insns ();
|
||||||
end_sequence ();
|
end_sequence ();
|
||||||
|
|
||||||
@@ -2688,7 +2693,7 @@ m68k_get_m68k_read_tp (void)
|
|||||||
/* Emit instruction sequence that calls __m68k_read_tp.
|
/* Emit instruction sequence that calls __m68k_read_tp.
|
||||||
A pseudo register with result of __m68k_read_tp call is returned. */
|
A pseudo register with result of __m68k_read_tp call is returned. */
|
||||||
|
|
||||||
static rtx
|
static rtx
|
||||||
m68k_call_m68k_read_tp (void)
|
m68k_call_m68k_read_tp (void)
|
||||||
{
|
{
|
||||||
rtx a0;
|
rtx a0;
|
||||||
@@ -2702,7 +2707,7 @@ m68k_call_m68k_read_tp (void)
|
|||||||
is the simpliest way of generating a call. The difference between
|
is the simpliest way of generating a call. The difference between
|
||||||
__m68k_read_tp() and libcall is that the result is returned in D0
|
__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
|
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. */
|
/* Emit the call sequence. */
|
||||||
m68k_libcall_value_in_a0_p = true;
|
m68k_libcall_value_in_a0_p = true;
|
||||||
@@ -2741,7 +2746,7 @@ m68k_legitimize_tls_address (rtx orig)
|
|||||||
rtx eqv;
|
rtx eqv;
|
||||||
rtx a0;
|
rtx a0;
|
||||||
rtx x;
|
rtx x;
|
||||||
|
|
||||||
/* Attach a unique REG_EQUIV, to allow the RTL optimizers to
|
/* Attach a unique REG_EQUIV, to allow the RTL optimizers to
|
||||||
share the LDM result with other LD model accesses. */
|
share the LDM result with other LD model accesses. */
|
||||||
eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
|
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
|
/* 68k family always modifies the stack pointer by at least 2, even for
|
||||||
byte pushes. The 5200 (ColdFire) does not do this. */
|
byte pushes. The 5200 (ColdFire) does not do this. */
|
||||||
|
|
||||||
/* This case is generated by pushqi1 pattern now. */
|
/* This case is generated by pushqi1 pattern now. */
|
||||||
gcc_assert (!(GET_CODE (operands[0]) == MEM
|
gcc_assert (!(GET_CODE (operands[0]) == MEM
|
||||||
&& GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
|
&& 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 (exp) == SET)
|
||||||
{
|
{
|
||||||
if (GET_CODE (SET_SRC (exp)) == CALL)
|
if (GET_CODE (SET_SRC (exp)) == CALL)
|
||||||
CC_STATUS_INIT;
|
CC_STATUS_INIT;
|
||||||
else if (ADDRESS_REG_P (SET_DEST (exp)))
|
else if (ADDRESS_REG_P (SET_DEST (exp)))
|
||||||
{
|
{
|
||||||
if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
|
if (cc_status.value1 && modified_in_p (cc_status.value1, insn))
|
||||||
cc_status.value1 = 0;
|
cc_status.value1 = 0;
|
||||||
if (cc_status.value2 && modified_in_p (cc_status.value2, insn))
|
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
|
/* fmoves to memory or data registers do not set the condition
|
||||||
codes. Normal moves _do_ set the condition codes, but not in
|
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))
|
&& (FP_REG_P (SET_SRC (exp))
|
||||||
|| GET_CODE (SET_SRC (exp)) == FIX
|
|| GET_CODE (SET_SRC (exp)) == FIX
|
||||||
|| FLOAT_MODE_P (GET_MODE (SET_DEST (exp)))))
|
|| 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. */
|
/* A pair of move insns doesn't produce a useful overall cc. */
|
||||||
else if (!FP_REG_P (SET_DEST (exp))
|
else if (!FP_REG_P (SET_DEST (exp))
|
||||||
&& !FP_REG_P (SET_SRC (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)) == REG
|
||||||
|| GET_CODE (SET_SRC (exp)) == MEM
|
|| GET_CODE (SET_SRC (exp)) == MEM
|
||||||
|| GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
|
|| GET_CODE (SET_SRC (exp)) == CONST_DOUBLE))
|
||||||
CC_STATUS_INIT;
|
CC_STATUS_INIT;
|
||||||
else if (SET_DEST (exp) != pc_rtx)
|
else if (SET_DEST (exp) != pc_rtx)
|
||||||
{
|
{
|
||||||
cc_status.flags = 0;
|
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.
|
ends with a move insn moving r2 in r2's mode.
|
||||||
Thus, the cc's are set for r2.
|
Thus, the cc's are set for r2.
|
||||||
This can set N bit spuriously. */
|
This can set N bit spuriously. */
|
||||||
cc_status.flags |= CC_NOT_NEGATIVE;
|
cc_status.flags |= CC_NOT_NEGATIVE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -4407,7 +4412,7 @@ output_move_const_single (rtx *operands)
|
|||||||
to get the desired constant. */
|
to get the desired constant. */
|
||||||
|
|
||||||
/* This code has been fixed for cross-compilation. */
|
/* This code has been fixed for cross-compilation. */
|
||||||
|
|
||||||
static int inited_68881_table = 0;
|
static int inited_68881_table = 0;
|
||||||
|
|
||||||
static const char *const strings_68881[7] = {
|
static const char *const strings_68881[7] = {
|
||||||
@@ -4475,7 +4480,7 @@ standard_68881_constant_p (rtx x)
|
|||||||
if (real_identical (r, &values_68881[i]))
|
if (real_identical (r, &values_68881[i]))
|
||||||
return (codes_68881[i]);
|
return (codes_68881[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GET_MODE (x) == SFmode)
|
if (GET_MODE (x) == SFmode)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -4760,7 +4765,7 @@ m68k_delegitimize_address (rtx orig_x)
|
|||||||
unspec = XEXP (addr.offset, 0);
|
unspec = XEXP (addr.offset, 0);
|
||||||
if (GET_CODE (unspec) == PLUS && CONST_INT_P (XEXP (unspec, 1)))
|
if (GET_CODE (unspec) == PLUS && CONST_INT_P (XEXP (unspec, 1)))
|
||||||
unspec = XEXP (unspec, 0);
|
unspec = XEXP (unspec, 0);
|
||||||
if (GET_CODE (unspec) != UNSPEC
|
if (GET_CODE (unspec) != UNSPEC
|
||||||
|| (XINT (unspec, 1) != UNSPEC_RELOC16
|
|| (XINT (unspec, 1) != UNSPEC_RELOC16
|
||||||
&& XINT (unspec, 1) != UNSPEC_RELOC32))
|
&& XINT (unspec, 1) != UNSPEC_RELOC32))
|
||||||
return orig_x;
|
return orig_x;
|
||||||
@@ -4781,7 +4786,7 @@ m68k_delegitimize_address (rtx orig_x)
|
|||||||
x = replace_equiv_address_nv (orig_x, x);
|
x = replace_equiv_address_nv (orig_x, x);
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* A C compound statement to output to stdio stream STREAM the
|
/* A C compound statement to output to stdio stream STREAM the
|
||||||
assembler syntax for an instruction operand that is a memory
|
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...))
|
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...)).
|
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
|
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
|
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) */
|
-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:
|
case CPU_CFV3:
|
||||||
insn_size = sched_get_attr_size_int (insn);
|
insn_size = sched_get_attr_size_int (insn);
|
||||||
|
|
||||||
/* ColdFire V3 and V4 cores have instruction buffers that can
|
/* ColdFire V3 and V4 cores have instruction buffers that can
|
||||||
accumulate up to 8 instructions regardless of instructions'
|
accumulate up to 8 instructions regardless of instructions'
|
||||||
sizes. So we should take care not to "prefetch" 24 one-word
|
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");
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user