Per Richard Biener's encouragement to go after low-hanging fruit in
cleaning up test results for non-primary/secondary ports, I've checked
in this patch which fixes several FAILs in the g++ testsuite for nios2.
Chung-Lin already wrote the patch for our local tree some time ago and
I've just re-tested it on mainline head before committing it.
The nios2 back end didn't previously implement
TARGET_ASM_OUTPUT_MI_THUNK. The approach here is similar to what other
backends do, but it got a little messy because we had to modify the PIC
helpers to allow the use of a specific temporary register RTX passed in
as a parameter instead of always allocating a new pseudo. We use R2 for
this purpose in the thunk (call-clobbered, but not used for parameter
passing).
-Sandra
2015-03-21 Chung-Lin Tang
Sandra Loosemore
gcc/
* config/nios2/nios2-protos.h (nios2_adjust_call_address): Adjust
function parameter declaration.
* config/nios2/nios2.md (call,call_value,sibcall,sibcall_value):
Update arguments to nios2_adjust_call_address().
(sibcall_internal): Rename from *sibcall.
(sibcall_value_internal): Rename from *sibcall_value.
* config/nios2/nios2.c (nios2_emit_add_constant): New function.
(nios2_large_got_address): Add target temp reg parameter.
(nios2_got_address): Adjust call to nios2_large_got_address, add
force_reg around it.
(nios2_load_pic_address): Add target temp reg parameter, replace call
to nios2_got_address with corresponding code.
(nios2_legitimize_constant_address): Update call to
nios2_load_pic_address.
(nios2_adjust_call_address): Add temp reg parameter, update PIC case
to use temp reg for PIC loading purposes.
(nios2_asm_output_mi_thunk): Implement TARGET_ASM_OUTPUT_MI_THUNK.
(TARGET_ASM_CAN_OUTPUT_MI_THUNK): Define.
(TARGET_ASM_OUTPUT_MI_THUNK): Likewise.
Index: gcc/config/nios2/nios2-protos.h
===
--- gcc/config/nios2/nios2-protos.h (revision 221369)
+++ gcc/config/nios2/nios2-protos.h (working copy)
@@ -31,7 +31,7 @@ extern void nios2_function_profiler (FIL
#ifdef RTX_CODE
extern int nios2_emit_move_sequence (rtx *, machine_mode);
extern void nios2_emit_expensive_div (rtx *, machine_mode);
-extern void nios2_adjust_call_address (rtx *);
+extern void nios2_adjust_call_address (rtx *, rtx);
extern rtx nios2_get_return_address (int);
extern void nios2_set_return_address (rtx, rtx);
Index: gcc/config/nios2/nios2.md
===
--- gcc/config/nios2/nios2.md (revision 221369)
+++ gcc/config/nios2/nios2.md (working copy)
@@ -726,7 +726,7 @@
(match_operand 1 "" ""))
(clobber (reg:SI RA_REGNO))])]
""
- "nios2_adjust_call_address (&operands[0]);")
+ "nios2_adjust_call_address (&operands[0], NULL_RTX);")
(define_expand "call_value"
[(parallel [(set (match_operand 0 "" "")
@@ -734,7 +734,7 @@
(match_operand 2 "" "")))
(clobber (reg:SI RA_REGNO))])]
""
- "nios2_adjust_call_address (&operands[1]);")
+ "nios2_adjust_call_address (&operands[1], NULL_RTX);")
(define_insn "*call"
[(call (mem:QI (match_operand:SI 0 "call_operand" "i,r"))
@@ -762,7 +762,7 @@
(match_operand 1 "" ""))
(return)])]
""
- "nios2_adjust_call_address (&operands[0]);")
+ "nios2_adjust_call_address (&operands[0], NULL_RTX);")
(define_expand "sibcall_value"
[(parallel [(set (match_operand 0 "" "")
@@ -770,9 +770,9 @@
(match_operand 2 "" "")))
(return)])]
""
- "nios2_adjust_call_address (&operands[1]);")
+ "nios2_adjust_call_address (&operands[1], NULL_RTX);")
-(define_insn "*sibcall"
+(define_insn "sibcall_internal"
[(call (mem:QI (match_operand:SI 0 "call_operand" "i,j"))
(match_operand 1 "" ""))
(return)]
@@ -782,7 +782,7 @@
jmp\\t%0"
[(set_attr "type" "control")])
-(define_insn "*sibcall_value"
+(define_insn "sibcall_value_internal"
[(set (match_operand 0 "register_operand" "")
(call (mem:QI (match_operand:SI 1 "call_operand" "i,j"))
(match_operand 2 "" "")))
Index: gcc/config/nios2/nios2.c
===
--- gcc/config/nios2/nios2.c (revision 221369)
+++ gcc/config/nios2/nios2.c (working copy)
@@ -489,6 +489,21 @@ nios2_emit_stack_limit_check (void)
/* Temp regno used inside prologue/epilogue. */
#define TEMP_REG_NUM 8
+static rtx
+nios2_emit_add_constant (rtx reg, HOST_WIDE_INT immed)
+{
+ rtx insn;
+ if (SMALL_INT (immed))
+insn = emit_insn (gen_add2_insn (reg, gen_int_mode (immed, Pmode)));
+ else
+{
+ rtx tmp = gen_rtx_REG (Pmode, TEMP_REG_NUM);
+ emit_move_insn (tmp, gen_int_mode (immed, Pmode));
+ insn = emit_insn (gen_add2_insn (reg, tmp));
+}
+ return insn;
+}
+
void
nios2_expand_prologue (void)
{
@@ -1229,12 +1244,12 @@ nios2_unspec_offset (rtx