@@ -126,7 +126,7 @@ extern int arm_const_double_inline_cost (rtx);
extern bool arm_const_double_by_parts (rtx);
extern bool arm_const_double_by_immediates (rtx);
extern const char *fp_immediate_constant (rtx);
-extern void arm_emit_call_insn (rtx, rtx);
+extern void arm_post_emit_call_insn (rtx, rtx);
extern const char *output_call (rtx *);
extern const char *output_call_mem (rtx *);
void arm_emit_movpair (rtx, rtx);
@@ -17602,16 +17602,14 @@ vfp_emit_fstmd (int base_reg, int count)
return count * 8;
}
-/* Emit a call instruction with pattern PAT. ADDR is the address of
- the call target. */
+/* Process a call instruction with pattern PAT after emission. ADDR is the
+ address of the call target. */
void
-arm_emit_call_insn (rtx pat, rtx addr)
+arm_post_emit_call_insn (rtx pat, rtx addr)
{
rtx insn;
- insn = emit_call_insn (pat);
-
/* The PIC register is live on entry to VxWorks PIC PLT entries.
If the call might use such an entry, add a use of the PIC register
to the instruction's CALL_INSN_FUNCTION_USAGE. */
@@ -9082,7 +9082,7 @@
"TARGET_EITHER"
"
{
- rtx callee, pat;
+ rtx callee;
/* In an untyped call, we can get NULL for operand 2. */
if (operands[2] == NULL_RTX)
@@ -9097,18 +9097,13 @@
: !REG_P (callee))
XEXP (operands[0], 0) = force_reg (Pmode, callee);
- pat = gen_call_internal (operands[0], operands[1], operands[2]);
- arm_emit_call_insn (pat, XEXP (operands[0], 0));
- DONE;
+ }"
+ []
+ "{
+ arm_post_emit_call_insn (_val, XEXP (operands[0], 0));
}"
)
-(define_expand "call_internal"
- [(parallel [(call (match_operand 0 "memory_operand" "")
- (match_operand 1 "general_operand" ""))
- (use (match_operand 2 "" ""))
- (clobber (reg:SI LR_REGNUM))])])
-
(define_insn "*call_reg_armv5"
[(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
(match_operand 1 "" ""))
@@ -9191,7 +9186,7 @@
"TARGET_EITHER"
"
{
- rtx pat, callee;
+ rtx callee;
/* In an untyped call, we can get NULL for operand 2. */
if (operands[3] == 0)
@@ -9205,21 +9200,13 @@
? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
: !REG_P (callee))
XEXP (operands[1], 0) = force_reg (Pmode, callee);
-
- pat = gen_call_value_internal (operands[0], operands[1],
- operands[2], operands[3]);
- arm_emit_call_insn (pat, XEXP (operands[1], 0));
- DONE;
+ }"
+ []
+ "{
+ arm_post_emit_call_insn (_val, XEXP (operands[1], 0));
}"
)
-(define_expand "call_value_internal"
- [(parallel [(set (match_operand 0 "" "")
- (call (match_operand 1 "memory_operand" "")
- (match_operand 2 "general_operand" "")))
- (use (match_operand 3 "" ""))
- (clobber (reg:SI LR_REGNUM))])])
-
(define_insn "*call_value_reg_armv5"
[(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
@@ -422,7 +422,8 @@ gen_expand (rtx expand)
/* If we don't have any C code to write, only one insn is being written,
and no MATCH_DUPs are present, we can just return the desired insn
like we do for a DEFINE_INSN. This saves memory. */
- if ((XSTR (expand, 3) == 0 || *XSTR (expand, 3) == '\0')
+ if (((XSTR (expand, 3) == 0 || *XSTR (expand, 3) == '\0'))
+ && (XSTR (expand, 5) == 0 || *XSTR (expand, 5) == '\0')
&& stats.max_opno >= stats.max_dup_opno
&& XVECLEN (expand, 1) == 1)
{
@@ -525,6 +526,23 @@ gen_expand (rtx expand)
printf (" _val = get_insns ();\n");
printf (" end_sequence ();\n");
+
+ if (XSTR (expand, 5) && *XSTR (expand, 5))
+ {
+ printf (" {\n");
+ if (stats.num_operand_vars > 0)
+ printf (" rtx operands[%d];\n", stats.num_operand_vars);
+
+ /* Output code to copy the arguments into `operands'. */
+ for (i = 0; i < stats.num_generator_args; i++)
+ printf (" operands[%d] = operand%d;\n", i, i);
+
+ print_md_ptr_loc (XSTR (expand, 5));
+ printf ("%s\n", XSTR (expand, 5));
+
+ printf (" }\n");
+ }
+
printf (" return _val;\n}\n\n");
}
@@ -933,8 +933,10 @@ DEF_RTL_EXPR(DEFINE_PEEPHOLE2, "define_peephole2", "EsES", RTX_EXTRA)
elements of `recog_data.operand' for use by the vector of
insn-patterns.
(`operands' is an alias here for `recog_data.operand').
- 5th: optionally, a vector of attributes for this expand. */
-DEF_RTL_EXPR(DEFINE_EXPAND, "define_expand", "sEssV", RTX_EXTRA)
+ 5th: optionally, a vector of attributes for this expand.
+ 6th operand: Extra C code to execute after generating the insns. This code
+ is not executed if DONE (or FAIL) is used in the 4th operand. */
+DEF_RTL_EXPR(DEFINE_EXPAND, "define_expand", "sEssVs", RTX_EXTRA)
/* Define a requirement for delay slots.
1st operand: Condition involving insn attributes that, if true,
--
1.8.3.2