Commit 04aff2c0 by DJ Delorie Committed by DJ Delorie

addsub.md (addhi3): Add two more alternatives, for mova with fb, and for fb+0 -> An.

* config/m32c/addsub.md (addhi3): Add two more alternatives, for
mova with fb, and for fb+0 -> An.

* config/m32c/mov.md (peephole2): Fix enabling logic.

* config/m32c/m32c.h (CTOR_LIST_BEGIN, CTOR_LIST_END,
DTOR_LIST_BEGIN, DTOR_LIST_END, CTORS_SECTION_ASM_OP,
DTORS_SECTION_ASM_OP, INIT_ARRAY_SECTION_ASM_OP,
FINI_ARRAY_SECTION_ASM_OP): Define.

* config/m32c/m32c.c (m32c_legitimize_address): Remove temporary variable.
(m32c_legitimize_reload_address): New logic to reload FB to An.
(m32c_output_reg_push): Add newline.
(m32c_output_reg_pop): Likewise.

From-SVN: r109648
parent 664a90c0
2006-01-12 DJ Delorie <dj@redhat.com>
* config/m32c/addsub.md (addhi3): Add two more alternatives, for
mova with fb, and for fb+0 -> An.
* config/m32c/mov.md (peephole2): Fix enabling logic.
* config/m32c/m32c.h (CTOR_LIST_BEGIN, CTOR_LIST_END,
DTOR_LIST_BEGIN, DTOR_LIST_END, CTORS_SECTION_ASM_OP,
DTORS_SECTION_ASM_OP, INIT_ARRAY_SECTION_ASM_OP,
FINI_ARRAY_SECTION_ASM_OP): Define.
* config/m32c/m32c.c (m32c_legitimize_address): Remove temporary variable.
(m32c_legitimize_reload_address): New logic to reload FB to An.
(m32c_output_reg_push): Add newline.
(m32c_output_reg_pop): Likewise.
2006-01-12 Ulrich Weigand <uweigand@de.ibm.com> 2006-01-12 Ulrich Weigand <uweigand@de.ibm.com>
* struct-equiv.c (find_dying_inputs): Fix off-by-one bug. * struct-equiv.c (find_dying_inputs): Fix off-by-one bug.
......
...@@ -36,11 +36,11 @@ ...@@ -36,11 +36,11 @@
(define_insn "addhi3" (define_insn "addhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" [(set (match_operand:HI 0 "nonimmediate_operand"
"=SdRhi,SdRhi,??Rmm,??Rmm, SdRhi,??Rmm, Rhi, !Rsp") "=SdRhi,SdRhi,??Rmm,??Rmm, SdRhi,??Rmm, Rhi, Raw, Raw, !Rsp")
(plus:HI (match_operand:HI 1 "general_operand" (plus:HI (match_operand:HI 1 "general_operand"
"%0,0,0,0, 0,0, Raw, 0") "%0,0,0,0, 0,0, Raw, Rfb, Rfb, 0")
(match_operand:HI 2 "general_operand" (match_operand:HI 2 "general_operand"
"IU2sSdRhi,?Rmm,IU2sSdRhi,?Rmm, IM2,IM2, IS2IU2, i")))] "IU2sSdRhi,?Rmm,IU2sSdRhi,?Rmm, IM2,IM2, IS2IU2, I00, IS1, i")))]
"" ""
"@ "@
add.w\t%2,%0 add.w\t%2,%0
...@@ -50,8 +50,10 @@ ...@@ -50,8 +50,10 @@
sub.w\t%m2,%0 sub.w\t%m2,%0
sub.w\t%m2,%0 sub.w\t%m2,%0
mova\t%d2[%1],%0 mova\t%d2[%1],%0
stc\t%1,%0
mova\t%D2[%1],%0
add.w\t%2,%0" add.w\t%2,%0"
[(set_attr "flags" "oszc,oszc,oszc,oszc,oszc,oszc,oszc,oszc")] [(set_attr "flags" "oszc,oszc,oszc,oszc,oszc,oszc,oszc,oszc,oszc,oszc")]
) )
(define_insn "addpsi3" (define_insn "addpsi3"
......
...@@ -1822,6 +1822,31 @@ m32c_reg_ok_for_base_p (rtx x, int strict) ...@@ -1822,6 +1822,31 @@ m32c_reg_ok_for_base_p (rtx x, int strict)
} }
} }
/* We have three choices for choosing fb->aN offsets. If we choose -128,
we need one MOVA -128[fb],aN opcode and 16 bit aN displacements,
like this:
EB 4B FF mova -128[$fb],$a0
D8 0C FF FF mov.w:Q #0,-1[$a0]
Alternately, we subtract the frame size, and hopefully use 8 bit aN
displacements:
7B F4 stc $fb,$a0
77 54 00 01 sub #256,$a0
D8 08 01 mov.w:Q #0,1[$a0]
If we don't offset (i.e. offset by zero), we end up with:
7B F4 stc $fb,$a0
D8 0C 00 FF mov.w:Q #0,-256[$a0]
We have to subtract *something* so that we have a PLUS rtx to mark
that we've done this reload. The -128 offset will never result in
an 8 bit aN offset, and the payoff for the second case is five
loads *if* those loads are within 256 bytes of the other end of the
frame, so the third case seems best. Note that we subtract the
zero, but detect that in the addhi3 pattern. */
#define BIG_FB_ADJ 0
/* Implements LEGITIMIZE_ADDRESS. The only address we really have to /* Implements LEGITIMIZE_ADDRESS. The only address we really have to
worry about is frame base offsets, as $fb has a limited worry about is frame base offsets, as $fb has a limited
displacement range. We deal with this by attempting to reload $fb displacement range. We deal with this by attempting to reload $fb
...@@ -1846,10 +1871,9 @@ m32c_legitimize_address (rtx * x ATTRIBUTE_UNUSED, ...@@ -1846,10 +1871,9 @@ m32c_legitimize_address (rtx * x ATTRIBUTE_UNUSED,
|| INTVAL (XEXP (*x, 1)) > (128 - GET_MODE_SIZE (mode)))) || INTVAL (XEXP (*x, 1)) > (128 - GET_MODE_SIZE (mode))))
{ {
/* reload FB to A_REGS */ /* reload FB to A_REGS */
rtx foo;
rtx temp = gen_reg_rtx (Pmode); rtx temp = gen_reg_rtx (Pmode);
*x = copy_rtx (*x); *x = copy_rtx (*x);
foo = emit_insn (gen_rtx_SET (VOIDmode, temp, XEXP (*x, 0))); emit_insn (gen_rtx_SET (VOIDmode, temp, XEXP (*x, 0)));
XEXP (*x, 0) = temp; XEXP (*x, 0) = temp;
return 1; return 1;
} }
...@@ -1875,7 +1899,47 @@ m32c_legitimize_reload_address (rtx * x, ...@@ -1875,7 +1899,47 @@ m32c_legitimize_reload_address (rtx * x,
*also* still trying to reload the whole address, and we'd run out *also* still trying to reload the whole address, and we'd run out
of address registers. So we let gcc do the naive (but safe) of address registers. So we let gcc do the naive (but safe)
reload instead, when the above function doesn't handle it for reload instead, when the above function doesn't handle it for
us. */ us.
The code below is a second attempt at the above. */
if (GET_CODE (*x) == PLUS
&& GET_CODE (XEXP (*x, 0)) == REG
&& REGNO (XEXP (*x, 0)) == FB_REGNO
&& GET_CODE (XEXP (*x, 1)) == CONST_INT
&& (INTVAL (XEXP (*x, 1)) < -128
|| INTVAL (XEXP (*x, 1)) > (128 - GET_MODE_SIZE (mode))))
{
rtx sum;
int offset = INTVAL (XEXP (*x, 1));
int adjustment = -BIG_FB_ADJ;
sum = gen_rtx_PLUS (Pmode, XEXP (*x, 0),
GEN_INT (adjustment));
*x = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - adjustment));
if (type == RELOAD_OTHER)
type = RELOAD_FOR_OTHER_ADDRESS;
push_reload (sum, NULL_RTX, &XEXP (*x, 0), NULL,
A_REGS, Pmode, VOIDmode, 0, 0, opnum,
type);
return 1;
}
if (GET_CODE (*x) == PLUS
&& GET_CODE (XEXP (*x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (*x, 0), 0)) == REG
&& REGNO (XEXP (XEXP (*x, 0), 0)) == FB_REGNO
&& GET_CODE (XEXP (XEXP (*x, 0), 1)) == CONST_INT
&& GET_CODE (XEXP (*x, 1)) == CONST_INT
)
{
if (type == RELOAD_OTHER)
type = RELOAD_FOR_OTHER_ADDRESS;
push_reload (XEXP (*x, 0), NULL_RTX, &XEXP (*x, 0), NULL,
A_REGS, Pmode, VOIDmode, 0, 0, opnum,
type);
return 1;
}
return 0; return 0;
} }
...@@ -2386,7 +2450,7 @@ m32c_output_reg_push (FILE * s, int regno) ...@@ -2386,7 +2450,7 @@ m32c_output_reg_push (FILE * s, int regno)
if (regno == FLG_REGNO) if (regno == FLG_REGNO)
fprintf (s, "\tpushc\tflg\n"); fprintf (s, "\tpushc\tflg\n");
else else
fprintf (s, "\tpush.%c\t%s", fprintf (s, "\tpush.%c\t%s\n",
" bwll"[reg_push_size (regno)], reg_names[regno]); " bwll"[reg_push_size (regno)], reg_names[regno]);
} }
...@@ -2397,7 +2461,7 @@ m32c_output_reg_pop (FILE * s, int regno) ...@@ -2397,7 +2461,7 @@ m32c_output_reg_pop (FILE * s, int regno)
if (regno == FLG_REGNO) if (regno == FLG_REGNO)
fprintf (s, "\tpopc\tflg\n"); fprintf (s, "\tpopc\tflg\n");
else else
fprintf (s, "\tpop.%c\t%s", fprintf (s, "\tpop.%c\t%s\n",
" bwll"[reg_push_size (regno)], reg_names[regno]); " bwll"[reg_push_size (regno)], reg_names[regno]);
} }
......
...@@ -575,6 +575,15 @@ typedef struct m32c_cumulative_args ...@@ -575,6 +575,15 @@ typedef struct m32c_cumulative_args
#define DATA_SECTION_ASM_OP ".data" #define DATA_SECTION_ASM_OP ".data"
#define BSS_SECTION_ASM_OP ".bss" #define BSS_SECTION_ASM_OP ".bss"
#define CTOR_LIST_BEGIN
#define CTOR_LIST_END
#define DTOR_LIST_BEGIN
#define DTOR_LIST_END
#define CTORS_SECTION_ASM_OP "\t.section\t.init_array,\"aw\",%init_array"
#define DTORS_SECTION_ASM_OP "\t.section\t.fini_array,\"aw\",%fini_array"
#define INIT_ARRAY_SECTION_ASM_OP "\t.section\t.init_array,\"aw\",%init_array"
#define FINI_ARRAY_SECTION_ASM_OP "\t.section\t.fini_array,\"aw\",%fini_array"
/* The Overall Framework of an Assembler File */ /* The Overall Framework of an Assembler File */
#define ASM_COMMENT_START ";" #define ASM_COMMENT_START ";"
......
...@@ -115,8 +115,9 @@ ...@@ -115,8 +115,9 @@
(mem:QHSI (match_operand:HPSI 4 "register_operand" "")))] (mem:QHSI (match_operand:HPSI 4 "register_operand" "")))]
"REGNO (operands[0]) == REGNO (operands[1]) "REGNO (operands[0]) == REGNO (operands[1])
&& REGNO (operands[0]) == REGNO (operands[4]) && REGNO (operands[0]) == REGNO (operands[4])
&& dead_or_set_p (peep2_next_insn (1), operands[4]) && (rtx_equal_p (operands[0], operands[3])
&& ! reg_mentioned_p (operands[0], operands[3])" || (dead_or_set_p (peep2_next_insn (1), operands[4])
&& ! reg_mentioned_p (operands[0], operands[3])))"
[(set (match_dup 3) [(set (match_dup 3)
(mem:QHSI (plus:HPSI (match_dup 1) (mem:QHSI (plus:HPSI (match_dup 1)
(match_dup 2))))] (match_dup 2))))]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment