diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3d9160e6940..2b0d211faf6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2013-09-17 DJ Delorie + + * 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 * config/sparc/t-rtems: Add leon3 multilibs. diff --git a/gcc/config/rl78/constraints.md b/gcc/config/rl78/constraints.md index 1edb58d8068..2c5ffd8419d 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 580609da2f9..1f30e637b72 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 d99cecfbff1..e7bd3deac7d 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