/* Subroutines for insn-output.c for Motorola 68000 family.
- Copyright (C) 1987, 93-98, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
This file is part of GNU CC.
#include "real.h"
#include "insn-config.h"
#include "conditions.h"
-#include "insn-flags.h"
#include "output.h"
#include "insn-attr.h"
#include "recog.h"
#include "toplev.h"
+#include "tm_p.h"
+#include "target.h"
+#include "target-def.h"
/* Needed for use_return_insn. */
#include "flags.h"
if SGS_SWITCH_TABLE. */
int switch_table_difference_label_flag;
-static rtx find_addr_reg ();
-rtx legitimize_pic_address ();
-void print_operand_address ();
+static rtx find_addr_reg PARAMS ((rtx));
+static const char *singlemove_string PARAMS ((rtx *));
\f
/* Alignment to use for loops and jumps */
sCC expanders peek at this to determine what to do for the
68060, which has no fsCC instructions. */
int m68k_last_compare_had_fp_operands;
+\f
+/* Initialize the GCC target structure. */
+struct gcc_target target = TARGET_INITIALIZER;
+\f
/* Sometimes certain combinations of command options do not make
sense on a particular target machine. You can define a macro
`OVERRIDE_OPTIONS' to take account of this. This macro, if
override_options ()
{
int def_align;
+ int i;
def_align = 1;
/* Validate -malign-loops= value, or provide default */
+ m68k_align_loops = def_align;
if (m68k_align_loops_string)
{
- m68k_align_loops = atoi (m68k_align_loops_string);
- if (m68k_align_loops < 1 || m68k_align_loops > MAX_CODE_ALIGN)
- fatal ("-malign-loops=%d is not between 1 and %d",
- m68k_align_loops, MAX_CODE_ALIGN);
+ i = atoi (m68k_align_loops_string);
+ if (i < 1 || i > MAX_CODE_ALIGN)
+ error ("-malign-loops=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
+ else
+ m68k_align_loops = i;
}
- else
- m68k_align_loops = def_align;
/* Validate -malign-jumps= value, or provide default */
+ m68k_align_jumps = def_align;
if (m68k_align_jumps_string)
{
- m68k_align_jumps = atoi (m68k_align_jumps_string);
- if (m68k_align_jumps < 1 || m68k_align_jumps > MAX_CODE_ALIGN)
- fatal ("-malign-jumps=%d is not between 1 and %d",
- m68k_align_jumps, MAX_CODE_ALIGN);
+ i = atoi (m68k_align_jumps_string);
+ if (i < 1 || i > MAX_CODE_ALIGN)
+ error ("-malign-jumps=%d is not between 1 and %d", i, MAX_CODE_ALIGN);
+ else
+ m68k_align_jumps = i;
}
- else
- m68k_align_jumps = def_align;
/* Validate -malign-functions= value, or provide default */
+ m68k_align_funcs = def_align;
if (m68k_align_funcs_string)
{
- m68k_align_funcs = atoi (m68k_align_funcs_string);
- if (m68k_align_funcs < 1 || m68k_align_funcs > MAX_CODE_ALIGN)
- fatal ("-malign-functions=%d is not between 1 and %d",
- m68k_align_funcs, MAX_CODE_ALIGN);
+ i = atoi (m68k_align_funcs_string);
+ if (i < 1 || i > MAX_CODE_ALIGN)
+ error ("-malign-functions=%d is not between 1 and %d",
+ i, MAX_CODE_ALIGN);
+ else
+ m68k_align_funcs = i;
}
- else
- m68k_align_funcs = def_align;
}
\f
/* This function generates the assembly code for function entry.
int fsize = (size + 3) & -4;
int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset;
+ /* If the stack limit is a symbol, we can check it here,
+ before actually allocating the space. */
+ if (current_function_limit_stack
+ && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
+ {
+#if defined (MOTOROLA)
+ asm_fprintf (stream, "\tcmp.l %0I%s+%d,%Rsp\n\ttrapcs\n",
+ XSTR (stack_limit_rtx, 0), fsize + 4);
+#else
+ asm_fprintf (stream, "\tcmpl %0I%s+%d,%Rsp\n\ttrapcs\n",
+ XSTR (stack_limit_rtx, 0), fsize + 4);
+#endif
+ }
if (frame_pointer_needed)
{
l = (char *) dwarf2out_cfi_label ();
cfa_store_offset += 4;
cfa_offset = cfa_store_offset;
- dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, cfa_offset);
dwarf2out_reg_save (l, FRAME_POINTER_REGNUM, -cfa_store_offset);
+ dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, cfa_offset);
cfa_store_offset += fsize;
}
}
mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM));
num_saved_regs--;
}
- if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+ if (flag_pic && current_function_uses_pic_offset_table)
{
mask |= 1 << (15 - PIC_OFFSET_TABLE_REGNUM);
num_saved_regs++;
#endif
#endif
+ /* If the stack limit is not a symbol, check it here.
+ This has the disadvantage that it may be too late... */
+ if (current_function_limit_stack)
+ {
+ if (REG_P (stack_limit_rtx))
+ {
+#if defined (MOTOROLA)
+ asm_fprintf (stream, "\tcmp.l %s,%Rsp\n\ttrapcs\n",
+ reg_names[REGNO (stack_limit_rtx)]);
+#else
+ asm_fprintf (stream, "\tcmpl %s,%Rsp\n\ttrapcs\n",
+ reg_names[REGNO (stack_limit_rtx)]);
+#endif
+ }
+ else if (GET_CODE (stack_limit_rtx) != SYMBOL_REF)
+ warning ("stack limit expression is not supported");
+ }
+
if (num_saved_regs <= 2)
{
/* Store each separately in the same order moveml uses.
for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno])
return 0;
-
+
+ if (flag_pic && current_function_uses_pic_offset_table)
+ return 0;
+
return 1;
}
nregs++;
mask |= 1 << regno;
}
- if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+ if (flag_pic && current_function_uses_pic_offset_table)
{
nregs++;
mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
}
}
-char *
+const char *
output_scc_di(op, operand1, operand2, dest)
rtx op;
rtx operand1;
return "";
}
-char *
+const char *
output_btst (operands, countop, dataop, insn, signpos)
rtx *operands;
rtx countop, dataop;
gen_rtx_PLUS (Pmode,
pic_offset_table_rtx, orig));
current_function_uses_pic_offset_table = 1;
- if (reload_in_progress)
- regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
RTX_UNCHANGING_P (pic_ref) = 1;
emit_move_insn (reg, pic_ref);
return reg;
\f
typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ } CONST_METHOD;
+static CONST_METHOD const_method PARAMS ((rtx));
+
#define USE_MOVQ(i) ((unsigned)((i) + 128) <= 255)
-CONST_METHOD
+static CONST_METHOD
const_method (constant)
rtx constant;
{
}
}
-char *
+const char *
output_move_const_into_data_reg (operands)
rtx *operands;
{
}
}
-char *
+const char *
output_move_simode_const (operands)
rtx *operands;
{
return "move%.l %1,%0";
}
-char *
+const char *
output_move_simode (operands)
rtx *operands;
{
return "move%.l %1,%0";
}
-char *
+const char *
output_move_himode (operands)
rtx *operands;
{
return "move%.w %1,%0";
}
-char *
+const char *
output_move_qimode (operands)
rtx *operands;
{
return "move%.b %1,%0";
}
-char *
+const char *
output_move_stricthi (operands)
rtx *operands;
{
return "move%.w %1,%0";
}
-char *
+const char *
output_move_strictqi (operands)
rtx *operands;
{
/* Return the best assembler insn template
for moving operands[1] into operands[0] as a fullword. */
-static char *
+static const char *
singlemove_string (operands)
rtx *operands;
{
/* Output assembler code to perform a doubleword move insn
with operands OPERANDS. */
-char *
+const char *
output_move_double (operands)
rtx *operands;
{
/* Output assembler code to perform a 32 bit 3 operand add. */
-char *
+const char *
output_addsi3 (operands)
rtx *operands;
{
cc_status.flags = CC_IN_68881;
}
\f
-char *
+const char *
output_move_const_double (operands)
rtx *operands;
{
}
}
-char *
+const char *
output_move_const_single (operands)
rtx *operands;
{
static int inited_68881_table = 0;
-char *strings_68881[7] = {
+static const char *const strings_68881[7] = {
"0.0",
"1.0",
"10.0",
static int inited_FPA_table = 0;
-char *strings_FPA[38] = {
+static const char *const strings_FPA[38] = {
/* small rationals */
"0.0",
"1.0",
return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
#else
- return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0)
+ return (GET_CODE (op) == CONST_INT
|| (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
#endif
}
int
pcrel_address (op, mode)
rtx op;
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
{
return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF
|| GET_CODE (op) == CONST);
}
-char *
+const char *
output_andsi3 (operands)
rtx *operands;
{
return "and%.l %2,%0";
}
-char *
+const char *
output_iorsi3 (operands)
rtx *operands;
{
return "or%.l %2,%0";
}
-char *
+const char *
output_xorsi3 (operands)
rtx *operands;
{