{ \
builtin_define ("bfin"); \
builtin_define ("BFIN"); \
+ builtin_define ("__ADSPBLACKFIN__"); \
+ if (TARGET_FDPIC) \
+ builtin_define ("__BFIN_FDPIC__"); \
+ if (TARGET_ID_SHARED_LIBRARY) \
+ builtin_define ("__ID_SHARED_LIB__"); \
} \
while (0)
#endif
+#define DRIVER_SELF_SPECS SUBTARGET_DRIVER_SELF_SPECS "\
+ %{mfdpic:%{!fpic:%{!fpie:%{!fPIC:%{!fPIE:\
+ %{!fno-pic:%{!fno-pie:%{!fno-PIC:%{!fno-PIE:-fpie}}}}}}}}} \
+"
+#ifndef SUBTARGET_DRIVER_SELF_SPECS
+# define SUBTARGET_DRIVER_SELF_SPECS
+#endif
+
+#define LINK_GCC_C_SEQUENCE_SPEC \
+ "%{mfdpic:%{!static: %L} %{static: %G %L %G}} \
+ %{!mfdpic:%G %L %G}"
+
+/* A C string constant that tells the GCC driver program options to pass to
+ the assembler. It can also specify how to translate options you give to GNU
+ CC into options for GCC to pass to the assembler. See the file `sun3.h'
+ for an example of this.
+
+ Do not define this macro if it does not need to do anything.
+
+ Defined in svr4.h. */
+#undef ASM_SPEC
+#define ASM_SPEC "\
+%{G*} %{v} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
+ %{mno-fdpic:-mnopic} %{mfdpic}"
+
+#define LINK_SPEC "\
+%{h*} %{v:-V} \
+%{b} \
+%{mfdpic:-melf32bfinfd -z text} \
+%{static:-dn -Bstatic} \
+%{shared:-G -Bdynamic} \
+%{symbolic:-Bsymbolic} \
+%{G*} \
+%{YP,*} \
+%{Qy:} %{!Qn:-Qy} \
+-init __init -fini __fini "
+
/* Generate DSP instructions, like DSP halfword loads */
#define TARGET_DSP (1)
to allocate such a register (if necessary). */
#define PIC_OFFSET_TABLE_REGNUM (REG_P5)
+#define FDPIC_FPTR_REGNO REG_P1
+#define FDPIC_REGNO REG_P3
+#define OUR_FDPIC_REG get_hard_reg_initial_val (SImode, FDPIC_REGNO)
+
/* A static chain register for nested functions. We need to use a
call-clobbered register for this. */
#define STATIC_CHAIN_REGNUM REG_P2
*/
#define FRAME_POINTER_REQUIRED (bfin_frame_pointer_required ())
-#define PARM_BOUNDRY 32
-
-#define STACK_BOUNDRY 32
-
/*#define DATA_ALIGNMENT(TYPE, BASIC-ALIGN) for arrays.. */
/* Make strings word-aligned so strcpy from constants will be faster. */
(TREE_CODE (EXP) == STRING_CST \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
-#define TRAMPOLINE_SIZE 18
+#define TRAMPOLINE_SIZE (TARGET_FDPIC ? 30 : 18)
#define TRAMPOLINE_TEMPLATE(FILE) \
- fprintf(FILE, "\t.dd\t0x0000e109\n"); /* p1.l = fn low */ \
- fprintf(FILE, "\t.dd\t0x0000e149\n"); /* p1.h = fn high */; \
- fprintf(FILE, "\t.dd\t0x0000e10a\n"); /* p2.l = sc low */; \
- fprintf(FILE, "\t.dd\t0x0000e14a\n"); /* p2.h = sc high */; \
- fprintf(FILE, "\t.dw\t0x0051\n"); /* jump (p1)*/
+ if (TARGET_FDPIC) \
+ { \
+ fprintf(FILE, "\t.dd\t0x00000000\n"); /* 0 */ \
+ fprintf(FILE, "\t.dd\t0x00000000\n"); /* 0 */ \
+ fprintf(FILE, "\t.dd\t0x0000e109\n"); /* p1.l = fn low */ \
+ fprintf(FILE, "\t.dd\t0x0000e149\n"); /* p1.h = fn high */ \
+ fprintf(FILE, "\t.dd\t0x0000e10a\n"); /* p2.l = sc low */ \
+ fprintf(FILE, "\t.dd\t0x0000e14a\n"); /* p2.h = sc high */ \
+ fprintf(FILE, "\t.dw\t0xac4b\n"); /* p3 = [p1 + 4] */ \
+ fprintf(FILE, "\t.dw\t0x9149\n"); /* p1 = [p1] */ \
+ fprintf(FILE, "\t.dw\t0x0051\n"); /* jump (p1)*/ \
+ } \
+ else \
+ { \
+ fprintf(FILE, "\t.dd\t0x0000e109\n"); /* p1.l = fn low */ \
+ fprintf(FILE, "\t.dd\t0x0000e149\n"); /* p1.h = fn high */ \
+ fprintf(FILE, "\t.dd\t0x0000e10a\n"); /* p2.l = sc low */ \
+ fprintf(FILE, "\t.dd\t0x0000e14a\n"); /* p2.h = sc high */ \
+ fprintf(FILE, "\t.dw\t0x0051\n"); /* jump (p1)*/ \
+ }
#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
initialize_trampoline (TRAMP, FNADDR, CXT)
5 return address registers RETS/I/X/N/E
1 arithmetic status register (ASTAT). */
-#define FIRST_PSEUDO_REGISTER 44
+#define FIRST_PSEUDO_REGISTER 50
-#define PREG_P(X) (REG_P (X) && REGNO (X) >= REG_P0 && REGNO (X) <= REG_P7)
-#define ADDRESS_REGNO_P(X) ((X) >= REG_P0 && (X) <= REG_M3)
#define D_REGNO_P(X) ((X) <= REG_R7)
+#define P_REGNO_P(X) ((X) >= REG_P0 && (X) <= REG_P7)
+#define I_REGNO_P(X) ((X) >= REG_I0 && (X) <= REG_I3)
+#define DP_REGNO_P(X) (D_REGNO_P (X) || P_REGNO_P (X))
+#define ADDRESS_REGNO_P(X) ((X) >= REG_P0 && (X) <= REG_M3)
+#define DREG_P(X) (REG_P (X) && D_REGNO_P (REGNO (X)))
+#define PREG_P(X) (REG_P (X) && P_REGNO_P (REGNO (X)))
+#define IREG_P(X) (REG_P (X) && I_REGNO_P (REGNO (X)))
+#define DPREG_P(X) (REG_P (X) && DP_REGNO_P (REGNO (X)))
#define REGISTER_NAMES { \
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", \
"A0", "A1", \
"CC", \
"RETS", "RETI", "RETX", "RETN", "RETE", "ASTAT", "SEQSTAT", "USP", \
- "ARGP" \
+ "ARGP", \
+ "LT0", "LT1", "LC0", "LC1", "LB0", "LB1" \
}
#define SHORT_REGISTER_NAMES { \
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, \
/*i0 i1 i2 i3 b0 b1 b2 b3 l0 l1 l2 l3 m0 m1 m2 m3 */ \
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, \
-/*a0 a1 cc rets/i/x/n/e astat seqstat usp argp */ \
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
+/*a0 a1 cc rets/i/x/n/e astat seqstat usp argp lt0/1 lc0/1 */ \
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+/*lb0/1 */ \
+ 1, 1 \
}
/* 1 for registers not available across function calls.
{ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, \
/*i0 i1 i2 i3 b0 b1 b2 b3 l0 l1 l2 l3 m0 m1 m2 m3 */ \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-/*a0 a1 cc rets/i/x/n/e astat seqstat usp argp */ \
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
+/*a0 a1 cc rets/i/x/n/e astat seqstat usp argp lt0/1 lc0/1 */ \
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+/*lb0/1 */ \
+ 1, 1 \
}
/* Order in which to allocate registers. Each register must be
REG_L0, REG_L1, REG_L2, REG_L3, REG_M0, REG_M1, REG_M2, REG_M3, \
REG_RETS, REG_RETI, REG_RETX, REG_RETN, REG_RETE, \
REG_ASTAT, REG_SEQSTAT, REG_USP, \
- REG_CC, REG_ARGP \
+ REG_CC, REG_ARGP, \
+ REG_LT0, REG_LT1, REG_LC0, REG_LC1, REG_LB0, REG_LB1 \
}
/* Macro to conditionally modify fixed_regs/call_used_regs. */
#define CONDITIONAL_REGISTER_USAGE \
{ \
conditional_register_usage(); \
- if (flag_pic) \
+ if (TARGET_FDPIC) \
+ call_used_regs[FDPIC_REGNO] = 1; \
+ if (!TARGET_FDPIC && flag_pic) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
EVEN_DREGS,
ODD_DREGS,
DREGS,
+ FDPIC_REGS,
+ FDPIC_FPTR_REGS,
PREGS_CLOBBERED,
PREGS,
+ IPREGS,
DPREGS,
MOST_REGS,
+ LT_REGS,
+ LC_REGS,
+ LB_REGS,
PROLOGUE_REGS,
NON_A_CC_REGS,
ALL_REGS, LIM_REG_CLASSES
"EVEN_DREGS", \
"ODD_DREGS", \
"DREGS", \
+ "FDPIC_REGS", \
+ "FDPIC_FPTR_REGS", \
"PREGS_CLOBBERED", \
"PREGS", \
+ "IPREGS", \
"DPREGS", \
"MOST_REGS", \
+ "LT_REGS", \
+ "LC_REGS", \
+ "LB_REGS", \
"PROLOGUE_REGS", \
"NON_A_CC_REGS", \
"ALL_REGS" }
{ 0x00000055, 0 }, /* EVEN_DREGS */ \
{ 0x000000aa, 0 }, /* ODD_DREGS */ \
{ 0x000000ff, 0 }, /* DREGS */ \
+ { 0x00000800, 0x000 }, /* FDPIC_REGS */ \
+ { 0x00000200, 0x000 }, /* FDPIC_FPTR_REGS */ \
{ 0x00004700, 0x800 }, /* PREGS_CLOBBERED */ \
{ 0x0000ff00, 0x800 }, /* PREGS */ \
+ { 0x000fff00, 0x800 }, /* IPREGS */ \
{ 0x0000ffff, 0x800 }, /* DPREGS */ \
{ 0xffffffff, 0x800 }, /* MOST_REGS */\
- { 0x00000000, 0x7f8 }, /* PROLOGUE_REGS */\
- { 0xffffffff, 0xff8 }, /* NON_A_CC_REGS */\
- { 0xffffffff, 0xfff }} /* ALL_REGS */
+ { 0x00000000, 0x3000 }, /* LT_REGS */\
+ { 0x00000000, 0xc000 }, /* LC_REGS */\
+ { 0x00000000, 0x30000 }, /* LB_REGS */\
+ { 0x00000000, 0x3f7f8 }, /* PROLOGUE_REGS */\
+ { 0xffffffff, 0x3fff8 }, /* NON_A_CC_REGS */\
+ { 0xffffffff, 0x3ffff }} /* ALL_REGS */
+
+#define IREG_POSSIBLE_P(OUTER) \
+ ((OUTER) == POST_INC || (OUTER) == PRE_INC \
+ || (OUTER) == POST_DEC || (OUTER) == PRE_DEC \
+ || (OUTER) == MEM || (OUTER) == ADDRESS)
+
+#define MODE_CODE_BASE_REG_CLASS(MODE, OUTER, INDEX) \
+ ((MODE) == HImode && IREG_POSSIBLE_P (OUTER) ? IPREGS : PREGS)
-#define BASE_REG_CLASS PREGS
#define INDEX_REG_CLASS PREGS
-#define REGNO_OK_FOR_BASE_STRICT_P(X) (REGNO_REG_CLASS (X) == BASE_REG_CLASS)
-#define REGNO_OK_FOR_BASE_NONSTRICT_P(X) \
- (((X) >= FIRST_PSEUDO_REGISTER) || REGNO_REG_CLASS (X) == BASE_REG_CLASS)
+#define REGNO_OK_FOR_BASE_STRICT_P(X, MODE, OUTER, INDEX) \
+ (P_REGNO_P (X) || (X) == REG_ARGP \
+ || (IREG_POSSIBLE_P (OUTER) && (MODE) == HImode \
+ && I_REGNO_P (X)))
+
+#define REGNO_OK_FOR_BASE_NONSTRICT_P(X, MODE, OUTER, INDEX) \
+ ((X) >= FIRST_PSEUDO_REGISTER \
+ || REGNO_OK_FOR_BASE_STRICT_P (X, MODE, OUTER, INDEX))
#ifdef REG_OK_STRICT
-#define REGNO_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_STRICT_P (X)
+#define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, OUTER, INDEX) \
+ REGNO_OK_FOR_BASE_STRICT_P (X, MODE, OUTER, INDEX)
#else
-#define REGNO_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_NONSTRICT_P (X)
+#define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, OUTER, INDEX) \
+ REGNO_OK_FOR_BASE_NONSTRICT_P (X, MODE, OUTER, INDEX)
#endif
-#define REG_OK_FOR_BASE_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X)))
-#define REG_OK_FOR_INDEX_P(X) 0
#define REGNO_OK_FOR_INDEX_P(X) 0
/* Get reg_class from a letter such as appears in the machine description. */
#define REG_CLASS_FROM_LETTER(LETTER) \
((LETTER) == 'a' ? PREGS : \
+ (LETTER) == 'Z' ? FDPIC_REGS : \
+ (LETTER) == 'Y' ? FDPIC_FPTR_REGS : \
(LETTER) == 'd' ? DREGS : \
(LETTER) == 'z' ? PREGS_CLOBBERED : \
(LETTER) == 'D' ? EVEN_DREGS : \
(LETTER) == 'A' ? EVEN_AREGS : \
(LETTER) == 'B' ? ODD_AREGS : \
(LETTER) == 'b' ? IREGS : \
- (LETTER) == 'B' ? BREGS : \
+ (LETTER) == 'v' ? BREGS : \
(LETTER) == 'f' ? MREGS : \
(LETTER) == 'c' ? CIRCREGS : \
(LETTER) == 'C' ? CCREGS : \
+ (LETTER) == 't' ? LT_REGS : \
+ (LETTER) == 'k' ? LC_REGS : \
+ (LETTER) == 'u' ? LB_REGS : \
(LETTER) == 'x' ? MOST_REGS : \
(LETTER) == 'y' ? PROLOGUE_REGS : \
(LETTER) == 'w' ? NON_A_CC_REGS : \
#define REGNO_REG_CLASS(REGNO) \
((REGNO) < REG_P0 ? DREGS \
: (REGNO) < REG_I0 ? PREGS \
- : (REGNO) == REG_ARGP ? BASE_REG_CLASS \
+ : (REGNO) == REG_ARGP ? PREGS \
: (REGNO) >= REG_I0 && (REGNO) <= REG_I3 ? IREGS \
: (REGNO) >= REG_L0 && (REGNO) <= REG_L3 ? LREGS \
: (REGNO) >= REG_B0 && (REGNO) <= REG_B3 ? BREGS \
: (REGNO) >= REG_M0 && (REGNO) <= REG_M3 ? MREGS \
: (REGNO) == REG_A0 || (REGNO) == REG_A1 ? AREGS \
+ : (REGNO) == REG_LT0 || (REGNO) == REG_LT1 ? LT_REGS \
+ : (REGNO) == REG_LC0 || (REGNO) == REG_LC1 ? LC_REGS \
+ : (REGNO) == REG_LB0 || (REGNO) == REG_LB1 ? LB_REGS \
: (REGNO) == REG_CC ? CCREGS \
: (REGNO) >= REG_RETS ? PROLOGUE_REGS \
: NO_REGS)
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+#define CLASS_MAX_NREGS(CLASS, MODE) \
+ ((MODE) == V2PDImode && (CLASS) == AREGS ? 2 \
+ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
#define HARD_REGNO_NREGS(REGNO, MODE) \
-((MODE) == PDImode && ((REGNO) == REG_A0 || (REGNO) == REG_A1) \
- ? 1 : CLASS_MAX_NREGS (GENERAL_REGS, MODE))
+ ((MODE) == PDImode && ((REGNO) == REG_A0 || (REGNO) == REG_A1) ? 1 \
+ : (MODE) == V2PDImode && ((REGNO) == REG_A0 || (REGNO) == REG_A1) ? 2 \
+ : CLASS_MAX_NREGS (GENERAL_REGS, MODE))
/* A C expression that is nonzero if hard register TO can be
considered for use as a rename register for FROM register */
perhaps another, smaller class. */
#define PREFERRED_RELOAD_CLASS(X, CLASS) (CLASS)
-#define SECONDARY_OUTPUT_RELOAD_CLASS(class,mode,x) \
- secondary_output_reload_class(class,mode,x)
-#define SECONDARY_INPUT_RELOAD_CLASS(class,mode,x) \
- secondary_input_reload_class(class,mode,x)
-
/* Function Calling Conventions. */
/* The type of the current function; normal functions are of type
do { fprintf (FILE, "_%s", NAME); \
} while (0)
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
- do { \
- int len = strlen (NAME); \
- char *temp = (char *) alloca (len + 4); \
- temp[0] = 'L'; \
- temp[1] = '_'; \
- strcpy (&temp[2], (NAME)); \
- temp[len + 2] = '_'; \
- temp[len + 3] = 0; \
- (OUTPUT) = (char *) alloca (strlen (NAME) + 13); \
- sprintf (OUTPUT, "_%s$%d", temp, LABELNO); \
- } while (0)
-
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
do { char __buf[256]; \
fprintf (FILE, "\t.dd\t"); \
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
do { \
- data_section(); \
+ switch_to_section (data_section); \
if ((SIZE) >= (unsigned int) 4 ) ASM_OUTPUT_ALIGN(FILE,2); \
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
ASM_OUTPUT_LABEL (FILE, NAME); \
/* This works for GAS and some other assemblers. */
#define SET_ASM_OP ".set "
-/* Don't know how to order these. UNALIGNED_WORD_ASM_OP is in
- dwarf2.out. */
-#define UNALIGNED_WORD_ASM_OP ".4byte"
-
/* DBX register number for a given compiler register number */
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)