static int add_constant ();
-static void dump_constants ();
+static int dump_constants ();
int current_function_anonymous_args;
extern int current_function_pretend_args_size;
/* Local label counter, used for constants in the pool and inside
pattern branches. */
-static int lf;
+static int lf = 100;
/* Used to work out sizes of instructions */
static int first_pc;
static int pc;
-
+#define MAYBE_DUMP_LEVEL 900
+#define MUST_DUMP_LEVEL 1000
static int dumpnext;
\f
/* Functions for generating procedure prologue and epilogue code */
int live_regs_mask = 0;
int d;
int i;
-
+ rtx delay_insn;
+
live_regs_mask = calc_live_regs (&d);
+
+ /* See if the delay insn is really ok for the slot. */
+ if (current_function_epilogue_delay_list) {
+ delay_insn = PATTERN (XEXP (current_function_epilogue_delay_list, 0));
+
+ if (GET_CODE (delay_insn) == SET
+ && SET_DEST (delay_insn) == stack_pointer_rtx)
+ {
+ /* Can not use this instruction in the delay slot because
+ it changes the stack pointer, so emit it now. */
+ final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
+ asm_out_file, 1, 0, 1);
+ current_function_epilogue_delay_list = 0;
+ }
+ }
+
+
/* Reclaim the room for the automatics. */
output_stack_adjust (f, 1, frame_size);
output_epilogue_vec ();
- dump_constants ();
+ dump_constants (0);
current_function_anonymous_args = 0;
}
\f
fprintf (stream, "LF%d", lf);
break;
case '!':
- dump_constants();
+ dump_constants (0);
break;
case '^':
lf++;
{
if (REGNO (operands[1]) == MACH_REG)
return "sts mach,%0\n\tsts macl,%R0";
- return "mov %1,%0\n\tmov %R1,%R0";
+ if (REGNO (operands[1]) > REGNO (operands[0]))
+ {
+ return "mov %1,%0\n\tmov %R1,%R0";
+ }
+ else
+ {
+ return "mov %R1,%R0\n\tmov %1,%0";
+ }
}
if (GET_CODE (operands[1]) == CONST_INT)
fprintf (asm_out_file, "\tb%c\tLF%d\n", logic ? 'f' : 't', label);
output_asm_insn ("bra %l0 ! 12 bit cond ", recog_operand);
fprintf (asm_out_file, "\tor r0,r0\n");
+ label = dump_constants (label);
fprintf (asm_out_file, "LF%d:\n", label);
- lf++;
return "";
case 8:
\f
/* Predicates used by the templates */
+/* Nonzero if OP is a normal arithmetic register. */
+
+int
+arith_reg_operand(op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (register_operand (op, mode))
+ {
+ if (GET_CODE (op) == REG)
+ return REGNO (op) != T_REG;
+ return 1;
+ }
+ return 0;
+}
+
+
/* Nonzero if OP is a valid source operand for an arithmetic insn. */
int
instruction than it can reach, so we'll stop accumulating
from that one and start fresh. */
target_pc = current_pc;
- target_insn_range = current_pc + 1000;
+ target_insn_range = current_pc + MAYBE_DUMP_LEVEL;
}
else
{
}
-/* Dump out the pending constant pool. */
+/* Dump out the pending constant pool.
+ If label provided then insert an branch in the middle of the table
+ */
-static void
-dump_constants ()
+static int
+dump_constants (label)
{
int i;
+ int rlabel = label;
+ int size = 0;
+
for (i = 0; i < pool_size; i++)
{
pool_node *p = pool_vector + i;
fprintf (asm_out_file, "\n\t! constants - waited %d\n", pc - first_pc);
fprintf (asm_out_file, "\t.align\t2\n");
fprintf (asm_out_file, "LK%d:", p->number);
+ size += GET_MODE_SIZE (p->mode);
+
switch (GET_MODE_CLASS (p->mode))
{
case MODE_INT:
assemble_real (u.d, p->mode);
}
}
-
+
+ /* After 200 bytes of table, stick in another branch */
+ if (label && size > 200)
+ {
+ rlabel = lf ++;
+ fprintf (asm_out_file,"LF%d:\tbra LF%d\n", label, rlabel);
+ fprintf (asm_out_file,"\tor r0,r0\n");
+ label = 0;
+ }
+
fprintf (asm_out_file, "\n");
}
pool_size = 0;
current_pc = 0;
target_insn_range = 0;
+ return rlabel;
+
}
fprintf (asm_out_file, "\t!constant table start\n");
fprintf (asm_out_file, "\tbra LF%d\n", lf);
fprintf (asm_out_file, "\tor r0,r0 ! wasted slot\n");
- dump_constants ();
+ dump_constants (0);
fprintf (asm_out_file, "LF%d:\n", lf++);
fprintf (asm_out_file, "\t!constant table end\n");
}
if (TARGET_DUMP_RTL)
print_rtl (asm_out_file, body);
- pc += get_attr_length (insn);
+
}
+
+ pc += get_attr_length (insn);
+
+ if (pool_size && pc - first_pc > MUST_DUMP_LEVEL)
+ {
+ /* For some reason we have not dumped out a constant table, and
+ we have emitted a lot of code. This can happen if the think
+ which wants the table is a long conditional branch (which has no
+ room for a constant table), and there has not been a move
+ constant anywhere. */
+ int label = lf++;
+ fprintf (asm_out_file, "\t!forced constant table\n");
+ fprintf (asm_out_file, "\tbra LF%d\n", label);
+ fprintf (asm_out_file, "\tor r0,r0 ! wasted slot\n");
+ label = dump_constants (label);
+ fprintf (asm_out_file, "LF%d:\n", label);
+ fprintf (asm_out_file, "\t!constant table end\n");
+ }
+
}
+