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
This commit is contained in:
parent
3fb9e74979
commit
887a8bd9fa
|
@ -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. */
|
||||
|
|
|
@ -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). */
|
||||
|
|
|
@ -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")))]
|
||||
""
|
||||
|
|
Loading…
Reference in New Issue