constraints.md: For each W* constraint...
* config/rl78/constraints.md: For each W* constraint, rename to C* and create a W* constraint that checks for an optional ES: prefix pattern also. * config/rl78/rl78.md (UNS_ES_ADDR): New. (es_addr): New. Used to wrap far addresses. * config/rl78/rl78-protos.h (rl78_es_addr): New. (rl78_es_base): New. * config/rl78/rl78.c (rl78_as_legitimate_address): Accept "unspec" wrapped far addresses. (rl78_print_operand_1): Unwrap far addresses before processing. (rl78_lo16): Wrap far addresses in unspecs. (rl78_es_addr): New. (rl78_es_base): New. (insn_ok_now): Check for not-yet-wrapped far addresses. (transcode_memory_rtx): Properly re-wrap far addresses. From-SVN: r202666
This commit is contained in:
parent
5c26a69a2a
commit
2e7c3f214d
@ -1,3 +1,21 @@
|
|||||||
|
2013-09-17 DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
* config/rl78/constraints.md: For each W* constraint, rename to C*
|
||||||
|
and create a W* constraint that checks for an optional ES: prefix
|
||||||
|
pattern also.
|
||||||
|
* config/rl78/rl78.md (UNS_ES_ADDR): New.
|
||||||
|
(es_addr): New. Used to wrap far addresses.
|
||||||
|
* config/rl78/rl78-protos.h (rl78_es_addr): New.
|
||||||
|
(rl78_es_base): New.
|
||||||
|
* config/rl78/rl78.c (rl78_as_legitimate_address): Accept "unspec"
|
||||||
|
wrapped far addresses.
|
||||||
|
(rl78_print_operand_1): Unwrap far addresses before processing.
|
||||||
|
(rl78_lo16): Wrap far addresses in unspecs.
|
||||||
|
(rl78_es_addr): New.
|
||||||
|
(rl78_es_base): New.
|
||||||
|
(insn_ok_now): Check for not-yet-wrapped far addresses.
|
||||||
|
(transcode_memory_rtx): Properly re-wrap far addresses.
|
||||||
|
|
||||||
2013-09-17 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
2013-09-17 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
* config/sparc/t-rtems: Add leon3 multilibs.
|
* config/sparc/t-rtems: Add leon3 multilibs.
|
||||||
|
@ -203,17 +203,24 @@
|
|||||||
; All the memory addressing schemes the RL78 supports
|
; All the memory addressing schemes the RL78 supports
|
||||||
; of the form W {register} {bytes of offset}
|
; of the form W {register} {bytes of offset}
|
||||||
; or W {register} {register}
|
; or W {register} {register}
|
||||||
|
; Additionally, the Cxx forms are the same as the Wxx forms, but without
|
||||||
|
; the ES: override.
|
||||||
|
|
||||||
; absolute address
|
; absolute address
|
||||||
(define_memory_constraint "Wab"
|
(define_memory_constraint "Cab"
|
||||||
"[addr]"
|
"[addr]"
|
||||||
(and (match_code "mem")
|
(and (match_code "mem")
|
||||||
(ior (match_test "CONSTANT_P (XEXP (op, 0))")
|
(ior (match_test "CONSTANT_P (XEXP (op, 0))")
|
||||||
(match_test "GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF"))
|
(match_test "GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF"))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(define_memory_constraint "Wab"
|
||||||
|
"es:[addr]"
|
||||||
|
(match_test "rl78_es_addr (op) && satisfies_constraint_Cab (rl78_es_base (op))
|
||||||
|
|| satisfies_constraint_Cab (op)")
|
||||||
|
)
|
||||||
|
|
||||||
(define_memory_constraint "Wbc"
|
(define_memory_constraint "Cbc"
|
||||||
"word16[BC]"
|
"word16[BC]"
|
||||||
(and (match_code "mem")
|
(and (match_code "mem")
|
||||||
(ior
|
(ior
|
||||||
@ -225,29 +232,49 @@
|
|||||||
(match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
(match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(define_memory_constraint "Wbc"
|
||||||
|
"es:word16[BC]"
|
||||||
|
(match_test "rl78_es_addr (op) && satisfies_constraint_Cbc (rl78_es_base (op))
|
||||||
|
|| satisfies_constraint_Cbc (op)")
|
||||||
|
)
|
||||||
|
|
||||||
(define_memory_constraint "Wde"
|
(define_memory_constraint "Cde"
|
||||||
"[DE]"
|
"[DE]"
|
||||||
(and (match_code "mem")
|
(and (match_code "mem")
|
||||||
(and (match_code "reg" "0")
|
(and (match_code "reg" "0")
|
||||||
(match_test "REGNO (XEXP (op, 0)) == DE_REG")))
|
(match_test "REGNO (XEXP (op, 0)) == DE_REG")))
|
||||||
)
|
)
|
||||||
|
(define_memory_constraint "Wde"
|
||||||
|
"es:[DE]"
|
||||||
|
(match_test "rl78_es_addr (op) && satisfies_constraint_Cde (rl78_es_base (op))
|
||||||
|
|| satisfies_constraint_Cde (op)")
|
||||||
|
)
|
||||||
|
|
||||||
(define_memory_constraint "Wca"
|
(define_memory_constraint "Cca"
|
||||||
"[AX..HL] for calls"
|
"[AX..HL] for calls"
|
||||||
(and (match_code "mem")
|
(and (match_code "mem")
|
||||||
(and (match_code "reg" "0")
|
(and (match_code "reg" "0")
|
||||||
(match_test "REGNO (XEXP (op, 0)) <= HL_REG")))
|
(match_test "REGNO (XEXP (op, 0)) <= HL_REG")))
|
||||||
)
|
)
|
||||||
|
(define_memory_constraint "Wca"
|
||||||
|
"es:[AX..HL] for calls"
|
||||||
|
(match_test "rl78_es_addr (op) && satisfies_constraint_Cca (rl78_es_base (op))
|
||||||
|
|| satisfies_constraint_Cca (op)")
|
||||||
|
)
|
||||||
|
|
||||||
(define_memory_constraint "Wcv"
|
(define_memory_constraint "Ccv"
|
||||||
"[AX..HL,r8-r23] for calls"
|
"[AX..HL,r8-r23] for calls"
|
||||||
(and (match_code "mem")
|
(and (match_code "mem")
|
||||||
(and (match_code "reg" "0")
|
(and (match_code "reg" "0")
|
||||||
(match_test "REGNO (XEXP (op, 0)) < 24")))
|
(match_test "REGNO (XEXP (op, 0)) < 24")))
|
||||||
)
|
)
|
||||||
|
(define_memory_constraint "Wcv"
|
||||||
|
"es:[AX..HL,r8-r23] for calls"
|
||||||
|
(match_test "rl78_es_addr (op) && satisfies_constraint_Ccv (rl78_es_base (op))
|
||||||
|
|| satisfies_constraint_Ccv (op)")
|
||||||
|
)
|
||||||
|
|
||||||
(define_memory_constraint "Wd2"
|
(define_memory_constraint "Cd2"
|
||||||
"word16[DE]"
|
"word16[DE]"
|
||||||
(and (match_code "mem")
|
(and (match_code "mem")
|
||||||
(ior
|
(ior
|
||||||
@ -259,15 +286,25 @@
|
|||||||
(match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
(match_test "uword_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(define_memory_constraint "Wd2"
|
||||||
|
"es:word16[DE]"
|
||||||
|
(match_test "rl78_es_addr (op) && satisfies_constraint_Cd2 (rl78_es_base (op))
|
||||||
|
|| satisfies_constraint_Cd2 (op)")
|
||||||
|
)
|
||||||
|
|
||||||
(define_memory_constraint "Whl"
|
(define_memory_constraint "Chl"
|
||||||
"[HL]"
|
"[HL]"
|
||||||
(and (match_code "mem")
|
(and (match_code "mem")
|
||||||
(and (match_code "reg" "0")
|
(and (match_code "reg" "0")
|
||||||
(match_test "REGNO (XEXP (op, 0)) == HL_REG")))
|
(match_test "REGNO (XEXP (op, 0)) == HL_REG")))
|
||||||
)
|
)
|
||||||
|
(define_memory_constraint "Whl"
|
||||||
|
"es:[HL]"
|
||||||
|
(match_test "rl78_es_addr (op) && satisfies_constraint_Chl (rl78_es_base (op))
|
||||||
|
|| satisfies_constraint_Chl (op)")
|
||||||
|
)
|
||||||
|
|
||||||
(define_memory_constraint "Wh1"
|
(define_memory_constraint "Ch1"
|
||||||
"byte8[HL]"
|
"byte8[HL]"
|
||||||
(and (match_code "mem")
|
(and (match_code "mem")
|
||||||
(and (match_code "plus" "0")
|
(and (match_code "plus" "0")
|
||||||
@ -275,14 +312,24 @@
|
|||||||
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == HL_REG"))
|
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == HL_REG"))
|
||||||
(match_test "ubyte_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
(match_test "ubyte_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
||||||
)
|
)
|
||||||
|
(define_memory_constraint "Wh1"
|
||||||
|
"es:byte8[HL]"
|
||||||
|
(match_test "rl78_es_addr (op) && satisfies_constraint_Ch1 (rl78_es_base (op))
|
||||||
|
|| satisfies_constraint_Ch1 (op)")
|
||||||
|
)
|
||||||
|
|
||||||
(define_memory_constraint "Whb"
|
(define_memory_constraint "Chb"
|
||||||
"[HL+B]"
|
"[HL+B]"
|
||||||
(and (match_code "mem")
|
(and (match_code "mem")
|
||||||
(match_test "rl78_hl_b_c_addr_p (XEXP (op, 0))"))
|
(match_test "rl78_hl_b_c_addr_p (XEXP (op, 0))"))
|
||||||
)
|
)
|
||||||
|
(define_memory_constraint "Whb"
|
||||||
|
"es:[HL+B]"
|
||||||
|
(match_test "rl78_es_addr (op) && satisfies_constraint_Chb (rl78_es_base (op))
|
||||||
|
|| satisfies_constraint_Chb (op)")
|
||||||
|
)
|
||||||
|
|
||||||
(define_memory_constraint "Ws1"
|
(define_memory_constraint "Cs1"
|
||||||
"word8[SP]"
|
"word8[SP]"
|
||||||
(and (match_code "mem")
|
(and (match_code "mem")
|
||||||
(ior
|
(ior
|
||||||
@ -294,6 +341,11 @@
|
|||||||
(match_test "ubyte_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
(match_test "ubyte_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(define_memory_constraint "Ws1"
|
||||||
|
"es:word8[SP]"
|
||||||
|
(match_test "rl78_es_addr (op) && satisfies_constraint_Cs1 (rl78_es_base (op))
|
||||||
|
|| satisfies_constraint_Cs1 (op)")
|
||||||
|
)
|
||||||
|
|
||||||
(define_memory_constraint "Wfr"
|
(define_memory_constraint "Wfr"
|
||||||
"ES/CS far pointer"
|
"ES/CS far pointer"
|
||||||
|
@ -42,3 +42,6 @@ void rl78_register_pragmas (void);
|
|||||||
bool rl78_regno_mode_code_ok_for_base_p (int, enum machine_mode, addr_space_t, int, int);
|
bool rl78_regno_mode_code_ok_for_base_p (int, enum machine_mode, addr_space_t, int, int);
|
||||||
void rl78_setup_peep_movhi (rtx *);
|
void rl78_setup_peep_movhi (rtx *);
|
||||||
bool rl78_virt_insns_ok (void);
|
bool rl78_virt_insns_ok (void);
|
||||||
|
|
||||||
|
bool rl78_es_addr (rtx);
|
||||||
|
rtx rl78_es_base (rtx);
|
||||||
|
@ -858,6 +858,10 @@ rl78_as_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x,
|
|||||||
{
|
{
|
||||||
rtx base, index, addend;
|
rtx base, index, addend;
|
||||||
|
|
||||||
|
if (GET_CODE (x) == UNSPEC
|
||||||
|
&& XINT (x, 1) == UNS_ES_ADDR)
|
||||||
|
x = XVECEXP (x, 0, 1);
|
||||||
|
|
||||||
if (as == ADDR_SPACE_GENERIC
|
if (as == ADDR_SPACE_GENERIC
|
||||||
&& GET_MODE (x) == SImode)
|
&& GET_MODE (x) == SImode)
|
||||||
return false;
|
return false;
|
||||||
@ -1290,7 +1294,10 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (rl78_far_p (op))
|
if (rl78_far_p (op))
|
||||||
fprintf (file, "es:");
|
{
|
||||||
|
fprintf (file, "es:");
|
||||||
|
op = gen_rtx_MEM (GET_MODE (op), XVECEXP (XEXP (op, 0), 0, 1));
|
||||||
|
}
|
||||||
if (letter == 'H')
|
if (letter == 'H')
|
||||||
{
|
{
|
||||||
op = adjust_address (op, HImode, 2);
|
op = adjust_address (op, HImode, 2);
|
||||||
@ -1847,6 +1854,8 @@ re-run regmove, but that has not yet been attempted.
|
|||||||
*/
|
*/
|
||||||
#define DEBUG_ALLOC 0
|
#define DEBUG_ALLOC 0
|
||||||
|
|
||||||
|
#define OP(x) (*recog_data.operand_loc[x])
|
||||||
|
|
||||||
/* This array is used to hold knowledge about the contents of the
|
/* This array is used to hold knowledge about the contents of the
|
||||||
real registers (A ... H), the memory-based registers (r8 ... r31)
|
real registers (A ... H), the memory-based registers (r8 ... r31)
|
||||||
and the first NUM_STACK_LOCS words on the stack. We use this to
|
and the first NUM_STACK_LOCS words on the stack. We use this to
|
||||||
@ -2072,6 +2081,31 @@ already_contains (rtx loc, rtx value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
rl78_es_addr (rtx addr)
|
||||||
|
{
|
||||||
|
if (GET_CODE (addr) == MEM)
|
||||||
|
addr = XEXP (addr, 0);
|
||||||
|
if (GET_CODE (addr) != UNSPEC)
|
||||||
|
return false;
|
||||||
|
if (XINT (addr, 1) != UNS_ES_ADDR)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtx
|
||||||
|
rl78_es_base (rtx addr)
|
||||||
|
{
|
||||||
|
if (GET_CODE (addr) == MEM)
|
||||||
|
addr = XEXP (addr, 0);
|
||||||
|
addr = XVECEXP (addr, 0, 1);
|
||||||
|
if (GET_CODE (addr) == CONST
|
||||||
|
&& GET_CODE (XEXP (addr, 0)) == ZERO_EXTRACT)
|
||||||
|
addr = XEXP (XEXP (addr, 0), 0);
|
||||||
|
/* Mode doesn't matter here. */
|
||||||
|
return gen_rtx_MEM (HImode, addr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Rescans an insn to see if it's recognized again. This is done
|
/* Rescans an insn to see if it's recognized again. This is done
|
||||||
carefully to ensure that all the constraint information is accurate
|
carefully to ensure that all the constraint information is accurate
|
||||||
for the newly matched insn. */
|
for the newly matched insn. */
|
||||||
@ -2079,6 +2113,7 @@ static bool
|
|||||||
insn_ok_now (rtx insn)
|
insn_ok_now (rtx insn)
|
||||||
{
|
{
|
||||||
rtx pattern = PATTERN (insn);
|
rtx pattern = PATTERN (insn);
|
||||||
|
int i;
|
||||||
|
|
||||||
INSN_CODE (insn) = -1;
|
INSN_CODE (insn) = -1;
|
||||||
|
|
||||||
@ -2095,6 +2130,14 @@ insn_ok_now (rtx insn)
|
|||||||
if (SET_P (pattern))
|
if (SET_P (pattern))
|
||||||
record_content (SET_DEST (pattern), SET_SRC (pattern));
|
record_content (SET_DEST (pattern), SET_SRC (pattern));
|
||||||
|
|
||||||
|
/* We need to detect far addresses that haven't been
|
||||||
|
converted to es/lo16 format. */
|
||||||
|
for (i=0; i<recog_data.n_operands; i++)
|
||||||
|
if (GET_CODE (OP(i)) == MEM
|
||||||
|
&& GET_MODE (XEXP (OP(i), 0)) == SImode
|
||||||
|
&& GET_CODE (XEXP (OP(i), 0)) != UNSPEC)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2155,8 +2198,6 @@ insn_ok_now (rtx insn)
|
|||||||
#define DE gen_rtx_REG (HImode, 4)
|
#define DE gen_rtx_REG (HImode, 4)
|
||||||
#define HL gen_rtx_REG (HImode, 6)
|
#define HL gen_rtx_REG (HImode, 6)
|
||||||
|
|
||||||
#define OP(x) (*recog_data.operand_loc[x])
|
|
||||||
|
|
||||||
/* Returns TRUE if R is a virtual register. */
|
/* Returns TRUE if R is a virtual register. */
|
||||||
static bool
|
static bool
|
||||||
is_virtual_register (rtx r)
|
is_virtual_register (rtx r)
|
||||||
@ -2195,14 +2236,20 @@ EM2 (int line ATTRIBUTE_UNUSED, rtx r)
|
|||||||
static rtx
|
static rtx
|
||||||
rl78_lo16 (rtx addr)
|
rl78_lo16 (rtx addr)
|
||||||
{
|
{
|
||||||
|
rtx r;
|
||||||
|
|
||||||
if (GET_CODE (addr) == SYMBOL_REF
|
if (GET_CODE (addr) == SYMBOL_REF
|
||||||
|| GET_CODE (addr) == CONST)
|
|| GET_CODE (addr) == CONST)
|
||||||
{
|
{
|
||||||
rtx r = gen_rtx_ZERO_EXTRACT (HImode, addr, GEN_INT (16), GEN_INT (0));
|
r = gen_rtx_ZERO_EXTRACT (HImode, addr, GEN_INT (16), GEN_INT (0));
|
||||||
r = gen_rtx_CONST (HImode, r);
|
r = gen_rtx_CONST (HImode, r);
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
return rl78_subreg (HImode, addr, SImode, 0);
|
else
|
||||||
|
r = rl78_subreg (HImode, addr, SImode, 0);
|
||||||
|
|
||||||
|
r = gen_es_addr (r);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a suitable RTX for the high half's lower byte of a __far address. */
|
/* Return a suitable RTX for the high half's lower byte of a __far address. */
|
||||||
@ -2306,6 +2353,7 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before)
|
|||||||
{
|
{
|
||||||
rtx base, index, addendr;
|
rtx base, index, addendr;
|
||||||
int addend = 0;
|
int addend = 0;
|
||||||
|
int need_es = 0;
|
||||||
|
|
||||||
if (! MEM_P (m))
|
if (! MEM_P (m))
|
||||||
return m;
|
return m;
|
||||||
@ -2322,6 +2370,7 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before)
|
|||||||
record_content (A, NULL_RTX);
|
record_content (A, NULL_RTX);
|
||||||
|
|
||||||
m = change_address (m, GET_MODE (m), rl78_lo16 (XEXP (m, 0)));
|
m = change_address (m, GET_MODE (m), rl78_lo16 (XEXP (m, 0)));
|
||||||
|
need_es = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
characterize_address (XEXP (m, 0), & base, & index, & addendr);
|
characterize_address (XEXP (m, 0), & base, & index, & addendr);
|
||||||
@ -2381,7 +2430,10 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before)
|
|||||||
fprintf (stderr, "\033[33m");
|
fprintf (stderr, "\033[33m");
|
||||||
debug_rtx (m);
|
debug_rtx (m);
|
||||||
#endif
|
#endif
|
||||||
m = change_address (m, GET_MODE (m), base);
|
if (need_es)
|
||||||
|
m = change_address (m, GET_MODE (m), gen_es_addr (base));
|
||||||
|
else
|
||||||
|
m = change_address (m, GET_MODE (m), base);
|
||||||
#if DEBUG_ALLOC
|
#if DEBUG_ALLOC
|
||||||
debug_rtx (m);
|
debug_rtx (m);
|
||||||
fprintf (stderr, "\033[0m");
|
fprintf (stderr, "\033[0m");
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
(UNS_RETB 3)
|
(UNS_RETB 3)
|
||||||
|
|
||||||
(UNS_SET_RB 10)
|
(UNS_SET_RB 10)
|
||||||
|
(UNS_ES_ADDR 11)
|
||||||
|
|
||||||
(UNS_TRAMPOLINE_INIT 20)
|
(UNS_TRAMPOLINE_INIT 20)
|
||||||
(UNS_TRAMPOLINE_UNINIT 21)
|
(UNS_TRAMPOLINE_UNINIT 21)
|
||||||
@ -432,3 +433,11 @@
|
|||||||
; end of mulsi macro"
|
; end of mulsi macro"
|
||||||
[(set_attr "valloc" "macax")]
|
[(set_attr "valloc" "macax")]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
(define_expand "es_addr"
|
||||||
|
[(unspec:SI [(reg:QI ES_REG)
|
||||||
|
(match_operand:HI 0 "" "")
|
||||||
|
] UNS_ES_ADDR)]
|
||||||
|
""
|
||||||
|
""
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user