From a2ef3db72b61490b5522f80abd7010ac404641d1 Mon Sep 17 00:00:00 2001 From: Bernardo Innocenti Date: Sat, 11 Oct 2003 05:06:45 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 21 +++- gcc/config/m68k/lb1sf68.asm | 182 +++++++++++++++++++++++----------- gcc/config/m68k/m68k-none.h | 1 + gcc/config/m68k/m68k-protos.h | 1 + gcc/config/m68k/m68k.c | 103 +++++++++++++++++-- gcc/config/m68k/m68k.h | 34 ++++++- gcc/config/m68k/m68k.md | 54 +--------- 7 files changed, 276 insertions(+), 120 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 07bca0fd134..d5e54a94b92 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,23 @@ -2003-09-11 Peter Barada +2003-10-11 Bernardo Innocenti + Paul Dale + + * 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 Bernardo Innocenti * config/m68k/m68k.c (m68k_frame): Move before protos referencing it. diff --git a/gcc/config/m68k/lb1sf68.asm b/gcc/config/m68k/lb1sf68.asm index 71aa9eebfe7..8c681ed5385 100644 --- a/gcc/config/m68k/lb1sf68.asm +++ b/gcc/config/m68k/lb1sf68.asm @@ -86,6 +86,76 @@ Boston, MA 02111-1307, USA. */ #define a6 REG (a6) #define fp REG (fp) #define sp REG (sp) +#define pc REG (pc) + +/* Provide a few macros to allow for PIC code support. + * With PIC, data is stored A5 relative so we've got to take a bit of special + * care to ensure that all loads of global data is via A5. PIC also requires + * jumps and subroutine calls to be PC relative rather than absolute. We cheat + * a little on this and in the PIC case, we use short offset branches and + * hope that the final object code is within range (which it should be). + */ +#ifndef __PIC__ + + /* Non PIC (absolute/relocatable) versions */ + + .macro PICCALL addr + jbsr \addr + .endm + + .macro PICJUMP addr + jmp \addr + .endm + + .macro PICLEA sym, reg + lea \sym, \reg + .endm + + .macro PICPEA sym, areg + pea \sym + .endm + +#else /* __PIC__ */ + + /* Common for -mid-shared-libary and -msep-data */ + + .macro PICCALL addr + bsr \addr + .endm + + .macro PICJUMP addr + bra \addr + .endm + +# if defined(__ID_SHARED_LIBRARY__) + + /* -mid-shared-library versions */ + + .macro PICLEA sym, reg + movel a5@(_current_shared_library_a5_offset_), \reg + movel \sym@GOT(\reg), \reg + .endm + + .macro PICPEA sym, areg + movel a5@(_current_shared_library_a5_offset_), \areg + movel \sym@GOT(\areg), sp@- + .endm + +# else /* !__ID_SHARED_LIBRARY__ */ + + /* Versions for -msep-data */ + + .macro PICLEA sym, reg + movel \sym@GOT(a5), \reg + .endm + + .macro PICPEA sym, areg + movel \sym@GOT(a5), sp@- + .endm + +# endif /* !__ID_SHARED_LIBRARY__ */ +#endif /* __PIC__ */ + #ifdef L_floatex @@ -213,7 +283,7 @@ TRUNCDFSF = 7 | void __clear_sticky_bits(void); SYM (__clear_sticky_bit): - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 #ifndef __mcoldfire__ movew IMM (0),a0@(STICK) #else @@ -246,7 +316,7 @@ SYM (__clear_sticky_bit): FPTRAP = 15 $_exception_handler: - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew d7,a0@(EBITS) | set __exception_bits #ifndef __mcoldfire__ orw d7,a0@(STICK) | and __sticky_bits @@ -282,7 +352,7 @@ $_exception_handler: andl d6,d7 #endif beq 1f | no, exit - pea SYM (_fpCCR) | yes, push address of _fpCCR + PICPEA SYM (_fpCCR),a1 | yes, push address of _fpCCR trap IMM (FPTRAP) | and trap #ifndef __mcoldfire__ 1: moveml sp@+,d2-d7 | restore data registers @@ -421,7 +491,7 @@ L1: movel sp@(8), d0 /* d0 = dividend */ L2: movel d1, sp@- movel d0, sp@- - jbsr SYM (__udivsi3) /* divide abs(dividend) by abs(divisor) */ + PICCALL SYM (__udivsi3) /* divide abs(dividend) by abs(divisor) */ addql IMM (8), sp tstb d2 @@ -441,13 +511,13 @@ SYM (__umodsi3): movel sp@(4), d0 /* d0 = dividend */ movel d1, sp@- movel d0, sp@- - jbsr SYM (__udivsi3) + PICCALL SYM (__udivsi3) addql IMM (8), sp movel sp@(8), d1 /* d1 = divisor */ #ifndef __mcoldfire__ movel d1, sp@- movel d0, sp@- - jbsr SYM (__mulsi3) /* d0 = (a/b)*b */ + PICCALL SYM (__mulsi3) /* d0 = (a/b)*b */ addql IMM (8), sp #else mulsl d1,d0 @@ -467,13 +537,13 @@ SYM (__modsi3): movel sp@(4), d0 /* d0 = dividend */ movel d1, sp@- movel d0, sp@- - jbsr SYM (__divsi3) + PICCALL SYM (__divsi3) addql IMM (8), sp movel sp@(8), d1 /* d1 = divisor */ #ifndef __mcoldfire__ movel d1, sp@- movel d0, sp@- - jbsr SYM (__mulsi3) /* d0 = (a/b)*b */ + PICCALL SYM (__mulsi3) /* d0 = (a/b)*b */ addql IMM (8), sp #else mulsl d1,d0 @@ -540,7 +610,7 @@ Ld$den: orl d7,d0 movew IMM (INEXACT_RESULT+UNDERFLOW),d7 moveq IMM (DOUBLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Ld$infty: Ld$overflow: @@ -550,7 +620,7 @@ Ld$overflow: orl d7,d0 movew IMM (INEXACT_RESULT+OVERFLOW),d7 moveq IMM (DOUBLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Ld$underflow: | Return 0 and set the exception flags @@ -558,7 +628,7 @@ Ld$underflow: movel d0,d1 movew IMM (INEXACT_RESULT+UNDERFLOW),d7 moveq IMM (DOUBLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Ld$inop: | Return a quiet NaN and set the exception flags @@ -566,7 +636,7 @@ Ld$inop: movel d0,d1 movew IMM (INEXACT_RESULT+INVALID_OPERATION),d7 moveq IMM (DOUBLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Ld$div$0: | Return a properly signed INFINITY and set the exception flags @@ -575,7 +645,7 @@ Ld$div$0: orl d7,d0 movew IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7 moveq IMM (DOUBLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler |============================================================================= |============================================================================= @@ -1015,8 +1085,8 @@ Ladddf$4: addl IMM (1),d4 #endif 1: - lea Ladddf$5,a0 | to return from rounding routine - lea SYM (_fpCCR),a1 | check the rounding mode + lea pc@(Ladddf$5),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode #ifdef __mcoldfire__ clrl d6 #endif @@ -1123,8 +1193,8 @@ Lsubdf$0: addl IMM (1),d4 #endif 1: - lea Lsubdf$1,a0 | to return from rounding routine - lea SYM (_fpCCR),a1 | check the rounding mode + lea pc@(Lsubdf$1),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode #ifdef __mcoldfire__ clrl d6 #endif @@ -1168,7 +1238,7 @@ Ladddf$a$small: #endif movel a6@(16),d0 movel a6@(20),d1 - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ #ifndef __mcoldfire__ moveml sp@+,d2-d7 | restore data registers @@ -1190,7 +1260,7 @@ Ladddf$b$small: #endif movel a6@(8),d0 movel a6@(12),d1 - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ #ifndef __mcoldfire__ moveml sp@+,d2-d7 | restore data registers @@ -1248,7 +1318,7 @@ Ladddf$ret$1: Ladddf$ret: | Normal exit. - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ orl d7,d0 | put sign bit back #ifndef __mcoldfire__ @@ -1610,7 +1680,7 @@ Lmuldf$a$0: bclr IMM (31),d2 | clear sign bit 1: cmpl IMM (0x7ff00000),d2 | check for non-finiteness bge Ld$inop | in case NaN or +/-INFINITY return NaN - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ #ifndef __mcoldfire__ moveml sp@+,d2-d7 @@ -1895,7 +1965,7 @@ Ldivdf$a$0: bne Ld$inop | 1: movel IMM (0),d0 | else return zero movel d0,d1 | - lea SYM (_fpCCR),a0 | clear exception flags + PICLEA SYM (_fpCCR),a0 | clear exception flags movew IMM (0),a0@ | #ifndef __mcoldfire__ moveml sp@+,d2-d7 | @@ -2035,8 +2105,8 @@ Lround$exit: orl d7,d3 | the bits which were flushed right movel a0,d7 | get back sign bit into d7 | Now call the rounding routine (which takes care of denormalized numbers): - lea Lround$0,a0 | to return from rounding routine - lea SYM (_fpCCR),a1 | check the rounding mode + lea pc@(Lround$0),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode #ifdef __mcoldfire__ clrl d6 #endif @@ -2084,7 +2154,7 @@ Lround$0: swap d0 | orl d7,d0 | and sign also - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ #ifndef __mcoldfire__ moveml sp@+,d2-d7 @@ -2126,7 +2196,7 @@ SYM (__negdf2): movel d0,d7 | else get sign and return INFINITY andl IMM (0x80000000),d7 bra Ld$infty -1: lea SYM (_fpCCR),a0 +1: PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ #ifndef __mcoldfire__ moveml sp@+,d2-d7 @@ -2424,7 +2494,7 @@ Lf$den: orl d7,d0 movew IMM (INEXACT_RESULT+UNDERFLOW),d7 moveq IMM (SINGLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Lf$infty: Lf$overflow: @@ -2433,21 +2503,21 @@ Lf$overflow: orl d7,d0 movew IMM (INEXACT_RESULT+OVERFLOW),d7 moveq IMM (SINGLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Lf$underflow: | Return 0 and set the exception flags movel IMM (0),d0 movew IMM (INEXACT_RESULT+UNDERFLOW),d7 moveq IMM (SINGLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Lf$inop: | Return a quiet NaN and set the exception flags movel IMM (QUIET_NaN),d0 movew IMM (INEXACT_RESULT+INVALID_OPERATION),d7 moveq IMM (SINGLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler Lf$div$0: | Return a properly signed INFINITY and set the exception flags @@ -2455,7 +2525,7 @@ Lf$div$0: orl d7,d0 movew IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7 moveq IMM (SINGLE_FLOAT),d6 - jmp $_exception_handler + PICJUMP $_exception_handler |============================================================================= |============================================================================= @@ -2737,8 +2807,8 @@ Laddsf$3: #endif addl IMM (1),d2 1: - lea Laddsf$4,a0 | to return from rounding routine - lea SYM (_fpCCR),a1 | check the rounding mode + lea pc@(Laddsf$4),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode #ifdef __mcoldfire__ clrl d6 #endif @@ -2802,8 +2872,8 @@ Lsubsf$0: | Note that we do not have to normalize, since in the subtraction bit | #FLT_MANT_DIG+1 is never set, and denormalized numbers are handled by | the rounding routines themselves. - lea Lsubsf$1,a0 | to return from rounding routine - lea SYM (_fpCCR),a1 | check the rounding mode + lea pc@(Lsubsf$1),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode #ifdef __mcoldfire__ clrl d6 #endif @@ -2834,7 +2904,7 @@ Lsubsf$1: | check for finiteness or zero). Laddsf$a$small: movel a6@(12),d0 - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ #ifndef __mcoldfire__ moveml sp@+,d2-d7 | restore data registers @@ -2848,7 +2918,7 @@ Laddsf$a$small: Laddsf$b$small: movel a6@(8),d0 - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ #ifndef __mcoldfire__ moveml sp@+,d2-d7 | restore data registers @@ -2905,7 +2975,7 @@ Laddsf$a: Laddsf$ret: | Normal exit (a and b nonzero, result is not NaN nor +/-infty). | We have to clear the exception flags (just the exception type). - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ orl d7,d0 | put sign bit #ifndef __mcoldfire__ @@ -3141,7 +3211,7 @@ Lmulsf$a$0: 1: bclr IMM (31),d1 | clear sign bit cmpl IMM (INFINITY),d1 | and check for a large exponent bge Lf$inop | if b is +/-INFINITY or NaN return NaN - lea SYM (_fpCCR),a0 | else return zero + PICLEA SYM (_fpCCR),a0 | else return zero movew IMM (0),a0@ | #ifndef __mcoldfire__ moveml sp@+,d2-d7 | @@ -3341,7 +3411,7 @@ Ldivsf$a$0: cmpl IMM (INFINITY),d1 | check for NaN bhi Lf$inop | movel IMM (0),d0 | else return zero - lea SYM (_fpCCR),a0 | + PICLEA SYM (_fpCCR),a0 | movew IMM (0),a0@ | #ifndef __mcoldfire__ moveml sp@+,d2-d7 | @@ -3444,8 +3514,8 @@ Lround$exit: 2: orl d6,d1 | this is a trick so we don't lose ' | the extra bits which were flushed right | Now call the rounding routine (which takes care of denormalized numbers): - lea Lround$0,a0 | to return from rounding routine - lea SYM (_fpCCR),a1 | check the rounding mode + lea pc@(Lround$0),a0 | to return from rounding routine + PICLEA SYM (_fpCCR),a1 | check the rounding mode #ifdef __mcoldfire__ clrl d6 #endif @@ -3493,7 +3563,7 @@ Lround$0: swap d0 | orl d7,d0 | and sign also - lea SYM (_fpCCR),a0 + PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ #ifndef __mcoldfire__ moveml sp@+,d2-d7 @@ -3534,7 +3604,7 @@ SYM (__negsf2): movel d0,d7 | else get sign and return INFINITY andl IMM (0x80000000),d7 bra Lf$infty -1: lea SYM (_fpCCR),a0 +1: PICLEA SYM (_fpCCR),a0 movew IMM (0),a0@ #ifndef __mcoldfire__ moveml sp@+,d2-d7 @@ -3742,7 +3812,7 @@ SYM (__eqdf2): movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2) unlk a6 rts #endif /* L_eqdf2 */ @@ -3757,7 +3827,7 @@ SYM (__nedf2): movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2) unlk a6 rts #endif /* L_nedf2 */ @@ -3772,7 +3842,7 @@ SYM (__gtdf2): movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2) unlk a6 rts #endif /* L_gtdf2 */ @@ -3787,7 +3857,7 @@ SYM (__gedf2): movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2) unlk a6 rts #endif /* L_gedf2 */ @@ -3802,7 +3872,7 @@ SYM (__ltdf2): movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2) unlk a6 rts #endif /* L_ltdf2 */ @@ -3817,7 +3887,7 @@ SYM (__ledf2): movl a6@(16),sp@- movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpdf2) + PICCALL SYM (__cmpdf2) unlk a6 rts #endif /* L_ledf2 */ @@ -3833,7 +3903,7 @@ SYM (__eqsf2): link a6,IMM (0) movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2) unlk a6 rts #endif /* L_eqsf2 */ @@ -3846,7 +3916,7 @@ SYM (__nesf2): link a6,IMM (0) movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2) unlk a6 rts #endif /* L_nesf2 */ @@ -3859,7 +3929,7 @@ SYM (__gtsf2): link a6,IMM (0) movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2) unlk a6 rts #endif /* L_gtsf2 */ @@ -3872,7 +3942,7 @@ SYM (__gesf2): link a6,IMM (0) movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2) unlk a6 rts #endif /* L_gesf2 */ @@ -3885,7 +3955,7 @@ SYM (__ltsf2): link a6,IMM (0) movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2) unlk a6 rts #endif /* L_ltsf2 */ @@ -3898,7 +3968,7 @@ SYM (__lesf2): link a6,IMM (0) movl a6@(12),sp@- movl a6@(8),sp@- - jbsr SYM (__cmpsf2) + PICCALL SYM (__cmpsf2) unlk a6 rts #endif /* L_lesf2 */ diff --git a/gcc/config/m68k/m68k-none.h b/gcc/config/m68k/m68k-none.h index b88a67ebc9a..79463b84abc 100644 --- a/gcc/config/m68k/m68k-none.h +++ b/gcc/config/m68k/m68k-none.h @@ -82,6 +82,7 @@ Unrecognized value in TARGET_CPU_DEFAULT. #undef 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)}}}}}}}}}}}}}}}}}} \ +%{fPIC:--pcrel} %{fpic:--pcrel} %{msep-data:--pcrel} %{mid-shared-library:--pcrel} \ " /* cc1/cc1plus always receives all the -m flags. If the specs strings above diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h index c54aea253e7..16800e83a61 100644 --- a/gcc/config/m68k/m68k-protos.h +++ b/gcc/config/m68k/m68k-protos.h @@ -38,6 +38,7 @@ extern const char *output_addsi3 (rtx *); extern const char *output_andsi3 (rtx *); extern const char *output_iorsi3 (rtx *); extern const char *output_xorsi3 (rtx *); +extern void m68k_output_pic_call (rtx dest); extern void output_dbcc_and_branch (rtx *); extern int const_uint32_operand (rtx, enum machine_mode); extern int const_sint32_operand (rtx, enum machine_mode); diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 105f2417ce4..be30fa656e0 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -74,6 +74,8 @@ const char *m68k_align_loops_string; const char *m68k_align_jumps_string; /* Specify power of two alignment used for functions. */ 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. */ int m68k_align_loops; @@ -167,6 +169,38 @@ override_options (void) 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 */ m68k_align_jumps = def_align; if (m68k_align_jumps_string) @@ -192,7 +226,7 @@ override_options (void) /* -fPIC uses 32-bit pc-relative displacements, which don't exist 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"); /* ??? 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) -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 - asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n", - reg_names[PIC_OFFSET_TABLE_REGNUM]); + asm_fprintf (stream, "\t%Olea (%Rpc, %U_GLOBAL_OFFSET_TABLE_@GOTPC), %s\n", + reg_names[PIC_OFFSET_TABLE_REGNUM]); #else - asm_fprintf (stream, "\tmovel %I%U_GLOBAL_OFFSET_TABLE_, %s\n", - reg_names[PIC_OFFSET_TABLE_REGNUM]); - asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n", - reg_names[PIC_OFFSET_TABLE_REGNUM], - reg_names[PIC_OFFSET_TABLE_REGNUM]); + asm_fprintf (stream, "\tmovel %I%U_GLOBAL_OFFSET_TABLE_, %s\n", + reg_names[PIC_OFFSET_TABLE_REGNUM]); + asm_fprintf (stream, "\tlea %Rpc@(0,%s:l),%s\n", + reg_names[PIC_OFFSET_TABLE_REGNUM], + reg_names[PIC_OFFSET_TABLE_REGNUM]); #endif + } } } @@ -1055,6 +1101,39 @@ flags_in_68881 (void) 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 floating point version of this sequence (Fdbcc). We also do not handle alternative conditions when CC_NO_OVERFLOW is @@ -3567,7 +3646,7 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, { if (TARGET_PCREL) fmt = "bra.l %o0"; - else + else if ((flag_pic == 1) || TARGET_68020) { #ifdef MOTOROLA #ifdef HPUX_ASM @@ -3587,6 +3666,10 @@ m68k_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, #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 { diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index 05e1dd55fab..cd512f28edd 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -83,14 +83,28 @@ Boston, MA 02111-1307, USA. */ if (TARGET_CF_HWDIV) \ builtin_define ("__mcfhwdiv__"); \ 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 ("machine=m68k"); \ } \ 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 quantities. */ @@ -305,6 +319,14 @@ extern int target_flags; N_("Align variables on a 32-bit boundary") }, \ { "no-align-int", -MASK_ALIGN_INT, \ 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, \ N_("Generate pc-relative code") }, \ { "strict-align", -MASK_NO_STRICT_ALIGNMENT, \ @@ -335,6 +357,8 @@ extern int target_flags; N_("Jump targets are aligned to this power of 2"), 0}, \ { "align-functions=", &m68k_align_funcs_string, \ 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 \ } @@ -411,6 +435,9 @@ extern int target_flags; /* Maximum power of 2 that code can be aligned to. */ #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. */ #define LOOP_ALIGN(LABEL) (m68k_align_loops) @@ -1638,6 +1665,7 @@ __transfer_from_trampoline () \ extern const char *m68k_align_loops_string; extern const char *m68k_align_jumps_string; extern const char *m68k_align_funcs_string; +extern const char *m68k_library_id_string; extern int m68k_align_loops; extern int m68k_align_jumps; extern int m68k_align_funcs; diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index a354d117ccf..685d37c0de7 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -6796,31 +6796,8 @@ "flag_pic" "* - if (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) - { - 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\"; + m68k_output_pic_call(operands[0]); + return \"\"; ") ;; Call subroutine, returning value in operand 0 @@ -6861,31 +6838,8 @@ ;; Operand 2 not really used on the m68000. "flag_pic" "* - if (GET_CODE (operands[1]) == MEM - && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) - { - 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\"; + m68k_output_pic_call(operands[1]); + return \"\"; ") ;; Call subroutine returning any type. -- 2.30.2