Re: Fix various x86 tests for --with-arch=bdver3

2014-03-29 Thread Uros Bizjak
On Fri, Mar 28, 2014 at 10:46 PM, Joseph S. Myers
 wrote:
> If you build an x86_64 toolchain with --with-arch enabling various
> instruction set extensions by default, this causes some tests to fail
> that aren't expecting those extensions to be enabled.  This patch
> fixes various tests failing like that for an x86_64-linux-gnu
> toolchain configured --with-arch=bdver3, generally by using
> appropriate -mno-* options in the tests, or in the case of
> gcc.dg/pr45416.c by adjusting the scan-assembler to allow the
> alternative instruction that gets used in this case.  It's quite
> likely other such failures appear for other --with-arch choices.
>
> Tested x86_64-linux-gnu.  OK to commit?
>
> In addition to the failures fixed by this patch, there are many
> gcc.dg/vect tests where having additional vector extensions enabled
> breaks their expectations; I'm not sure of the best way to handle
> those.  And you get
>
> FAIL: gcc.target/i386/avx512f-vfmaddXXXpd-2.c (test for excess errors)
> FAIL: gcc.target/i386/avx512f-vfmaddXXXps-2.c (test for excess errors)
> FAIL: gcc.target/i386/avx512f-vfmaddsubXXXpd-2.c (test for excess errors)
> FAIL: gcc.target/i386/avx512f-vfmaddsubXXXps-2.c (test for excess errors)
> FAIL: gcc.target/i386/avx512f-vfmsubXXXpd-2.c (test for excess errors)
> FAIL: gcc.target/i386/avx512f-vfmsubXXXps-2.c (test for excess errors)
> FAIL: gcc.target/i386/avx512f-vfmsubaddXXXpd-2.c (test for excess errors)
> FAIL: gcc.target/i386/avx512f-vfmsubaddXXXps-2.c (test for excess errors)
> FAIL: gcc.target/i386/avx512f-vfnmaddXXXpd-2.c (test for excess errors)
> FAIL: gcc.target/i386/avx512f-vfnmaddXXXps-2.c (test for excess errors)
> FAIL: gcc.target/i386/avx512f-vfnmsubXXXpd-2.c (test for excess errors)
> FAIL: gcc.target/i386/avx512f-vfnmsubXXXps-2.c (test for excess errors)
>
> which are assembler errors such as "operand type mismatch for
> `vfmaddpd'" - it looks like the compiler isn't really prepared for the
> -mavx512f -mfma4 combination, but I'm not sure what the best way to
> handle it is (producing invalid output doesn't seem right, however).

I will look into these.

> If you test with -march=bdver3 in the multilib options (runtest
> --target_board=unix/-march=bdver3) rather than as the configured
> default, you get extra failures for the usual reason of multilib
> options going after the options from dg-options (which I propose to
> address in the usual way using dg-skip-if for -march= options
> different from the one present in dg-options).
>
> 2014-03-28  Joseph Myers  
>
> * gcc.dg/pr45416.c: Allow bextr on x86.
> * gcc.target/i386/fma4-builtin.c, gcc.target/i386/fma4-fma-2.c,
> gcc.target/i386/fma4-fma.c, gcc.target/i386/fma4-vector-2.c,
> gcc.target/i386/fma4-vector.c: Use -mno-fma.
> * gcc.target/i386/l_fma_double_1.c,
> gcc.target/i386/l_fma_double_2.c,
> gcc.target/i386/l_fma_double_3.c,
> gcc.target/i386/l_fma_double_4.c,
> gcc.target/i386/l_fma_double_5.c,
> gcc.target/i386/l_fma_double_6.c, gcc.target/i386/l_fma_float_1.c,
> gcc.target/i386/l_fma_float_2.c, gcc.target/i386/l_fma_float_3.c,
> gcc.target/i386/l_fma_float_4.c, gcc.target/i386/l_fma_float_5.c,
> gcc.target/i386/l_fma_float_6.c: Use -mno-fma4.
> * gcc.target/i386/pr27971.c: Use -mno-tbm.
> * gcc.target/i386/pr42542-4a.c: Use -mno-avx.
> * gcc.target/i386/pr59390.c: Use -mno-fma -mno-fma4.

OK.

Thanks,
Uros.


Re: [PATCH] [4.8 branch] PR rtl-optimization/60700: Backport revision 201326

2014-03-29 Thread Eric Botcazou
> Revision 201326 fixes a shrink-wrap bug which is also a regression
> on 4.8 branch.  This patch backports it to 4.8 branch.  OK for 4.8
> branch.

Yes, thanks.

> I also include a testcase for PR rtl-optimization/60700.  OK for
> trunk and 4.8 branch?

I'd remove #include .

-- 
Eric Botcazou


Re: [PATCH] [4.8 branch] PR rtl-optimization/60700: Backport revision 201326

2014-03-29 Thread Jakub Jelinek
On Sat, Mar 29, 2014 at 09:38:38AM +0100, Eric Botcazou wrote:
> > Revision 201326 fixes a shrink-wrap bug which is also a regression
> > on 4.8 branch.  This patch backports it to 4.8 branch.  OK for 4.8
> > branch.
> 
> Yes, thanks.
> 
> > I also include a testcase for PR rtl-optimization/60700.  OK for
> > trunk and 4.8 branch?
> 
> I'd remove #include .

You'd then have to use __SIZE_TYPE__ in malloc prototype or just drop
the prototype and use __builtin_malloc.

Jakub


[patch] Fix texinfo warnings for doc/gcc.texi [was: Re: doc bugs]

2014-03-29 Thread Tobias Burnus

H.J. Lu wrote:

On Fri, Mar 28, 2014 at 12:41 PM, Mike Stump  wrote:

Since we are nearing release, I thought I'd mention I see:
../../gcc/gcc/doc/invoke.texi:1114: warning: node next `Overall Options' in 
menu `C Dialect Options' and in sectioning `Invoking G++' differ

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59055


I think one reason that there are (and were) that many warnings is that 
only recently texinfo gained support for diagnosing these issues. (Or 
maybe not that recent but distributions were slow in adapting newer 
texinfo versions.)


Attached is a warning-removal patch.
OK for the trunk?

Regarding invoke.texi: It had (nearly) the same @menu twice, once under 
@chapter where it belongs to and once under a @section where it doesn't.


Tobias
2014-03-29  Tobias Burnus  

	PR other/59055
	* doc/bugreport.texi (Bugs): Remove nodes pointing to the
	nirvana.
	* doc/gcc.texi (Service): Update description in the @menu
	* doc/invoke.texi (Option Summary): Remove misplaced and
	duplicated @menu.

diff --git a/gcc/doc/bugreport.texi b/gcc/doc/bugreport.texi
index be03522..e465c24 100644
--- a/gcc/doc/bugreport.texi
+++ b/gcc/doc/bugreport.texi
@@ -16,11 +16,9 @@ report the problem.
 @menu
 * Criteria:  Bug Criteria.   Have you really found a bug?
 * Reporting: Bug Reporting.  How to report a bug effectively.
-* Known: Trouble.Known problems.
-* Help: Service. Where to ask for help.
 @end menu
 
-@node Bug Criteria,Bug Reporting,,Bugs
+@node Bug Criteria
 @section Have You Found a Bug?
 @cindex bug criteria
 
@@ -83,7 +81,7 @@ If you are an experienced user of one of the languages GCC supports, your
 suggestions for improvement of GCC are welcome in any case.
 @end itemize
 
-@node Bug Reporting,,Bug Criteria,Bugs
+@node Bug Reporting
 @section How and where to Report Bugs
 @cindex compiler bugs, reporting
 
diff --git a/gcc/doc/gcc.texi b/gcc/doc/gcc.texi
index 1e0fc46..c1f3857 100644
--- a/gcc/doc/gcc.texi
+++ b/gcc/doc/gcc.texi
@@ -140,7 +140,7 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}.
 * Gcov::@command{gcov}---a test coverage program.
 * Trouble:: If you have trouble using GCC.
 * Bugs::How, why and where to report bugs.
-* Service:: How to find suppliers of support for GCC.
+* Service:: How To Get Help with GCC
 * Contributing::How to contribute to testing and developing GCC.
 
 * Funding:: How to help assure funding for free software.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 78ddde0..b623b05 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1088,28 +1088,6 @@ See S/390 and zSeries Options.
 -fvisibility -fstrict-volatile-bitfields -fsync-libcalls}
 @end table
 
-@menu
-* Overall Options:: Controlling the kind of output:
-an executable, object files, assembler files,
-or preprocessed source.
-* C Dialect Options::   Controlling the variant of C language compiled.
-* C++ Dialect Options:: Variations on C++.
-* Objective-C and Objective-C++ Dialect Options:: Variations on Objective-C
-and Objective-C++.
-* Language Independent Options:: Controlling how diagnostics should be
-formatted.
-* Warning Options:: How picky should the compiler be?
-* Debugging Options::   Symbol tables, measurements, and debugging dumps.
-* Optimize Options::How much optimization?
-* Preprocessor Options:: Controlling header files and macro definitions.
- Also, getting dependency information for Make.
-* Assembler Options::   Passing options to the assembler.
-* Link Options::Specifying libraries and so on.
-* Directory Options::   Where to find header files and libraries.
-Where to find the compiler executable files.
-* Spec Files::  How to pass switches to sub-processes.
-* Target Options::  Running a cross-compiler, or an old version of GCC.
-@end menu
 
 @node Overall Options
 @section Options Controlling the Kind of Output


Re: [RFC][PATCH][MIPS] Patch to enable LRA for MIPS backend

2014-03-29 Thread Richard Sandiford
First of all, thanks a lot for doing this.

Robert Suchanek  writes:
> diff --git gcc/config/mips/mips.c gcc/config/mips/mips.c
> index 143169b..f27a801 100644
> --- gcc/config/mips/mips.c
> +++ gcc/config/mips/mips.c
> @@ -2255,7 +2255,7 @@ mips_regno_mode_ok_for_base_p (int regno, enum 
> machine_mode mode,
>   All in all, it seems more consistent to only enforce this restriction
>   during and after reload.  */
>if (TARGET_MIPS16 && regno == STACK_POINTER_REGNUM)
> -return !strict_p || GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 
> 8;
> +return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
>  
>return TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
>  }

Not sure about this one.  We would need to update the comment that
explains why "!strict_p" is there, but AFAIK reason (1) would still apply.

Was this needed for correctness or because it gave better code?

> +/* Return a register priority for hard reg REGNO.  */
> +
> +static int
> +mips_register_priority (int hard_regno)
> +{
> +  if (TARGET_MIPS16)
> +   {
> + /* Treat MIPS16 registers with higher priority than other regs.  */
> + switch (hard_regno)
> +   {
> +   case 2:
> +   case 3:
> +   case 4:
> +   case 5:
> +   case 6:
> +   case 7:
> +   case 16:
> +   case 17:
> + return 1;
> +   default:
> + return 0;
> +   }
> +   }
> +  return 0;
> +}
> +

Easier as:

  if (TARGET_MIPS16
  && TEST_HARD_REG_BIT (reg_class_contents[M16_REGS], hard_regno))
return 1;
  return 0;

> diff --git gcc/config/mips/mips.h gcc/config/mips/mips.h
> index a786d4c..712008f 100644
> --- gcc/config/mips/mips.h
> +++ gcc/config/mips/mips.h
> @@ -1871,10 +1871,12 @@ enum reg_class
>  {
>NO_REGS,   /* no registers in set */
>M16_REGS,  /* mips16 directly accessible registers */
> +  M16F_REGS, /* mips16 + frame */

Constraints are supposed to be operating on real registers, after
elimination, so it seems odd to include a fake register.  What went
wrong with just M16_REGS?

> +  SPILL_REGS,/* All but $sp and call preserved regs 
> are in here */
...
> +  { 0x0003fffc, 0x, 0x, 0x, 0x, 0x 
> },/* SPILL_REGS */\

These two don't seem to match.  I think literally it would be 0x0300fffc,
but maybe you had to make SPILL_REGS a superset of M16_REGs?

> +/* Add costs to hard registers based on frequency. This helps to negate
> +   some of the reduced cost associated with argument registers which 
> +   unfairly promotes their use and increases register pressure */
> +#define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(REGNO)   \
> +  (TARGET_MIPS16 && optimize_size   \
> +   ? ((REGNO) >= 4 && (REGNO) <= 7 ? 2 : 0) : 0)

So we would be trying to use, say, $4 for the first incoming argument
even after it had been spilled?  Hmm.

Since this change is aimed specifically at one heuristic, I wonder
whether we should parameterise that heuristic somehow rather than
try to use a general hook to undo it.  But I don't think there's
anything particularly special about MIPS16 here, so maybe it's too
eager for all targets.

> diff --git gcc/config/mips/mips.md gcc/config/mips/mips.md
> index 1e3e9e6..ababd5e 100644
> --- gcc/config/mips/mips.md
> +++ gcc/config/mips/mips.md
> @@ -1622,40 +1622,66 @@
>  ;; copy instructions.  Reload therefore thinks that the second alternative
>  ;; is two reloads more costly than the first.  We add "*?*?" to the first
>  ;; alternative as a counterweight.
> +;;
> +;; LRA simulates reload but the cost of reloading scratches is lower
> +;; than of the classic reload. For the time being, removing the counterweight
> +;; for LRA is more profitable.
>  (define_insn "*mul_acc_si"
> -  [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?")
> - (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
> -   (match_operand:SI 2 "register_operand" "d,d"))
> -  (match_operand:SI 3 "register_operand" "0,d")))
> -   (clobber (match_scratch:SI 4 "=X,l"))
> -   (clobber (match_scratch:SI 5 "=X,&d"))]
> +  [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d?")
> + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
> +   (match_operand:SI 2 "register_operand" "d,d,d"))
> +  (match_operand:SI 3 "register_operand" "0,0,d")))
> +   (clobber (match_scratch:SI 4 "=X,X,l"))
> +   (clobber (match_scratch:SI 5 "=X,X,&d"))]
>"GENERATE_MADD_MSUB && !TARGET_MIPS16"
>"@
>  madd\t%1,%2
> +madd\t%1,%2
>  #"
>[(set_attr "type"  "imadd")
> (set_attr "accum_in"  "3")
> (set_attr "mode"  "SI")
> -   (set_attr "insn_count" "1,2")])
> +   (set_attr "insn_count" "1,1,2")
> +   (set (attr "enabled")
> +(cond [(and (eq_attr "alternative" "0")
> +  

Re: [RFA][PATCH][pr target/60648] Fix non-canonical RTL from x86 backend -- P1 regression

2014-03-29 Thread Jakub Jelinek
On Fri, Mar 28, 2014 at 07:12:26PM +0100, Jakub Jelinek wrote:
> On Fri, Mar 28, 2014 at 12:04:00PM -0600, Jeff Law wrote:
> > Here's the updated patch.  It uses simplify_gen_binary in expr.c to
> > simplify the address expression as we're building it.  It also uses
> > copy_addr_to_reg in the x86 backend to avoid the possibility of
> > generating non-canonical RTL there too.
> > 
> > By accident I interrupted the regression test cycle, so that is
> > still running.  OK for the trunk if that passes?
> 
> Ok, thanks.

Sorry for not catching this earlier, but the testcase was misplaced,
the two dg-do compile directives where only one was limited to i?86/x86_64
meant the test was run on all targets and explicit -fPIC could break on
non-pic targets and explicit -m32 broke on all targets that don't support
-m32.

Fixed thusly, verified the test still fails
(RUNTESTFLAGS='--target_board=unix\{-m32,-m64\} dg-torture.exp=pr60648.C')
without your fix and works with it and committed as obvious.

2014-03-29  Jakub Jelinek  

PR target/60648
* g++.dg/pr60648.C: Move test to...
* g++.dg/torture/pr60648.C: ... here.  Run on all targets, remove
dg-options, add for fpic targets dg-additional-options -fPIC.

--- gcc/testsuite/g++.dg/pr60648.C.jj   2014-03-28 23:06:43.0 +0100
+++ gcc/testsuite/g++.dg/pr60648.C  2014-03-29 12:02:03.014367559 +0100
@@ -1,73 +0,0 @@
-/* { dg-do compile } */
-/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O3 -fPIC -m32" }  */
-
-enum component
-{
-  Ex,
-  Ez,
-  Hy,
-  Permeability
-};
-enum derived_component
-{};
-enum direction
-{
-  X,
-  Y,
-  Z,
-  R,
-  P,
-  NO_DIRECTION
-};
-derived_component a;
-component *b;
-component c;
-direction d;
-inline direction fn1 (component p1)
-{
-  switch (p1)
-{
-case 0:
-  return Y;
-case 1:
-  return Z;
-case Permeability:
-  return NO_DIRECTION;
-}
-  return X;
-}
-
-inline component fn2 (direction p1)
-{
-  switch (p1)
-{
-case 0:
-case 1:
-  return component ();
-case Z:
-case R:
-  return component (1);
-case P:
-  return component (3);
-}
-}
-
-void fn3 ()
-{
-  direction e;
-  switch (0)
-  case 0:
-  switch (a)
-{
-case 0:
-  c = Ex;
-  b[1] = Hy;
-}
-  e = fn1 (b[1]);
-  b[1] = fn2 (e);
-  d = fn1 (c);
-}
-
-
-
--- gcc/testsuite/g++.dg/torture/pr60648.C.jj   2014-03-29 12:01:57.999392178 
+0100
+++ gcc/testsuite/g++.dg/torture/pr60648.C  2014-03-29 12:05:44.452182659 
+0100
@@ -0,0 +1,70 @@
+// PR target/60648
+// { dg-do compile }
+// { dg-additional-options "-fPIC" { target fpic } }
+
+enum component
+{
+  Ex,
+  Ez,
+  Hy,
+  Permeability
+};
+enum derived_component
+{};
+enum direction
+{
+  X,
+  Y,
+  Z,
+  R,
+  P,
+  NO_DIRECTION
+};
+derived_component a;
+component *b;
+component c;
+direction d;
+inline direction fn1 (component p1)
+{
+  switch (p1)
+{
+case 0:
+  return Y;
+case 1:
+  return Z;
+case Permeability:
+  return NO_DIRECTION;
+}
+  return X;
+}
+
+inline component fn2 (direction p1)
+{
+  switch (p1)
+{
+case 0:
+case 1:
+  return component ();
+case Z:
+case R:
+  return component (1);
+case P:
+  return component (3);
+}
+}
+
+void fn3 ()
+{
+  direction e;
+  switch (0)
+  case 0:
+  switch (a)
+{
+case 0:
+  c = Ex;
+  b[1] = Hy;
+}
+  e = fn1 (b[1]);
+  b[1] = fn2 (e);
+  d = fn1 (c);
+}

Jakub


Re: patch to fix PR 60650

2014-03-29 Thread Jakub Jelinek
On Thu, Mar 27, 2014 at 02:51:38PM -0400, Vladimir Makarov wrote:
> 2014-03-27  Vladimir Makarov  
> 
> PR rtl-optimization/60650
> * gcc.target/arm/pr60650.c: New.

The test fails for me with:
spawn -ignore SIGHUP 
/builddir/build/BUILD/gcc-4.9.0-20140328/obj-armv7hl-redhat-linux-gnueabi/gcc/xgcc
 
-B/builddir/build/BUILD/gcc-4.9.0-20140328/obj-armv7hl-redhat-linux-gnueabi/gcc/builddir/build/BUILD/gcc-4.9.0-20140328/gcc/testsuite/gcc.target/arm/pr60650.c
 -fno-diagnostics-show-caret -fdiagnostics-color=never -O2 
-fno-omit-frame-pointer -mabi=apcs-gnu -march=armv7-a -S -o pr60650.s
/builddir/build/BUILD/gcc-4.9.0-20140328/gcc/testsuite/gcc.target/arm/pr60650.c:1:0:
 sorry, unimplemented: -mfloat-abi=hard and VFP
compiler exited with status 1
Does one have to pass -mfloat-abi= option too unconditionally?
Can somebody from the ARM/Linaro people handle this?

Also:

> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pr60650.c
...
> +  asm ("1\t.long ");

This asm looks quite bogus, and with
asm ("");
it ICEs the same way, can it be changed?

> +  __builtin_unreachable ();
> +}
> +}

Jakub


Re: [RFC][PATCH][MIPS] Patch to enable LRA for MIPS backend

2014-03-29 Thread Jakub Jelinek
On Sat, Mar 29, 2014 at 01:07:40AM +, Robert Suchanek wrote:
> This patch enables LRA by default for MIPS. The classic reload is still
> available and can be enabled via -mreload switch. 

FYI, all other targets that have LRA optionally selectable or deselectable
use -mno-lra for this (even when -mlra is the default), it would be better
for consistency not to invent new switch names for that.

Jakub


Re: [RFA][PATCH][pr target/60648] Fix non-canonical RTL from x86 backend -- P1 regression

2014-03-29 Thread Andreas Schwab
Jeff Law  writes:

> diff --git a/gcc/testsuite/g++.dg/pr60648.C b/gcc/testsuite/g++.dg/pr60648.C
> new file mode 100644
> index 000..80c0561
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/pr60648.C
> @@ -0,0 +1,73 @@
> +/* { dg-do compile } */
> +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
> +/* { dg-options "-O3 -fPIC -m32" }  */

xg++: error: unrecognized command line option '-m32'

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."


Re: [PATCH] Fix PR c++/60626

2014-03-29 Thread Jason Merrill

OK.

Jason


[patch, libgfortran] Wrong result for UTF-8/UCS-4 list-directed and namelist read and nml write

2014-03-29 Thread Jerry DeLisle
Hi all,

The attached patch fixes namelist read/write and list directed read/write to
support UTF-8.

I have attached a preliminary test case to use to experiment with this.  I will
need to set it up for the testsuite still.

Regression tested on x86-64-linux-gnu.

OK for trunk or wait?

Regards,

Jerry

2014-03-29  Jerry DeLisle  

PR libfortran/52539
* io/list_read.c: Add uchar typedef. (push_char4): New function
to save kind=4 character. (next_char_utf8): New function to read
a single UTF-8 encoded character value. (read_chracter): Update
to use the new functions for reading UTF-8 strings.
(list_formatted_read_scalar): Update to handle list directed
reads of UTF-8 strings. (nml_read_obj): Likewise update for
UTF-8 strings in namelists.
* io/write.c (nml_write_obj): Add kind=4 character support for
namelist writes.
Index: list_read.c
===
--- list_read.c	(revision 208931)
+++ list_read.c	(working copy)
@@ -32,7 +32,9 @@ see the files COPYING3 and COPYING.RUNTIME respect
 #include 
 #include 
 
+typedef unsigned char uchar;
 
+
 /* List directed input.  Several parsing subroutines are practically
reimplemented from formatted input, the reason being that there are
all kinds of small differences between formatted and list directed
@@ -97,7 +99,38 @@ push_char (st_parameter_dt *dtp, char c)
   dtp->u.p.saved_string[dtp->u.p.saved_used++] = c;
 }
 
+/* Save a KIND=4 character to a string buffer, enlarging the buffer
+   as necessary.  */
 
+static void
+push_char4 (st_parameter_dt *dtp, gfc_char4_t c)
+{
+  gfc_char4_t *new, *p = (gfc_char4_t *) dtp->u.p.saved_string;
+
+  if (p == NULL)
+{
+  dtp->u.p.saved_string = xcalloc (SCRATCH_SIZE, sizeof (gfc_char4_t));
+  dtp->u.p.saved_length = SCRATCH_SIZE;
+  dtp->u.p.saved_used = 0;
+  p = (gfc_char4_t *) dtp->u.p.saved_string;
+}
+
+  if (dtp->u.p.saved_used >= dtp->u.p.saved_length)
+{
+  dtp->u.p.saved_length = 2 * dtp->u.p.saved_length;
+  new = realloc (p, dtp->u.p.saved_length);
+  if (new == NULL)
+	generate_error (&dtp->common, LIBERROR_OS, NULL);
+  p = new;
+  
+  memset (new + dtp->u.p.saved_used, 0, 
+	  dtp->u.p.saved_length - dtp->u.p.saved_used);
+}
+
+  p[dtp->u.p.saved_used++] = c;
+}
+
+
 /* Free the input buffer if necessary.  */
 
 static void
@@ -247,6 +280,57 @@ done:
 }
 
 
+static gfc_char4_t
+next_char_utf8 (st_parameter_dt *dtp) 
+{
+  static const uchar masks[6] = { 0x7F, 0x1F, 0x0F, 0x07, 0x02, 0x01 };
+  static const uchar patns[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+  int i, nb;
+  gfc_char4_t c;
+
+  c = next_char (dtp);
+  if (c < 0x80)
+return c;
+
+  /* The number of leading 1-bits in the first byte indicates how many
+ bytes follow.  */
+  for (nb = 2; nb < 7; nb++)
+if ((c & ~masks[nb-1]) == patns[nb-1])
+  goto found;
+  goto invalid;
+	
+ found:
+  c = (c & masks[nb-1]);
+
+  /* Decode the bytes read.  */
+  for (i = 1; i < nb; i++)
+{
+  gfc_char4_t n = next_char (dtp);
+
+  if ((n & 0xC0) != 0x80)
+	goto invalid;
+
+  c = ((c << 6) + (n & 0x3F));
+}
+
+  /* Make sure the shortest possible encoding was used.  */
+  if (c <=  0x7F && nb > 1) goto invalid;
+  if (c <= 0x7FF && nb > 2) goto invalid;
+  if (c <=0x && nb > 3) goto invalid;
+  if (c <=  0x1F && nb > 4) goto invalid;
+  if (c <= 0x3FF && nb > 5) goto invalid;
+
+  /* Make sure the character is valid.  */
+  if (c > 0x7FFF || (c >= 0xD800 && c <= 0xDFFF))
+goto invalid;
+
+  return c;
+  
+ invalid:
+  generate_error (&dtp->common, LIBERROR_READ_VALUE, "Invalid UTF-8 encoding");
+  return (gfc_char4_t) '?';
+}
+
 /* Push a character back onto the input.  */
 
 static void
@@ -1087,51 +1171,98 @@ read_character (st_parameter_dt *dtp, int length _
 }
 
  get_string:
-  for (;;)
-{
-  if ((c = next_char (dtp)) == EOF)
-	goto done_eof;
-  switch (c)
-	{
-	case '"':
-	case '\'':
-	  if (c != quote)
-	{
+
+  if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
+for (;;)
+  {
+	if ((c = next_char_utf8 (dtp)) == EOF)
+	  goto done_eof;
+	switch (c)
+	  {
+	  case '"':
+	  case '\'':
+	if (c != quote)
+	  {
+		push_char4 (dtp, c);
+		break;
+	  }
+  
+	/* See if we have a doubled quote character or the end of
+	   the string.  */
+  
+	if ((c = next_char_utf8 (dtp)) == EOF)
+	  goto done_eof;
+	if (c == quote)
+	  {
+		push_char4 (dtp, quote);
+		break;
+	  }
+  
+	unget_char (dtp, c);
+	goto done;
+  
+	  CASE_SEPARATORS:
+	if (quote == ' ')
+	  {
+		unget_char (dtp, c);
+		goto done;
+	  }
+  
+	if (c != '\n' && c != '\r')
+	  push_char4 (dtp, c);
+	break;
+  
+	  default:
+	push_char4 (dtp, c);
+	break;
+	  }
+  }
+  else
+for (;;)
+  {
+	if ((c = next_char (dtp