/* Definitions of target machine for GNU compiler. TMS320C[34]x
Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003 Free Software Foundation, Inc.
+ 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl).
#define TARGET_C40 (target_flags & C40_FLAG)
#define TARGET_C44 (target_flags & C44_FLAG)
-/* Define some options to control code generation. */
+/* Nonzero to use load_immed_addr pattern rather than forcing memory
+ addresses into memory. */
#define TARGET_LOAD_ADDRESS (1 || (! TARGET_C3X && ! TARGET_SMALL))
+
/* Nonzero to convert direct memory references into HIGH/LO_SUM pairs
during RTL generation. */
#define TARGET_EXPOSE_LDP 0
+
/* Nonzero to force loading of direct memory references into a register. */
#define TARGET_LOAD_DIRECT_MEMS 0
#define TARGET_RPTS_CYCLES(CYCLES) (TARGET_RPTS || (CYCLES) < c4x_rpts_cycles)
-#define BCT_CHECK_LOOP_ITERATIONS !(TARGET_LOOP_UNSIGNED)
-
/* -mcpu=XX with XX = target DSP version number. */
extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string;
is defined since the MPY|ADD insns require the classes R0R1_REGS and
R2R3_REGS which are used by the function return registers (R0,R1) and
the register arguments (R2,R3), respectively. I'm reluctant to define
- this macro since it stomps on many potential optimisations. Ideally
+ this macro since it stomps on many potential optimizations. Ideally
it should have a register class argument so that not all the register
- classes gets penalised for the sake of a naughty few... For long
+ classes gets penalized for the sake of a naughty few... For long
double arithmetic we need two additional registers that we can use as
spill registers. */
}
CUMULATIVE_ARGS;
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
(c4x_init_cumulative_args (&CUM, FNTYPE, LIBNAME))
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
#define CALLER_SAVE_PROFITABLE(REFS,CALLS) 0
-/* Never pass data by reference. */
-
-#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0
-
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
/* 1 if N is a possible register number for function argument passing. */
/* How Scalar Function Values Are Returned. */
#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx(REG, TYPE_MODE(VALTYPE), R0_REGNO) /* Return in R0. */
+ gen_rtx_REG (TYPE_MODE(VALTYPE), R0_REGNO) /* Return in R0. */
#define LIBCALL_VALUE(MODE) \
- gen_rtx(REG, MODE, R0_REGNO) /* Return in R0. */
+ gen_rtx_REG (MODE, R0_REGNO) /* Return in R0. */
#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == R0_REGNO)
/* How Large Values Are Returned. */
#define DEFAULT_PCC_STRUCT_RETURN 0
-#define STRUCT_VALUE_REGNUM AR0_REGNO /* AR0. */
-
-/* Varargs handling. */
-
-#define EXPAND_BUILTIN_VA_ARG(valist, type) \
- c4x_va_arg (valist, type)
/* Generating Code for Profiling. */
fprintf (FILE, "\tpop\tar2\n"); \
}
-/* Implicit Calls to Library Routines. */
-
-#define MULQI3_LIBCALL "__mulqi3"
-#define DIVQI3_LIBCALL "__divqi3"
-#define UDIVQI3_LIBCALL "__udivqi3"
-#define MODQI3_LIBCALL "__modqi3"
-#define UMODQI3_LIBCALL "__umodqi3"
-
-#define DIVQF3_LIBCALL "__divqf3"
-
-#define MULHF3_LIBCALL "__mulhf3"
-#define DIVHF3_LIBCALL "__divhf3"
-
-#define MULHI3_LIBCALL "__mulhi3"
-#define SMULHI3_LIBCALL "__smulhi3_high"
-#define UMULHI3_LIBCALL "__umulhi3_high"
-#define DIVHI3_LIBCALL "__divhi3"
-#define UDIVHI3_LIBCALL "__udivhi3"
-#define MODHI3_LIBCALL "__modhi3"
-#define UMODHI3_LIBCALL "__umodhi3"
-
-#define FLOATHIQF2_LIBCALL "__floathiqf2"
-#define FLOATUNSHIQF2_LIBCALL "__ufloathiqf2"
-#define FIX_TRUNCQFHI2_LIBCALL "__fix_truncqfhi2"
-#define FIXUNS_TRUNCQFHI2_LIBCALL "__ufix_truncqfhi2"
-
-#define FLOATHIHF2_LIBCALL "__floathihf2"
-#define FLOATUNSHIHF2_LIBCALL "__ufloathihf2"
-#define FIX_TRUNCHFHI2_LIBCALL "__fix_trunchfhi2"
-#define FIXUNS_TRUNCHFHI2_LIBCALL "__ufix_trunchfhi2"
-
-#define FFS_LIBCALL "__ffs"
-
-#define INIT_TARGET_OPTABS \
- do { \
- smul_optab->handlers[(int) QImode].libfunc \
- = init_one_libfunc (MULQI3_LIBCALL); \
- sdiv_optab->handlers[(int) QImode].libfunc \
- = init_one_libfunc (DIVQI3_LIBCALL); \
- udiv_optab->handlers[(int) QImode].libfunc \
- = init_one_libfunc (UDIVQI3_LIBCALL); \
- smod_optab->handlers[(int) QImode].libfunc \
- = init_one_libfunc (MODQI3_LIBCALL); \
- umod_optab->handlers[(int) QImode].libfunc \
- = init_one_libfunc (UMODQI3_LIBCALL); \
- sdiv_optab->handlers[(int) QFmode].libfunc \
- = init_one_libfunc (DIVQF3_LIBCALL); \
- smul_optab->handlers[(int) HFmode].libfunc \
- = init_one_libfunc (MULHF3_LIBCALL); \
- sdiv_optab->handlers[(int) HFmode].libfunc \
- = init_one_libfunc (DIVHF3_LIBCALL); \
- smul_optab->handlers[(int) HImode].libfunc \
- = init_one_libfunc (MULHI3_LIBCALL); \
- sdiv_optab->handlers[(int) HImode].libfunc \
- = init_one_libfunc (DIVHI3_LIBCALL); \
- udiv_optab->handlers[(int) HImode].libfunc \
- = init_one_libfunc (UDIVHI3_LIBCALL); \
- smod_optab->handlers[(int) HImode].libfunc \
- = init_one_libfunc (MODHI3_LIBCALL); \
- umod_optab->handlers[(int) HImode].libfunc \
- = init_one_libfunc (UMODHI3_LIBCALL); \
- ffs_optab->handlers[(int) QImode].libfunc \
- = init_one_libfunc (FFS_LIBCALL); \
- smulhi3_libfunc \
- = init_one_libfunc(SMULHI3_LIBCALL); \
- umulhi3_libfunc \
- = init_one_libfunc(UMULHI3_LIBCALL); \
- fix_truncqfhi2_libfunc \
- = init_one_libfunc(FIX_TRUNCQFHI2_LIBCALL); \
- fixuns_truncqfhi2_libfunc \
- = init_one_libfunc(FIXUNS_TRUNCQFHI2_LIBCALL); \
- fix_trunchfhi2_libfunc \
- = init_one_libfunc(FIX_TRUNCHFHI2_LIBCALL); \
- fixuns_trunchfhi2_libfunc \
- = init_one_libfunc(FIXUNS_TRUNCHFHI2_LIBCALL); \
- floathiqf2_libfunc \
- = init_one_libfunc(FLOATHIQF2_LIBCALL); \
- floatunshiqf2_libfunc \
- = init_one_libfunc(FLOATUNSHIQF2_LIBCALL); \
- floathihf2_libfunc \
- = init_one_libfunc(FLOATHIHF2_LIBCALL); \
- floatunshihf2_libfunc \
- = init_one_libfunc(FLOATUNSHIHF2_LIBCALL); \
- } while (0)
-
-#define TARGET_MEM_FUNCTIONS
-
/* CC_NOOVmode should be used when the first operand is a PLUS, MINUS, NEG
or MULT.
CCmode should be used when no special processing is needed. */
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ \
- if (c4x_check_legit_addr (MODE, X, 0)) \
+ if (c4x_legitimate_address_p (MODE, X, 0)) \
goto ADDR; \
}
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ \
- if (c4x_check_legit_addr (MODE, X, 1)) \
+ if (c4x_legitimate_address_p (MODE, X, 1)) \
goto ADDR; \
}
#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
{ \
rtx new; \
+ \
new = c4x_legitimize_address (X, MODE); \
if (new != NULL_RTX) \
{ \
if (! TARGET_SMALL) \
{ \
int i; \
- X = gen_rtx_LO_SUM (GET_MODE (X), \
+ (X) = gen_rtx_LO_SUM (GET_MODE (X), \
gen_rtx_HIGH (GET_MODE (X), X), X); \
i = push_reload (XEXP (X, 0), NULL_RTX, \
&XEXP (X, 0), NULL, \
rld[i].reg_rtx = gen_rtx_REG (Pmode, DP_REGNO); \
rld[i].nocombine = 1; \
} \
+ else \
+ { \
+ /* make_memloc in reload will substitute invalid memory \
+ references. We need to fix them up. */ \
+ (X) = gen_rtx_LO_SUM (Pmode, gen_rtx_REG (Pmode, DP_REGNO), (X)); \
+ } \
goto WIN; \
} \
else if (MODE != HImode \
FINI_SECTION_FUNCTION
#define INIT_SECTION_FUNCTION \
-extern void init_section PARAMS ((void)); \
+extern void init_section (void); \
void \
-init_section () \
+init_section (void) \
{ \
if (in_section != in_init) \
{ \
/* Overall Framework of an Assembler File. */
-/* We need to have a data section we can identify so that we can set
- the DP register back to a data pointer in the small memory model.
- This is only required for ISRs if we are paranoid that someone
- may have quietly changed this register on the sly. */
-
-#define ASM_FILE_START(FILE) \
-{ \
- int dspversion = 0; \
- if (TARGET_C30) dspversion = 30; \
- if (TARGET_C31) dspversion = 31; \
- if (TARGET_C32) dspversion = 32; \
- if (TARGET_C33) dspversion = 33; \
- if (TARGET_C40) dspversion = 40; \
- if (TARGET_C44) dspversion = 44; \
- fprintf (FILE, "\t.version\t%d\n", dspversion); \
- fprintf (FILE, "\t.file\t"); \
- if (TARGET_TI) \
- { \
- const char *p; \
- const char *after_dir = main_input_filename; \
- for (p = main_input_filename; *p; p++) \
- if (*p == '/') \
- after_dir = p + 1; \
- output_quoted_string (FILE, after_dir); \
- } \
- else \
- output_quoted_string (FILE, main_input_filename); \
- fputs ("\n\t.data\ndata_sec:\n", FILE); \
-}
#define ASM_COMMENT_START ";"
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
c4x_external_ref (NAME)
-/* A C statement to output on FILE an assembler pseudo-op to
- declare a library function named external.
- (Only needed to keep asm30 happy for ___divqf3 etc.) */
-
-#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
-c4x_external_ref (XSTR (FUN, 0))
-
-#define ASM_FILE_END(FILE) \
-c4x_file_end (FILE)
-
/* The prefix to add to user-visible assembler symbols. */
#define USER_LABEL_PREFIX "_"
This is suitable for output with `assemble_name'. */
#define ASM_GENERATE_INTERNAL_LABEL(BUFFER, PREFIX, NUM) \
- sprintf (BUFFER, "*%s%d", PREFIX, NUM)
+ sprintf (BUFFER, "*%s%lu", PREFIX, (unsigned long)(NUM))
/* A C statement to output to the stdio stream STREAM assembler code which
defines (equates) the symbol NAME to have the value VALUE. */
tmp2 = expand_shift (LSHIFT_EXPR, QImode, \
GEN_INT (0x5069), size_int (16), 0, 1); \
emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \
- emit_move_insn (gen_rtx (MEM, QImode, \
- plus_constant (tramp, 0)), tmp1); \
+ emit_move_insn (gen_rtx_MEM (QImode, \
+ plus_constant (TRAMP, 0)), tmp1); \
tmp1 = expand_and (QImode, FNADDR, GEN_INT (0xffff), 0); \
tmp2 = expand_shift (LSHIFT_EXPR, QImode, \
GEN_INT (0x1069), size_int (16), 0, 1); \
emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \
- emit_move_insn (gen_rtx (MEM, QImode, \
- plus_constant (tramp, 2)), tmp1); \
+ emit_move_insn (gen_rtx_MEM (QImode, \
+ plus_constant (TRAMP, 2)), tmp1); \
tmp1 = expand_shift (RSHIFT_EXPR, QImode, CXT, \
size_int (16), 0, 1); \
tmp2 = expand_shift (LSHIFT_EXPR, QImode, \
GEN_INT (0x5068), size_int (16), 0, 1); \
emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \
- emit_move_insn (gen_rtx (MEM, QImode, \
- plus_constant (tramp, 3)), tmp1); \
+ emit_move_insn (gen_rtx_MEM (QImode, \
+ plus_constant (TRAMP, 3)), tmp1); \
tmp1 = expand_and (QImode, CXT, GEN_INT (0xffff), 0); \
tmp2 = expand_shift (LSHIFT_EXPR, QImode, \
GEN_INT (0x1068), size_int (16), 0, 1); \
emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \
- emit_move_insn (gen_rtx (MEM, QImode, \
- plus_constant (tramp, 6)), tmp1); \
+ emit_move_insn (gen_rtx_MEM (QImode, \
+ plus_constant (TRAMP, 6)), tmp1); \
} \
else \
{ \
- emit_move_insn (gen_rtx (MEM, QImode, \
+ emit_move_insn (gen_rtx_MEM (QImode, \
plus_constant (TRAMP, 8)), FNADDR); \
- emit_move_insn (gen_rtx (MEM, QImode, \
+ emit_move_insn (gen_rtx_MEM (QImode, \
plus_constant (TRAMP, 9)), CXT); \
} \
}
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-/* We need to use direct addressing for large constants and addresses
- that cannot fit within an instruction. We must check for these
- after after the final jump optimisation pass, since this may
- introduce a local_move insn for a SYMBOL_REF. This pass
- must come before delayed branch slot filling since it can generate
- additional instructions. */
-
-#define MACHINE_DEPENDENT_REORG(INSNS) c4x_process_after_reload(INSNS)
-
#define DBR_OUTPUT_SEQEND(FILE) \
if (final_sequence != NULL_RTX) \
{ \
C4X_BUILTIN_FRIEEE, /* frieee (only C4x) */
C4X_BUILTIN_RCPF /* fast_invf (only C4x) */
};
+
+
+/* Hack to overcome use of libgcc2.c using auto-host.h to determine
+ HAVE_GAS_HIDDEN. */
+#undef HAVE_GAS_HIDDEN