static int calc_live_regs PARAMS ((int *, int *));
static void mark_use PARAMS ((rtx, rtx *));
static HOST_WIDE_INT rounded_frame_size PARAMS ((int));
+static rtx mark_constant_pool_use PARAMS ((rtx));
\f
/* Print the operand address in x to the stream. */
break;
default:
+ x = mark_constant_pool_use (x);
output_addr_const (stream, x);
break;
}
fprintf (stream, "\n\tnop");
break;
case 'O':
+ x = mark_constant_pool_use (x);
output_addr_const (stream, x);
break;
case 'R':
{
rtx value; /* Value in table. */
rtx label; /* Label of value. */
+ rtx wend; /* End of window. */
enum machine_mode mode; /* Mode of value. */
} pool_node;
#define MAX_POOL_SIZE (1020/4)
static pool_node pool_vector[MAX_POOL_SIZE];
static int pool_size;
+static rtx pool_window_label;
+static int pool_window_last;
/* ??? If we need a constant in HImode which is the truncated value of a
constant we need in SImode, we could combine the two entries thus saving
rtx last_value;
{
int i;
- rtx lab;
+ rtx lab, new, ref, newref;
/* First see if we've already got it. */
for (i = 0; i < pool_size; i++)
}
if (rtx_equal_p (x, pool_vector[i].value))
{
- lab = 0;
+ lab = new = 0;
if (! last_value
|| ! i
|| ! rtx_equal_p (last_value, pool_vector[i-1].value))
{
- lab = pool_vector[i].label;
- if (! lab)
- pool_vector[i].label = lab = gen_label_rtx ();
+ new = gen_label_rtx ();
+ LABEL_REFS (new) = pool_vector[i].label;
+ pool_vector[i].label = lab = new;
}
+ if (lab && pool_window_label)
+ {
+ newref = gen_rtx_LABEL_REF (VOIDmode, pool_window_label);
+ ref = pool_vector[pool_window_last].wend;
+ LABEL_NEXTREF (newref) = ref;
+ pool_vector[pool_window_last].wend = newref;
+ }
+ if (new)
+ pool_window_label = new;
+ pool_window_last = i;
return lab;
}
}
lab = gen_label_rtx ();
pool_vector[pool_size].mode = mode;
pool_vector[pool_size].label = lab;
+ pool_vector[pool_size].wend = NULL_RTX;
+ if (lab && pool_window_label)
+ {
+ newref = gen_rtx_LABEL_REF (VOIDmode, pool_window_label);
+ ref = pool_vector[pool_window_last].wend;
+ LABEL_NEXTREF (newref) = ref;
+ pool_vector[pool_window_last].wend = newref;
+ }
+ if (lab)
+ pool_window_label = lab;
+ pool_window_last = pool_size;
pool_size++;
return lab;
}
{
int i;
int need_align = 1;
+ rtx lab, ref;
/* Do two passes, first time dump out the HI sized constants. */
scan = emit_insn_after (gen_align_2 (), scan);
need_align = 0;
}
- scan = emit_label_after (p->label, scan);
- scan = emit_insn_after (gen_consttable_2 (p->value), scan);
+ for (lab = p->label; lab; lab = LABEL_REFS (lab))
+ scan = emit_label_after (lab, scan);
+ scan = emit_insn_after (gen_consttable_2 (p->value, const0_rtx),
+ scan);
+ for (ref = p->wend; ref; ref = LABEL_NEXTREF (ref))
+ {
+ lab = XEXP (ref, 0);
+ scan = emit_insn_after (gen_consttable_window_end (lab), scan);
+ }
}
}
scan = emit_label_after (gen_label_rtx (), scan);
scan = emit_insn_after (gen_align_4 (), scan);
}
- if (p->label)
- scan = emit_label_after (p->label, scan);
- scan = emit_insn_after (gen_consttable_4 (p->value), scan);
+ for (lab = p->label; lab; lab = LABEL_REFS (lab))
+ scan = emit_label_after (lab, scan);
+ scan = emit_insn_after (gen_consttable_4 (p->value, const0_rtx),
+ scan);
break;
case DFmode:
case DImode:
scan = emit_label_after (gen_label_rtx (), scan);
scan = emit_insn_after (gen_align_4 (), scan);
}
- if (p->label)
- scan = emit_label_after (p->label, scan);
- scan = emit_insn_after (gen_consttable_8 (p->value), scan);
+ for (lab = p->label; lab; lab = LABEL_REFS (lab))
+ scan = emit_label_after (lab, scan);
+ scan = emit_insn_after (gen_consttable_8 (p->value, const0_rtx),
+ scan);
break;
default:
abort ();
break;
}
+
+ if (p->mode != HImode)
+ {
+ for (ref = p->wend; ref; ref = LABEL_NEXTREF (ref))
+ {
+ lab = XEXP (ref, 0);
+ scan = emit_insn_after (gen_consttable_window_end (lab), scan);
+ }
+ }
}
scan = emit_insn_after (gen_consttable_end (), scan);
scan = emit_barrier_after (scan);
pool_size = 0;
+ pool_window_label = NULL_RTX;
+ pool_window_last = 0;
}
/* Return non-zero if constant would be an ok source for a
}
return orig;
}
+
+/* Mark the use of a constant in the literal table. If the constant
+ has multiple labels, make it unique. */
+static rtx mark_constant_pool_use (x)
+ rtx x;
+{
+ rtx insn, lab, pattern;
+
+ if (x == NULL)
+ return x;
+
+ switch (GET_CODE (x))
+ {
+ case LABEL_REF:
+ x = XEXP (x, 0);
+ case CODE_LABEL:
+ break;
+ default:
+ return x;
+ }
+
+ /* Get the first label in the list of labels for the same constant
+ and delete another labels in the list. */
+ lab = x;
+ for (insn = PREV_INSN (x); insn; insn = PREV_INSN (insn))
+ {
+ if (GET_CODE (insn) != CODE_LABEL
+ || LABEL_REFS (insn) != NEXT_INSN (insn))
+ break;
+ lab = insn;
+ }
+
+ for (insn = LABEL_REFS (lab); insn; insn = LABEL_REFS (insn))
+ INSN_DELETED_P (insn) = 1;
+
+ /* Mark constants in a window. */
+ for (insn = NEXT_INSN (x); insn; insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) != INSN)
+ continue;
+
+ pattern = PATTERN (insn);
+ if (GET_CODE (pattern) != UNSPEC_VOLATILE)
+ continue;
+
+ switch (XINT (pattern, 1))
+ {
+ case UNSPECV_CONST2:
+ case UNSPECV_CONST4:
+ case UNSPECV_CONST8:
+ XVECEXP (pattern, 0, 1) = const1_rtx;
+ break;
+ case UNSPECV_WINDOW_END:
+ if (XVECEXP (pattern, 0, 0) == x)
+ return lab;
+ break;
+ case UNSPECV_CONST_END:
+ return lab;
+ default:
+ break;
+ }
+ }
+
+ return lab;
+}
(UNSPECV_CONST2 2)
(UNSPECV_CONST4 4)
(UNSPECV_CONST8 6)
+ (UNSPECV_WINDOW_END 10)
(UNSPECV_CONST_END 11)
])
; 2 byte integer in line
(define_insn "consttable_2"
- [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
+ [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
+ (match_operand 1 "" "")]
UNSPECV_CONST2)]
""
"*
{
- assemble_integer (operands[0], 2, 1);
+ if (operands[1] != const0_rtx)
+ assemble_integer (operands[0], 2, 1);
return \"\";
}"
[(set_attr "length" "2")
; 4 byte integer in line
(define_insn "consttable_4"
- [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
+ [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
+ (match_operand 1 "" "")]
UNSPECV_CONST4)]
""
"*
{
- assemble_integer (operands[0], 4, 1);
+ if (operands[1] != const0_rtx)
+ assemble_integer (operands[0], 4, 1);
return \"\";
}"
[(set_attr "length" "4")
; 8 byte integer in line
(define_insn "consttable_8"
- [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")]
+ [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
+ (match_operand 1 "" "")]
UNSPECV_CONST8)]
""
"*
{
- assemble_integer (operands[0], 8, 1);
+ if (operands[1] != const0_rtx)
+ assemble_integer (operands[0], 8, 1);
return \"\";
}"
[(set_attr "length" "8")
; 4 byte floating point
(define_insn "consttable_sf"
- [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")]
+ [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
+ (match_operand 1 "" "")]
UNSPECV_CONST4)]
""
"*
{
- union real_extract u;
- memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
- assemble_real (u.d, SFmode);
+ if (operands[1] != const0_rtx)
+ {
+ union real_extract u;
+ memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
+ assemble_real (u.d, SFmode);
+ }
return \"\";
}"
[(set_attr "length" "4")
; 8 byte floating point
(define_insn "consttable_df"
- [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")]
+ [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
+ (match_operand 1 "" "")]
UNSPECV_CONST8)]
""
"*
{
- union real_extract u;
- memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
- assemble_real (u.d, DFmode);
+ if (operands[1] != const0_rtx)
+ {
+ union real_extract u;
+ memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
+ assemble_real (u.d, DFmode);
+ }
return \"\";
}"
[(set_attr "length" "8")
"* return output_jump_label_table ();"
[(set_attr "in_delay_slot" "no")])
+; emitted at the end of the window in the literal table.
+
+(define_insn "consttable_window_end"
+ [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
+ ""
+ ""
+ [(set_attr "length" "0")
+ (set_attr "in_delay_slot" "no")])
+
;; -------------------------------------------------------------------------
;; Misc
;; -------------------------------------------------------------------------