From 4d0f9e202c487441921273ac485a2de480cdd9cc Mon Sep 17 00:00:00 2001 From: Wolfgang Thaller Date: Sat, 15 Apr 2017 23:31:48 +0200 Subject: [PATCH] m68k: uppercase pascal functions for linking --- gcc/gcc/config/m68k/m68k.c | 105 ++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 36 deletions(-) diff --git a/gcc/gcc/config/m68k/m68k.c b/gcc/gcc/config/m68k/m68k.c index 224ba3b5d4..ac42ff59fa 100644 --- a/gcc/gcc/config/m68k/m68k.c +++ b/gcc/gcc/config/m68k/m68k.c @@ -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; +} +