diff options
author | DJ Delorie <dj@redhat.com> | 2013-09-17 17:00:59 -0400 |
---|---|---|
committer | DJ Delorie <dj@gcc.gnu.org> | 2013-09-17 17:00:59 -0400 |
commit | 2e7c3f214d24739ffc7039a884167a47a36f5352 (patch) | |
tree | af3806e18b02ddc8be01b2dade06dd0e006ea385 /gcc/config/rl78 | |
parent | 5c26a69a2a9a4c4c6280e7d21d6e48f64b11cf75 (diff) | |
download | gcc-2e7c3f214d24739ffc7039a884167a47a36f5352.zip gcc-2e7c3f214d24739ffc7039a884167a47a36f5352.tar.gz gcc-2e7c3f214d24739ffc7039a884167a47a36f5352.tar.bz2 |
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
Diffstat (limited to 'gcc/config/rl78')
-rw-r--r-- | gcc/config/rl78/constraints.md | 72 | ||||
-rw-r--r-- | gcc/config/rl78/rl78-protos.h | 3 | ||||
-rw-r--r-- | gcc/config/rl78/rl78.c | 66 | ||||
-rw-r--r-- | gcc/config/rl78/rl78.md | 9 |
4 files changed, 133 insertions, 17 deletions
diff --git a/gcc/config/rl78/constraints.md b/gcc/config/rl78/constraints.md index 1edb58d..2c5ffd8 100644 --- a/gcc/config/rl78/constraints.md +++ b/gcc/config/rl78/constraints.md @@ -203,17 +203,24 @@ ; All the memory addressing schemes the RL78 supports ; of the form W {register} {bytes of offset} ; or W {register} {register} +; Additionally, the Cxx forms are the same as the Wxx forms, but without +; the ES: override. ; absolute address -(define_memory_constraint "Wab" +(define_memory_constraint "Cab" "[addr]" (and (match_code "mem") (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")) ) ) +(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]" (and (match_code "mem") (ior @@ -225,29 +232,49 @@ (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]" (and (match_code "mem") (and (match_code "reg" "0") (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" (and (match_code "mem") (and (match_code "reg" "0") (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" (and (match_code "mem") (and (match_code "reg" "0") (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]" (and (match_code "mem") (ior @@ -259,15 +286,25 @@ (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]" (and (match_code "mem") (and (match_code "reg" "0") (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]" (and (match_code "mem") (and (match_code "plus" "0") @@ -275,14 +312,24 @@ (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == HL_REG")) (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]" (and (match_code "mem") (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]" (and (match_code "mem") (ior @@ -294,6 +341,11 @@ (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" "ES/CS far pointer" diff --git a/gcc/config/rl78/rl78-protos.h b/gcc/config/rl78/rl78-protos.h index 580609d..1f30e63 100644 --- a/gcc/config/rl78/rl78-protos.h +++ b/gcc/config/rl78/rl78-protos.h @@ -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); void rl78_setup_peep_movhi (rtx *); bool rl78_virt_insns_ok (void); + +bool rl78_es_addr (rtx); +rtx rl78_es_base (rtx); diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index d99cecf..e7bd3de 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -858,6 +858,10 @@ rl78_as_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x, { 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 && GET_MODE (x) == SImode) return false; @@ -1290,7 +1294,10 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) else { 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') { 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 OP(x) (*recog_data.operand_loc[x]) + /* This array is used to hold knowledge about the contents of the real registers (A ... H), the memory-based registers (r8 ... r31) 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; } +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 carefully to ensure that all the constraint information is accurate for the newly matched insn. */ @@ -2079,6 +2113,7 @@ static bool insn_ok_now (rtx insn) { rtx pattern = PATTERN (insn); + int i; INSN_CODE (insn) = -1; @@ -2095,6 +2130,14 @@ insn_ok_now (rtx insn) if (SET_P (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; } } @@ -2155,8 +2198,6 @@ insn_ok_now (rtx insn) #define DE gen_rtx_REG (HImode, 4) #define HL gen_rtx_REG (HImode, 6) -#define OP(x) (*recog_data.operand_loc[x]) - /* Returns TRUE if R is a virtual register. */ static bool is_virtual_register (rtx r) @@ -2195,14 +2236,20 @@ EM2 (int line ATTRIBUTE_UNUSED, rtx r) static rtx rl78_lo16 (rtx addr) { + rtx r; + if (GET_CODE (addr) == SYMBOL_REF || 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); - 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. */ @@ -2306,6 +2353,7 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) { rtx base, index, addendr; int addend = 0; + int need_es = 0; if (! MEM_P (m)) return m; @@ -2322,6 +2370,7 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) record_content (A, NULL_RTX); m = change_address (m, GET_MODE (m), rl78_lo16 (XEXP (m, 0))); + need_es = 1; } 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"); debug_rtx (m); #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 debug_rtx (m); fprintf (stderr, "\033[0m"); diff --git a/gcc/config/rl78/rl78.md b/gcc/config/rl78/rl78.md index 314c37e..e1cbbb0 100644 --- a/gcc/config/rl78/rl78.md +++ b/gcc/config/rl78/rl78.md @@ -45,6 +45,7 @@ (UNS_RETB 3) (UNS_SET_RB 10) + (UNS_ES_ADDR 11) (UNS_TRAMPOLINE_INIT 20) (UNS_TRAMPOLINE_UNINIT 21) @@ -432,3 +433,11 @@ ; end of mulsi macro" [(set_attr "valloc" "macax")] ) + +(define_expand "es_addr" + [(unspec:SI [(reg:QI ES_REG) + (match_operand:HI 0 "" "") + ] UNS_ES_ADDR)] + "" + "" +) |