+2004-03-28 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11-protos.h (m68hc11_page0_symbol_p): Declare.
+
+ * config/m68hc11/m68hc11.c (m68hc11_handle_page0_attribute): New.
+ (m68hc11_attribute_table): New attribute "page0" to mark a global
+ variable as being allocated from within page0 section.
+ (m68hc11_encode_label): New function.
+ (m68hc11_strip_name_encoding): New function.
+ (m68hc11_page0_symbol_p): New function.
+ (m68hc11_indirect_p): Accept global variables marked in page0.
+ (m68hc11_encode_section_info): Lookup "page0" attribute.
+
+ * config/m68hc11/m68hc11.h (EXTRA_CONSTRAINT): 'R' constraint also
+ represents access to page0 variables.
+
+ * config/m68hc11/m68hc11.md ("*logicalsi3_zexthi"): Use gen_rtx_REG.
+ ("*logicalsi3_silshl16_zext"): Likewise.
+ ("*ashldi3_const32"): Likewise.
+ (peephole2 ashift): Likewise.
+
2004-03-28 Joseph S. Myers <jsm@polyomino.org.uk>
* c-tree.h (C_DECL_REGISTER): New.
/* Subroutines for code generation on Motorola 68HC11 and 68HC12.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Stephane Carrez (stcarrez@nerim.fr)
This file is part of GCC.
static void m68hc11_asm_out_destructor (rtx, int);
static void m68hc11_file_start (void);
static void m68hc11_encode_section_info (tree, rtx, int);
+static const char *m68hc11_strip_name_encoding (const char* str);
static unsigned int m68hc11_section_type_flags (tree, const char*, int);
static int autoinc_mode (rtx);
static int m68hc11_make_autoinc_notes (rtx *, void *);
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY m68hc11_return_in_memory
+#undef TARGET_STRIP_NAME_ENCODING
+#define TARGET_STRIP_NAME_ENCODING m68hc11_strip_name_encoding
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
int
rtx op = XEXP (operand, 0);
int addr_mode;
+ if (m68hc11_page0_symbol_p (op))
+ return 1;
+
if (symbolic_memory_operand (op, mode))
return TARGET_M6812;
\f
/* Declaration of types. */
+/* Handle an "tiny_data" attribute; arguments as in
+ struct attribute_spec.handler. */
+static tree
+m68hc11_handle_page0_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+ tree decl = *node;
+
+ if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
+ {
+ DECL_SECTION_NAME (decl) = build_string (6, ".page0");
+ }
+ else
+ {
+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
const struct attribute_spec m68hc11_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
{ "trap", 0, 0, false, true, true, m68hc11_handle_fntype_attribute },
{ "far", 0, 0, false, true, true, m68hc11_handle_fntype_attribute },
{ "near", 0, 0, false, true, true, m68hc11_handle_fntype_attribute },
+ { "page0", 0, 0, false, false, false, m68hc11_handle_page0_attribute },
{ NULL, 0, 0, false, false, false, NULL }
};
return NULL_TREE;
}
+/* Undo the effects of the above. */
+
+static const char *
+m68hc11_strip_name_encoding (const char *str)
+{
+ return str + (*str == '*' || *str == '@' || *str == '&');
+}
+
+static void
+m68hc11_encode_label (tree decl)
+{
+ const char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+ int len = strlen (str);
+ char *newstr = alloca (len + 2);
+
+ newstr[0] = '@';
+ strcpy (&newstr[1], str);
+
+ XSTR (XEXP (DECL_RTL (decl), 0), 0) = ggc_alloc_string (newstr, len + 1);
+}
+
+/* Return 1 if this is a symbol in page0 */
+int
+m68hc11_page0_symbol_p (rtx x)
+{
+ switch (GET_CODE (x))
+ {
+ case SYMBOL_REF:
+ return XSTR (x, 0) != 0 && XSTR (x, 0)[0] == '@';
+
+ case CONST:
+ return m68hc11_page0_symbol_p (XEXP (x, 0));
+
+ case PLUS:
+ if (!m68hc11_page0_symbol_p (XEXP (x, 0)))
+ return 0;
+
+ return GET_CODE (XEXP (x, 1)) == CONST_INT
+ && INTVAL (XEXP (x, 1)) < 256
+ && INTVAL (XEXP (x, 1)) >= 0;
+
+ default:
+ return 0;
+ }
+}
/* We want to recognize trap handlers so that we handle calls to traps
in a special manner (by issuing the trap). This information is stored
int trap_handler;
int is_far = 0;
+ if (TREE_CODE (decl) == VAR_DECL)
+ {
+ if (lookup_attribute ("page0", DECL_ATTRIBUTES (decl)) != 0)
+ m68hc11_encode_label (decl);
+ return;
+ }
+
if (TREE_CODE (decl) != FUNCTION_DECL)
return;
{
operands[5] = operands[1];
/* Make all the (set (REG:x) (REG:y)) a nop set. */
- operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM);
- operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM);
+ operands[4] = gen_rtx_REG (HImode, HARD_D_REGNUM);
+ operands[6] = gen_rtx_REG (HImode, HARD_X_REGNUM);
}
else
{
{
FAIL;
}
- emit_move_insn (gen_rtx (REG, HImode, HARD_X_REGNUM), operands[2]);
- emit_insn (gen_swap_areg (gen_rtx (REG, HImode, HARD_D_REGNUM),
- gen_rtx (REG, HImode, HARD_X_REGNUM)));
+ emit_move_insn (gen_rtx_REG (HImode, HARD_X_REGNUM), operands[2]);
+ emit_insn (gen_swap_areg (gen_rtx_REG (HImode, HARD_D_REGNUM),
+ gen_rtx_REG (HImode, HARD_X_REGNUM)));
}
- operands[4] = gen_rtx (REG, HImode, HARD_D_REGNUM);
- operands[6] = gen_rtx (REG, HImode, HARD_X_REGNUM);
+ operands[4] = gen_rtx_REG (HImode, HARD_D_REGNUM);
+ operands[6] = gen_rtx_REG (HImode, HARD_X_REGNUM);
operands[5] = operands[2];
operands[7] = operands[1];
/* Adjust first operand if it uses SP so that we take into
account the above push. Can occur only for 68HC12. */
- if (reg_mentioned_p (gen_rtx (REG, HImode, HARD_SP_REGNUM),
+ if (reg_mentioned_p (gen_rtx_REG (HImode, HARD_SP_REGNUM),
operands[1]))
operands[1] = adjust_address (operands[1],
GET_MODE (operands[0]), 4);
"operands[3] = m68hc11_gen_highpart (HImode, operands[2]);
if (X_REG_P (operands[2]))
{
- operands[4] = gen_rtx (REG, HImode, HARD_X_REGNUM);
- operands[5] = gen_rtx (REG, HImode, HARD_D_REGNUM);
+ operands[4] = gen_rtx_REG (HImode, HARD_X_REGNUM);
+ operands[5] = gen_rtx_REG (HImode, HARD_D_REGNUM);
}
else
{
operands[4] = m68hc11_gen_lowpart (HImode, operands[2]);
- operands[5] = gen_rtx (REG, HImode, HARD_X_REGNUM);
+ operands[5] = gen_rtx_REG (HImode, HARD_X_REGNUM);
}
")
(set (match_operand:HI 3 "nonimmediate_operand" "") (reg:HI D_REGNUM))
(set (match_operand:HI 4 "nonimmediate_operand" "") (reg:HI X_REGNUM))]
"!X_REG_P (operands[1])
- && peep2_reg_dead_p (2, gen_rtx (REG, HImode, D_REGNUM))
- && peep2_reg_dead_p (3, gen_rtx (REG, HImode, X_REGNUM))"
+ && peep2_reg_dead_p (2, gen_rtx_REG (HImode, D_REGNUM))
+ && peep2_reg_dead_p (3, gen_rtx_REG (HImode, X_REGNUM))"
[(set (reg:HI D_REGNUM) (match_dup 5))
(set (reg:HI D_REGNUM) (ashift:HI (reg:HI D_REGNUM) (const_int 1)))
(set (match_dup 3) (reg:HI D_REGNUM))