summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2005-08-31 19:51:17 +0000
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2005-08-31 19:51:17 +0000
commitc8cd180539a9197a2dee3c57623a69a87b04da0c (patch)
tree23a10c4a00c941e09d8222480d6289afc911bfc3 /gcc
parentd3d7bd46ab93a3cbbb0937f125dcac88aa847a1c (diff)
downloadgcc-c8cd180539a9197a2dee3c57623a69a87b04da0c.tar.gz
2005-08-31 J"orn Rennecke <joern.rennecke@st.com>
gcc: PR target/21255 * sh.c (print_operand, %R and %S): Add handling of floating point registers, memory, constants and invalid operands. gcc/testsuite: PR target/21255 * gcc.dg/pr21255-1.c: New test. * gcc.dg/pr21255-2-mb.c: Likewise. * gcc.dg/pr21255-2-ml.c: Likewise. * gcc.dg/pr21255-3.c: Likewise. * gcc.dg/pr21255-4.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103700 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/sh/sh.c59
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/gcc.dg/pr21255-1.c15
-rw-r--r--gcc/testsuite/gcc.dg/pr21255-2-mb.c19
-rw-r--r--gcc/testsuite/gcc.dg/pr21255-2-ml.c19
-rw-r--r--gcc/testsuite/gcc.dg/pr21255-3.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr21255-4.c13
8 files changed, 151 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 86aa8ff20bc..5debe6887f1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-08-31 J"orn Rennecke <joern.rennecke@st.com>
+
+ PR target/21255
+ * sh.c (print_operand, %R and %S): Add handling of floating point
+ registers, memory, constants and invalid operands.
+
2005-08-31 Daniel Berlin <dberlin@dberlin.org>
* ipa-pure-const.c: Change dump name.
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 1fbdcee13ac..6f1442e59b9 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -734,11 +734,66 @@ print_operand (FILE *stream, rtx x, int code)
x = mark_constant_pool_use (x);
output_addr_const (stream, x);
break;
+ /* N.B.: %R / %S / %T adjust memory addresses by four.
+ For SHMEDIA, that means they can be used to access the first and
+ second 32 bit part of a 64 bit (or larger) value that
+ might be held in floating point registers or memory.
+ While they can be used to access 64 bit parts of a larger value
+ held in general purpose registers, that won't work with memory -
+ neither for fp registers, since the frxx names are used. */
case 'R':
- fputs (reg_names[REGNO (x) + LSW], (stream));
+ if (REG_P (x) || GET_CODE (x) == SUBREG)
+ {
+ regno = true_regnum (x);
+ regno += FP_REGISTER_P (regno) ? 1 : LSW;
+ fputs (reg_names[regno], (stream));
+ }
+ else if (MEM_P (x))
+ {
+ x = adjust_address (x, SImode, 4 * LSW);
+ print_operand_address (stream, XEXP (x, 0));
+ }
+ else
+ {
+ rtx sub = NULL_RTX;
+
+ mode = GET_MODE (x);
+ if (mode == VOIDmode)
+ mode = DImode;
+ if (GET_MODE_SIZE (mode) >= 8)
+ sub = simplify_subreg (SImode, x, mode, 4 * LSW);
+ if (sub)
+ print_operand (stream, sub, 0);
+ else
+ output_operand_lossage ("invalid operand to %%R");
+ }
break;
case 'S':
- fputs (reg_names[REGNO (x) + MSW], (stream));
+ if (REG_P (x) || GET_CODE (x) == SUBREG)
+ {
+ regno = true_regnum (x);
+ regno += FP_REGISTER_P (regno) ? 0 : MSW;
+ fputs (reg_names[regno], (stream));
+ }
+ else if (MEM_P (x))
+ {
+ x = adjust_address (x, SImode, 4 * MSW);
+ print_operand_address (stream, XEXP (x, 0));
+ }
+ else
+ {
+ rtx sub = NULL_RTX;
+
+ mode = GET_MODE (x);
+ if (mode == VOIDmode)
+ mode = DImode;
+ if (GET_MODE_SIZE (mode) >= 8)
+ sub = simplify_subreg (SImode, x, mode, 4 * MSW);
+ if (sub)
+ print_operand (stream, sub, 0);
+ else
+ output_operand_lossage ("invalid operand to %%S");
+ }
break;
case 'T':
/* Next word of a double. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a0e340a0823..35176b6d09e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2005-08-31 J"orn Rennecke <joern.rennecke@st.com>
+
+ PR target/21255
+ * gcc.dg/pr21255-1.c: New test.
+ * gcc.dg/pr21255-2-mb.c: Likewise.
+ * gcc.dg/pr21255-2-ml.c: Likewise.
+ * gcc.dg/pr21255-3.c: Likewise.
+ * gcc.dg/pr21255-4.c: Likewise.
+
2005-08-31 Dale Johannesen <dalej@apple.com>
* gcc.dg/20050830-1.c: New.
diff --git a/gcc/testsuite/gcc.dg/pr21255-1.c b/gcc/testsuite/gcc.dg/pr21255-1.c
new file mode 100644
index 00000000000..0508e809b6b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr21255-1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-final { scan-assembler "mov fr4,fr.; mov fr5,fr." } } */
+double
+f (double d)
+{
+ double r;
+
+#if defined (__SH_FPU_DOUBLE__) && !TARGET_SHMEDIA
+ asm ("mov %S1,%S0; mov %R1,%R0" : "=f" (r) : "f" (d));
+#else
+ asm ("mov fr4,fr4; mov fr5,fr5");
+#endif
+ return r;
+}
diff --git a/gcc/testsuite/gcc.dg/pr21255-2-mb.c b/gcc/testsuite/gcc.dg/pr21255-2-mb.c
new file mode 100644
index 00000000000..ac2ce687e1e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr21255-2-mb.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-mb -O2 -fomit-frame-pointer" } */
+/* { dg-final { scan-assembler "mov @r.,r.; mov @\\(4,r.\\),r." } } */
+double d;
+
+double
+f (void)
+{
+ double r;
+
+/* If -ml from the target options is passed after -mb from dg-options, we
+ end up with th reverse endianness. */
+#if TARGET_SHMEDIA || defined (__LITTLE_ENDIAN__)
+ asm ("mov @r1,r3; mov @(4,r1),r4");
+#else
+ asm ("mov %S1,%S0; mov %R1,%R0" : "=&r" (r) : "m" (d));
+#endif
+ return r;
+}
diff --git a/gcc/testsuite/gcc.dg/pr21255-2-ml.c b/gcc/testsuite/gcc.dg/pr21255-2-ml.c
new file mode 100644
index 00000000000..c63a573ea9d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr21255-2-ml.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-ml -O2 -fomit-frame-pointer" } */
+/* { dg-final { scan-assembler "mov @\\(4,r.\\),r.; mov @r.,r." } } */
+double d;
+
+double
+f (void)
+{
+ double r;
+
+/* If -mb from the target options is passed after -ml from dg-options, we
+ end up with th reverse endianness. */
+#if TARGET_SHMEDIA || defined (__BIG_ENDIAN__)
+ asm ("mov @(4,r1),r4; mov @r1,r3");
+#else
+ asm ("mov %S1,%S0; mov %R1,%R0" : "=&r" (r) : "m" (d));
+#endif
+ return r;
+}
diff --git a/gcc/testsuite/gcc.dg/pr21255-3.c b/gcc/testsuite/gcc.dg/pr21255-3.c
new file mode 100644
index 00000000000..7edd8cb7c1c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr21255-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-final { scan-assembler "mov #?0,r.*; mov #?20,r" } } */
+/* { dg-final { scan-assembler "mov #?1077149696,r.*; mov #?0,r" } } */
+double
+f ()
+{
+ double r;
+
+ asm ("mov %S1,%S0; mov %R1,%R0" : "=r" (r) : "i" (20));
+ asm ("mov %S1,%S0; mov %R1,%R0" : "+r" (r) : "i" (20.));
+ return r;
+}
diff --git a/gcc/testsuite/gcc.dg/pr21255-4.c b/gcc/testsuite/gcc.dg/pr21255-4.c
new file mode 100644
index 00000000000..72a632c9dc5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr21255-4.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+double
+f ()
+{
+ double r;
+
+ asm ("mov %S1,%S0; mov %R1,%R0" : "=r" (r) : "i" (f));
+/* { dg-error "invalid operand to %S" "" {target "sh*-*-*" } 9 } */
+/* { dg-error "invalid operand to %R" "" {target "sh*-*-*" } 9 } */
+ return r;
+}