int i386_align_jumps; /* power of two alignment for non-loop jumps */
int i386_align_funcs; /* power of two alignment for functions */
-\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
if (! strcmp (ix86_isa_string, processor_target_table[i].name))
{
ix86_isa = processor_target_table[i].processor;
+ if (ix86_cpu_string == (char *)0)
+ ix86_cpu_string = processor_target_table[i].name;
break;
}
ix86_isa = PROCESSOR_DEFAULT;
}
- if (ix86_cpu_string == (char *)0)
- ix86_cpu_string = PROCESSOR_DEFAULT_STRING;
-
for (j = 0; j < ptt_size; j++)
if (! strcmp (ix86_cpu_string, processor_target_table[j].name))
{
}
else
i386_align_funcs = def_align;
+
+ if (TARGET_OMIT_LEAF_FRAME_POINTER) /* keep nonleaf frame pointers */
+ flag_omit_frame_pointer = 1;
}
\f
/* A C statement (sans semicolon) to choose the order in which to
xops[0] = pic_offset_table_rtx;
xops[1] = stack_pointer_rtx;
+ /* deep branch prediction favors having a return for every call */
if (pic_reg_used && TARGET_DEEP_BRANCH_PREDICTION)
{
+ if (pic_label_rtx == 0)
pic_label_rtx = (rtx) gen_label_rtx ();
ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (pic_label_rtx));
output_asm_insn ("movl (%1),%0", xops);
}
}
-/* This function generates the assembly code for function entry.
- FILE is an stdio stream to output the code to.
- SIZE is an int: how many units of temporary storage to allocate. */
+/* Set up the stack and frame (if desired) for the function. */
void
function_prologue (file, size)
FILE *file;
int size;
+{
+}
+
+/* This function generates the assembly code for function entry.
+ FILE is an stdio stream to output the code to.
+ SIZE is an int: how many units of temporary storage to allocate. */
+
+void
+ix86_expand_prologue ()
{
register int regno;
int limit;
rtx xops[4];
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
|| current_function_uses_const_pool);
+ long tsize = get_frame_size ();
xops[0] = stack_pointer_rtx;
xops[1] = frame_pointer_rtx;
- xops[2] = GEN_INT (size);
+ xops[2] = GEN_INT (tsize);
if (frame_pointer_needed)
{
- output_asm_insn ("push%L1 %1", xops);
- output_asm_insn (AS2 (mov%L0,%0,%1), xops);
+ emit_insn (gen_rtx (SET, 0,
+ gen_rtx (MEM, SImode,
+ gen_rtx (PRE_DEC, SImode, stack_pointer_rtx)),
+ frame_pointer_rtx));
+ emit_move_insn (xops[1], xops[0]);
+/* output_asm_insn ("push%L1 %1", xops); */
+/* output_asm_insn (AS2 (mov%L0,%0,%1), xops); */
}
- if (size)
- output_asm_insn (AS2 (sub%L0,%2,%0), xops);
+ if (tsize)
+ emit_insn (gen_rtx (SET, SImode,
+ xops[0],
+ gen_rtx (MINUS, SImode,
+ xops[0],
+ xops[2])));
+
+/* output_asm_insn (AS2 (sub%L0,%2,%0), xops);*/
/* Note If use enter it is NOT reversed args.
This one is not reversed from intel!!
|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
{
xops[0] = gen_rtx (REG, SImode, regno);
- output_asm_insn ("push%L0 %0", xops);
+ emit_insn (gen_rtx (SET, 0,
+ gen_rtx (MEM, SImode,
+ gen_rtx (PRE_DEC, SImode, stack_pointer_rtx)),
+ xops[0]));
+/* output_asm_insn ("push%L0 %0", xops);*/
}
- if (pic_reg_used && TARGET_PENTIUMPRO)
+ if (pic_reg_used && TARGET_DEEP_BRANCH_PREDICTION)
{
xops[0] = pic_offset_table_rtx;
+ if (pic_label_rtx == 0)
+ pic_label_rtx = (rtx) gen_label_rtx ();
xops[1] = pic_label_rtx;
- output_asm_insn (AS1 (call,%P1), xops);
- output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_,%0", xops);
+ emit_insn (gen_prologue_get_pc (xops[0], gen_rtx (CONST_INT, Pmode, CODE_LABEL_NUMBER(xops[1]))));
+/* output_asm_insn (AS1 (call,%P1), xops);*/
+ emit_insn (gen_prologue_set_got (xops[0],
+ gen_rtx (SYMBOL_REF, Pmode, "$_GLOBAL_OFFSET_TABLE_"),
+ gen_rtx (CONST_INT, Pmode, CODE_LABEL_NUMBER(xops[1]))));
+/* output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_,%0", xops);*/
}
- else {
+ else if (pic_reg_used)
+ {
xops[0] = pic_offset_table_rtx;
xops[1] = (rtx) gen_label_rtx ();
- output_asm_insn (AS1 (call,%P1), xops);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
- output_asm_insn (AS1 (pop%L0,%0), xops);
- output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
+ emit_insn (gen_prologue_get_pc (xops[0], gen_rtx (CONST_INT, Pmode, CODE_LABEL_NUMBER(xops[1]))));
+ SCHED_GROUP_P (get_last_insn()) = 1;
+/* output_asm_insn (AS1 (call,%P1), xops);*/
+/* ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));*/
+ emit_insn (gen_pop (xops[0]));
+/* output_asm_insn (AS1 (pop%L0,%0), xops);*/
+ emit_insn (gen_prologue_set_got (xops[0],
+ gen_rtx (SYMBOL_REF, Pmode, "$_GLOBAL_OFFSET_TABLE_"),
+ gen_rtx (CONST_INT, Pmode, CODE_LABEL_NUMBER (xops[1]))));
+/* output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);*/
}
}
+/* Restore function stack, frame, and registers. */
+
+void
+function_epilogue (file, size)
+ FILE *file;
+ int size;
+{
+}
+
/* Return 1 if it is appropriate to emit `ret' instructions in the
body of a function. Do this only if the epilogue is simple, needing a
couple of insns. Prior to reloading, we can't tell how many registers
- must be saved, so return 0 then.
+ must be saved, so return 0 then. Return 0 if there is no frame
+ marker to de-allocate.
If NON_SAVING_SETJMP is defined and true, then it is not possible
for the epilogue to be simple, so return 0. This is a special case
- since NON_SAVING_SETJMP will not cause regs_ever_live to change until
- final, but jump_optimize may need to know sooner if a `return' is OK. */
+ since NON_SAVING_SETJMP will not cause regs_ever_live to change
+ until final, but jump_optimize may need to know sooner if a
+ `return' is OK. */
int
-simple_386_epilogue ()
+ix86_can_use_return_insn_p ()
{
int regno;
int nregs = 0;
SIZE is an int: how many units of temporary storage to deallocate. */
void
-function_epilogue (file, size)
- FILE *file;
- int size;
+ix86_expand_epilogue ()
{
register int regno;
register int nregs, limit;
rtx xops[3];
int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
|| current_function_uses_const_pool);
+ long tsize = get_frame_size ();
/* Compute the number of registers to pop */
leal, this is faster. For now restore multiple registers the old
way. */
- offset = -size - (nregs * UNITS_PER_WORD);
+ offset = -tsize - (nregs * UNITS_PER_WORD);
xops[2] = stack_pointer_rtx;
{
if (frame_pointer_needed)
{
- xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
- output_asm_insn (AS2 (lea%L2,%0,%2), xops);
+ xops[0] = adj_offsettable_operand (AT_BP (QImode), offset);
+ emit_insn (gen_movsi_lea (xops[2], XEXP (xops[0], 0)));
+/* output_asm_insn (AS2 (lea%L2,%0,%2), xops);*/
}
for (regno = 0; regno < limit; regno++)
|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
{
xops[0] = gen_rtx (REG, SImode, regno);
- output_asm_insn ("pop%L0 %0", xops);
+ emit_insn (gen_pop (xops[0]));
+/* output_asm_insn ("pop%L0 %0", xops);*/
}
}
else
{
xops[0] = gen_rtx (REG, SImode, regno);
xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
- output_asm_insn (AS2 (mov%L0,%1,%0), xops);
+ emit_move_insn (xops[0], xops[1]);
+/* output_asm_insn (AS2 (mov%L0,%1,%0), xops);*/
offset += 4;
}
/* If not an i386, mov & pop is faster than "leave". */
if (TARGET_USE_LEAVE)
- output_asm_insn ("leave", xops);
+ emit_insn (gen_leave());
+/* output_asm_insn ("leave", xops);*/
else
{
xops[0] = frame_pointer_rtx;
- output_asm_insn (AS2 (mov%L2,%0,%2), xops);
- output_asm_insn ("pop%L0 %0", xops);
+ xops[1] = stack_pointer_rtx;
+ emit_move_insn (xops[1], xops[0]); /* final ignores this */
+/* output_asm_insn (AS2 (mov%L2,%0,%2), xops);*/
+ emit_insn (gen_pop (xops[0]));
+/* output_asm_insn ("pop%L0 %0", xops);*/
}
}
- else if (size)
+ else if (tsize)
{
/* If there is no frame pointer, we must still release the frame. */
- xops[0] = GEN_INT (size);
- output_asm_insn (AS2 (add%L2,%0,%2), xops);
+ xops[0] = GEN_INT (tsize);
+ emit_insn (gen_rtx (SET, SImode,
+ xops[2],
+ gen_rtx (PLUS, SImode,
+ xops[2],
+ xops[0])));
+/* output_asm_insn (AS2 (add%L2,%0,%2), xops);*/
}
#ifdef FUNCTION_BLOCK_PROFILER_EXIT
{
/* ??? Which register to use here? */
xops[0] = gen_rtx (REG, SImode, 2);
- output_asm_insn ("pop%L0 %0", xops);
- output_asm_insn (AS2 (add%L2,%1,%2), xops);
- output_asm_insn ("jmp %*%0", xops);
+ emit_insn (gen_pop (xops[0]));
+/* output_asm_insn ("pop%L0 %0", xops);*/
+ emit_insn (gen_rtx (SET, SImode,
+ xops[2],
+ gen_rtx (PLUS, SImode,
+ xops[1],
+ xops[2])));
+/* output_asm_insn (AS2 (add%L2,%1,%2), xops);*/
+ emit_jump_insn (xops[0]);
+/* output_asm_insn ("jmp %*%0", xops);*/
}
else
- output_asm_insn ("ret %1", xops);
+ emit_jump_insn (gen_return_internal ());
+/* output_asm_insn ("ret %1", xops);*/
}
else
- output_asm_insn ("ret", xops);
+/* output_asm_insn ("ret", xops);*/;
+ emit_jump_insn (gen_return_internal ());
}
\f