Commit e6219736 by Jeff Law

h8300.c (one_insn_adds_subs_operand): New function.

        * h8300/h8300.c (one_insn_adds_subs_operand): New function.
        (h8300_adjust_insn_length): New function.
        * h8300/h8300.h (ADJUST_INSN_LENGTH): Define.
        * h8300/h8300.md: Remove obsolete comments.
        (move patterns): Tweak constraints.
        (tst patterns): Use "register_operand" for predicate.
        (adds pattern): Use one_insn_adds_subs_operand to get length
        computation correct.
        (subs pattern): Similarly.
        (movstrhi): Remove unused expander.
        (fancy*, pxor, and-not patterns): Remove.  No longer needed.

From-SVN: r11907
parent 731a7b1f
......@@ -454,6 +454,24 @@ adds_subs_operand (op, mode)
return 0;
}
/* Return nonzero if op is an adds/subs operand which only requires
one insn to implement. It is assumed that OP is already an adds/subs
operand. */
int
one_insn_adds_subs_operand (op, mode)
rtx op;
enum machine_mode mode;
{
int val = INTVAL (op);
if (val == 1 || val == -1
|| val == 2 || val == -2
|| (TARGET_H8300H
&& (val == 4 || val == -4)))
return 1;
return 0;
}
char *
output_adds_subs (operands)
rtx *operands;
......@@ -2253,3 +2271,76 @@ output_simode_bld (bild, log2, operands)
/* All done. */
return "";
}
/* Given INSN and it's current length LENGTH, return the adjustment
(in bytes) to correctly compute INSN's length.
We use this to get the lengths of various memory references correct. */
h8300_adjust_insn_length (insn, length)
rtx insn;
int length;
{
rtx pat = PATTERN (insn);
/* Adjust length for reg->mem and mem->reg copies. */
if (GET_CODE (pat) == SET
&& (GET_CODE (SET_SRC (pat)) == MEM
|| GET_CODE (SET_DEST (pat)) == MEM))
{
/* This insn might need a length adjustment. */
rtx addr;
if (GET_CODE (SET_SRC (pat)) == MEM)
addr = XEXP (SET_SRC (pat), 0);
else
addr = XEXP (SET_DEST (pat), 0);
/* On the H8/300, only one adjustment is necessary; if the
address mode is register indirect, then this insn is two
bytes shorter than indicated in the machine description. */
if (TARGET_H8300 && GET_CODE (addr) == REG)
return -2;
/* On the H8/300H, register indirect is 6 bytes shorter than
indicated in the machine description. */
if (TARGET_H8300H && GET_CODE (addr) == REG)
return -6;
/* On the H8/300H, reg + d, for small displacements is 4 bytes
shorter than indicated in the machine description. */
if (TARGET_H8300H
&& GET_CODE (addr) == PLUS
&& GET_CODE (XEXP (addr, 0)) == REG
&& GET_CODE (XEXP (addr, 1)) == CONST_INT
&& INTVAL (XEXP (addr, 1)) > -32768
&& INTVAL (XEXP (addr, 1)) < 32767)
return -4;
}
/* Loading some constants needs adjustment. */
if (GET_CODE (pat) == SET
&& GET_CODE (SET_SRC (pat)) == CONST_INT
&& GET_MODE (SET_DEST (pat)) == SImode
&& INTVAL (SET_SRC (pat)) != 0)
{
if (TARGET_H8300
&& ((INTVAL (SET_SRC (pat)) & 0xffff) == 0
|| ((INTVAL (SET_SRC (pat)) >> 16) & 0xffff) == 0))
return -2;
if (TARGET_H8300H)
{
int val = INTVAL (SET_SRC (pat));
if (val == (val & 0xff)
|| val == (val & 0xff00))
return -6;
if (val == -4 || val == -2 || val == -1)
return -6;
}
}
return 0;
}
......@@ -929,6 +929,9 @@ extern int h8300_valid_machine_decl_attribute ();
#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
h8300_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
LENGTH += h8300_adjust_insn_length (INSN, LENGTH);
/* Compute the cost of computing a constant rtl expression RTX
whose rtx-code is CODE. The body of this macro is a portion
of a switch statement. If the code is computed here,
......
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