Commit a2ef3db7 by Bernardo Innocenti

lb1sf68.asm: Add __PIC__ and __ID_SHARED_LIBRARY__ support.

	* config/m68k/lb1sf68.asm: Add __PIC__ and __ID_SHARED_LIBRARY__
	support.
	* config/m68k/m68k-none.h (ASM_SPEC): Pass --pcrel to assembler on
	-fpic, -fPIC, -msep-data and -mid-shared-library.
	* config/m68k/m68k.c (m68k_library_id_string): New global variable.
	(override_options): Add -msep-data and -mshared-library-id support.
	(m68k_output_function_prologue): Generate code to load A5 for
	TARGET_ID_SHARED_LIBRARY and TARGET_SEP_DATA.
	(m68k_output_mi_thunk): Emit indirect jump on TARGET_ID_SHARED_LIBRARY.
	(m68k_output_pic_call): New function.
	* gcc/config/m68k/m68k.h (TARGET_SEP_DATA): New target flag.
	(TARGET_ID_SHARED_LIBRARY): Ditto.
	(TARGET_SWITCHES): Add switches for -mid-shared-library and -msep-data.
	* gcc/config/m68k/m68k.md (call): Call m68k_output_pic_call().
	(call_value): Likewise.

From-SVN: r72324
parent 4f5acf56
2003-09-11 Peter Barada <peter@baradas.org> 2003-10-11 Bernardo Innocenti <bernie@develer.com>
Paul Dale <pauli@snapgear.com>
* config/m68k/lb1sf68.asm: Add __PIC__ and __ID_SHARED_LIBRARY__
support.
* config/m68k/m68k-none.h (ASM_SPEC): Pass --pcrel to assembler on
-fpic, -fPIC, -msep-data and -mid-shared-library.
* config/m68k/m68k.c (m68k_library_id_string): New global variable.
(override_options): Add -msep-data and -mshared-library-id support.
(m68k_output_function_prologue): Generate code to load A5 for
TARGET_ID_SHARED_LIBRARY and TARGET_SEP_DATA.
(m68k_output_mi_thunk): Emit indirect jump on TARGET_ID_SHARED_LIBRARY.
(m68k_output_pic_call): New function.
* gcc/config/m68k/m68k.h (TARGET_SEP_DATA): New target flag.
(TARGET_ID_SHARED_LIBRARY): Ditto.
(TARGET_SWITCHES): Add switches for -mid-shared-library and -msep-data.
* gcc/config/m68k/m68k.md (call): Call m68k_output_pic_call().
(call_value): Likewise.
2003-10-11 Peter Barada <peter@baradas.org>
Bernardo Innocenti <bernie@develer.com> Bernardo Innocenti <bernie@develer.com>
* config/m68k/m68k.c (m68k_frame): Move before protos referencing it. * config/m68k/m68k.c (m68k_frame): Move before protos referencing it.
......
...@@ -82,6 +82,7 @@ Unrecognized value in TARGET_CPU_DEFAULT. ...@@ -82,6 +82,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
#undef ASM_SPEC #undef ASM_SPEC
#define ASM_SPEC "\ #define ASM_SPEC "\
%{m68851}%{mno-68851}%{m68881}%{mno-68881}%{msoft-float:-mno-68881} %{m68000}%{m68302}%{mc68000}%{m68010}%{m68020}%{mc68020}%{m68030}%{m68040}%{m68020-40:-mc68040} %{m68020-60:-mc68040} %{m68060}%{mcpu32}%{m68332}%{m5200}%{m5206e}%{m528x}%{m5307}%{m5407}%{!mc68000:%{!m68000:%{!m68302:%{!m68010:%{!mc68020:%{!m68020:%{!m68030:%{!m68040:%{!m68020-40:%{!m68020-60:%{!m68060:%{!mcpu32:%{!m68332:%{!m5200:%{!m5206e:%{!m528x:%{!m5307:%{!m5407:%(asm_cpu_default)}}}}}}}}}}}}}}}}}} \ %{m68851}%{mno-68851}%{m68881}%{mno-68881}%{msoft-float:-mno-68881} %{m68000}%{m68302}%{mc68000}%{m68010}%{m68020}%{mc68020}%{m68030}%{m68040}%{m68020-40:-mc68040} %{m68020-60:-mc68040} %{m68060}%{mcpu32}%{m68332}%{m5200}%{m5206e}%{m528x}%{m5307}%{m5407}%{!mc68000:%{!m68000:%{!m68302:%{!m68010:%{!mc68020:%{!m68020:%{!m68030:%{!m68040:%{!m68020-40:%{!m68020-60:%{!m68060:%{!mcpu32:%{!m68332:%{!m5200:%{!m5206e:%{!m528x:%{!m5307:%{!m5407:%(asm_cpu_default)}}}}}}}}}}}}}}}}}} \
%{fPIC:--pcrel} %{fpic:--pcrel} %{msep-data:--pcrel} %{mid-shared-library:--pcrel} \
" "
/* cc1/cc1plus always receives all the -m flags. If the specs strings above /* cc1/cc1plus always receives all the -m flags. If the specs strings above
......
...@@ -38,6 +38,7 @@ extern const char *output_addsi3 (rtx *); ...@@ -38,6 +38,7 @@ extern const char *output_addsi3 (rtx *);
extern const char *output_andsi3 (rtx *); extern const char *output_andsi3 (rtx *);
extern const char *output_iorsi3 (rtx *); extern const char *output_iorsi3 (rtx *);
extern const char *output_xorsi3 (rtx *); extern const char *output_xorsi3 (rtx *);
extern void m68k_output_pic_call (rtx dest);
extern void output_dbcc_and_branch (rtx *); extern void output_dbcc_and_branch (rtx *);
extern int const_uint32_operand (rtx, enum machine_mode); extern int const_uint32_operand (rtx, enum machine_mode);
extern int const_sint32_operand (rtx, enum machine_mode); extern int const_sint32_operand (rtx, enum machine_mode);
......
...@@ -74,6 +74,8 @@ const char *m68k_align_loops_string; ...@@ -74,6 +74,8 @@ const char *m68k_align_loops_string;
const char *m68k_align_jumps_string; const char *m68k_align_jumps_string;
/* Specify power of two alignment used for functions. */ /* Specify power of two alignment used for functions. */
const char *m68k_align_funcs_string; const char *m68k_align_funcs_string;
/* Specify the identification number of the library being built */
const char *m68k_library_id_string;
/* Specify power of two alignment used for loops. */ /* Specify power of two alignment used for loops. */
int m68k_align_loops; int m68k_align_loops;
...@@ -167,6 +169,38 @@ override_options (void) ...@@ -167,6 +169,38 @@ override_options (void)
m68k_align_loops = i; m68k_align_loops = i;
} }
/* Library identification */
if (m68k_library_id_string)
{
int id;
if (! TARGET_ID_SHARED_LIBRARY)
error ("-mshared-library-id= specified without -mid-shared-library");
id = atoi (m68k_library_id_string);
if (id < 0 || id > MAX_LIBRARY_ID)
error ("-mshared-library-id=%d is not between 0 and %d", id, MAX_LIBRARY_ID);
/* From now on, m68k_library_id_string will contain the library offset. */
asprintf ((char **)&m68k_library_id_string, "%d", (id * -4) - 4);
}
else
/* If TARGET_ID_SHARED_LIBRARY is enabled, this will point to the
current library. */
m68k_library_id_string = "_current_shared_library_a5_offset_";
/* Sanity check to ensure that msep-data and mid-sahred-library are not
* both specified together. Doing so simply doesn't make sense.
*/
if (TARGET_SEP_DATA && TARGET_ID_SHARED_LIBRARY)
error ("cannot specify both -msep-data and -mid-shared-library");
/* If we're generating code for a separate A5 relative data segment,
* we've got to enable -fPIC as well. This might be relaxable to
* -fpic but it hasn't been tested properly.
*/
if (TARGET_SEP_DATA || TARGET_ID_SHARED_LIBRARY)
flag_pic = 2;
/* Validate -malign-jumps= value, or provide default */ /* Validate -malign-jumps= value, or provide default */
m68k_align_jumps = def_align; m68k_align_jumps = def_align;
if (m68k_align_jumps_string) if (m68k_align_jumps_string)
...@@ -192,7 +226,7 @@ override_options (void) ...@@ -192,7 +226,7 @@ override_options (void)
/* -fPIC uses 32-bit pc-relative displacements, which don't exist /* -fPIC uses 32-bit pc-relative displacements, which don't exist
until the 68020. */ until the 68020. */
if (! TARGET_68020 && flag_pic == 2) if (!TARGET_68020 && !TARGET_COLDFIRE && (flag_pic == 2))
error("-fPIC is not currently supported on the 68000 or 68010\n"); error("-fPIC is not currently supported on the 68000 or 68010\n");
/* ??? A historic way of turning on pic, or is this intended to /* ??? A historic way of turning on pic, or is this intended to
...@@ -639,18 +673,30 @@ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size) ...@@ -639,18 +673,30 @@ m68k_output_function_prologue (FILE *stream, HOST_WIDE_INT size)
-cfa_offset + n_regs++ * 4); -cfa_offset + n_regs++ * 4);
} }
} }
if (flag_pic && current_function_uses_pic_offset_table) if (!TARGET_SEP_DATA && flag_pic &&
(current_function_uses_pic_offset_table ||
(!current_function_is_leaf && TARGET_ID_SHARED_LIBRARY)))
{ {
if (TARGET_ID_SHARED_LIBRARY)
{
asm_fprintf (stream, "\tmovel %s@(%s), %s\n",
reg_names[PIC_OFFSET_TABLE_REGNUM],
m68k_library_id_string,
reg_names[PIC_OFFSET_TABLE_REGNUM]);
}
else
{
#ifdef MOTOROLA #ifdef MOTOROLA
asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n", asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n",
reg_names[PIC_OFFSET_TABLE_REGNUM]); reg_names[PIC_OFFSET_TABLE_REGNUM]);
#else #else
asm_fprintf (stream, "\tmovel %I%U_GLOBAL_OFFSET_TABLE_, %s\n", asm_fprintf (stream, "\tmovel %I%U_GLOBAL_OFFSET_TABLE_, %s\n",
reg_names[PIC_OFFSET_TABLE_REGNUM]); reg_names[PIC_OFFSET_TABLE_REGNUM]);
asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n", asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n",
reg_names[PIC_OFFSET_TABLE_REGNUM], reg_names[PIC_OFFSET_TABLE_REGNUM],
reg_names[PIC_OFFSET_TABLE_REGNUM]); reg_names[PIC_OFFSET_TABLE_REGNUM]);
#endif #endif
}
} }
} }
...@@ -1055,6 +1101,39 @@ flags_in_68881 (void) ...@@ -1055,6 +1101,39 @@ flags_in_68881 (void)
return cc_status.flags & CC_IN_68881; return cc_status.flags & CC_IN_68881;
} }
/* Output a BSR instruction suitable for PIC code. */
void
m68k_output_pic_call(rtx dest)
{
const char *out;
if (!(GET_CODE (dest) == MEM && GET_CODE (XEXP (dest, 0)) == SYMBOL_REF))
out = "jsr %0";
/* We output a BSR instruction if we've using -fpic or we're building for
* a target that supports long branches. If we're building -fPIC on the
* 68000, 68010 or ColdFire we generate one of two sequences:
* a shorter one that uses a GOT entry or a longer one that doesn't.
* We'll use the -Os command-line flag to decide which to generate.
* Both sequences take the same time to execute on the ColdFire.
*/
else if (TARGET_PCREL)
out = "bsr.l %o0";
else if ((flag_pic == 1) || TARGET_68020)
#ifdef HPUX_ASM
out = "bsr.l %0";
#elif defined(USE_GAS)
out = "bsr.l %0@PLTPC";
#else
out = "bsr %0@PLTPC";
#endif
else if (optimize_size || TARGET_ID_SHARED_LIBRARY)
out = "move.l %0@GOT(%%a5), %%a1\n\tjsr (%%a1)";
else
out = "lea %0-.-8,%%a1\n\tjsr 0(%%pc,%%a1)";
output_asm_insn(out, &dest);
}
/* 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
...@@ -3567,7 +3646,7 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -3567,7 +3646,7 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
{ {
if (TARGET_PCREL) if (TARGET_PCREL)
fmt = "bra.l %o0"; fmt = "bra.l %o0";
else else if ((flag_pic == 1) || TARGET_68020)
{ {
#ifdef MOTOROLA #ifdef MOTOROLA
#ifdef HPUX_ASM #ifdef HPUX_ASM
...@@ -3587,6 +3666,10 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -3587,6 +3666,10 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
#endif #endif
#endif #endif
} }
else if (optimize_size || TARGET_ID_SHARED_LIBRARY)
fmt = "move.l %0@GOT(%%a5), %%a1\n\tjmp (%%a1)";
else
fmt = "lea %0-.-8,%%a1\n\tjsr 0(%%pc,%%a1)";
} }
else else
{ {
......
...@@ -83,14 +83,28 @@ Boston, MA 02111-1307, USA. */ ...@@ -83,14 +83,28 @@ Boston, MA 02111-1307, USA. */
if (TARGET_CF_HWDIV) \ if (TARGET_CF_HWDIV) \
builtin_define ("__mcfhwdiv__"); \ builtin_define ("__mcfhwdiv__"); \
if (flag_pic) \ if (flag_pic) \
builtin_define ("__pic__"); \ { \
if (flag_pic > 1) \ builtin_define ("__pic__"); \
builtin_define ("__PIC__"); \ if (flag_pic > 1) \
builtin_define ("__PIC__"); \
} \
builtin_assert ("cpu=m68k"); \ builtin_assert ("cpu=m68k"); \
builtin_assert ("machine=m68k"); \ builtin_assert ("machine=m68k"); \
} \ } \
while (0) while (0)
/* Support A5 relative data seperate from text.
* This option implies -fPIC, however it inhibits the generation of the
* A5 save/restore in functions and the loading of a5 with a got pointer.
*/
#define MASK_SEP_DATA 0x100000
#define TARGET_SEP_DATA (target_flags & MASK_SEP_DATA)
/* Compile using library ID based shared libraries.
* Set a specific ID using the -mshared-library-id=xxx option.
*/
#define MASK_ID_SHARED_LIBRARY 0x200000
#define TARGET_ID_SHARED_LIBRARY (target_flags & MASK_ID_SHARED_LIBRARY)
/* Classify the groups of pseudo-ops used to assemble QI, HI and SI /* Classify the groups of pseudo-ops used to assemble QI, HI and SI
quantities. */ quantities. */
...@@ -305,6 +319,14 @@ extern int target_flags; ...@@ -305,6 +319,14 @@ extern int target_flags;
N_("Align variables on a 32-bit boundary") }, \ N_("Align variables on a 32-bit boundary") }, \
{ "no-align-int", -MASK_ALIGN_INT, \ { "no-align-int", -MASK_ALIGN_INT, \
N_("Align variables on a 16-bit boundary") }, \ N_("Align variables on a 16-bit boundary") }, \
{ "sep-data", MASK_SEP_DATA, \
N_("Enable separate data segment") }, \
{ "no-sep-data", -MASK_SEP_DATA, \
N_("Disable separate data segment") }, \
{ "id-shared-library", MASK_ID_SHARED_LIBRARY, \
N_("Enable ID based shared library") }, \
{ "no-id-shared-library", -MASK_ID_SHARED_LIBRARY, \
N_("Disable ID based shared library") }, \
{ "pcrel", MASK_PCREL, \ { "pcrel", MASK_PCREL, \
N_("Generate pc-relative code") }, \ N_("Generate pc-relative code") }, \
{ "strict-align", -MASK_NO_STRICT_ALIGNMENT, \ { "strict-align", -MASK_NO_STRICT_ALIGNMENT, \
...@@ -335,6 +357,8 @@ extern int target_flags; ...@@ -335,6 +357,8 @@ extern int target_flags;
N_("Jump targets are aligned to this power of 2"), 0}, \ N_("Jump targets are aligned to this power of 2"), 0}, \
{ "align-functions=", &m68k_align_funcs_string, \ { "align-functions=", &m68k_align_funcs_string, \
N_("Function starts are aligned to this power of 2"), 0}, \ N_("Function starts are aligned to this power of 2"), 0}, \
{ "shared-library-id=", &m68k_library_id_string, \
N_("ID of shared library to build"), 0}, \
SUBTARGET_OPTIONS \ SUBTARGET_OPTIONS \
} }
...@@ -411,6 +435,9 @@ extern int target_flags; ...@@ -411,6 +435,9 @@ extern int target_flags;
/* Maximum power of 2 that code can be aligned to. */ /* Maximum power of 2 that code can be aligned to. */
#define MAX_CODE_ALIGN 2 /* 4 byte alignment */ #define MAX_CODE_ALIGN 2 /* 4 byte alignment */
/* Maximum number of library ids we permit */
#define MAX_LIBRARY_ID 255
/* Align loop starts for optimal branching. */ /* Align loop starts for optimal branching. */
#define LOOP_ALIGN(LABEL) (m68k_align_loops) #define LOOP_ALIGN(LABEL) (m68k_align_loops)
...@@ -1638,6 +1665,7 @@ __transfer_from_trampoline () \ ...@@ -1638,6 +1665,7 @@ __transfer_from_trampoline () \
extern const char *m68k_align_loops_string; extern const char *m68k_align_loops_string;
extern const char *m68k_align_jumps_string; extern const char *m68k_align_jumps_string;
extern const char *m68k_align_funcs_string; extern const char *m68k_align_funcs_string;
extern const char *m68k_library_id_string;
extern int m68k_align_loops; extern int m68k_align_loops;
extern int m68k_align_jumps; extern int m68k_align_jumps;
extern int m68k_align_funcs; extern int m68k_align_funcs;
......
...@@ -6796,31 +6796,8 @@ ...@@ -6796,31 +6796,8 @@
"flag_pic" "flag_pic"
"* "*
if (GET_CODE (operands[0]) == MEM m68k_output_pic_call(operands[0]);
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) return \"\";
{
if (TARGET_PCREL) return \"bsr.l %o0\";
#ifdef MOTOROLA
#ifdef HPUX_ASM
return \"bsr.l %0\";
#else
#ifdef USE_GAS
return \"bsr.l %0@PLTPC\";
#else
return \"bsr %0@PLTPC\";
#endif
#endif
#else
#ifdef USE_GAS
return \"bsr.l %0\";
#else
/* The ',a1' is a dummy argument telling the Sun assembler we want PIC,
GAS just plain ignores it. FIXME: not anymore, gas doesn't! */
return \"jbsr %0,a1\";
#endif
#endif
}
return \"jsr %0\";
") ")
;; Call subroutine, returning value in operand 0 ;; Call subroutine, returning value in operand 0
...@@ -6861,31 +6838,8 @@ ...@@ -6861,31 +6838,8 @@
;; Operand 2 not really used on the m68000. ;; Operand 2 not really used on the m68000.
"flag_pic" "flag_pic"
"* "*
if (GET_CODE (operands[1]) == MEM m68k_output_pic_call(operands[1]);
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) return \"\";
{
if (TARGET_PCREL) return \"bsr.l %o1\";
#ifdef MOTOROLA
#ifdef HPUX_ASM
return \"bsr.l %1\";
#else
#ifdef USE_GAS
return \"bsr.l %1@PLTPC\";
#else
return \"bsr %1@PLTPC\";
#endif
#endif
#else
#ifdef USE_GAS
return \"bsr.l %1\";
#else
/* The ',a1' is a dummy argument telling the Sun assembler we want PIC
GAS just plain ignores it. FIXME: Not anymore, gas doesn't! */
return \"jbsr %1,a1\";
#endif
#endif
}
return \"jsr %1\";
") ")
;; Call subroutine returning any type. ;; Call subroutine returning any type.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment