From 633e4eb4aecc1658799c7647f73b050d12aafdfa Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Thu, 29 May 2003 00:08:36 +0000 Subject: xtensa-protos.h (smalloffset_double_mem_p): Delete. * config/xtensa/xtensa-protos.h (smalloffset_double_mem_p): Delete. (xtensa_split_operand_pair): New proto. * config/xtensa/xtensa.c (move_operand): Handle DFmode and DImode. (smalloffset_double_mem_p): Delete. (gen_float_relational, printx, print_operand, xtensa_va_arg): Fix whitespace. (xtensa_split_operand_pair): New. (xtensa_dbx_register_number): Fix formatting. * config/xtensa/xtensa.h (EXTRA_CONSTRAINT): Remove 'S' constraint. * config/xtensa/xtensa.md (movdi, movdf): Force constants to memory instead of splitting them into single-word moves. Remove unnecessary checks for reload_in_progress and reload_completed. (movdi_internal, movdf_internal): Change to post-reload split patterns. Add constraints to allow constant operands. (movsf_internal): Allow CONST_INT operands. From-SVN: r67215 --- gcc/ChangeLog | 18 ++++ gcc/config/xtensa/xtensa-protos.h | 2 +- gcc/config/xtensa/xtensa.c | 137 ++++++++++++++++++++--------- gcc/config/xtensa/xtensa.h | 2 - gcc/config/xtensa/xtensa.md | 178 +++++++++----------------------------- 5 files changed, 156 insertions(+), 181 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f9541bb..3998831 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2003-05-28 Bob Wilson + + * config/xtensa/xtensa-protos.h (smalloffset_double_mem_p): Delete. + (xtensa_split_operand_pair): New proto. + * config/xtensa/xtensa.c (move_operand): Handle DFmode and DImode. + (smalloffset_double_mem_p): Delete. + (gen_float_relational, printx, print_operand, xtensa_va_arg): + Fix whitespace. + (xtensa_split_operand_pair): New. + (xtensa_dbx_register_number): Fix formatting. + * config/xtensa/xtensa.h (EXTRA_CONSTRAINT): Remove 'S' constraint. + * config/xtensa/xtensa.md (movdi, movdf): Force constants to memory + instead of splitting them into single-word moves. Remove unnecessary + checks for reload_in_progress and reload_completed. + (movdi_internal, movdf_internal): Change to post-reload split patterns. + Add constraints to allow constant operands. + (movsf_internal): Allow CONST_INT operands. + 2003-05-27 Danny Smith * config.gcc (i[34567]86-*-mingw32*): Add host makefile diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h index b5ca611..7800f0f 100644 --- a/gcc/config/xtensa/xtensa-protos.h +++ b/gcc/config/xtensa/xtensa-protos.h @@ -54,7 +54,6 @@ extern int ubranch_operand PARAMS ((rtx, enum machine_mode)); extern int call_insn_operand PARAMS ((rtx, enum machine_mode)); extern int move_operand PARAMS ((rtx, enum machine_mode)); extern int smalloffset_mem_p PARAMS ((rtx)); -extern int smalloffset_double_mem_p PARAMS ((rtx)); extern int constantpool_address_p PARAMS ((rtx)); extern int constantpool_mem_p PARAMS ((rtx)); extern int const_float_1_operand PARAMS ((rtx, enum machine_mode)); @@ -67,6 +66,7 @@ extern void xtensa_expand_conditional_branch PARAMS ((rtx *, enum rtx_code)); extern int xtensa_expand_conditional_move PARAMS ((rtx *, int)); extern int xtensa_expand_scc PARAMS ((rtx *)); extern int xtensa_expand_block_move PARAMS ((rtx *)); +extern void xtensa_split_operand_pair PARAMS ((rtx *, enum machine_mode)); extern int xtensa_emit_move_sequence PARAMS ((rtx *, enum machine_mode)); extern bool xtensa_copy_incoming_a7 PARAMS ((rtx *, enum machine_mode)); extern void xtensa_emit_block_move PARAMS ((rtx *, rtx *, int)); diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index 18ed9d3..d3ec724 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -599,19 +599,32 @@ move_operand (op, mode) || memory_operand (op, mode)) return TRUE; - if (mode == SFmode) - return TARGET_CONST16 && CONSTANT_P (op); + switch (mode) + { + case DFmode: + case SFmode: + return TARGET_CONST16 && CONSTANT_P (op); - /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and - result in 0/1. */ - if (GET_CODE (op) == CONSTANT_P_RTX) - return TRUE; + case DImode: + case SImode: + if (TARGET_CONST16) + return CONSTANT_P (op); + /* fall through */ - if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op))) - return TRUE; + case HImode: + case QImode: + /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and + result in 0/1. */ + if (GET_CODE (op) == CONSTANT_P_RTX) + return TRUE; + + if (GET_CODE (op) == CONST_INT && xtensa_simm12b (INTVAL (op))) + return TRUE; + break; - if (mode == SImode) - return TARGET_CONST16 && CONSTANT_P (op); + default: + break; + } return FALSE; } @@ -641,16 +654,6 @@ smalloffset_mem_p (op) int -smalloffset_double_mem_p (op) - rtx op; -{ - if (!smalloffset_mem_p (op)) - return FALSE; - return smalloffset_mem_p (adjust_address (op, GET_MODE (op), 4)); -} - - -int constantpool_address_p (addr) rtx addr; { @@ -1014,7 +1017,7 @@ gen_float_relational (test_code, cmp0, cmp1) case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break; case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break; case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break; - default: + default: fatal_insn ("bad test", gen_rtx (test_code, VOIDmode, cmp0, cmp1)); reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */ } @@ -1207,6 +1210,53 @@ xtensa_expand_scc (operands) } +/* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is + for the output, i.e., the input operands are twice as big as MODE. */ + +void +xtensa_split_operand_pair (operands, mode) + rtx operands[4]; + enum machine_mode mode; +{ + switch (GET_CODE (operands[1])) + { + case REG: + operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1); + operands[2] = gen_rtx_REG (mode, REGNO (operands[1])); + break; + + case MEM: + operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode)); + operands[2] = adjust_address (operands[1], mode, 0); + break; + + case CONST_INT: + case CONST_DOUBLE: + split_double (operands[1], &operands[2], &operands[3]); + break; + + default: + abort (); + } + + switch (GET_CODE (operands[0])) + { + case REG: + operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1); + operands[0] = gen_rtx_REG (mode, REGNO (operands[0])); + break; + + case MEM: + operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode)); + operands[0] = adjust_address (operands[0], mode, 0); + break; + + default: + abort (); + } +} + + /* Emit insns to move operands[1] into operands[0]. Return 1 if we have written out everything that needs to be done to do the move. Otherwise, return 0 and the caller will emit the move @@ -1658,24 +1708,27 @@ xtensa_dbx_register_number (regno) int regno; { int first = -1; - - if (GP_REG_P (regno)) { - regno -= GP_REG_FIRST; - first = 0; - } - else if (BR_REG_P (regno)) { - regno -= BR_REG_FIRST; - first = 16; - } - else if (FP_REG_P (regno)) { - regno -= FP_REG_FIRST; - /* The current numbering convention is that TIE registers are - numbered in libcc order beginning with 256. We can't guarantee - that the FP registers will come first, so the following is just - a guess. It seems like we should make a special case for FP - registers and give them fixed numbers < 256. */ - first = 256; - } + + if (GP_REG_P (regno)) + { + regno -= GP_REG_FIRST; + first = 0; + } + else if (BR_REG_P (regno)) + { + regno -= BR_REG_FIRST; + first = 16; + } + else if (FP_REG_P (regno)) + { + regno -= FP_REG_FIRST; + /* The current numbering convention is that TIE registers are + numbered in libcc order beginning with 256. We can't guarantee + that the FP registers will come first, so the following is just + a guess. It seems like we should make a special case for FP + registers and give them fixed numbers < 256. */ + first = 256; + } else if (ACC_REG_P (regno)) { first = 0; @@ -1885,7 +1938,7 @@ override_options () a null pointer for X and the punctuation character for CODE. 'a', 'c', 'l', and 'n' are reserved. - + The Xtensa specific codes are: 'd' CONST_INT, print as signed decimal @@ -2041,7 +2094,7 @@ print_operand (file, x, letter) print_operand (file, XEXP (XEXP (x, 0), 1), 0); } else - { + { output_addr_const (file, x); fputs (letter == 't' ? "@h" : "@l", file); } @@ -2608,7 +2661,7 @@ xtensa_va_arg (valist, type) size = gen_reg_rtx (SImode); emit_move_insn (size, va_size); - + if (BYTES_BIG_ENDIAN) { rtx lab_use_va_size = gen_label_rtx (); diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index 9b7f261..0322109 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -691,7 +691,6 @@ extern enum reg_class xtensa_char_to_class[256]; operand types. R = memory that can be accessed with a 4-bit unsigned offset - S = memory where the second word can be addressed with a 4-bit offset T = memory in a constant pool (addressable with a pc-relative load) U = memory *NOT* in a constant pool @@ -713,7 +712,6 @@ extern enum reg_class xtensa_char_to_class[256]; && reload_in_progress && GET_CODE (OP) == REG \ && REGNO (OP) >= FIRST_PSEUDO_REGISTER) \ : ((CODE) == 'R') ? smalloffset_mem_p (OP) \ - : ((CODE) == 'S') ? smalloffset_double_mem_p (OP) \ : ((CODE) == 'T') ? !TARGET_CONST16 && constantpool_mem_p (OP) \ : ((CODE) == 'U') ? !constantpool_mem_p (OP) \ : FALSE) diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index 40bf5c0..26bad87 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -922,83 +922,35 @@ "" " { - if (CONSTANT_P (operands[1]) - && register_operand (operands[0], DImode)) - { - rtx src0, src1, dst0, dst1; - dst0 = operand_subword (operands[0], 0, 1, DImode); - src0 = operand_subword (operands[1], 0, 1, DImode); - dst1 = operand_subword (operands[0], 1, 1, DImode); - src1 = operand_subword (operands[1], 1, 1, DImode); - if (!dst0 || !src0 || !dst1 || !src1) - abort (); - emit_insn (gen_movsi (dst0, src0)); - emit_insn (gen_movsi (dst1, src1)); - DONE; - } + if (CONSTANT_P (operands[1]) && !TARGET_CONST16) + operands[1] = force_const_mem (DImode, operands[1]); - if (!(reload_in_progress | reload_completed)) - { - if (!register_operand (operands[0], DImode) - && !register_operand (operands[1], DImode)) - operands[1] = force_reg (DImode, operands[1]); + if (!register_operand (operands[0], DImode) + && !register_operand (operands[1], DImode)) + operands[1] = force_reg (DImode, operands[1]); - if (xtensa_copy_incoming_a7 (operands, DImode)) - DONE; - } + if (xtensa_copy_incoming_a7 (operands, DImode)) + DONE; }") -(define_insn "movdi_internal" - [(set (match_operand:DI 0 "nonimmed_operand" "=D,D,S,a,a,U") - (match_operand:DI 1 "nonimmed_operand" "d,S,d,r,U,r"))] +(define_insn_and_split "movdi_internal" + [(set (match_operand:DI 0 "nonimmed_operand" "=a,W,a,a,U") + (match_operand:DI 1 "move_operand" "r,i,T,U,r"))] "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)" - "* + "#" + "reload_completed" + [(set (match_dup 0) (match_dup 2)) + (set (match_dup 1) (match_dup 3))] { - rtx dstreg; - switch (which_alternative) + xtensa_split_operand_pair (operands, SImode); + if (reg_overlap_mentioned_p (operands[0], operands[3])) { - case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\"; - case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\"; - case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\"; - case 5: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\"; - - case 1: - case 4: - /* Check if the first half of the destination register is used - in the source address. If so, reverse the order of the loads - so that the source address doesn't get clobbered until it is - no longer needed. */ - - dstreg = operands[0]; - if (GET_CODE (dstreg) == SUBREG) - dstreg = SUBREG_REG (dstreg); - if (GET_CODE (dstreg) != REG) - abort(); - - if (reg_mentioned_p (dstreg, operands[1])) - { - switch (which_alternative) - { - case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\"; - case 4: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\"; - } - } - else - { - switch (which_alternative) - { - case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\"; - case 4: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\"; - } - } + rtx tmp; + tmp = operands[0], operands[0] = operands[1], operands[1] = tmp; + tmp = operands[2], operands[2] = operands[3], operands[3] = tmp; } - abort (); - return \"\"; -}" - [(set_attr "type" "move,load,store,move,load,store") - (set_attr "mode" "DI") - (set_attr "length" "4,4,4,6,6,6")]) +}) ;; 32-bit Integer moves @@ -1122,7 +1074,7 @@ (define_insn "movsf_internal" [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,W,a,a,U") - (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,F,T,U,r"))] + (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,iF,T,U,r"))] "((register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)) && !(FP_REG_P (xt_true_regnum (operands[0])) @@ -1187,82 +1139,36 @@ "" " { - if (CONSTANT_P (operands[1])) - { - rtx src0, src1, dst0, dst1; - dst0 = operand_subword (operands[0], 0, 1, DFmode); - src0 = operand_subword (operands[1], 0, 1, DFmode); - dst1 = operand_subword (operands[0], 1, 1, DFmode); - src1 = operand_subword (operands[1], 1, 1, DFmode); - if (!dst0 || !src0 || !dst1 || !src1) - abort (); - emit_insn (gen_movsi (dst0, src0)); - emit_insn (gen_movsi (dst1, src1)); - DONE; - } + if (CONSTANT_P (operands[1]) && !TARGET_CONST16) + operands[1] = force_const_mem (DFmode, operands[1]); - if (!(reload_in_progress | reload_completed)) - { - if (!register_operand (operands[0], DFmode) - && !register_operand (operands[1], DFmode)) - operands[1] = force_reg (DFmode, operands[1]); + if (!register_operand (operands[0], DFmode) + && !register_operand (operands[1], DFmode)) + operands[1] = force_reg (DFmode, operands[1]); - if (xtensa_copy_incoming_a7 (operands, DFmode)) - DONE; - } + if (xtensa_copy_incoming_a7 (operands, DFmode)) + DONE; }") -(define_insn "movdf_internal" - [(set (match_operand:DF 0 "nonimmed_operand" "=D,D,S,a,a,U") - (match_operand:DF 1 "nonimmed_operand" "d,S,d,r,U,r"))] +(define_insn_and_split "movdf_internal" + [(set (match_operand:DF 0 "nonimmed_operand" "=a,W,a,a,U") + (match_operand:DF 1 "move_operand" "r,iF,T,U,r"))] "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)" - "* + "#" + "reload_completed" + [(set (match_dup 0) (match_dup 2)) + (set (match_dup 1) (match_dup 3))] { - rtx dstreg; - switch (which_alternative) + xtensa_split_operand_pair (operands, SFmode); + if (reg_overlap_mentioned_p (operands[0], operands[3])) { - case 0: return \"mov.n\\t%0, %1\;mov.n\\t%D0, %D1\"; - case 2: return \"%v0s32i.n\\t%1, %0\;s32i.n\\t%D1, %N0\"; - case 3: return \"mov\\t%0, %1\;mov\\t%D0, %D1\"; - case 5: return \"%v0s32i\\t%1, %0\;s32i\\t%D1, %N0\"; - - case 1: - case 4: - /* Check if the first half of the destination register is used - in the source address. If so, reverse the order of the loads - so that the source address doesn't get clobbered until it is - no longer needed. */ - - dstreg = operands[0]; - if (GET_CODE (dstreg) == SUBREG) - dstreg = SUBREG_REG (dstreg); - if (GET_CODE (dstreg) != REG) - abort (); - - if (reg_mentioned_p (dstreg, operands[1])) - { - switch (which_alternative) - { - case 1: return \"%v1l32i.n\\t%D0, %N1\;l32i.n\\t%0, %1\"; - case 4: return \"%v1l32i\\t%D0, %N1\;l32i\\t%0, %1\"; - } - } - else - { - switch (which_alternative) - { - case 1: return \"%v1l32i.n\\t%0, %1\;l32i.n\\t%D0, %N1\"; - case 4: return \"%v1l32i\\t%0, %1\;l32i\\t%D0, %N1\"; - } - } + rtx tmp; + tmp = operands[0], operands[0] = operands[1], operands[1] = tmp; + tmp = operands[2], operands[2] = operands[3], operands[3] = tmp; } - abort (); - return \"\"; -}" - [(set_attr "type" "move,load,store,move,load,store") - (set_attr "mode" "DF") - (set_attr "length" "4,4,4,6,6,6")]) +}) + ;; Block moves -- cgit v1.1