aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKazu Hirata <kazu@cs.umass.edu>2003-06-25 03:47:31 +0000
committerKazu Hirata <kazu@gcc.gnu.org>2003-06-25 03:47:31 +0000
commit7948a9eac2804420e87161f936fead7287008502 (patch)
tree0bf426478719158e95f27032408a66d645db9ed9
parente5b0e711e87da60282d32ee364bfc9ca77fa6360 (diff)
downloadgcc-7948a9eac2804420e87161f936fead7287008502.zip
gcc-7948a9eac2804420e87161f936fead7287008502.tar.gz
gcc-7948a9eac2804420e87161f936fead7287008502.tar.bz2
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
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/h8300/h8300-protos.h1
-rw-r--r--gcc/config/h8300/h8300.c344
-rw-r--r--gcc/config/h8300/h8300.md31
4 files changed, 284 insertions, 108 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f30e835..d443295 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,21 @@
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.
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index d170869..e7ddff8 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -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 *);
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index e82ee95..3a5334b 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -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
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 5533cd8..ec9f1c6 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -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")])
;; ----------------------------------------------------------------------