aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1996-05-07 20:36:19 -0600
committerJeff Law <law@gcc.gnu.org>1996-05-07 20:36:19 -0600
commit887a8bd9fa39dc2bb96ce479a0c1b5b13d88c654 (patch)
tree5c3671694562fc8e5bb0d77d3fb8e37a8ac6099f /gcc
parent3fb9e749791211cb3df74e5ae929579a29bb6861 (diff)
downloadgcc-887a8bd9fa39dc2bb96ce479a0c1b5b13d88c654.zip
gcc-887a8bd9fa39dc2bb96ce479a0c1b5b13d88c654.tar.gz
gcc-887a8bd9fa39dc2bb96ce479a0c1b5b13d88c654.tar.bz2
h8300.c: Include obstack.h.
* h8300/h8300.c: Include obstack.h. (bit_memory_operand): New function. (print_operand): Append ":16" to a memory reference to the tiny data area. (h8300_tiny_data_p): New function. (h8300_valid_machine_decl_attribute): Accept "tiny_data". Fix typo. (h8300_encode_label): New function. (h8300_adjust_insn_length): References to the tiny data section are two bytes shorter than normal accesses on the H8/300H. * h8300/h8300.h (OK_FOR_U): Fix thinko. (ENCODE_SECTION_INFO): Encode info for tiny data variables. (STRIP_NAME_ENCODING): Define. * h8300/h8300.md (movqi insn): Fix length for a constant load. (movstrictqi): Likewise. (movhi, movstricthi): Likewise. (memory btst patterns): Add register to the constraints to keep reload happy. From-SVN: r11955
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/h8300/h8300.c76
-rw-r--r--gcc/config/h8300/h8300.h29
-rw-r--r--gcc/config/h8300/h8300.md42
3 files changed, 116 insertions, 31 deletions
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 21748e9..f086caf 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -35,6 +35,7 @@ Boston, MA 02111-1307, USA. */
#include "recog.h"
#include "expr.h"
#include "tree.h"
+#include "obstack.h"
/* Forward declarations. */
void print_operand_address ();
@@ -615,6 +616,15 @@ bit_operand (op, mode)
}
}
+int
+bit_memory_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return (GET_CODE (op) == MEM
+ && EXTRA_CONSTRAINT (op, 'U'));
+}
+
/* Recognize valid operators for bit test. */
int
@@ -1193,6 +1203,9 @@ print_operand (file, x, code)
&& GET_CODE (XEXP (x, 0)) == SYMBOL_REF
&& SYMBOL_REF_FLAG (XEXP (x, 0)))
fprintf (file, ":8");
+ if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
+ && TINY_DATA_NAME_P (XSTR (XEXP (x, 0), 0)))
+ fprintf (file, ":16");
break;
case CONST_INT:
@@ -2188,7 +2201,7 @@ h8300_funcvec_function_p (func)
return a != NULL_TREE;
}
-/* Return nonzero if DECL is a variable that's in the tiny
+/* Return nonzero if DECL is a variable that's in the eight bit
data area. */
int
@@ -2204,6 +2217,22 @@ h8300_eightbit_data_p (decl)
return a != NULL_TREE;
}
+/* Return nonzero if DECL is a variable that's in the tiny
+ data area. */
+
+int
+h8300_tiny_data_p (decl)
+ tree decl;
+{
+ tree a;
+
+ if (TREE_CODE (decl) != VAR_DECL)
+ return 0;
+
+ a = lookup_attribute ("tiny_data", DECL_MACHINE_ATTRIBUTES (decl));
+ return a != NULL_TREE;
+}
+
/* Return nonzero if ATTR is a valid attribute for DECL.
ATTRIBUTES are any existing attributes and ARGS are the arguments
supplied with ATTR.
@@ -2214,7 +2243,13 @@ h8300_eightbit_data_p (decl)
interrupt handler.
function_vector: This function should be called through the
- function vector. */
+ function vector.
+
+ eightbit_data: This variable lives in the 8-bit data area and can
+ be referenced with 8-bit absolute memory addresses.
+
+ tiny_data: This variable lives in the tiny data area and can be
+ referenced with 16-bit absolute memory references. */
int
h8300_valid_machine_decl_attribute (decl, attributes, attr, args)
@@ -2238,13 +2273,41 @@ h8300_valid_machine_decl_attribute (decl, attributes, attr, args)
warning ("Only initialized variables can be placed into the 8-bit area.");
return 0;
}
- DECL_SECTION_NAME (decl) = build_string (8, ".eight");
+ DECL_SECTION_NAME (decl) = build_string (7, ".eight");
+ return 1;
+ }
+
+ if (is_attribute_p ("tiny_data", attr)
+ && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
+ {
+ if (DECL_INITIAL (decl) == NULL_TREE)
+ {
+ warning ("Only initialized variables can be placed into the 8-bit area.");
+ return 0;
+ }
+ DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
return 1;
}
return 0;
}
+extern struct obstack *saveable_obstack;
+
+h8300_encode_label (decl)
+ tree decl;
+{
+ char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+ int len = strlen (str);
+ char *newstr;
+
+ newstr = obstack_alloc (saveable_obstack, len + 2);
+
+ strcpy (newstr + 1, str);
+ *newstr = '*';
+ XSTR (XEXP (DECL_RTL (decl), 0), 0) = newstr;
+}
+
char *
output_simode_bld (bild, log2, operands)
int bild;
@@ -2316,6 +2379,13 @@ h8300_adjust_insn_length (insn, length)
&& INTVAL (XEXP (addr, 1)) > -32768
&& INTVAL (XEXP (addr, 1)) < 32767)
return -4;
+
+ /* On the H8/300H, abs:16 is two bytes shorter than the
+ more general abs:24. */
+ if (TARGET_H8300H
+ && GET_CODE (addr) == SYMBOL_REF
+ && TINY_DATA_NAME_P (XSTR (addr, 0)))
+ return -2;
}
/* Loading some constants needs adjustment. */
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index 069797f..3020fbe 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -150,7 +150,7 @@ do { \
/* Define this if most significant word of a multiword number is lowest
numbered.
This is true on an H8/300 (actually we can make it up, but we choose to
- be consistent. */
+ be consistent). */
#define WORDS_BIG_ENDIAN 1
/* Number of bits in an addressable storage unit */
@@ -784,8 +784,7 @@ struct rtx_def *function_arg();
/* Extra constraints - 'U' if for an operand valid for a bset
destination; i.e. a register, register indirect, or the
- eightbit memory region (a SYMBOL_REF with the SYMBOL_REF_FLAG
- set. */
+ eightbit memory region (a SYMBOL_REF with an SYMBOL_REF_FLAG set). */
#define OK_FOR_U(OP) \
((GET_CODE (OP) == REG && REG_OK_FOR_BASE_P (OP)) \
|| (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
@@ -795,7 +794,7 @@ struct rtx_def *function_arg();
|| (GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == CONST \
&& GET_CODE (XEXP (XEXP (OP, 0), 0)) == PLUS \
&& GET_CODE (XEXP (XEXP (XEXP (OP, 0), 0), 0)) == SYMBOL_REF \
- && SYMBOL_REF_FLAG (XEXP (XEXP (XEXP (OP, 0), 0), 0)) \
+ && SYMBOL_REF_FLAG (XEXP (XEXP (OP, 0), 0)) \
&& GET_CODE (XEXP (XEXP (XEXP (OP, 0), 0), 1)) == CONST_INT))
#define EXTRA_CONSTRAINT(OP, C) \
@@ -1106,16 +1105,28 @@ readonly_data() \
} \
}
+#define TINY_DATA_NAME_P(NAME) (*(NAME) == '*')
+
/* If we are referencing a function that is supposed to be called
through the function vector, the SYMBOL_REF_FLAG in the rtl
so the call patterns can generate the correct code. */
#define ENCODE_SECTION_INFO(DECL) \
- if ((TREE_CODE (DECL) == FUNCTION_DECL \
+ if (TREE_CODE (DECL) == FUNCTION_DECL \
&& h8300_funcvec_function_p (DECL)) \
- || ((TREE_STATIC (DECL) || DECL_EXTERNAL (DECL)) \
- && TREE_CODE (DECL) == VAR_DECL \
- && h8300_eightbit_data_p (DECL))) \
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;
+ SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \
+ else if ((TREE_STATIC (DECL) || DECL_EXTERNAL (DECL)) \
+ && TREE_CODE (DECL) == VAR_DECL \
+ && h8300_eightbit_data_p (DECL)) \
+ SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \
+ else if ((TREE_STATIC (DECL) || DECL_EXTERNAL (DECL)) \
+ && TREE_CODE (DECL) == VAR_DECL \
+ && h8300_tiny_data_p (DECL)) \
+ h8300_encode_label (DECL);
+
+/* Store the user-specified part of SYMBOL_NAME in VAR.
+ This is sort of inverse to ENCODE_SECTION_INFO. */
+#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
+ (VAR) = (SYMBOL_NAME) + ((SYMBOL_NAME)[0] == '*' || (SYMBOL_NAME)[0] == '@');
/* How to refer to registers in assembler output.
This sequence is indexed by compiler's hard-register-number (see above). */
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 059a91f..f714b84 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -116,8 +116,8 @@
(set_attr "cc" "set")])
(define_insn ""
- [(set (match_operand:QI 0 "general_operand_dst" "=r,r,<,r,o")
- (match_operand:QI 1 "general_operand_src" "I,r>,r,io,r"))]
+ [(set (match_operand:QI 0 "general_operand_dst" "=r,r,<,r,r,o")
+ (match_operand:QI 1 "general_operand_src" "I,r>,r,i,o,r"))]
"register_operand (operands[0],QImode)
|| register_operand (operands[1], QImode)"
"@
@@ -125,12 +125,13 @@
mov.b %R1,%X0
mov.b %X1,%R0
mov.b %R1,%X0
+ mov.b %R1,%X0
mov.b %X1,%R0"
[(set_attr_alternative "length"
- [(const_int 2) (const_int 2) (const_int 2)
+ [(const_int 2) (const_int 2) (const_int 2) (const_int 2)
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
- (set_attr "cc" "set_zn_c0,set,set,set,set")])
+ (set_attr "cc" "set_zn_c0,set,set,set,set,set")])
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand_dst" "")
@@ -147,17 +148,18 @@
}")
(define_insn "movstrictqi"
- [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "=r,r,r"))
- (match_operand:QI 1 "general_operand_src" "I,r,io"))]
+ [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "=r,r,r,r"))
+ (match_operand:QI 1 "general_operand_src" "I,r,i,o"))]
""
"@
sub.b %X0,%X0
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) (const_int 2) (const_int 2)
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
- (set_attr "cc" "set_zn_c0,set,set")])
+ (set_attr "cc" "set_zn_c0,set,set,set")])
;; movhi
@@ -178,8 +180,8 @@
(set_attr "cc" "set")])
(define_insn ""
- [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,o")
- (match_operand:HI 1 "general_operand_src" "I,r>,r,io,r"))]
+ [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,o")
+ (match_operand:HI 1 "general_operand_src" "I,r>,r,i,o,r"))]
"register_operand (operands[0],HImode)
|| register_operand (operands[1], HImode)"
"@
@@ -187,12 +189,13 @@
mov.w %T1,%T0
mov.w %T1,%T0
mov.w %T1,%T0
+ mov.w %T1,%T0
mov.w %T1,%T0"
[(set_attr_alternative "length"
- [(const_int 2) (const_int 2) (const_int 2)
+ [(const_int 2) (const_int 2) (const_int 2) (const_int 4)
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
- (set_attr "cc" "set_zn_c0,set,set,set,set")])
+ (set_attr "cc" "set_zn_c0,set,set,set,set,set")])
(define_expand "movhi"
[(set (match_operand:HI 0 "general_operand_dst" "")
@@ -209,17 +212,18 @@
}")
(define_insn "movstricthi"
- [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "=r,r,r"))
- (match_operand:HI 1 "general_operand_src" "I,r,io"))]
+ [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "=r,r,r,r"))
+ (match_operand:HI 1 "general_operand_src" "I,r,i,o"))]
""
"@
sub.w %T0,%T0
mov.w %T1,%T0
+ mov.w %T1,%T0
mov.w %T1,%T0"
[(set_attr_alternative "length"
- [(const_int 2) (const_int 2)
+ [(const_int 2) (const_int 2) (const_int 4)
(if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
- (set_attr "cc" "set_zn_c0,set,set")])
+ (set_attr "cc" "set_zn_c0,set,set,set")])
;; movsi
@@ -453,7 +457,7 @@
;; ----------------------------------------------------------------------
(define_insn ""
- [(set (cc0) (zero_extract:QI (match_operand:QI 0 "memory_operand" "U")
+ [(set (cc0) (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "rU")
(const_int 1)
(match_operand:QI 1 "const_int_operand" "n")))]
""
@@ -462,7 +466,7 @@
(set_attr "cc" "set_zn_c0")])
(define_insn ""
- [(set (cc0) (zero_extract:HI (match_operand:QI 0 "memory_operand" "U")
+ [(set (cc0) (zero_extract:HI (match_operand:QI 0 "bit_memory_operand" "rU")
(const_int 1)
(match_operand:QI 1 "const_int_operand" "n")))]
""
@@ -471,7 +475,7 @@
(set_attr "cc" "set_zn_c0")])
(define_insn ""
- [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "U")
+ [(set (cc0) (zero_extract:SI (match_operand:QI 0 "bit_memory_operand" "rU")
(const_int 1)
(match_operand:QI 1 "const_int_operand" "n")))]
""