aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Nemet <anemet@caviumnetworks.com>2008-11-18 02:08:24 +0000
committerAdam Nemet <anemet@caviumnetworks.com>2008-11-18 02:08:24 +0000
commit072e26c79103928df61536f3b39690bb8b2a21b4 (patch)
tree5a743df1e9e72a72b5cbac89bebae2c44dd3bd74
parent31e8d4582a0fe96218103a043b7596a6cef1b2ad (diff)
* expmed.c (extract_bit_field_1): Also use a temporary and
convert_extracted_bit_field when the conversion from ext_mode to the target mode requires explicit truncation. testsuite/ * gcc.c-torture/execute/20081117-1.c: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@141960 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/expmed.c8
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20081117-1.c24
4 files changed, 41 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0477d27532c..da96cb50c60 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2008-11-17 Adam Nemet <anemet@caviumnetworks.com>
+
+ * expmed.c (extract_bit_field_1): Also use a temporary and
+ convert_extracted_bit_field when the conversion from ext_mode to
+ the target mode requires explicit truncation.
+
2008-11-17 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips.h (REG_ALLOC_ORDER): Put accumulators first.
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 0c7e611e188..70a0d18bcb5 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -1533,7 +1533,13 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
if (GET_MODE (xtarget) != ext_mode)
{
- if (REG_P (xtarget))
+ /* Don't use LHS paradoxical subreg if explicit truncation is needed
+ between the mode of the extraction (word_mode) and the target
+ mode. Instead, create a temporary and use convert_move to set
+ the target. */
+ if (REG_P (xtarget)
+ && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (xtarget)),
+ GET_MODE_BITSIZE (ext_mode)))
{
xtarget = gen_lowpart (ext_mode, xtarget);
if (GET_MODE_SIZE (ext_mode)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2bc32017299..0af6cad0a3d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2008-11-17 Adam Nemet <anemet@caviumnetworks.com>
+
+ * gcc.c-torture/execute/20081117-1.c: New test.
+
2008-11-17 Richard Sandiford <rdsandiford@googlemail.com>
* gcc.target/mips/dspr2-MULT.c: Just check for $ac1 and $ac2.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20081117-1.c b/gcc/testsuite/gcc.c-torture/execute/20081117-1.c
new file mode 100644
index 00000000000..bff7464cbae
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20081117-1.c
@@ -0,0 +1,24 @@
+extern void abort (void);
+
+struct s
+{
+ unsigned long long a:16;
+ unsigned long long b:32;
+ unsigned long long c:16;
+};
+
+__attribute__ ((noinline)) unsigned
+f (struct s s, unsigned i)
+{
+ return s.b == i;
+}
+
+struct s s = { 1, 0x87654321u, 2};
+
+int
+main ()
+{
+ if (!f (s, 0x87654321u))
+ abort ();
+ return 0;
+}