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:
DJ Delorie 2013-09-17 17:00:59 -04:00 committed by DJ Delorie
parent 5c26a69a2a
commit 2e7c3f214d
5 changed files with 151 additions and 17 deletions

View File

@ -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.

View File

@ -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"

View File

@ -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);

View File

@ -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");

View File

@ -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)]
""
""
)