aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/m32c
diff options
context:
space:
mode:
authorDJ Delorie <dj@gcc.gnu.org>2006-06-26 17:10:22 -0400
committerDJ Delorie <dj@gcc.gnu.org>2006-06-26 17:10:22 -0400
commitff485e71cf8f300fc80c6e8c9ca0b0fd0c3590ca (patch)
treeb6ce301684ee79ed60fcdfb68b5e1526c7ecba3f /gcc/config/m32c
parent500c353d7290b4a91a66fd5cd009048b6b387984 (diff)
downloadgcc-ff485e71cf8f300fc80c6e8c9ca0b0fd0c3590ca.zip
gcc-ff485e71cf8f300fc80c6e8c9ca0b0fd0c3590ca.tar.gz
gcc-ff485e71cf8f300fc80c6e8c9ca0b0fd0c3590ca.tar.bz2
[multiple changes]
2006-06-26 DJ Delorie <dj@redhat.com> * config/m32c/m32c.c (m32c_print_operand): Fix sign-merging logic. 2006-06-26 Naveen H.S <naveenh@kpitcummins.com> Jayant Sonar <jayants@kpitcummins.com> Jaydeep Vipradas <jaydeepv@kpitcummins.com> * 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. From-SVN: r115023
Diffstat (limited to 'gcc/config/m32c')
-rw-r--r--gcc/config/m32c/addsub.md95
-rw-r--r--gcc/config/m32c/bitops.md83
-rw-r--r--gcc/config/m32c/m32c-protos.h1
-rw-r--r--gcc/config/m32c/m32c.c113
-rw-r--r--gcc/config/m32c/mov.md11
5 files changed, 297 insertions, 6 deletions
diff --git a/gcc/config/m32c/addsub.md b/gcc/config/m32c/addsub.md
index 8358756..45bd3cd 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 56d6a75..87322d3 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 a7bcd33..6979da2 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 6fddc4b..4c2219e 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 791ac5d..fde98d3 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