Commit 7948a9ea by Kazu Hirata Committed by Kazu Hirata

h8300-protos.h: Add a prototype for compute_mov_length.

	* config/h8300/h8300-protos.h: Add a prototype for
	compute_mov_length.
	* config/h8300/h8300.c (compute_mov_length): New.
	* config/h8300/h8300.md (*movqi_h8300): Use it.
	(*movqi_h8300hs): Likewise.
	(movstrictqi): Likewise.
	(*movhi_h8300): Likewise.
	(*movhi_h8300hs): Likewise.
	(movstricthi): Likewise.
	(*movsi_h8300): Likewise.
	(*movsf_h8300): Likewise.
	(*movsi_h8300hs): Likewise.
	(*movsf_h8300hs): Likewise.

From-SVN: r68454
parent e5b0e711
2003-06-24 Kazu Hirata <kazu@cs.umass.edu>
* config/h8300/h8300-protos.h: Add a prototype for
compute_mov_length.
* config/h8300/h8300.c (compute_mov_length): New.
* config/h8300/h8300.md (*movqi_h8300): Use it.
(*movqi_h8300hs): Likewise.
(movstrictqi): Likewise.
(*movhi_h8300): Likewise.
(*movhi_h8300hs): Likewise.
(movstricthi): Likewise.
(*movsi_h8300): Likewise.
(*movsf_h8300): Likewise.
(*movsi_h8300hs): Likewise.
(*movsf_h8300hs): Likewise.
2003-06-24 Kazu Hirata <kazu@cs.umass.edu>
* jump.c (next_nondeleted_insn): Remove.
* rtl.h: Remove the prototype for next_nondeleted_insn.
......
......@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA. */
/* Declarations for functions used in insn-output.c. */
#ifdef RTX_CODE
extern unsigned int compute_mov_length (rtx *);
extern const char *output_plussi (rtx *);
extern unsigned int compute_plussi_length (rtx *);
extern int compute_plussi_cc (rtx *);
......
......@@ -1806,6 +1806,255 @@ bit_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
|| code == IOR);
}
/* Return the length of mov instruction. */
unsigned int
compute_mov_length (rtx *operands)
{
/* If the mov instruction involves a memory operand, we compute the
length, assuming the largest addressing mode is used, and then
adjust later in the function. Otherwise, we compute and return
the exact length in one step. */
enum machine_mode mode = GET_MODE (operands[0]);
rtx dest = operands[0];
rtx src = operands[1];
rtx addr;
if (GET_CODE (src) == MEM)
addr = XEXP (src, 0);
else if (GET_CODE (dest) == MEM)
addr = XEXP (dest, 0);
else
addr = NULL_RTX;
if (TARGET_H8300)
{
unsigned int base_length;
switch (mode)
{
case QImode:
if (addr == NULL_RTX)
return 2;
/* The eightbit addressing is available only in QImode, so
go ahead and take care of it. */
if (h8300_eightbit_constant_address_p (addr))
return 2;
base_length = 4;
break;
case HImode:
if (addr == NULL_RTX)
{
if (REG_P (src))
return 2;
if (src == const0_rtx)
return 2;
return 4;
}
base_length = 4;
break;
case SImode:
if (addr == NULL_RTX)
{
if (REG_P (src))
return 4;
if (GET_CODE (src) == CONST_INT)
{
if (src == const0_rtx)
return 4;
if ((INTVAL (src) & 0xffff) == 0)
return 6;
if ((INTVAL (src) & 0xffff) == 0)
return 6;
}
return 8;
}
base_length = 8;
break;
case SFmode:
if (addr == NULL_RTX)
{
if (REG_P (src))
return 4;
if (src == const0_rtx)
return 2;
return 6;
}
base_length = 8;
break;
default:
abort ();
}
/* Adjust the length based on the addressing mode used.
Specifically, we subtract the difference between the actual
length and the longest one, which is @(d:16,Rs). For SImode
and SFmode, we double the adjustment because two mov.w are
used to do the job. */
/* @Rs+ and @-Rd are 2 bytes shorter than the longest. */
if (GET_CODE (addr) == PRE_DEC
|| GET_CODE (addr) == POST_INC)
{
if (mode == QImode || mode == HImode)
return base_length - 2;
else
/* In SImode and SFmode, we use two mov.w instructions, so
double the adustment. */
return base_length - 4;
}
/* @Rs and @Rd are 2 bytes shorter than the longest. Note that
in SImode and SFmode, the second mov.w involves an address
with displacement, namely @(2,Rs) or @(2,Rd), so we subtract
only 2 bytes. */
if (GET_CODE (addr) == REG)
return base_length - 2;
return base_length;
}
else
{
unsigned int base_length;
switch (mode)
{
case QImode:
if (addr == NULL_RTX)
return 2;
/* The eightbit addressing is available only in QImode, so
go ahead and take care of it. */
if (h8300_eightbit_constant_address_p (addr))
return 2;
base_length = 8;
break;
case HImode:
if (addr == NULL_RTX)
{
if (REG_P (src))
return 2;
if (src == const0_rtx)
return 2;
return 4;
}
base_length = 8;
break;
case SImode:
if (addr == NULL_RTX)
{
if (REG_P (src))
{
if (REGNO (src) == MAC_REG || REGNO (dest) == MAC_REG)
return 4;
else
return 2;
}
if (GET_CODE (src) == CONST_INT)
{
int val = INTVAL (src);
if (val == 0)
return 2;
if (val == (val & 0x00ff) || val == (val & 0xff00))
return 4;
switch (val & 0xffffffff)
{
case 0xffffffff:
case 0xfffffffe:
case 0xfffffffc:
case 0x0000ffff:
case 0x0000fffe:
case 0xffff0000:
case 0xfffe0000:
case 0x00010000:
case 0x00020000:
return 4;
}
}
return 6;
}
base_length = 10;
break;
case SFmode:
if (addr == NULL_RTX)
{
if (REG_P (src))
return 2;
if (src == const0_rtx)
return 2;
return 6;
}
base_length = 10;
break;
default:
abort ();
}
/* Adjust the length based on the addressing mode used.
Specifically, we subtract the difference between the actual
length and the longest one, which is @(d:24,ERs). */
/* @ERs+ and @-ERd are 6 bytes shorter than the longest. */
if (GET_CODE (addr) == PRE_DEC
|| GET_CODE (addr) == POST_INC)
return base_length - 6;
/* @ERs and @ERd are 6 bytes shorter than the longest. */
if (GET_CODE (addr) == REG)
return base_length - 6;
/* @(d:16,ERs) and @(d:16,ERd) are 4 bytes shorter than the
longest. */
if (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 base_length - 4;
/* @aa:16 is 4 bytes shorter than the longest. */
if (h8300_tiny_constant_address_p (addr))
return base_length - 4;
/* @aa:24 is 2 bytes shorter than the longest. */
if (CONSTANT_P (addr))
return base_length - 2;
return base_length;
}
}
const char *
output_plussi (rtx *operands)
{
......@@ -4067,101 +4316,6 @@ h8300_adjust_insn_length (rtx insn, int length ATTRIBUTE_UNUSED)
if (get_attr_adjust_length (insn) == ADJUST_LENGTH_NO)
return 0;
/* 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);
if (TARGET_H8300)
{
/* On the H8/300, we subtract the difference between the
actual length and the longest one, which is @(d:16,ERs). */
/* @Rs is 2 bytes shorter than the longest. */
if (GET_CODE (addr) == REG)
return -2;
/* @aa:8 is 2 bytes shorter than the longest. */
if (GET_MODE (SET_SRC (pat)) == QImode
&& h8300_eightbit_constant_address_p (addr))
return -2;
}
else
{
/* On the H8/300H and H8S, we subtract the difference
between the actual length and the longest one, which is
@(d:24,ERs). */
/* @ERs is 6 bytes shorter than the longest. */
if (GET_CODE (addr) == REG)
return -6;
/* @(d:16,ERs) is 6 bytes shorter than the longest. */
if (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;
/* @aa:8 is 6 bytes shorter than the longest. */
if (GET_MODE (SET_SRC (pat)) == QImode
&& h8300_eightbit_constant_address_p (addr))
return -6;
/* @aa:16 is 4 bytes shorter than the longest. */
if (h8300_tiny_constant_address_p (addr))
return -4;
/* @aa:24 is 2 bytes shorter than the longest. */
if (GET_CODE (addr) == CONST_INT)
return -2;
}
}
/* 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)
{
int val = INTVAL (SET_SRC (pat));
if (TARGET_H8300
&& ((val & 0xffff) == 0
|| ((val >> 16) & 0xffff) == 0))
return -2;
if (TARGET_H8300H || TARGET_H8300S)
{
if (val == (val & 0xff)
|| val == (val & 0xff00))
return 4 - 6;
switch (val & 0xffffffff)
{
case 0xffffffff:
case 0xfffffffe:
case 0xfffffffc:
case 0x0000ffff:
case 0x0000fffe:
case 0xffff0000:
case 0xfffe0000:
case 0x00010000:
case 0x00020000:
return 4 - 6;
}
}
}
/* Rotations need various adjustments. */
if (GET_CODE (pat) == SET
&& (GET_CODE (SET_SRC (pat)) == ROTATE
......
......@@ -179,7 +179,8 @@
mov.b %R1,%X0
mov.b %R1,%X0
mov.b %X1,%R0"
[(set_attr "length" "2,2,2,2,8,8")
[(set (attr "length")
(symbol_ref "compute_mov_length (operands)"))
(set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv")])
(define_expand "movqi"
......@@ -205,9 +206,8 @@
mov.b %X1,%X0
mov.b %R1,%X0
mov.b %R1,%X0"
[(set_attr_alternative "length"
[(const_int 2) (const_int 2) (const_int 2)
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
[(set (attr "length")
(symbol_ref "compute_mov_length (operands)"))
(set_attr "cc" "set_zn,set_znv,set_znv,set_znv")])
;; movhi
......@@ -260,7 +260,8 @@
mov.w %T1,%T0
mov.w %T1,%T0
mov.w %T1,%T0"
[(set_attr "length" "2,2,2,4,4,4")
[(set (attr "length")
(symbol_ref "compute_mov_length (operands)"))
(set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
(define_insn "*movhi_h8300hs"
......@@ -276,7 +277,8 @@
mov.w %T1,%T0
mov.w %T1,%T0
mov.w %T1,%T0"
[(set_attr "length" "2,2,2,4,8,8")
[(set (attr "length")
(symbol_ref "compute_mov_length (operands)"))
(set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
(define_expand "movhi"
......@@ -302,9 +304,8 @@
mov.w %T1,%T0
mov.w %T1,%T0
mov.w %T1,%T0"
[(set_attr_alternative "length"
[(const_int 2) (const_int 2) (const_int 4)
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
[(set (attr "length")
(symbol_ref "compute_mov_length (operands)"))
(set_attr "cc" "set_zn,set_znv,set_znv,set_znv")])
;; movsi
......@@ -416,7 +417,8 @@
abort ();
}
}"
[(set_attr "length" "4,4,8,8,4,4")
[(set (attr "length")
(symbol_ref "compute_mov_length (operands)"))
(set_attr "cc" "clobber")])
(define_insn "*movsf_h8300"
......@@ -472,7 +474,8 @@
abort ();
}
}"
[(set_attr "length" "4,4,8,8,4,4")
[(set (attr "length")
(symbol_ref "compute_mov_length (operands)"))
(set_attr "cc" "clobber")])
(define_insn "*movsi_h8300hs"
......@@ -547,7 +550,8 @@
}
return \"mov.l %S1,%S0\";
}"
[(set_attr "length" "2,2,6,4,4,10,10,2,6,4")
[(set (attr "length")
(symbol_ref "compute_mov_length (operands)"))
(set_attr "cc" "set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
(define_insn "*movsf_h8300h"
......@@ -563,7 +567,8 @@
mov.l %S1,%S0
mov.l %S1,%S0
mov.l %S1,%S0"
[(set_attr "length" "2,2,10,10,4,4")
[(set (attr "length")
(symbol_ref "compute_mov_length (operands)"))
(set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
;; ----------------------------------------------------------------------
......
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