From 54536dfe44f9ad18006cd7c9e2e1fd7a63ec8f4c Mon Sep 17 00:00:00 2001 From: dj Date: Mon, 26 Jun 2006 21:10:22 +0000 Subject: [PATCH] 2006-06-26 DJ Delorie * config/m32c/m32c.c (m32c_print_operand): Fix sign-merging logic. 2006-06-26 Naveen H.S Jayant Sonar Jaydeep Vipradas * config/m32c/addsub.md (addsi3, addsi3_1, addsi3_2): New. (subsi3, subsi3_1, subsi3_2): New. * config/m32c/bitops.md (andsi3, iorsi3, xorsi3): New. * config/m32c/mov.md (SI mov peephole): New. * config/m32c/m32.c (m32c_immd_dbl_mov): New. * config/m32c/m32c-protos.h (m32c_immd_dbl_mov): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@115023 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 15 ++++++ gcc/config/m32c/addsub.md | 95 +++++++++++++++++++++++++++++++++++ gcc/config/m32c/bitops.md | 83 +++++++++++++++++++++++++++++++ gcc/config/m32c/m32c-protos.h | 1 + gcc/config/m32c/m32c.c | 113 +++++++++++++++++++++++++++++++++++++++--- gcc/config/m32c/mov.md | 11 ++++ 6 files changed, 312 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 88384c05fdb..6066846ef8f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2006-06-26 DJ Delorie + + * config/m32c/m32c.c (m32c_print_operand): Fix sign-merging logic. + +2006-06-26 Naveen H.S + Jayant Sonar + Jaydeep Vipradas + + * config/m32c/addsub.md (addsi3, addsi3_1, addsi3_2): New. + (subsi3, subsi3_1, subsi3_2): New. + * config/m32c/bitops.md (andsi3, iorsi3, xorsi3): New. + * config/m32c/mov.md (SI mov peephole): New. + * config/m32c/m32.c (m32c_immd_dbl_mov): New. + * config/m32c/m32c-protos.h (m32c_immd_dbl_mov): New. + 2006-06-26 Olivier Hainque * function.c (aggregate_value_p): Honor DECL_BY_REFERENCE on diff --git a/gcc/config/m32c/addsub.md b/gcc/config/m32c/addsub.md index 83587564ebd..45bd3cd3664 100644 --- a/gcc/config/m32c/addsub.md +++ b/gcc/config/m32c/addsub.md @@ -72,6 +72,56 @@ [(set_attr "flags" "oszc,oszc,oszc,oszc,oszc,n,n")] ) +(define_expand "addsi3" + [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm") + (plus:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0") + (match_operand:SI 2 "mrai_operand" "iRsiSd,?Rmm,iRsiSd,?Rmm")))] + "TARGET_A24 ||TARGET_A16" + "" + ) + +(define_insn "addsi3_1" + [(set (match_operand:SI 0 "mra_operand" "=RsiSd,??Rmm,RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") + (plus:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0,0,0") + (match_operand 2 "mrai_operand" "IU2,IU2,i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] + "TARGET_A16" + "* + + switch (which_alternative) + { + case 0: + return \"add.w %X2,%h0\;adcf.w %H0\"; + case 1: + return \"add.w %X2,%h0\;adcf.w %H0\"; + case 2: + output_asm_insn (\"add.w %X2,%h0\",operands); + operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); + return \"adc.w %X2,%H0\"; + case 3: + return \"add.w %h2,%h0\;adc.w %H2,%H0\"; + case 4: + output_asm_insn (\"add.w %X2,%h0\",operands); + operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); + return \"adc.w %X2,%H0\"; + case 5: + return \"add.w %h2,%h0\;adc.w %H2,%H0\"; + case 6: + return \"add.w %h2,%h0\;adc.w %H2,%H0\"; + case 7: + return \"add.w %h2,%h0\;adc.w %H2,%H0\"; + }" + [(set_attr "flags" "x,x,x,x,x,x,x,x")] +) + +(define_insn "addsi3_2" + [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm") + (plus:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0") + (match_operand:SI 2 "mrai_operand" "iRsiSd,?Rmm,iRsiSd,?Rmm")))] + "TARGET_A24" + "add.l\t%2,%0" + [(set_attr "flags" "oszc")] +) + (define_insn "subqi3" [(set (match_operand:QI 0 "mra_or_sp_operand" "=SdRhl,SdRhl,??Rmm,??Rmm, Raa,Raa,SdRhl,??Rmm, *Rsp") @@ -111,6 +161,51 @@ [(set_attr "flags" "oszc")] ) +(define_expand "subsi3" + [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm") + (minus:SI (match_operand:SI 1 "mra_operand" "0,0,0,0") + (match_operand:SI 2 "mrai_operand" "iRsiSd,?Rmm,iRsiSd,?Rmm")))] + "TARGET_A24 ||TARGET_A16" + "" +) + +(define_insn "subsi3_1" + [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") + (minus:SI (match_operand:SI 1 "mra_operand" "0,0,0,0,0,0") + (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] + "TARGET_A16" + "* + switch (which_alternative) + { + case 0: + output_asm_insn (\"sub.w %X2,%h0\",operands); + operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); + return \"sbb.w %X2,%H0\"; + case 1: + return \"sub.w %h2,%h0\;sbb.w %H2,%H0\"; + case 2: + output_asm_insn (\"sub.w %X2,%h0\",operands); + operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); + return \"sbb.w %X2,%H0\"; + case 3: + return \"sub.w %h2,%h0\;sbb.w %H2,%H0\"; + case 4: + return \"sub.w %h2,%h0\;sbb.w %H2,%H0\"; + case 5: + return \"sub.w %h2,%h0\;sbb.w %H2,%H0\"; + }" + [(set_attr "flags" "x,x,x,x,x,x")] +) + +(define_insn "subsi3_2" + [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm") + (minus:SI (match_operand:SI 1 "mra_operand" "0,0,0,0") + (match_operand:SI 2 "mrai_operand" "iRsiSd,?Rmm,iRsiSd,?Rmm")))] + "TARGET_A24" + "sub.l\t%2,%0" + [(set_attr "flags" "oszc,oszc,oszc,oszc")] +) + (define_insn "negqi2" [(set (match_operand:QI 0 "mra_operand" "=SdRhl,??Rmm") (neg:QI (match_operand:QI 1 "mra_operand" "0,0")))] diff --git a/gcc/config/m32c/bitops.md b/gcc/config/m32c/bitops.md index 56d6a75e163..87322d38629 100644 --- a/gcc/config/m32c/bitops.md +++ b/gcc/config/m32c/bitops.md @@ -113,6 +113,33 @@ [(set_attr "flags" "n,n,n,sz,sz,sz,sz")] ) +(define_insn "andsi3" + [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") + (and:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0") + (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] + "" + "* + switch (which_alternative) + { + case 0: + output_asm_insn (\"and.w %X2,%h0\",operands); + operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); + return \"and.w %X2,%H0\"; + case 1: + return \"and.w %h2,%h0\;and.w %H2,%H0\"; + case 2: + output_asm_insn (\"and.w %X2,%h0\",operands); + operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); + return \"and.w %X2,%H0\"; + case 3: + return \"and.w %h2,%h0\;and.w %H2,%H0\"; + case 4: + return \"and.w %h2,%h0\;and.w %H2,%H0\"; + case 5: + return \"and.w %h2,%h0\;and.w %H2,%H0\"; + }" + [(set_attr "flags" "x,x,x,x,x,x")] +) (define_insn "iorqi3_16" @@ -264,6 +291,34 @@ DONE;" ) +(define_insn "iorsi3" + [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") + (ior:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0") + (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] + "" + "* + switch (which_alternative) + { + case 0: + output_asm_insn (\"or.w %X2,%h0\",operands); + operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); + return \"or.w %X2,%H0\"; + case 1: + return \"or.w %h2,%h0\;or.w %H2,%H0\"; + case 2: + output_asm_insn (\"or.w %X2,%h0\",operands); + operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); + return \"or.w %X2,%H0\"; + case 3: + return \"or.w %h2,%h0\;or.w %H2,%H0\"; + case 4: + return \"or.w %h2,%h0\;or.w %H2,%H0\"; + case 5: + return \"or.w %h2,%h0\;or.w %H2,%H0\"; + }" + [(set_attr "flags" "x,x,x,x,x,x")] +) + (define_insn "xorqi3" [(set (match_operand:QI 0 "mra_operand" "=RhlSd,RhlSd,??Rmm,??Rmm") (xor:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0") @@ -282,6 +337,34 @@ [(set_attr "flags" "sz,sz,sz,sz")] ) +(define_insn "xorsi3" + [(set (match_operand:SI 0 "mra_operand" "=RsiSd,RsiSd,??Rmm,??Rmm,??Rmm,RsiSd") + (xor:SI (match_operand:SI 1 "mra_operand" "%0,0,0,0,0,0") + (match_operand:SI 2 "mrai_operand" "i,?Rmm,i,RsiSd,?Rmm,RsiSd")))] + "" + "* + switch (which_alternative) + { + case 0: + output_asm_insn (\"xor.w %X2,%h0\",operands); + operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); + return \"xor.w %X2,%H0\"; + case 1: + return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; + case 2: + output_asm_insn (\"xor.w %X2,%h0\",operands); + operands[2]= GEN_INT (INTVAL (operands[2]) >> 16); + return \"xor.w %X2,%H0\"; + case 3: + return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; + case 4: + return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; + case 5: + return \"xor.w %h2,%h0\;xor.w %H2,%H0\"; + }" + [(set_attr "flags" "x,x,x,x,x,x")] +) + (define_insn "one_cmplqi2" [(set (match_operand:QI 0 "mra_operand" "=RhlSd,??Rmm") (not:QI (match_operand:QI 1 "mra_operand" "0,0")))] diff --git a/gcc/config/m32c/m32c-protos.h b/gcc/config/m32c/m32c-protos.h index a7bcd334393..6979da278a2 100644 --- a/gcc/config/m32c/m32c-protos.h +++ b/gcc/config/m32c/m32c-protos.h @@ -72,6 +72,7 @@ int m32c_extra_constraint_p (rtx, char, const char *); int m32c_extra_constraint_p2 (rtx, char, const char *); int m32c_hard_regno_nregs (int, MM); int m32c_hard_regno_ok (int, MM); +bool m32c_immd_dbl_mov (rtx *, MM); rtx m32c_incoming_return_addr_rtx (void); void m32c_initialize_trampoline (rtx, rtx, rtx); int m32c_legitimate_address_p (MM, rtx, int); diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index 6fddc4b2760..4c2219e23d8 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -2301,6 +2301,7 @@ m32c_print_operand (FILE * file, rtx x, int code) const char *comma; HOST_WIDE_INT ival; int unsigned_const = 0; + int force_sign; /* Multiplies; constants are converted to sign-extended format but we need unsigned, so 'u' and 'U' tell us what size unsigned we @@ -2463,6 +2464,7 @@ m32c_print_operand (FILE * file, rtx x, int code) code = 0; encode_pattern (x); + force_sign = 0; for (i = 0; conversions[i].pattern; i++) if (conversions[i].code == code && streq (conversions[i].pattern, pattern)) @@ -2576,6 +2578,8 @@ m32c_print_operand (FILE * file, rtx x, int code) /* Integers used as addresses are unsigned. */ ival &= (TARGET_A24 ? 0xffffff : 0xffff); } + if (force_sign && ival >= 0) + fputc ('+', file); fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival); break; } @@ -2620,13 +2624,14 @@ m32c_print_operand (FILE * file, rtx x, int code) /* Signed displacements off symbols need to have signs blended cleanly. */ if (conversions[i].format[j] == '+' - && (!code || code == 'I') + && (!code || code == 'D' || code == 'd') && ISDIGIT (conversions[i].format[j + 1]) - && GET_CODE (patternr[conversions[i].format[j + 1] - '0']) - == CONST_INT - && INTVAL (patternr[conversions[i].format[j + 1] - '0']) < - 0) - continue; + && (GET_CODE (patternr[conversions[i].format[j + 1] - '0']) + == CONST_INT)) + { + force_sign = 1; + continue; + } fputc (conversions[i].format[j], file); } break; @@ -2787,6 +2792,102 @@ m32c_mov_ok (rtx * operands, enum machine_mode mode ATTRIBUTE_UNUSED) return true; } +/* Returns TRUE if two consecutive HImode mov instructions, generated + for moving an immediate double data to a double data type variable + location, can be combined into single SImode mov instruction. */ +bool +m32c_immd_dbl_mov (rtx * operands, + enum machine_mode mode ATTRIBUTE_UNUSED) +{ + int flag = 0, okflag = 0, offset1 = 0, offset2 = 0, offsetsign = 0; + const char *str1; + const char *str2; + + if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF + && MEM_SCALAR_P (operands[0]) + && !MEM_IN_STRUCT_P (operands[0]) + && GET_CODE (XEXP (operands[2], 0)) == CONST + && GET_CODE (XEXP (XEXP (operands[2], 0), 0)) == PLUS + && GET_CODE (XEXP (XEXP (XEXP (operands[2], 0), 0), 0)) == SYMBOL_REF + && GET_CODE (XEXP (XEXP (XEXP (operands[2], 0), 0), 1)) == CONST_INT + && MEM_SCALAR_P (operands[2]) + && !MEM_IN_STRUCT_P (operands[2])) + flag = 1; + + else if (GET_CODE (XEXP (operands[0], 0)) == CONST + && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == PLUS + && GET_CODE (XEXP (XEXP (XEXP (operands[0], 0), 0), 0)) == SYMBOL_REF + && MEM_SCALAR_P (operands[0]) + && !MEM_IN_STRUCT_P (operands[0]) + && !(XINT (XEXP (XEXP (XEXP (operands[0], 0), 0), 1), 0) %4) + && GET_CODE (XEXP (operands[2], 0)) == CONST + && GET_CODE (XEXP (XEXP (operands[2], 0), 0)) == PLUS + && GET_CODE (XEXP (XEXP (XEXP (operands[2], 0), 0), 0)) == SYMBOL_REF + && MEM_SCALAR_P (operands[2]) + && !MEM_IN_STRUCT_P (operands[2])) + flag = 2; + + else if (GET_CODE (XEXP (operands[0], 0)) == PLUS + && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG + && REGNO (XEXP (XEXP (operands[0], 0), 0)) == FB_REGNO + && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT + && MEM_SCALAR_P (operands[0]) + && !MEM_IN_STRUCT_P (operands[0]) + && !(XINT (XEXP (XEXP (operands[0], 0), 1), 0) %4) + && REGNO (XEXP (XEXP (operands[2], 0), 0)) == FB_REGNO + && GET_CODE (XEXP (XEXP (operands[2], 0), 1)) == CONST_INT + && MEM_SCALAR_P (operands[2]) + && !MEM_IN_STRUCT_P (operands[2])) + flag = 3; + + else + return false; + + switch (flag) + { + case 1: + str1 = XSTR (XEXP (operands[0], 0), 0); + str2 = XSTR (XEXP (XEXP (XEXP (operands[2], 0), 0), 0), 0); + if (strcmp (str1, str2) == 0) + okflag = 1; + else + okflag = 0; + break; + case 2: + str1 = XSTR (XEXP (XEXP (XEXP (operands[0], 0), 0), 0), 0); + str2 = XSTR (XEXP (XEXP (XEXP (operands[2], 0), 0), 0), 0); + if (strcmp(str1,str2) == 0) + okflag = 1; + else + okflag = 0; + break; + case 3: + offset1 = XINT (XEXP (XEXP (operands[0], 0), 1), 0); + offset2 = XINT (XEXP (XEXP (operands[2], 0), 1), 0); + offsetsign = offset1 >> ((sizeof (offset1) * 8) -1); + if (((offset2-offset1) == 2) && offsetsign != 0) + okflag = 1; + else + okflag = 0; + break; + default: + okflag = 0; + } + + if (okflag == 1) + { + HOST_WIDE_INT val; + operands[4] = gen_rtx_MEM (SImode, XEXP (operands[0], 0)); + + val = (XINT (operands[3], 0) << 16) + (XINT (operands[1], 0) & 0xFFFF); + operands[5] = gen_rtx_CONST_INT (VOIDmode, val); + + return true; + } + + return false; +} + /* Expanders */ /* Subregs are non-orthogonal for us, because our registers are all diff --git a/gcc/config/m32c/mov.md b/gcc/config/m32c/mov.md index 791ac5dcdbd..fde98d3723c 100644 --- a/gcc/config/m32c/mov.md +++ b/gcc/config/m32c/mov.md @@ -135,6 +135,17 @@ (match_dup 3))] "") +; Peephole to generate SImode mov instructions for storing an +; immediate double data to a memory location. +(define_peephole2 + [(set (match_operand:HI 0 "memory_operand" "") + (match_operand 1 "const_int_operand" "")) + (set (match_operand:HI 2 "memory_operand" "") + (match_operand 3 "const_int_operand" ""))] + "TARGET_A24 && m32c_immd_dbl_mov (operands, HImode)" + [(set (match_dup 4) (match_dup 5))] + "" +) ; Some PSI moves must be split. (define_split -- 2.11.4.GIT