m68hc11.c (m68hc11_addr_mode): New variable.
* config/m68hc11/m68hc11.c (m68hc11_addr_mode): New variable. (m68hc11_mov_addr_mode): Likewise. (m68hc11_override_options): Initialize them based on target. (register_indirect_p): Allow a MEM for indirect addressing modes and use flags to control what is allowed. (m68hc11_small_indexed_indirect_p): Use m68hc11_mov_addr_mode for supported addressing modes. (m68hc11_register_indirect_p): Use m68hc11_addr_mode. (go_if_legitimate_address_internal): Likewise. (m68hc11_indirect_p): Likewise and check the mode. (print_operand): Allow a (MEM (MEM)) and generate indirect addressing. From-SVN: r78792
This commit is contained in:
parent
d6da68b9d4
commit
de70723b1d
@ -1,3 +1,17 @@
|
||||
2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
|
||||
|
||||
* config/m68hc11/m68hc11.c (m68hc11_addr_mode): New variable.
|
||||
(m68hc11_mov_addr_mode): Likewise.
|
||||
(m68hc11_override_options): Initialize them based on target.
|
||||
(register_indirect_p): Allow a MEM for indirect addressing modes and
|
||||
use flags to control what is allowed.
|
||||
(m68hc11_small_indexed_indirect_p): Use m68hc11_mov_addr_mode for
|
||||
supported addressing modes.
|
||||
(m68hc11_register_indirect_p): Use m68hc11_addr_mode.
|
||||
(go_if_legitimate_address_internal): Likewise.
|
||||
(m68hc11_indirect_p): Likewise and check the mode.
|
||||
(print_operand): Allow a (MEM (MEM)) and generate indirect addressing.
|
||||
|
||||
2004-03-02 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* builtins.c (BUILTIN_SETJMP_FRAME_VALUE): Remove.
|
||||
|
@ -139,6 +139,16 @@ unsigned char m68hc11_reg_valid_for_index[FIRST_PSEUDO_REGISTER];
|
||||
This is 1 for 68HC11 and 0 for 68HC12. */
|
||||
int m68hc11_sp_correction;
|
||||
|
||||
#define ADDR_STRICT 0x01 /* Accept only registers in class A_REGS */
|
||||
#define ADDR_INCDEC 0x02 /* Post/Pre inc/dec */
|
||||
#define ADDR_INDEXED 0x04 /* D-reg index */
|
||||
#define ADDR_OFFSET 0x08
|
||||
#define ADDR_INDIRECT 0x10 /* Accept (mem (mem ...)) for [n,X] */
|
||||
#define ADDR_CONST 0x20 /* Accept const and symbol_ref */
|
||||
|
||||
int m68hc11_addr_mode;
|
||||
int m68hc11_mov_addr_mode;
|
||||
|
||||
/* Comparison operands saved by the "tstxx" and "cmpxx" expand patterns. */
|
||||
rtx m68hc11_compare_op0;
|
||||
rtx m68hc11_compare_op1;
|
||||
@ -298,6 +308,8 @@ m68hc11_override_options (void)
|
||||
m68hc11_reg_valid_for_base[HARD_Z_REGNUM] = 1;
|
||||
m68hc11_sp_correction = 1;
|
||||
m68hc11_tmp_regs_class = D_REGS;
|
||||
m68hc11_addr_mode = ADDR_OFFSET;
|
||||
m68hc11_mov_addr_mode = 0;
|
||||
if (m68hc11_soft_reg_count == 0 && !TARGET_M6812)
|
||||
m68hc11_soft_reg_count = "4";
|
||||
}
|
||||
@ -317,6 +329,10 @@ m68hc11_override_options (void)
|
||||
m68hc11_reg_valid_for_index[HARD_D_REGNUM] = 1;
|
||||
m68hc11_sp_correction = 0;
|
||||
m68hc11_tmp_regs_class = TMP_REGS;
|
||||
m68hc11_addr_mode = ADDR_INDIRECT | ADDR_OFFSET | ADDR_CONST
|
||||
| (TARGET_AUTO_INC_DEC ? ADDR_INCDEC : 0);
|
||||
m68hc11_mov_addr_mode = ADDR_OFFSET | ADDR_CONST
|
||||
| (TARGET_AUTO_INC_DEC ? ADDR_INCDEC : 0);
|
||||
target_flags &= ~MASK_M6811;
|
||||
target_flags |= MASK_NO_DIRECT_MODE;
|
||||
if (m68hc11_soft_reg_count == 0)
|
||||
@ -551,18 +567,25 @@ preferred_reload_class (rtx operand, enum reg_class class)
|
||||
For 68hc11: n,r with n in [0..255] and r in A_REGS class
|
||||
For 68hc12: n,r no constraint on the constant, r in A_REGS class. */
|
||||
static int
|
||||
register_indirect_p (rtx operand, enum machine_mode mode, int strict)
|
||||
register_indirect_p (rtx operand, enum machine_mode mode, int addr_mode)
|
||||
{
|
||||
rtx base, offset;
|
||||
|
||||
switch (GET_CODE (operand))
|
||||
{
|
||||
case MEM:
|
||||
if ((addr_mode & ADDR_INDIRECT) && GET_MODE_SIZE (mode) <= 2)
|
||||
return register_indirect_p (XEXP (operand, 0), mode,
|
||||
addr_mode & (ADDR_STRICT | ADDR_OFFSET));
|
||||
return 0;
|
||||
|
||||
case POST_INC:
|
||||
case PRE_INC:
|
||||
case POST_DEC:
|
||||
case PRE_DEC:
|
||||
if (TARGET_M6812 && TARGET_AUTO_INC_DEC)
|
||||
return register_indirect_p (XEXP (operand, 0), mode, strict);
|
||||
if (addr_mode & ADDR_INCDEC)
|
||||
return register_indirect_p (XEXP (operand, 0), mode,
|
||||
addr_mode & ADDR_STRICT);
|
||||
return 0;
|
||||
|
||||
case PLUS:
|
||||
@ -574,36 +597,57 @@ register_indirect_p (rtx operand, enum machine_mode mode, int strict)
|
||||
if (GET_CODE (offset) == MEM)
|
||||
return 0;
|
||||
|
||||
/* Indexed addressing mode with 2 registers. */
|
||||
if (GET_CODE (base) == REG && GET_CODE (offset) == REG)
|
||||
{
|
||||
if (!(addr_mode & ADDR_INDEXED))
|
||||
return 0;
|
||||
|
||||
addr_mode &= ADDR_STRICT;
|
||||
if (REGNO_OK_FOR_BASE_P2 (REGNO (base), addr_mode)
|
||||
&& REGNO_OK_FOR_INDEX_P2 (REGNO (offset), addr_mode))
|
||||
return 1;
|
||||
|
||||
if (REGNO_OK_FOR_BASE_P2 (REGNO (offset), addr_mode)
|
||||
&& REGNO_OK_FOR_INDEX_P2 (REGNO (base), addr_mode))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(addr_mode & ADDR_OFFSET))
|
||||
return 0;
|
||||
|
||||
if (GET_CODE (base) == REG)
|
||||
{
|
||||
if (!VALID_CONSTANT_OFFSET_P (offset, mode))
|
||||
if (!VALID_CONSTANT_OFFSET_P (offset, mode))
|
||||
return 0;
|
||||
|
||||
if (strict == 0)
|
||||
if (!(addr_mode & ADDR_STRICT))
|
||||
return 1;
|
||||
|
||||
return REGNO_OK_FOR_BASE_P2 (REGNO (base), strict);
|
||||
return REGNO_OK_FOR_BASE_P2 (REGNO (base), 1);
|
||||
}
|
||||
|
||||
if (GET_CODE (offset) == REG)
|
||||
{
|
||||
if (!VALID_CONSTANT_OFFSET_P (base, mode))
|
||||
return 0;
|
||||
|
||||
if (strict == 0)
|
||||
if (!(addr_mode & ADDR_STRICT))
|
||||
return 1;
|
||||
|
||||
return REGNO_OK_FOR_BASE_P2 (REGNO (offset), strict);
|
||||
return REGNO_OK_FOR_BASE_P2 (REGNO (offset), 1);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case REG:
|
||||
return REGNO_OK_FOR_BASE_P2 (REGNO (operand), strict);
|
||||
return REGNO_OK_FOR_BASE_P2 (REGNO (operand), addr_mode & ADDR_STRICT);
|
||||
|
||||
case CONST_INT:
|
||||
if (TARGET_M6811)
|
||||
return 0;
|
||||
|
||||
return VALID_CONSTANT_OFFSET_P (operand, mode);
|
||||
if (addr_mode & ADDR_CONST)
|
||||
return VALID_CONSTANT_OFFSET_P (operand, mode);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
@ -616,6 +660,7 @@ int
|
||||
m68hc11_small_indexed_indirect_p (rtx operand, enum machine_mode mode)
|
||||
{
|
||||
rtx base, offset;
|
||||
int addr_mode;
|
||||
|
||||
if (GET_CODE (operand) == REG && reload_in_progress
|
||||
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
|
||||
@ -635,7 +680,8 @@ m68hc11_small_indexed_indirect_p (rtx operand, enum machine_mode mode)
|
||||
if (PUSH_POP_ADDRESS_P (operand))
|
||||
return 1;
|
||||
|
||||
if (!register_indirect_p (operand, mode, reload_completed))
|
||||
addr_mode = m68hc11_mov_addr_mode | (reload_completed ? ADDR_STRICT : 0);
|
||||
if (!register_indirect_p (operand, mode, addr_mode))
|
||||
return 0;
|
||||
|
||||
if (TARGET_M6812 && GET_CODE (operand) == PLUS
|
||||
@ -676,18 +722,29 @@ m68hc11_small_indexed_indirect_p (rtx operand, enum machine_mode mode)
|
||||
int
|
||||
m68hc11_register_indirect_p (rtx operand, enum machine_mode mode)
|
||||
{
|
||||
int addr_mode;
|
||||
|
||||
if (GET_CODE (operand) == REG && reload_in_progress
|
||||
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
|
||||
&& reg_equiv_memory_loc[REGNO (operand)])
|
||||
{
|
||||
operand = reg_equiv_memory_loc[REGNO (operand)];
|
||||
operand = eliminate_regs (operand, 0, NULL_RTX);
|
||||
}
|
||||
if (GET_CODE (operand) != MEM)
|
||||
return 0;
|
||||
|
||||
operand = XEXP (operand, 0);
|
||||
return register_indirect_p (operand, mode,
|
||||
(reload_completed | reload_in_progress));
|
||||
addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
|
||||
return register_indirect_p (operand, mode, addr_mode);
|
||||
}
|
||||
|
||||
static int
|
||||
go_if_legitimate_address_internal (rtx operand, enum machine_mode mode,
|
||||
int strict)
|
||||
{
|
||||
int addr_mode;
|
||||
|
||||
if (CONSTANT_ADDRESS_P (operand) && TARGET_M6812)
|
||||
{
|
||||
/* Reject the global variables if they are too wide. This forces
|
||||
@ -697,7 +754,8 @@ go_if_legitimate_address_internal (rtx operand, enum machine_mode mode,
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (register_indirect_p (operand, mode, strict))
|
||||
addr_mode = m68hc11_addr_mode | (strict ? ADDR_STRICT : 0);
|
||||
if (register_indirect_p (operand, mode, addr_mode))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -984,18 +1042,20 @@ m68hc11_symbolic_p (rtx operand, enum machine_mode mode)
|
||||
int
|
||||
m68hc11_indirect_p (rtx operand, enum machine_mode mode)
|
||||
{
|
||||
if (GET_CODE (operand) == MEM)
|
||||
if (GET_CODE (operand) == MEM && GET_MODE (operand) == mode)
|
||||
{
|
||||
rtx op = XEXP (operand, 0);
|
||||
int addr_mode;
|
||||
|
||||
if (symbolic_memory_operand (op, mode))
|
||||
return 0;
|
||||
return TARGET_M6812;
|
||||
|
||||
if (reload_in_progress)
|
||||
return 1;
|
||||
|
||||
operand = XEXP (operand, 0);
|
||||
return register_indirect_p (operand, mode, reload_completed);
|
||||
addr_mode = m68hc11_addr_mode | (reload_completed ? ADDR_STRICT : 0);
|
||||
return register_indirect_p (operand, mode, addr_mode);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2247,7 +2307,21 @@ print_operand (FILE *file, rtx op, int letter)
|
||||
abort ();
|
||||
break;
|
||||
|
||||
case MEM:
|
||||
if (TARGET_M6812)
|
||||
{
|
||||
fprintf (file, "[");
|
||||
print_operand_address (file, XEXP (base, 0));
|
||||
fprintf (file, "]");
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (m68hc11_page0_symbol_p (base))
|
||||
fprintf (file, "*");
|
||||
|
||||
output_address (base);
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user