Patchwork [ARM] ISO/IEC TR 18037 fixed-point support

login
register
mail settings
Submitter Julian Brown
Date May 11, 2011, 2 p.m.
Message ID <20110511150017.0ab31927@rex.config>
Download mbox | patch
Permalink /patch/95242/
State New
Headers show

Comments

Julian Brown - May 11, 2011, 2 p.m.
Hi,

This patch implements the ARM target-specific parts required to support
fixed-point operations as specified in the draft ISO/IEC technical
report TR 18037:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1275.pdf

Only basic arithmetic operations are implemented (addition, subtraction,
multiplication, on various data types, with saturating and
non-saturating variants where appropriate). Other functionality is
provided by support functions in libgcc (type conversions,
comparisons, and so on). Although more efficient versions of some of
these could be implemented inline, it seems to me they would mostly use
regular integer operations: I'm not at all sure that building that into
each target rather than teaching generic code how to do it is a
sensible way to go.

The patch implements:

  * Addition and subtraction for fract and accum values (short,
    regular, long).

  * Addition and subtraction for word-size vectors of fract and accum
    values (both saturating and non-saturating).  (It's a little unclear
    how useful these are.)

  * Multiplication of fract values: short, regular and long. (There's
    no point in implementing saturating versions of these, AFAICT).

  * Multiplication of accum values: unsigned and signed, saturating and
    non-saturating. Short and regular only, no long.

Those seem to be the variations which can be implemented using
efficient or fairly-efficient instruction sequences. Most of the
fancier ARM multiplication instructions don't seem very useful for
these kinds of operations, and so are still unsupported.

I've not altered the "default" sizes for numbers of fractional &
integral bits for the fixed-point types: they seem to map onto ARM
instructions as well as anything else would.

I've added a single (execution) test case to exercise the new
operations a little. Additionally the generic fixed-point.exp tests
pass with the patch.

The instructions using "APSR_nzcvq" require a recent-enough version of
binutils to include the following patch to assemble emitted code:

http://sourceware.org/ml/binutils/2011-04/msg00021.html

There's currently no support for "long long" fixed-point types, since
those imply support for TImode arithmetic, which isn't sensible on ARM.
I've modified tests to make optional the requirement for long long
support.

A note about ARM EABI compliance: nothing is specified in the EABI for
fixed-point types. Vendor-specific helper functions are supposed to go
in their own namespace, so the patch renames the fixed-point helper
functions from "__foo" to "__gnu_foo", and causes them to be linked
statically with libgcc by not giving them versioned symbols: at some
later date if/when fixed-point helpers are added to the ARM EABI, those
helpers can replace the __gnu_foo ones, be given suitably versioned
symbols, etc.

Non-saturating sub-word-sized fixed-point quantities are never
sign/zero-extended after being operated on, including at ABI
boundaries. This means that bits outside the size of the type are
undefined when passing them to/returning them from functions. Again,
this behaviour may need to be tightened up if/when fixed-point support
gets added to the ARM EABI. Otherwise, fixed-point values are passed and
returned like integers.

Tested with cross to ARM Linux. OK to apply?

Thanks,

Julian

ChangeLog

    gcc/
    * optabs.c (prepare_cmp_insn): Use correct biasing for fixed-point
    comparison helpers.
    * final.c (output_addr_const): Print fixed-point constants as
    decimal not hex (avoiding an assembler overflow warning for
    negative byte constants).
    * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Support FIXED_CST.
    * config/arm/arm.c (arm_fixed_point_supported_p): New.
    (TARGET_FIXED_POINT_SUPPORTED_P): Define target macro using above.
    (arm_fixed_mode_set): New struct.
    (arm_set_fixed_optab_libfunc): New.
    (arm_set_fixed_conv_libfunc): New.
    (arm_init_libfuncs): Initialise fixed-point helper libfuncs with
    ARM-specific names.
    (arm_scalar_mode_supported_p): Support fixed-point modes.
    (arm_vector_mode_supported_p): Support vector fixed-point modes.
    * config/arm/arm-modes.def (FRACT, UFRACT, ACCUM, UACCUM): Declare
    vector modes.
    * predicates.md (sat_shift_operator): New predicate.
    * config/arm/arm-fixed.md: New.
    * config/arm/arm.md: Include arm-fixed.md.
    * config/arm/fixed-bit-machine.h: New.
    * config/fixed-bit.h (fixed-bit-machine.h): Include.
    (DECORATE_FIXED_NAME): Conditionally define if undefined. Use
    throughout file to decorate function names.
    * config/fixed-bit-mach-generic.h: New.
 
    libgcc/
    * config.host (arm*-*-linux*, arm*-*-uclinux*, arm*-*-eabi*)
    (arm*-*-nucleuseabi*, arm*-*-symbianelf*): Add arm/t-fixed-point
    makefile fragment.
    * Makefile.in (FIXED_BIT_MACHINE): New rule. Include
    target-specific or generic fixed_bit_machine_header to decorate the
    names of fixed-point helper functions.
    * config/arm/t-fixed-point: New.
    * fixed-obj.mk ($(o)_s$(objext)): Depend on $(FIXED_BIT_MACHINE).

    gcc/testsuite/
    * gcc.target/arm/fixed-point-exec.c: New test.
    * gcc.dg/fixed-point/func-scalar.c: Include longlong-support.h.
    Avoid long long tests on targets which don't support them.
    * gcc.dg/fixed-point/unary.c: Likewise.
    * gcc.dg/fixed-point/muldiv-warning.c: Likewise.
    * gcc.dg/fixed-point/operator-logical.c: Likewise.
    * gcc.dg/fixed-point/func-array.c: Likewise.
    * gcc.dg/fixed-point/func-struct.c: Likewise.
    * gcc.dg/fixed-point/func-vararg-mixed.c: Likewise.
    * gcc.dg/fixed-point/binary.c: Likewise.
    * gcc.dg/fixed-point/comma.c: Likewise.
    * gcc.dg/fixed-point/func-mixed.c: Likewise.
    * gcc.dg/fixed-point/func-vararg.c: Likewise.
    * gcc.dg/fixed-point/operator-cond.c: Likewise.
    * gcc.dg/fixed-point/loop-index.c: Likewise.
    * gcc.dg/fixed-point/convert.c: Likewise.
    * gcc.dg/fixed-point/allop-const.c: Likewise.
    * gcc.dg/fixed-point/call-by-value.c: Likewise.
    * gcc.dg/fixed-point/longlong-support.h: New.
Julian Brown - May 13, 2011, 11:27 a.m.
On Wed, 11 May 2011 15:45:52 +0100
Richard Sandiford <rdsandiford@googlemail.com> wrote:

> Julian Brown <julian@codesourcery.com> writes:
> > Tested with cross to ARM Linux. OK to apply?
> 
> Just out of interest, are you able to test the patch on MIPS as well?
> I was wondering whether the fixed-point results there change after the
> target-independent parts of the patch.  (I think MIPS is still the
> only port with in-tree fixed-point support.)

I ran tests for 32-bit big-endian MIPS (since that was what came out by
default with our build infrastructure...) and I don't see any change in
test results.

Cheers,

Julian
Julian Brown - May 13, 2011, 2:01 p.m.
On Wed, 11 May 2011 15:27:37 +0000 (UTC)
"Joseph S. Myers" <joseph@codesourcery.com> wrote:

> On Wed, 11 May 2011, Julian Brown wrote:
> 
> > There's currently no support for "long long" fixed-point types,
> > since those imply support for TImode arithmetic, which isn't
> > sensible on ARM. I've modified tests to make optional the
> > requirement for long long support.
> 
> I wonder how those tests work, or don't work, on 32-bit MIPS, which
> ought to have the same issue....

Well they do seem to work, though I haven't investigated why.

> Is there a reason for having a separate function, rather than just
> using hook_bool_void_true (with this comment going on the definition
> of TARGET_FIXED_POINT_SUPPORTED_P)?
> 
> I don't see any change to the code in gcc/configure.ac that handles 
> --enable-fixed-point to know that ARM targets now support it.  Since
> the default hook returns ENABLE_FIXED_POINT, maybe if you fixed the
> configure test you wouldn't need to define the hook for ARM at all....

I've done the latter: note you'll now need to configure with
"--enable-fixed-point" to turn fixed-point on for ARM.

> It might make sense to send the machine-independent parts separately, 
> under a separate subject heading, with an explanation for why each
> bit is needed.

I've done this (and the other bits you pointed out). See:

http://gcc.gnu.org/ml/gcc-patches/2011-05/msg00964.html
http://gcc.gnu.org/ml/gcc-patches/2011-05/msg00965.html
http://gcc.gnu.org/ml/gcc-patches/2011-05/msg00966.html
http://gcc.gnu.org/ml/gcc-patches/2011-05/msg00967.html
http://gcc.gnu.org/ml/gcc-patches/2011-05/msg00969.html
http://gcc.gnu.org/ml/gcc-patches/2011-05/msg00968.html

Cheers,

Julian
Joseph S. Myers - May 13, 2011, 2:56 p.m.
On Fri, 13 May 2011, Julian Brown wrote:

> On Wed, 11 May 2011 15:27:37 +0000 (UTC)
> "Joseph S. Myers" <joseph@codesourcery.com> wrote:
> 
> > On Wed, 11 May 2011, Julian Brown wrote:
> > 
> > > There's currently no support for "long long" fixed-point types,
> > > since those imply support for TImode arithmetic, which isn't
> > > sensible on ARM. I've modified tests to make optional the
> > > requirement for long long support.
> > 
> > I wonder how those tests work, or don't work, on 32-bit MIPS, which
> > ought to have the same issue....
> 
> Well they do seem to work, though I haven't investigated why.

I think that does need further investigation, since it means that at least 
the claimed reason for needing patch 5/6 has something wrong with it.  
Maybe there's a reason it's appropriate to disable those types and tests 
on some targets, but it's not "those imply support for TImode arithmetic".

Patch

commit 1c54db2b3b1113da24385c2aa551521753ab1832
Author: Julian Brown <julian@henry8.codesourcery.com>
Date:   Wed May 11 04:42:46 2011 -0700

    Fixed-point extension support for ARM.

diff --git a/gcc/config/arm/arm-fixed.md b/gcc/config/arm/arm-fixed.md
new file mode 100644
index 0000000..b19745e
--- /dev/null
+++ b/gcc/config/arm/arm-fixed.md
@@ -0,0 +1,402 @@ 
+;; Copyright 2011 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+;;
+;; This file contains ARM instructions that support fixed-point operations.
+
+(define_mode_iterator FIXED [QQ HQ SQ UQQ UHQ USQ HA SA UHA USA])
+
+(define_mode_iterator ADDSUB [V4QQ V2HQ V2HA])
+
+(define_mode_iterator UQADDSUB [V4UQQ V2UHQ UQQ UHQ V2UHA UHA])
+
+(define_mode_iterator QADDSUB [V4QQ V2HQ QQ HQ V2HA HA SQ SA])
+
+(define_mode_iterator QMUL [HQ HA])
+
+(define_mode_attr qaddsub_suf [(V4UQQ "8") (V2UHQ "16") (UQQ "8") (UHQ "16")
+			       (V2UHA "16") (UHA "16")
+			       (V4QQ "8") (V2HQ "16") (QQ "8") (HQ "16")
+			       (V2HA "16") (HA "16") (SQ "") (SA "")])
+
+(define_insn "add<mode>3"
+  [(set (match_operand:FIXED 0 "s_register_operand" "=r")
+	(plus:FIXED (match_operand:FIXED 1 "s_register_operand" "r")
+		    (match_operand:FIXED 2 "s_register_operand" "r")))]
+  "TARGET_32BIT"
+  "add%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")])
+
+(define_insn "add<mode>3"
+  [(set (match_operand:ADDSUB 0 "s_register_operand" "=r")
+	(plus:ADDSUB (match_operand:ADDSUB 1 "s_register_operand" "r")
+		     (match_operand:ADDSUB 2 "s_register_operand" "r")))]
+  "TARGET_INT_SIMD"
+  "sadd<qaddsub_suf>%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")])
+
+(define_insn "usadd<mode>3"
+  [(set (match_operand:UQADDSUB 0 "s_register_operand" "=r")
+	(us_plus:UQADDSUB (match_operand:UQADDSUB 1 "s_register_operand" "r")
+			  (match_operand:UQADDSUB 2 "s_register_operand" "r")))]
+  "TARGET_INT_SIMD"
+  "uqadd<qaddsub_suf>%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")])
+
+(define_insn "ssadd<mode>3"
+  [(set (match_operand:QADDSUB 0 "s_register_operand" "=r")
+	(ss_plus:QADDSUB (match_operand:QADDSUB 1 "s_register_operand" "r")
+			 (match_operand:QADDSUB 2 "s_register_operand" "r")))]
+  "TARGET_INT_SIMD"
+  "qadd<qaddsub_suf>%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")])
+
+(define_insn "sub<mode>3"
+  [(set (match_operand:FIXED 0 "s_register_operand" "=r")
+	(minus:FIXED (match_operand:FIXED 1 "s_register_operand" "r")
+		     (match_operand:FIXED 2 "s_register_operand" "r")))]
+  "TARGET_32BIT"
+  "sub%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")])
+
+(define_insn "sub<mode>3"
+  [(set (match_operand:ADDSUB 0 "s_register_operand" "=r")
+	(minus:ADDSUB (match_operand:ADDSUB 1 "s_register_operand" "r")
+		      (match_operand:ADDSUB 2 "s_register_operand" "r")))]
+  "TARGET_INT_SIMD"
+  "ssub<qaddsub_suf>%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")])
+
+(define_insn "ussub<mode>3"
+  [(set (match_operand:UQADDSUB 0 "s_register_operand" "=r")
+	(us_minus:UQADDSUB
+	  (match_operand:UQADDSUB 1 "s_register_operand" "r")
+	  (match_operand:UQADDSUB 2 "s_register_operand" "r")))]
+  "TARGET_INT_SIMD"
+  "uqsub<qaddsub_suf>%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")])
+
+(define_insn "sssub<mode>3"
+  [(set (match_operand:QADDSUB 0 "s_register_operand" "=r")
+	(ss_minus:QADDSUB (match_operand:QADDSUB 1 "s_register_operand" "r")
+			  (match_operand:QADDSUB 2 "s_register_operand" "r")))]
+  "TARGET_INT_SIMD"
+  "qsub<qaddsub_suf>%?\\t%0, %1, %2"
+  [(set_attr "predicable" "yes")])
+
+;; Fractional multiplies.
+
+; Note: none of these do any rounding.
+
+(define_expand "mulqq3"
+  [(set (match_operand:QQ 0 "s_register_operand" "")
+	(mult:QQ (match_operand:QQ 1 "s_register_operand" "")
+		 (match_operand:QQ 2 "s_register_operand" "")))]
+  "TARGET_DSP_MULTIPLY && arm_arch_thumb2"
+{
+  rtx tmp1 = gen_reg_rtx (HImode);
+  rtx tmp2 = gen_reg_rtx (HImode);
+  rtx tmp3 = gen_reg_rtx (SImode);
+  
+  emit_insn (gen_extendqihi2 (tmp1, gen_lowpart (QImode, operands[1])));
+  emit_insn (gen_extendqihi2 (tmp2, gen_lowpart (QImode, operands[2])));
+  emit_insn (gen_mulhisi3 (tmp3, tmp1, tmp2));
+  emit_insn (gen_extv (gen_lowpart (SImode, operands[0]), tmp3, GEN_INT (8),
+		       GEN_INT (7)));
+  DONE;
+})
+
+(define_expand "mulhq3"
+  [(set (match_operand:HQ 0 "s_register_operand" "")
+	(mult:HQ (match_operand:HQ 1 "s_register_operand" "")
+		 (match_operand:HQ 2 "s_register_operand" "")))]
+  "TARGET_DSP_MULTIPLY && arm_arch_thumb2"
+{
+  rtx tmp = gen_reg_rtx (SImode);
+
+  emit_insn (gen_mulhisi3 (tmp, gen_lowpart (HImode, operands[1]),
+			   gen_lowpart (HImode, operands[2])));
+  /* We're doing a s.15 * s.15 multiplication, getting an s.30 result.  Extract
+     an s.15 value from that.  This won't overflow/saturate for _Fract
+     values.  */
+  emit_insn (gen_extv (gen_lowpart (SImode, operands[0]), tmp,
+		       GEN_INT (16), GEN_INT (15)));
+  DONE;
+})
+
+(define_expand "mulsq3"
+  [(set (match_operand:SQ 0 "s_register_operand" "")
+	(mult:SQ (match_operand:SQ 1 "s_register_operand" "")
+		 (match_operand:SQ 2 "s_register_operand" "")))]
+  "TARGET_32BIT && arm_arch3m"
+{
+  rtx tmp1 = gen_reg_rtx (DImode);
+  rtx tmp2 = gen_reg_rtx (SImode);
+  rtx tmp3 = gen_reg_rtx (SImode);
+  
+  /* s.31 * s.31 -> s.62 multiplication.  */
+  emit_insn (gen_mulsidi3 (tmp1, gen_lowpart (SImode, operands[1]),
+			   gen_lowpart (SImode, operands[2])));
+  emit_insn (gen_lshrsi3 (tmp2, gen_lowpart (SImode, tmp1), GEN_INT (31)));
+  emit_insn (gen_ashlsi3 (tmp3, simplify_gen_subreg (SImode, tmp1, DImode, 4),
+			  GEN_INT (1)));
+  emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]), tmp2, tmp3));
+
+  DONE;
+})
+
+;; Accumulator multiplies.
+
+(define_expand "mulsa3"
+  [(set (match_operand:SA 0 "s_register_operand" "")
+	(mult:SA (match_operand:SA 1 "s_register_operand" "")
+		 (match_operand:SA 2 "s_register_operand" "")))]
+  "TARGET_32BIT && arm_arch3m"
+{
+  rtx tmp1 = gen_reg_rtx (DImode);
+  rtx tmp2 = gen_reg_rtx (SImode);
+  rtx tmp3 = gen_reg_rtx (SImode);
+  
+  emit_insn (gen_mulsidi3 (tmp1, gen_lowpart (SImode, operands[1]),
+			   gen_lowpart (SImode, operands[2])));
+  emit_insn (gen_lshrsi3 (tmp2, gen_lowpart (SImode, tmp1), GEN_INT (15)));
+  emit_insn (gen_ashlsi3 (tmp3, simplify_gen_subreg (SImode, tmp1, DImode, 4),
+			  GEN_INT (17)));
+  emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]), tmp2, tmp3));
+
+  DONE;
+})
+
+(define_expand "mulusa3"
+  [(set (match_operand:USA 0 "s_register_operand" "")
+	(mult:USA (match_operand:USA 1 "s_register_operand" "")
+		  (match_operand:USA 2 "s_register_operand" "")))]
+  "TARGET_32BIT && arm_arch3m"
+{
+  rtx tmp1 = gen_reg_rtx (DImode);
+  rtx tmp2 = gen_reg_rtx (SImode);
+  rtx tmp3 = gen_reg_rtx (SImode);
+  
+  emit_insn (gen_umulsidi3 (tmp1, gen_lowpart (SImode, operands[1]),
+			    gen_lowpart (SImode, operands[2])));
+  emit_insn (gen_lshrsi3 (tmp2, gen_lowpart (SImode, tmp1), GEN_INT (16)));
+  emit_insn (gen_ashlsi3 (tmp3, simplify_gen_subreg (SImode, tmp1, DImode, 4),
+			  GEN_INT (16)));
+  emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]), tmp2, tmp3));
+  
+  DONE;
+})
+
+;; The code sequence emitted by this insn pattern uses the Q flag, which GCC
+;; doesn't generally know about, so we don't bother expanding to individual
+;; instructions.  It may be better to just use an out-of-line asm libcall for
+;; this.
+
+(define_insn "ssmulsa3"
+  [(set (match_operand:SA 0 "s_register_operand" "=r")
+	(ss_mult:SA (match_operand:SA 1 "s_register_operand" "r")
+		    (match_operand:SA 2 "s_register_operand" "r")))
+   (clobber (match_scratch:DI 3 "=r"))
+   (clobber (match_scratch:SI 4 "=r"))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_32BIT && arm_arch6"
+{
+  /* s16.15 * s16.15 -> s32.30.  */
+  output_asm_insn ("smull\\t%Q3, %R3, %1, %2", operands);
+
+  if (TARGET_ARM)
+    output_asm_insn ("msr\\tAPSR_nzcvq, #0", operands);
+  else
+    {
+      output_asm_insn ("mov\\t%4, #0", operands);
+      output_asm_insn ("msr\\tAPSR_nzcvq, %4", operands);
+    }
+
+  /* We have:
+      31  high word  0     31  low word  0 
+
+    [ S i i .... i i i ] [ i f f f ... f f ]
+                        |
+			v
+	     [ S i ... i f ... f f ]
+
+    Need 16 integral bits, so saturate at 15th bit of high word.  */
+
+  output_asm_insn ("ssat\\t%R3, #15, %R3", operands);
+  output_asm_insn ("mrs\\t%4, APSR", operands);
+  output_asm_insn ("tst\\t%4, #1<<27", operands);
+  if (TARGET_THUMB2)
+    output_asm_insn ("it\\tne", operands);
+  output_asm_insn ("mvnne\\t%Q3, %R3, asr #32", operands);
+  output_asm_insn ("mov\\t%0, %Q3, lsr #15", operands);
+  output_asm_insn ("orr\\t%0, %0, %R3, asl #17", operands);
+  return "";
+}
+  [(set_attr "conds" "clob")
+   (set (attr "length")
+	(if_then_else (eq_attr "is_thumb" "yes")
+		      (const_int 38)
+		      (const_int 32)))])
+
+;; Same goes for this.
+
+(define_insn "usmulusa3"
+  [(set (match_operand:USA 0 "s_register_operand" "=r")
+	(us_mult:USA (match_operand:USA 1 "s_register_operand" "r")
+		     (match_operand:USA 2 "s_register_operand" "r")))
+   (clobber (match_scratch:DI 3 "=r"))
+   (clobber (match_scratch:SI 4 "=r"))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_32BIT && arm_arch6"
+{
+  /* 16.16 * 16.16 -> 32.32.  */
+  output_asm_insn ("umull\\t%Q3, %R3, %1, %2", operands);
+
+  if (TARGET_ARM)
+    output_asm_insn ("msr\\tAPSR_nzcvq, #0", operands);
+  else
+    {
+      output_asm_insn ("mov\\t%4, #0", operands);
+      output_asm_insn ("msr\\tAPSR_nzcvq, %4", operands);
+    }
+
+  /* We have:
+      31  high word  0     31  low word  0 
+
+    [ i i i .... i i i ] [ f f f f ... f f ]
+                        |
+			v
+	     [ i i ... i f ... f f ]
+
+    Need 16 integral bits, so saturate at 16th bit of high word.  */
+
+  output_asm_insn ("usat\\t%R3, #16, %R3", operands);
+  output_asm_insn ("mrs\\t%4, APSR", operands);
+  output_asm_insn ("tst\\t%4, #1<<27", operands);
+  if (TARGET_THUMB2)
+    output_asm_insn ("it\\tne", operands);
+  output_asm_insn ("sbfxne\\t%Q3, %R3, #15, #1", operands);
+  output_asm_insn ("lsr\\t%0, %Q3, #16", operands);
+  output_asm_insn ("orr\\t%0, %0, %R3, asl #16", operands);
+  return "";
+}
+  [(set_attr "conds" "clob")
+   (set (attr "length")
+	(if_then_else (eq_attr "is_thumb" "yes")
+		      (const_int 38)
+		      (const_int 32)))])
+
+(define_expand "mulha3"
+  [(set (match_operand:HA 0 "s_register_operand" "")
+	(mult:HA (match_operand:HA 1 "s_register_operand" "")
+		 (match_operand:HA 2 "s_register_operand" "")))]
+  "TARGET_DSP_MULTIPLY && arm_arch_thumb2"
+{
+  rtx tmp = gen_reg_rtx (SImode);
+  
+  emit_insn (gen_mulhisi3 (tmp, gen_lowpart (HImode, operands[1]),
+			   gen_lowpart (HImode, operands[2])));
+  emit_insn (gen_extv (gen_lowpart (SImode, operands[0]), tmp, GEN_INT (16),
+		       GEN_INT (7)));
+
+  DONE;
+})
+
+(define_expand "muluha3"
+  [(set (match_operand:UHA 0 "s_register_operand" "")
+	(mult:UHA (match_operand:UHA 1 "s_register_operand" "")
+		  (match_operand:UHA 2 "s_register_operand" "")))]
+  "TARGET_DSP_MULTIPLY"
+{
+  rtx tmp1 = gen_reg_rtx (SImode);
+  rtx tmp2 = gen_reg_rtx (SImode);
+  rtx tmp3 = gen_reg_rtx (SImode);
+  
+  /* 8.8 * 8.8 -> 16.16 multiply.  */
+  emit_insn (gen_zero_extendhisi2 (tmp1, gen_lowpart (HImode, operands[1])));
+  emit_insn (gen_zero_extendhisi2 (tmp2, gen_lowpart (HImode, operands[2])));
+  emit_insn (gen_mulsi3 (tmp3, tmp1, tmp2));
+  emit_insn (gen_extzv (gen_lowpart (SImode, operands[0]), tmp3,
+			GEN_INT (16), GEN_INT (8)));
+
+  DONE;
+})
+
+(define_expand "ssmulha3"
+  [(set (match_operand:HA 0 "s_register_operand" "")
+	(ss_mult:HA (match_operand:HA 1 "s_register_operand" "")
+		    (match_operand:HA 2 "s_register_operand" "")))]
+  "TARGET_32BIT && arm_arch6"
+{
+  rtx tmp = gen_reg_rtx (SImode);
+  rtx rshift;
+  
+  emit_insn (gen_mulhisi3 (tmp, gen_lowpart (HImode, operands[1]),
+			   gen_lowpart (HImode, operands[2])));
+
+  rshift = gen_rtx_ASHIFTRT (SImode, tmp, GEN_INT (7));
+
+  emit_insn (gen_rtx_SET (VOIDmode, gen_lowpart (HImode, operands[0]),
+			  gen_rtx_SS_TRUNCATE (HImode, rshift)));
+
+  DONE;
+})
+
+(define_expand "usmuluha3"
+  [(set (match_operand:UHA 0 "s_register_operand" "")
+	(us_mult:UHA (match_operand:UHA 1 "s_register_operand" "")
+		     (match_operand:UHA 2 "s_register_operand" "")))]
+  "TARGET_32BIT && arm_arch6"
+{
+  rtx tmp1 = gen_reg_rtx (SImode);
+  rtx tmp2 = gen_reg_rtx (SImode);
+  rtx tmp3 = gen_reg_rtx (SImode);
+  rtx rshift_tmp = gen_reg_rtx (SImode);
+  
+  /* Note: there's no smul[bt][bt] equivalent for unsigned multiplies.  Use a
+     normal 32x32->32-bit multiply instead.  */
+  emit_insn (gen_zero_extendhisi2 (tmp1, gen_lowpart (HImode, operands[1])));
+  emit_insn (gen_zero_extendhisi2 (tmp2, gen_lowpart (HImode, operands[2])));
+  
+  emit_insn (gen_mulsi3 (tmp3, tmp1, tmp2));
+
+  /* The operand to "usat" is signed, so we cannot use the "..., asr #8"
+     form of that instruction since the multiplication result TMP3 may have the
+     top bit set, thus be negative and saturate to zero.  Use a separate
+     logical right-shift instead.  */
+  emit_insn (gen_lshrsi3 (rshift_tmp, tmp3, GEN_INT (8)));
+  emit_insn (gen_arm_usatsihi (gen_lowpart (HImode, operands[0]), rshift_tmp));
+
+  DONE;
+})
+
+(define_insn "arm_ssatsihi_shift"
+  [(set (match_operand:HI 0 "s_register_operand" "=r")
+	(ss_truncate:HI (match_operator:SI 1 "sat_shift_operator"
+			  [(match_operand:SI 2 "s_register_operand" "r")
+			   (match_operand:SI 3 "immediate_operand" "I")])))]
+  "TARGET_32BIT && arm_arch6"
+  "ssat%?\\t%0, #16, %2%S1"
+  [(set_attr "predicable" "yes")
+   (set_attr "type" "alu_shift")])
+
+(define_insn "arm_usatsihi"
+  [(set (match_operand:HI 0 "s_register_operand" "=r")
+	(us_truncate:HI (match_operand:SI 1 "s_register_operand")))]
+  "TARGET_INT_SIMD"
+  "usat%?\\t%0, #16, %1"
+  [(set_attr "predicable" "yes")])
diff --git a/gcc/config/arm/arm-modes.def b/gcc/config/arm/arm-modes.def
index 24e3d90..7f19ebe 100644
--- a/gcc/config/arm/arm-modes.def
+++ b/gcc/config/arm/arm-modes.def
@@ -70,6 +70,12 @@  VECTOR_MODES (INT, 16);       /* V16QI V8HI V4SI V2DI */
 VECTOR_MODES (FLOAT, 8);      /*            V4HF V2SF */
 VECTOR_MODES (FLOAT, 16);     /*       V8HF V4SF V2DF */
 
+/* Fraction and accumulator vector modes.  */
+VECTOR_MODES (FRACT, 4);      /* V4QQ  V2HQ */
+VECTOR_MODES (UFRACT, 4);     /* V4UQQ V2UHQ */
+VECTOR_MODES (ACCUM, 4);      /*       V2HA */
+VECTOR_MODES (UACCUM, 4);     /*       V2UHA */
+
 /* Opaque integer modes for 3, 4, 6 or 8 Neon double registers (2 is
    TImode).  */
 INT_MODE (EI, 24);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 4f9c2aa..aa725bb 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -255,6 +255,7 @@  static bool arm_builtin_support_vector_misalignment (enum machine_mode mode,
 static void arm_conditional_register_usage (void);
 static reg_class_t arm_preferred_rename_class (reg_class_t rclass);
 static unsigned int arm_autovectorize_vector_sizes (void);
+static bool arm_fixed_point_supported_p (void);
 
 
 /* Table of machine attributes.  */
@@ -609,6 +610,10 @@  static const struct default_options arm_option_optimization_table[] =
 #define TARGET_PREFERRED_RENAME_CLASS \
   arm_preferred_rename_class
 
+#undef TARGET_FIXED_POINT_SUPPORTED_P
+#define TARGET_FIXED_POINT_SUPPORTED_P \
+  arm_fixed_point_supported_p
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Obstack for minipool constant handling.  */
@@ -1068,6 +1073,49 @@  bit_count (unsigned long value)
   return count;
 }
 
+typedef struct
+{
+  enum machine_mode mode;
+  const char *name;
+} arm_fixed_mode_set;
+
+/* A small helper for setting fixed-point library libfuncs.  */
+
+static void
+arm_set_fixed_optab_libfunc (optab optable, enum machine_mode mode,
+			     const char *funcname, const char *modename,
+			     int num_suffix)
+{
+  char buffer[50];
+  
+  if (num_suffix == 0)
+    sprintf (buffer, "__gnu_%s%s", funcname, modename);
+  else
+    sprintf (buffer, "__gnu_%s%s%d", funcname, modename, num_suffix);
+  
+  set_optab_libfunc (optable, mode, buffer);
+}
+
+static void
+arm_set_fixed_conv_libfunc (convert_optab optable, enum machine_mode to,
+			    enum machine_mode from, const char *funcname,
+			    const char *toname, const char *fromname)
+{
+  char buffer[50];
+  char *maybe_suffix_2 = "";
+  
+  /* Follow the logic for selecting a "2" suffix in fixed-bit.h.  */
+  if (ALL_FIXED_POINT_MODE_P (from) && ALL_FIXED_POINT_MODE_P (to)
+      && UNSIGNED_FIXED_POINT_MODE_P (from) == UNSIGNED_FIXED_POINT_MODE_P (to)
+      && ALL_FRACT_MODE_P (from) == ALL_FRACT_MODE_P (to))
+    maybe_suffix_2 = "2";
+  
+  sprintf (buffer, "__gnu_%s%s%s%s", funcname, fromname, toname,
+	   maybe_suffix_2);
+
+  set_conv_libfunc (optable, to, from, buffer);
+}
+
 /* Set up library functions unique to ARM.  */
 
 static void
@@ -1213,6 +1261,137 @@  arm_init_libfuncs (void)
       break;
     }
 
+  /* Use names prefixed with __gnu_ for fixed-point helper functions.  */
+  {
+    const arm_fixed_mode_set fixed_arith_modes[] =
+      {
+	{ QQmode, "qq" },
+	{ UQQmode, "uqq" },
+	{ HQmode, "hq" },
+	{ UHQmode, "uhq" },
+	{ SQmode, "sq" },
+	{ USQmode, "usq" },
+	{ DQmode, "dq" },
+	{ UDQmode, "udq" },
+	{ TQmode, "tq" },
+	{ UTQmode, "utq" },
+	{ HAmode, "ha" },
+	{ UHAmode, "uha" },
+	{ SAmode, "sa" },
+	{ USAmode, "usa" },
+	{ DAmode, "da" },
+	{ UDAmode, "uda" },
+	{ TAmode, "ta" },
+	{ UTAmode, "uta" }
+      };
+    const arm_fixed_mode_set fixed_conv_modes[] =
+      {
+	{ QQmode, "qq" },
+	{ UQQmode, "uqq" },
+	{ HQmode, "hq" },
+	{ UHQmode, "uhq" },
+	{ SQmode, "sq" },
+	{ USQmode, "usq" },
+	{ DQmode, "dq" },
+	{ UDQmode, "udq" },
+	{ TQmode, "tq" },
+	{ UTQmode, "utq" },
+	{ HAmode, "ha" },
+	{ UHAmode, "uha" },
+	{ SAmode, "sa" },
+	{ USAmode, "usa" },
+	{ DAmode, "da" },
+	{ UDAmode, "uda" },
+	{ TAmode, "ta" },
+	{ UTAmode, "uta" },
+	{ QImode, "qi" },
+	{ HImode, "hi" },
+	{ SImode, "si" },
+	{ DImode, "di" },
+	{ TImode, "ti" },
+	{ SFmode, "sf" },
+	{ DFmode, "df" }
+      };
+    unsigned int i, j;
+
+    for (i = 0; i < ARRAY_SIZE (fixed_arith_modes); i++)
+      {
+	arm_set_fixed_optab_libfunc (add_optab, fixed_arith_modes[i].mode,
+				     "add", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (ssadd_optab, fixed_arith_modes[i].mode,
+				     "ssadd", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (usadd_optab, fixed_arith_modes[i].mode,
+				     "usadd", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (sub_optab, fixed_arith_modes[i].mode,
+				     "sub", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (sssub_optab, fixed_arith_modes[i].mode,
+				     "sssub", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (ussub_optab, fixed_arith_modes[i].mode,
+				     "ussub", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (smul_optab, fixed_arith_modes[i].mode,
+				     "mul", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (ssmul_optab, fixed_arith_modes[i].mode,
+				     "ssmul", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (usmul_optab, fixed_arith_modes[i].mode,
+				     "usmul", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (sdiv_optab, fixed_arith_modes[i].mode,
+				     "div", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (udiv_optab, fixed_arith_modes[i].mode,
+				     "udiv", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (ssdiv_optab, fixed_arith_modes[i].mode,
+				     "ssdiv", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (usdiv_optab, fixed_arith_modes[i].mode,
+				     "usdiv", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (neg_optab, fixed_arith_modes[i].mode,
+				     "neg", fixed_arith_modes[i].name, 2);
+	arm_set_fixed_optab_libfunc (ssneg_optab, fixed_arith_modes[i].mode,
+				     "ssneg", fixed_arith_modes[i].name, 2);
+	arm_set_fixed_optab_libfunc (usneg_optab, fixed_arith_modes[i].mode,
+				     "usneg", fixed_arith_modes[i].name, 2);
+	arm_set_fixed_optab_libfunc (ashl_optab, fixed_arith_modes[i].mode,
+				     "ashl", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (ashr_optab, fixed_arith_modes[i].mode,
+				     "ashr", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (lshr_optab, fixed_arith_modes[i].mode,
+				     "lshr", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (ssashl_optab, fixed_arith_modes[i].mode,
+				     "ssashl", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (usashl_optab, fixed_arith_modes[i].mode,
+				     "usashl", fixed_arith_modes[i].name, 3);
+	arm_set_fixed_optab_libfunc (cmp_optab, fixed_arith_modes[i].mode,
+				     "cmp", fixed_arith_modes[i].name, 2);
+      }
+
+    for (i = 0; i < ARRAY_SIZE (fixed_conv_modes); i++)
+      for (j = 0; j < ARRAY_SIZE (fixed_conv_modes); j++)
+	{
+	  if (i == j
+	      || (!ALL_FIXED_POINT_MODE_P (fixed_conv_modes[i].mode)
+		  && !ALL_FIXED_POINT_MODE_P (fixed_conv_modes[j].mode)))
+	    continue;
+
+	  arm_set_fixed_conv_libfunc (fract_optab, fixed_conv_modes[i].mode,
+				      fixed_conv_modes[j].mode, "fract",
+				      fixed_conv_modes[i].name,
+				      fixed_conv_modes[j].name);
+	  arm_set_fixed_conv_libfunc (satfract_optab,
+				      fixed_conv_modes[i].mode,
+				      fixed_conv_modes[j].mode, "satfract",
+				      fixed_conv_modes[i].name,
+				      fixed_conv_modes[j].name);
+	  arm_set_fixed_conv_libfunc (fractuns_optab,
+				      fixed_conv_modes[i].mode,
+				      fixed_conv_modes[j].mode, "fractuns",
+				      fixed_conv_modes[i].name,
+				      fixed_conv_modes[j].name);
+	  arm_set_fixed_conv_libfunc (satfractuns_optab,
+				      fixed_conv_modes[i].mode,
+				      fixed_conv_modes[j].mode, "satfractuns",
+				      fixed_conv_modes[i].name,
+				      fixed_conv_modes[j].name);
+	}
+  }
+
   if (TARGET_AAPCS_BASED)
     synchronize_libfunc = init_one_libfunc ("__sync_synchronize");
 }
@@ -19333,6 +19512,12 @@  arm_scalar_mode_supported_p (enum machine_mode mode)
 {
   if (mode == HFmode)
     return (arm_fp16_format != ARM_FP16_FORMAT_NONE);
+  else if (mode == QQmode || mode == HQmode || mode == SQmode
+	   || mode == UQQmode || mode == UHQmode || mode == USQmode
+	   || mode == HAmode || mode == SAmode || mode == UHAmode
+	   || mode == USAmode || mode == DQmode || mode == UDQmode
+	   || mode == DAmode || mode == UDAmode)
+    return true;
   else
     return default_scalar_mode_supported_p (mode);
 }
@@ -22454,6 +22639,11 @@  arm_vector_mode_supported_p (enum machine_mode mode)
 	  || (mode == V8QImode)))
     return true;
 
+  if (TARGET_INT_SIMD && (mode == V4UQQmode || mode == V4QQmode
+      || mode == V2UHQmode || mode == V2HQmode || mode == V2UHAmode
+      || mode == V2HAmode))
+    return true;
+
   return false;
 }
 
@@ -23904,4 +24094,17 @@  arm_attr_length_push_multi(rtx parallel_op, rtx first_op)
   return 4;
 }
 
+/* Return TRUE if fixed-point operations are supported.  */
+
+bool
+arm_fixed_point_supported_p (void)
+{
+  /* At least some operations helpful for fixed-point support are available
+     from arch3m onwards -- 32 bit x 32 bit -> 64 bit multiplies.  There's not
+     much point in arbitrarily restricting fixed-point support to particular
+     architecture versions though since gaps can be filled by libcalls, so
+     return TRUE unconditionally.  */
+  return true;
+}
+
 #include "gt-arm.h"
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 40ebf35..8a1dd76 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -10751,3 +10751,5 @@ 
 (include "neon.md")
 ;; Synchronization Primitives
 (include "sync.md")
+;; Fixed-point patterns
+(include "arm-fixed.md")
diff --git a/gcc/config/arm/fixed-bit-machine.h b/gcc/config/arm/fixed-bit-machine.h
new file mode 100644
index 0000000..c7ce8ec
--- /dev/null
+++ b/gcc/config/arm/fixed-bit-machine.h
@@ -0,0 +1,29 @@ 
+/* Machine-specific override for fixed-point support routine names.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* To be EABI-compliant (until the EABI supports fixed-point functionality),
+   use the __gnu_ namespace for fixed-point helper functions.  */
+
+#ifdef __ARM_EABI__
+#define DECORATE_FIXED_NAME(X) __gnu_ ## X
+#endif
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 891a974..f1800dc 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -227,6 +227,13 @@ 
 	    (match_code "ashift,ashiftrt,lshiftrt,rotatert"))
        (match_test "mode == GET_MODE (op)")))
 
+;; True for shift operators which can be used with saturation instructions.
+(define_special_predicate "sat_shift_operator"
+  (and (match_code "ashift,ashiftrt")
+       (match_test "GET_CODE (XEXP (op, 1)) == CONST_INT
+		    && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1)) <= 32)")
+       (match_test "mode == GET_MODE (op)")))
+
 ;; True for MULT, to identify which variant of shift_operator is in use.
 (define_special_predicate "mult_operator"
   (match_code "mult"))
diff --git a/gcc/config/fixed-bit-mach-generic.h b/gcc/config/fixed-bit-mach-generic.h
new file mode 100644
index 0000000..c25f0a5
--- /dev/null
+++ b/gcc/config/fixed-bit-mach-generic.h
@@ -0,0 +1,22 @@ 
+/* Null machine-specific override for fixed-point support routine names.
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
diff --git a/gcc/config/fixed-bit.h b/gcc/config/fixed-bit.h
index 562772d..1cce4ef 100644
--- a/gcc/config/fixed-bit.h
+++ b/gcc/config/fixed-bit.h
@@ -25,6 +25,13 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #ifndef _FIXED_BIT_H
 #define _FIXED_BIT_H
 
+#include "fixed-bit-machine.h"
+
+/* This macro may be overridden for a given target in fixed-bit-machine.h.  */
+#ifndef DECORATE_FIXED_NAME
+#define DECORATE_FIXED_NAME(X) __ ## X
+#endif
+
 /* To use this file we need to define one of the following:
    QQ_MODE, UQQ_MODE, HQ_MODE, UHQ_MODE, SQ_MODE, USQ_MODE, DQ_MODE, UDQ_MODE,
    TQ_MODE, UTQ_MODE, HA_MODE, UHA_MODE, SA_MODE, USA_MODE, DA_MODE, UDA_MODE,
@@ -445,35 +452,37 @@  typedef union
 #define IBITS		IBITS2(MODE_NAME)
 #define I_F_BITS	(FBITS + IBITS)
 
-#define FIXED_OP(OP,MODE,NUM)	OP ## MODE ## NUM
-
-#define FIXED_SATURATE1_TEMP(NAME)	FIXED_OP(__saturate1,NAME,)
-#define FIXED_SATURATE2_TEMP(NAME)	FIXED_OP(__saturate2,NAME,)
-#define FIXED_MULHELPER_TEMP(NAME)	FIXED_OP(__mulhelper,NAME,)
-#define FIXED_DIVHELPER_TEMP(NAME)	FIXED_OP(__divhelper,NAME,)
-#define FIXED_ASHLHELPER_TEMP(NAME)	FIXED_OP(__ashlhelper,NAME,)
-#define FIXED_ADD_TEMP(NAME)	FIXED_OP(__add,NAME,3)
-#define FIXED_SSADD_TEMP(NAME)	FIXED_OP(__ssadd,NAME,3)
-#define FIXED_USADD_TEMP(NAME)	FIXED_OP(__usadd,NAME,3)
-#define FIXED_SUB_TEMP(NAME)	FIXED_OP(__sub,NAME,3)
-#define FIXED_SSSUB_TEMP(NAME)	FIXED_OP(__sssub,NAME,3)
-#define FIXED_USSUB_TEMP(NAME)	FIXED_OP(__ussub,NAME,3)
-#define FIXED_MUL_TEMP(NAME)	FIXED_OP(__mul,NAME,3)
-#define FIXED_SSMUL_TEMP(NAME)	FIXED_OP(__ssmul,NAME,3)
-#define FIXED_USMUL_TEMP(NAME)	FIXED_OP(__usmul,NAME,3)
-#define FIXED_DIV_TEMP(NAME)	FIXED_OP(__div,NAME,3)
-#define FIXED_UDIV_TEMP(NAME)	FIXED_OP(__udiv,NAME,3)
-#define FIXED_SSDIV_TEMP(NAME)	FIXED_OP(__ssdiv,NAME,3)
-#define FIXED_USDIV_TEMP(NAME)	FIXED_OP(__usdiv,NAME,3)
-#define FIXED_NEG_TEMP(NAME)	FIXED_OP(__neg,NAME,2)
-#define FIXED_SSNEG_TEMP(NAME)	FIXED_OP(__ssneg,NAME,2)
-#define FIXED_USNEG_TEMP(NAME)	FIXED_OP(__usneg,NAME,2)
-#define FIXED_ASHL_TEMP(NAME)	FIXED_OP(__ashl,NAME,3)
-#define FIXED_ASHR_TEMP(NAME)	FIXED_OP(__ashr,NAME,3)
-#define FIXED_LSHR_TEMP(NAME)	FIXED_OP(__lshr,NAME,3)
-#define FIXED_SSASHL_TEMP(NAME)	FIXED_OP(__ssashl,NAME,3)
-#define FIXED_USASHL_TEMP(NAME)	FIXED_OP(__usashl,NAME,3)
-#define FIXED_CMP_TEMP(NAME)	FIXED_OP(__cmp,NAME,2)
+#define FIXED_OP3(OP,MODE,NUM)	OP ## MODE ## NUM
+#define FIXED_OP2(OP,MODE,NUM)	FIXED_OP3 (OP, MODE, NUM)
+#define FIXED_OP(OP,MODE,NUM)	FIXED_OP2 (DECORATE_FIXED_NAME (OP), MODE, NUM)
+
+#define FIXED_SATURATE1_TEMP(NAME)	FIXED_OP(saturate1,NAME,)
+#define FIXED_SATURATE2_TEMP(NAME)	FIXED_OP(saturate2,NAME,)
+#define FIXED_MULHELPER_TEMP(NAME)	FIXED_OP(mulhelper,NAME,)
+#define FIXED_DIVHELPER_TEMP(NAME)	FIXED_OP(divhelper,NAME,)
+#define FIXED_ASHLHELPER_TEMP(NAME)	FIXED_OP(ashlhelper,NAME,)
+#define FIXED_ADD_TEMP(NAME)	FIXED_OP(add,NAME,3)
+#define FIXED_SSADD_TEMP(NAME)	FIXED_OP(ssadd,NAME,3)
+#define FIXED_USADD_TEMP(NAME)	FIXED_OP(usadd,NAME,3)
+#define FIXED_SUB_TEMP(NAME)	FIXED_OP(sub,NAME,3)
+#define FIXED_SSSUB_TEMP(NAME)	FIXED_OP(sssub,NAME,3)
+#define FIXED_USSUB_TEMP(NAME)	FIXED_OP(ussub,NAME,3)
+#define FIXED_MUL_TEMP(NAME)	FIXED_OP(mul,NAME,3)
+#define FIXED_SSMUL_TEMP(NAME)	FIXED_OP(ssmul,NAME,3)
+#define FIXED_USMUL_TEMP(NAME)	FIXED_OP(usmul,NAME,3)
+#define FIXED_DIV_TEMP(NAME)	FIXED_OP(div,NAME,3)
+#define FIXED_UDIV_TEMP(NAME)	FIXED_OP(udiv,NAME,3)
+#define FIXED_SSDIV_TEMP(NAME)	FIXED_OP(ssdiv,NAME,3)
+#define FIXED_USDIV_TEMP(NAME)	FIXED_OP(usdiv,NAME,3)
+#define FIXED_NEG_TEMP(NAME)	FIXED_OP(neg,NAME,2)
+#define FIXED_SSNEG_TEMP(NAME)	FIXED_OP(ssneg,NAME,2)
+#define FIXED_USNEG_TEMP(NAME)	FIXED_OP(usneg,NAME,2)
+#define FIXED_ASHL_TEMP(NAME)	FIXED_OP(ashl,NAME,3)
+#define FIXED_ASHR_TEMP(NAME)	FIXED_OP(ashr,NAME,3)
+#define FIXED_LSHR_TEMP(NAME)	FIXED_OP(lshr,NAME,3)
+#define FIXED_SSASHL_TEMP(NAME)	FIXED_OP(ssashl,NAME,3)
+#define FIXED_USASHL_TEMP(NAME)	FIXED_OP(usashl,NAME,3)
+#define FIXED_CMP_TEMP(NAME)	FIXED_OP(cmp,NAME,2)
 
 #if defined (MODE_NAME)
 #if defined (DINT_C_TYPE)
@@ -1146,14 +1155,22 @@  extern FIXED_C_TYPE FIXED_USASHL (FIXED_C_TYPE, word_type);
 #define TO_HAVE_PADDING_BITS	(TO_PADDING_BITS > 0)
 #endif /* TO_TYPE == 4  */
 
-#define FIXED_CONVERT_OP(OP,FROM,TO)	OP ## FROM ## TO
-#define FIXED_CONVERT_OP2(OP,FROM,TO)	OP ## FROM ## TO ## 2
-#define FRACT_TEMP(N1,N2)		FIXED_CONVERT_OP(__fract,N1,N2)
-#define FRACT2_TEMP(N1,N2)		FIXED_CONVERT_OP2(__fract,N1,N2)
-#define SATFRACT_TEMP(N1,N2)		FIXED_CONVERT_OP(__satfract,N1,N2)
-#define SATFRACT2_TEMP(N1,N2)		FIXED_CONVERT_OP2(__satfract,N1,N2)
-#define FRACTUNS_TEMP(N1,N2)		FIXED_CONVERT_OP(__fractuns,N1,N2)
-#define SATFRACTUNS_TEMP(N1,N2)		FIXED_CONVERT_OP(__satfractuns,N1,N2)
+#define FIXED_CONVERT_OP_B(OP,FROM,TO)	OP ## FROM ## TO
+#define FIXED_CONVERT_OP_A(OP,FROM,TO)	FIXED_CONVERT_OP_B(OP, FROM, TO)
+#define FIXED_CONVERT_OP(OP,FROM,TO) \
+  FIXED_CONVERT_OP_A (DECORATE_FIXED_NAME (OP), FROM, TO)
+
+#define FIXED_CONVERT_OP2_B(OP,FROM,TO)	OP ## FROM ## TO ## 2
+#define FIXED_CONVERT_OP2_A(OP,FROM,TO)	FIXED_CONVERT_OP2_B (OP, FROM, TO)
+#define FIXED_CONVERT_OP2(OP,FROM,TO) \
+  FIXED_CONVERT_OP2_A (DECORATE_FIXED_NAME (OP), FROM, TO)
+
+#define FRACT_TEMP(N1,N2)		FIXED_CONVERT_OP(fract,N1,N2)
+#define FRACT2_TEMP(N1,N2)		FIXED_CONVERT_OP2(fract,N1,N2)
+#define SATFRACT_TEMP(N1,N2)		FIXED_CONVERT_OP(satfract,N1,N2)
+#define SATFRACT2_TEMP(N1,N2)		FIXED_CONVERT_OP2(satfract,N1,N2)
+#define FRACTUNS_TEMP(N1,N2)		FIXED_CONVERT_OP(fractuns,N1,N2)
+#define SATFRACTUNS_TEMP(N1,N2)		FIXED_CONVERT_OP(satfractuns,N1,N2)
 
 /* Define conversions from fixed-point to fixed-point.  */
 #if FROM_TYPE == 4 && TO_TYPE == 4
diff --git a/gcc/final.c b/gcc/final.c
index 7e1ae90..b147ddf 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -3633,8 +3633,7 @@  output_addr_const (FILE *file, rtx x)
       break;
 
     case CONST_FIXED:
-      fprintf (file, HOST_WIDE_INT_PRINT_HEX,
-	       (unsigned HOST_WIDE_INT) CONST_FIXED_VALUE_LOW (x));
+      fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_FIXED_VALUE_LOW (x));
       break;
 
     case PLUS:
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 62e123b..a1b85b8 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -3930,11 +3930,13 @@  prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
 	 result against 1 in the biased case, and zero in the unbiased
 	 case. For unsigned comparisons always compare against 1 after
 	 biasing the unbiased result by adding 1. This gives us a way to
-	 represent LTU. */
+	 represent LTU.
+	 The comparisons in the fixed-point helper library are always
+	 biased.  */
       x = result;
       y = const1_rtx;
 
-      if (!TARGET_LIB_INT_CMP_BIASED)
+      if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
 	{
 	  if (unsignedp)
 	    x = plus_constant (result, 1);
diff --git a/gcc/testsuite/gcc.dg/fixed-point/allop-const.c b/gcc/testsuite/gcc.dg/fixed-point/allop-const.c
index 1cf8598..fdcb046 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/allop-const.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/allop-const.c
@@ -12,6 +12,8 @@ 
 
    Check if all operations on constants are ok.  */
 
+#include "longlong-support.h"
+
 #define ALLOPCONST(TYPE,NAME,POSTFIX) \
 	TYPE NAME ## plus = +0.1 ## POSTFIX; \
 	unsigned TYPE NAME ## u_plus = +0.1u ## POSTFIX; \
@@ -140,8 +142,8 @@ 
 ALLOPCONST(short _Fract, sf, hr);
 ALLOPCONST(_Fract, f, r);
 ALLOPCONST(long _Fract, lf, lr);
-ALLOPCONST(long long _Fract, llf, llr);
+LLFRACT_TEST (ALLOPCONST(long long _Fract, llf, llr));
 ALLOPCONST(short _Accum, sa, hk);
 ALLOPCONST(_Accum, a, k);
 ALLOPCONST(long _Accum, la, lk);
-ALLOPCONST(long long _Accum, lla, llk);
+LLACCUM_TEST (ALLOPCONST(long long _Accum, lla, llk));
diff --git a/gcc/testsuite/gcc.dg/fixed-point/binary.c b/gcc/testsuite/gcc.dg/fixed-point/binary.c
index e2cb6ea..35d9b56 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/binary.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/binary.c
@@ -11,6 +11,8 @@ 
 
    Check binary operators + - * / << >> < <= >= > == != += -= *= /= <<= >>=.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 
 #define BINARY(TYPE,POSTFIX) \
@@ -114,45 +116,45 @@  int main ()
   BINARY(short _Fract, hr);
   BINARY(_Fract, r);
   BINARY(long _Fract, lr);
-  BINARY(long long _Fract, llr);
+  LLFRACT_TEST (BINARY(long long _Fract, llr));
   BINARY(unsigned short _Fract, uhr);
   BINARY(unsigned _Fract, ur);
   BINARY(unsigned long _Fract, ulr);
-  BINARY(unsigned long long _Fract, ullr);
+  ULLFRACT_TEST (BINARY(unsigned long long _Fract, ullr));
   BINARY(_Sat short _Fract, hr);
   BINARY(_Sat _Fract, r);
   BINARY(_Sat long _Fract, lr);
-  BINARY(_Sat long long _Fract, llr);
+  LLFRACT_TEST (BINARY(_Sat long long _Fract, llr));
   BINARY(_Sat unsigned short _Fract, uhr);
   BINARY(_Sat unsigned _Fract, ur);
   BINARY(_Sat unsigned long _Fract, ulr);
-  BINARY(_Sat unsigned long long _Fract, ullr);
+  ULLFRACT_TEST (BINARY(_Sat unsigned long long _Fract, ullr));
   BINARY(short _Accum, hk);
   BINARY(_Accum, k);
   BINARY(long _Accum, lk);
-  BINARY(long long _Accum, llk);
+  LLACCUM_TEST (BINARY(long long _Accum, llk));
   BINARY(unsigned short _Accum, uhk);
   BINARY(unsigned _Accum, uk);
   BINARY(unsigned long _Accum, ulk);
-  BINARY(unsigned long long _Accum, ullk);
+  ULLACCUM_TEST (BINARY(unsigned long long _Accum, ullk));
   BINARY(_Sat short _Accum, hk);
   BINARY(_Sat _Accum, k);
   BINARY(_Sat long _Accum, lk);
-  BINARY(_Sat long long _Accum, llk);
+  LLACCUM_TEST (BINARY(_Sat long long _Accum, llk));
   BINARY(_Sat unsigned short _Accum, uhk);
   BINARY(_Sat unsigned _Accum, uk);
   BINARY(_Sat unsigned long _Accum, ulk);
-  BINARY(_Sat unsigned long long _Accum, ullk);
+  ULLACCUM_TEST (BINARY(_Sat unsigned long long _Accum, ullk));
 
   FRACT_SAT_BINARY(_Sat short _Fract, hr);
   FRACT_SAT_BINARY(_Sat _Fract, r);
   FRACT_SAT_BINARY(_Sat long _Fract, lr);
-  FRACT_SAT_BINARY(_Sat long long _Fract, llr);
+  LLFRACT_TEST (FRACT_SAT_BINARY(_Sat long long _Fract, llr));
 
   FRACT_SAT_UNS_BINARY(_Sat unsigned short _Fract, uhr);
   FRACT_SAT_UNS_BINARY(_Sat unsigned _Fract, ur);
   FRACT_SAT_UNS_BINARY(_Sat unsigned long _Fract, ulr);
-  FRACT_SAT_UNS_BINARY(_Sat unsigned long long _Fract, ullr);
+  ULLFRACT_TEST (FRACT_SAT_UNS_BINARY(_Sat unsigned long long _Fract, ullr));
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/call-by-value.c b/gcc/testsuite/gcc.dg/fixed-point/call-by-value.c
index 8b9d822..09bef43 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/call-by-value.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/call-by-value.c
@@ -8,6 +8,8 @@ 
 
    This test is copied from gcc.dg/dfp/ and changed for fixed-point types.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 
 #define FOO_FUN(NAME,TYPE,VALUE) \
@@ -27,35 +29,35 @@  int foo ## NAME (TYPE z) \
 FOO_FUN (sf, short _Fract, 0.2hr)
 FOO_FUN (f, _Fract, 0.2r)
 FOO_FUN (lf, long _Fract, 0.2lr)
-FOO_FUN (llf, long long _Fract, 0.2llr)
+LLFRACT_TEST (FOO_FUN (llf, long long _Fract, 0.2llr))
 FOO_FUN (usf, unsigned short _Fract, 0.2uhr)
 FOO_FUN (uf, unsigned _Fract, 0.2ur)
 FOO_FUN (ulf, unsigned long _Fract, 0.2ulr)
-FOO_FUN (ullf, unsigned long long _Fract, 0.2ullr)
+ULLFRACT_TEST (FOO_FUN (ullf, unsigned long long _Fract, 0.2ullr))
 FOO_FUN (Ssf, _Sat short _Fract, 0.2hr)
 FOO_FUN (Sf, _Sat _Fract, 0.2r)
 FOO_FUN (Slf, _Sat long _Fract, 0.2lr)
-FOO_FUN (Sllf, _Sat long long _Fract, 0.2llr)
+LLFRACT_TEST (FOO_FUN (Sllf, _Sat long long _Fract, 0.2llr))
 FOO_FUN (Susf, _Sat unsigned short _Fract, 0.2uhr)
 FOO_FUN (Suf, _Sat unsigned _Fract, 0.2ur)
 FOO_FUN (Sulf, _Sat unsigned long _Fract, 0.2ulr)
-FOO_FUN (Sullf, _Sat unsigned long long _Fract, 0.2ullr)
+ULLFRACT_TEST (FOO_FUN (Sullf, _Sat unsigned long long _Fract, 0.2ullr))
 FOO_FUN (sa, short _Accum, 0.2hk)
 FOO_FUN (a, _Accum, 0.2k)
 FOO_FUN (la, long _Accum, 0.2lk)
-FOO_FUN (lla, long long _Accum, 0.2llk)
+LLACCUM_TEST (FOO_FUN (lla, long long _Accum, 0.2llk))
 FOO_FUN (usa, unsigned short _Accum, 0.2uhk)
 FOO_FUN (ua, unsigned _Accum, 0.2uk)
 FOO_FUN (ula, unsigned long _Accum, 0.2ulk)
-FOO_FUN (ulla, unsigned long long _Accum, 0.2ullk)
+ULLACCUM_TEST (FOO_FUN (ulla, unsigned long long _Accum, 0.2ullk))
 FOO_FUN (Ssa, _Sat short _Accum, 0.2hk)
 FOO_FUN (Sa, _Sat _Accum, 0.2k)
 FOO_FUN (Sla, _Sat long _Accum, 0.2lk)
-FOO_FUN (Slla, _Sat long long _Accum, 0.2llk)
+LLACCUM_TEST (FOO_FUN (Slla, _Sat long long _Accum, 0.2llk))
 FOO_FUN (Susa, _Sat unsigned short _Accum, 0.2uhk)
 FOO_FUN (Sua, _Sat unsigned _Accum, 0.2uk)
 FOO_FUN (Sula, _Sat unsigned long _Accum, 0.2ulk)
-FOO_FUN (Sulla, _Sat unsigned long long _Accum, 0.2ullk)
+ULLACCUM_TEST (FOO_FUN (Sulla, _Sat unsigned long long _Accum, 0.2ullk))
 
 int
 main ()
@@ -63,35 +65,35 @@  main ()
   FOO_TEST (sf, short _Fract, 0.2hr)
   FOO_TEST (f, _Fract, 0.2r)
   FOO_TEST (lf, long _Fract, 0.2lr)
-  FOO_TEST (llf, long long _Fract, 0.2llr)
+  LLFRACT_TEST (FOO_TEST (llf, long long _Fract, 0.2llr))
   FOO_TEST (usf, unsigned short _Fract, 0.2uhr)
   FOO_TEST (uf, unsigned _Fract, 0.2ur)
   FOO_TEST (ulf, unsigned long _Fract, 0.2ulr)
-  FOO_TEST (ullf, unsigned long long _Fract, 0.2ullr)
+  ULLFRACT_TEST (FOO_TEST (ullf, unsigned long long _Fract, 0.2ullr))
   FOO_TEST (Ssf, _Sat short _Fract, 0.2hr)
   FOO_TEST (Sf, _Sat _Fract, 0.2r)
   FOO_TEST (Slf, _Sat long _Fract, 0.2lr)
-  FOO_TEST (Sllf, _Sat long long _Fract, 0.2llr)
+  LLFRACT_TEST (FOO_TEST (Sllf, _Sat long long _Fract, 0.2llr))
   FOO_TEST (Susf, _Sat unsigned short _Fract, 0.2uhr)
   FOO_TEST (Suf, _Sat unsigned _Fract, 0.2ur)
   FOO_TEST (Sulf, _Sat unsigned long _Fract, 0.2ulr)
-  FOO_TEST (Sullf, _Sat unsigned long long _Fract, 0.2ullr)
+  ULLFRACT_TEST (FOO_TEST (Sullf, _Sat unsigned long long _Fract, 0.2ullr))
   FOO_TEST (sa, short _Accum, 0.2hk)
   FOO_TEST (a, _Accum, 0.2k)
   FOO_TEST (la, long _Accum, 0.2lk)
-  FOO_TEST (lla, long long _Accum, 0.2llk)
+  LLACCUM_TEST (FOO_TEST (lla, long long _Accum, 0.2llk))
   FOO_TEST (usa, unsigned short _Accum, 0.2uhk)
   FOO_TEST (ua, unsigned _Accum, 0.2uk)
   FOO_TEST (ula, unsigned long _Accum, 0.2ulk)
-  FOO_TEST (ulla, unsigned long long _Accum, 0.2ullk)
+  ULLACCUM_TEST (FOO_TEST (ulla, unsigned long long _Accum, 0.2ullk))
   FOO_TEST (Ssa, _Sat short _Accum, 0.2hk)
   FOO_TEST (Sa, _Sat _Accum, 0.2k)
   FOO_TEST (Sla, _Sat long _Accum, 0.2lk)
-  FOO_TEST (Slla, _Sat long long _Accum, 0.2llk)
+  LLACCUM_TEST (FOO_TEST (Slla, _Sat long long _Accum, 0.2llk))
   FOO_TEST (Susa, _Sat unsigned short _Accum, 0.2uhk)
   FOO_TEST (Sua, _Sat unsigned _Accum, 0.2uk)
   FOO_TEST (Sula, _Sat unsigned long _Accum, 0.2ulk)
-  FOO_TEST (Sulla, _Sat unsigned long long _Accum, 0.2ullk)
+  ULLACCUM_TEST (FOO_TEST (Sulla, _Sat unsigned long long _Accum, 0.2ullk))
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/convert.c b/gcc/testsuite/gcc.dg/fixed-point/convert.c
index f4e373f..16f5ab0 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/convert.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/convert.c
@@ -5,6 +5,8 @@ 
 
    Check conversions involving fixed-point.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 
 /* Fixed-point to fixed-point.  */
@@ -102,51 +104,51 @@  extern void abort (void);
   CONV(TYPE, POSTFIX, short _Fract, hr) \
   CONV(TYPE, POSTFIX, _Fract, r) \
   CONV(TYPE, POSTFIX, long _Fract, lr) \
-  CONV(TYPE, POSTFIX, long long _Fract, llr) \
+  LLFRACT_TEST (CONV(TYPE, POSTFIX, long long _Fract, llr)) \
   CONV(TYPE, POSTFIX, unsigned short _Fract, uhr) \
   CONV(TYPE, POSTFIX, unsigned _Fract, ur) \
   CONV(TYPE, POSTFIX, unsigned long _Fract, ulr) \
-  CONV(TYPE, POSTFIX, unsigned long long _Fract, ullr) \
+  ULLFRACT_TEST (CONV(TYPE, POSTFIX, unsigned long long _Fract, ullr)) \
   CONV(TYPE, POSTFIX, short _Accum, hk) \
   CONV(TYPE, POSTFIX, _Accum, k) \
   CONV(TYPE, POSTFIX, long _Accum, lk) \
-  CONV(TYPE, POSTFIX, long long _Accum, llk) \
+  LLACCUM_TEST (CONV(TYPE, POSTFIX, long long _Accum, llk)) \
   CONV(TYPE, POSTFIX, unsigned short _Accum, uhk) \
   CONV(TYPE, POSTFIX, unsigned _Accum, uk) \
   CONV(TYPE, POSTFIX, unsigned long _Accum, ulk) \
-  CONV(TYPE, POSTFIX, unsigned long long _Accum, ullk) \
+  ULLACCUM_TEST (CONV(TYPE, POSTFIX, unsigned long long _Accum, ullk)) \
   CONV(_Sat TYPE, POSTFIX, short _Fract, hr) \
   CONV(_Sat TYPE, POSTFIX, _Fract, r) \
   CONV(_Sat TYPE, POSTFIX, long _Fract, lr) \
-  CONV(_Sat TYPE, POSTFIX, long long _Fract, llr) \
+  LLFRACT_TEST (CONV(_Sat TYPE, POSTFIX, long long _Fract, llr)) \
   CONV(_Sat TYPE, POSTFIX, unsigned short _Fract, uhr) \
   CONV(_Sat TYPE, POSTFIX, unsigned _Fract, ur) \
   CONV(_Sat TYPE, POSTFIX, unsigned long _Fract, ulr) \
-  CONV(_Sat TYPE, POSTFIX, unsigned long long _Fract, ullr) \
+  ULLFRACT_TEST (CONV(_Sat TYPE, POSTFIX, unsigned long long _Fract, ullr)) \
   CONV(_Sat TYPE, POSTFIX, short _Accum, hk) \
   CONV(_Sat TYPE, POSTFIX, _Accum, k) \
   CONV(_Sat TYPE, POSTFIX, long _Accum, lk) \
-  CONV(_Sat TYPE, POSTFIX, long long _Accum, llk) \
+  LLACCUM_TEST (CONV(_Sat TYPE, POSTFIX, long long _Accum, llk)) \
   CONV(_Sat TYPE, POSTFIX, unsigned short _Accum, uhk) \
   CONV(_Sat TYPE, POSTFIX, unsigned _Accum, uk) \
   CONV(_Sat TYPE, POSTFIX, unsigned long _Accum, ulk) \
-  CONV(_Sat TYPE, POSTFIX, unsigned long long _Accum, ullk) \
+  ULLACCUM_TEST (CONV(_Sat TYPE, POSTFIX, unsigned long long _Accum, ullk)) \
   CONV(TYPE, POSTFIX, _Sat short _Fract, hr) \
   CONV(TYPE, POSTFIX, _Sat _Fract, r) \
   CONV(TYPE, POSTFIX, _Sat long _Fract, lr) \
-  CONV(TYPE, POSTFIX, _Sat long long _Fract, llr) \
+  LLFRACT_TEST (CONV(TYPE, POSTFIX, _Sat long long _Fract, llr)) \
   CONV(TYPE, POSTFIX, _Sat unsigned short _Fract, uhr) \
   CONV(TYPE, POSTFIX, _Sat unsigned _Fract, ur) \
   CONV(TYPE, POSTFIX, _Sat unsigned long _Fract, ulr) \
-  CONV(TYPE, POSTFIX, _Sat unsigned long long _Fract, ullr) \
+  ULLFRACT_TEST (CONV(TYPE, POSTFIX, _Sat unsigned long long _Fract, ullr)) \
   CONV(TYPE, POSTFIX, _Sat short _Accum, hk) \
   CONV(TYPE, POSTFIX, _Sat _Accum, k) \
   CONV(TYPE, POSTFIX, _Sat long _Accum, lk) \
-  CONV(TYPE, POSTFIX, _Sat long long _Accum, llk) \
+  LLACCUM_TEST (CONV(TYPE, POSTFIX, _Sat long long _Accum, llk)) \
   CONV(TYPE, POSTFIX, _Sat unsigned short _Accum, uhk) \
   CONV(TYPE, POSTFIX, _Sat unsigned _Accum, uk) \
   CONV(TYPE, POSTFIX, _Sat unsigned long _Accum, ulk) \
-  CONV(TYPE, POSTFIX, _Sat unsigned long long _Accum, ullk) \
+  ULLACCUM_TEST (CONV(TYPE, POSTFIX, _Sat unsigned long long _Accum, ullk)) \
   CONV_INT(TYPE, POSTFIX, signed char) \
   CONV_INT(TYPE, POSTFIX, short) \
   CONV_INT(TYPE, POSTFIX, int) \
@@ -219,58 +221,58 @@  extern void abort (void);
   CONV2(TYPE, -3.2 ## POSTFIX, _Sat _Fract, -0.5r - 0.5r) \
   CONV2(TYPE, 3.2 ## POSTFIX, _Sat long _Fract, 1.0lr) \
   CONV2(TYPE, -3.2 ## POSTFIX, _Sat long _Fract, -0.5lr - 0.5lr) \
-  CONV2(TYPE, 3.2 ## POSTFIX, _Sat long long _Fract, 1.0llr) \
-  CONV2(TYPE, -3.2 ## POSTFIX, _Sat long long _Fract, -0.5llr - 0.5llr) \
+  LLFRACT_TEST (CONV2(TYPE, 3.2 ## POSTFIX, _Sat long long _Fract, 1.0llr)) \
+  LLFRACT_TEST (CONV2(TYPE, -3.2 ## POSTFIX, _Sat long long _Fract, -0.5llr - 0.5llr)) \
   CONV2(TYPE, 3.2 ## POSTFIX, _Sat unsigned short _Fract, 1.0uhr) \
   CONV2(TYPE, -3.2 ## POSTFIX, _Sat unsigned short _Fract, 0.0uhr) \
   CONV2(TYPE, 3.2 ## POSTFIX, _Sat unsigned _Fract, 1.0ur) \
   CONV2(TYPE, -3.2 ## POSTFIX, _Sat unsigned _Fract, 0.0ur) \
   CONV2(TYPE, 3.2 ## POSTFIX, _Sat unsigned long _Fract, 1.0ulr) \
   CONV2(TYPE, -3.2 ## POSTFIX, _Sat unsigned long _Fract, 0.0ulr) \
-  CONV2(TYPE, 3.2 ## POSTFIX, _Sat unsigned long long _Fract, 1.0ullr) \
-  CONV2(TYPE, -3.2 ## POSTFIX, _Sat unsigned long long _Fract, 0.0ullr) \
+  ULLFRACT_TEST (CONV2(TYPE, 3.2 ## POSTFIX, _Sat unsigned long long _Fract, 1.0ullr)) \
+  ULLFRACT_TEST (CONV2(TYPE, -3.2 ## POSTFIX, _Sat unsigned long long _Fract, 0.0ullr)) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat short _Fract, 1.0hr) \
   CONV2(TYPE, -1.0 ## POSTFIX, _Sat short _Fract, -0.5hr - 0.5hr) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat _Fract, 1.0r) \
   CONV2(TYPE, -1.0 ## POSTFIX, _Sat _Fract, -0.5r - 0.5r) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat long _Fract, 1.0lr) \
   CONV2(TYPE, -1.0 ## POSTFIX, _Sat long _Fract, -0.5lr - 0.5lr) \
-  CONV2(TYPE, 1.0 ## POSTFIX, _Sat long long _Fract, 1.0llr) \
-  CONV2(TYPE, -1.0 ## POSTFIX, _Sat long long _Fract, -0.5llr - 0.5llr) \
+  LLFRACT_TEST (CONV2(TYPE, 1.0 ## POSTFIX, _Sat long long _Fract, 1.0llr)) \
+  LLFRACT_TEST (CONV2(TYPE, -1.0 ## POSTFIX, _Sat long long _Fract, -0.5llr - 0.5llr)) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat unsigned short _Fract, 1.0uhr) \
   CONV2(TYPE, -1.0 ## POSTFIX, _Sat unsigned short _Fract, 0.0uhr) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat unsigned _Fract, 1.0ur) \
   CONV2(TYPE, -1.0 ## POSTFIX, _Sat unsigned _Fract, 0.0ur) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat unsigned long _Fract, 1.0ulr) \
   CONV2(TYPE, -1.0 ## POSTFIX, _Sat unsigned long _Fract, 0.0ulr) \
-  CONV2(TYPE, 1.0 ## POSTFIX, _Sat unsigned long long _Fract, 1.0ullr) \
-  CONV2(TYPE, -1.0 ## POSTFIX, _Sat unsigned long long _Fract, 0.0ullr)
+  ULLFRACT_TEST (CONV2(TYPE, 1.0 ## POSTFIX, _Sat unsigned long long _Fract, 1.0ullr)) \
+  ULLFRACT_TEST (CONV2(TYPE, -1.0 ## POSTFIX, _Sat unsigned long long _Fract, 0.0ullr))
 
 /* Unsigned accum to _Sat unsigned/signed fract.  */
 #define SAT_CONV2(TYPE, POSTFIX) \
   CONV2(TYPE, 3.2 ## POSTFIX, _Sat short _Fract, 1.0hr) \
   CONV2(TYPE, 3.2 ## POSTFIX, _Sat _Fract, 1.0r) \
   CONV2(TYPE, 3.2 ## POSTFIX, _Sat long _Fract, 1.0lr) \
-  CONV2(TYPE, 3.2 ## POSTFIX, _Sat long long _Fract, 1.0llr) \
+  LLFRACT_TEST (CONV2(TYPE, 3.2 ## POSTFIX, _Sat long long _Fract, 1.0llr)) \
   CONV2(TYPE, 3.2 ## POSTFIX, _Sat unsigned short _Fract, 1.0uhr) \
   CONV2(TYPE, 3.2 ## POSTFIX, _Sat unsigned _Fract, 1.0ur) \
   CONV2(TYPE, 3.2 ## POSTFIX, _Sat unsigned long _Fract, 1.0ulr) \
-  CONV2(TYPE, 3.2 ## POSTFIX, _Sat unsigned long long _Fract, 1.0ullr) \
+  ULLFRACT_TEST (CONV2(TYPE, 3.2 ## POSTFIX, _Sat unsigned long long _Fract, 1.0ullr)) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat short _Fract, 1.0hr) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat _Fract, 1.0r) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat long _Fract, 1.0lr) \
-  CONV2(TYPE, 1.0 ## POSTFIX, _Sat long long _Fract, 1.0llr) \
+  LLFRACT_TEST (CONV2(TYPE, 1.0 ## POSTFIX, _Sat long long _Fract, 1.0llr)) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat unsigned short _Fract, 1.0uhr) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat unsigned _Fract, 1.0ur) \
   CONV2(TYPE, 1.0 ## POSTFIX, _Sat unsigned long _Fract, 1.0ulr) \
-  CONV2(TYPE, 1.0 ## POSTFIX, _Sat unsigned long long _Fract, 1.0ullr)
+  ULLFRACT_TEST (CONV2(TYPE, 1.0 ## POSTFIX, _Sat unsigned long long _Fract, 1.0ullr))
 
 /* Signed fract to _Sat unsigned fract.  */
 #define SAT_CONV3(TYPE, POSTFIX) \
   CONV2(TYPE, -0.5 ## POSTFIX, _Sat unsigned short _Fract, 0.0uhr) \
   CONV2(TYPE, -0.5 ## POSTFIX, _Sat unsigned  _Fract, 0.0ur) \
   CONV2(TYPE, -0.5 ## POSTFIX, _Sat unsigned long _Fract, 0.0ulr) \
-  CONV2(TYPE, -0.5 ## POSTFIX, _Sat unsigned long long _Fract, 0.0ullr)
+  ULLFRACT_TEST (CONV2(TYPE, -0.5 ## POSTFIX, _Sat unsigned long long _Fract, 0.0ullr))
 
 /* Signed integer to _Sat signed/unsigned fract.  */
 #define SAT_CONV4(TYPE) \
@@ -280,51 +282,51 @@  extern void abort (void);
   CONV2(TYPE, -100, _Sat _Fract, -0.5r - 0.5r) \
   CONV2(TYPE, 100, _Sat long _Fract, 1.0lr) \
   CONV2(TYPE, -100, _Sat long _Fract, -0.5lr - 0.5lr) \
-  CONV2(TYPE, 100, _Sat long long _Fract, 1.0llr) \
-  CONV2(TYPE, -100, _Sat long long _Fract, -0.5llr - 0.5llr) \
+  LLFRACT_TEST (CONV2(TYPE, 100, _Sat long long _Fract, 1.0llr)) \
+  LLFRACT_TEST (CONV2(TYPE, -100, _Sat long long _Fract, -0.5llr - 0.5llr)) \
   CONV2(TYPE, 100, _Sat unsigned short _Fract, 1.0uhr) \
   CONV2(TYPE, -100, _Sat unsigned short _Fract, 0.0uhr) \
   CONV2(TYPE, 100, _Sat unsigned _Fract, 1.0ur) \
   CONV2(TYPE, -100, _Sat unsigned _Fract, 0.0ur) \
   CONV2(TYPE, 100, _Sat unsigned long _Fract, 1.0ulr) \
   CONV2(TYPE, -100, _Sat unsigned long _Fract, 0.0ulr) \
-  CONV2(TYPE, 100, _Sat unsigned long long _Fract, 1.0ullr) \
-  CONV2(TYPE, -100, _Sat unsigned long long _Fract, 0.0ullr) \
+  ULLFRACT_TEST (CONV2(TYPE, 100, _Sat unsigned long long _Fract, 1.0ullr)) \
+  ULLFRACT_TEST (CONV2(TYPE, -100, _Sat unsigned long long _Fract, 0.0ullr)) \
   CONV2(TYPE, 1, _Sat short _Fract, 1.0hr) \
   CONV2(TYPE, -1, _Sat short _Fract, -0.5hr - 0.5hr) \
   CONV2(TYPE, 1, _Sat _Fract, 1.0r) \
   CONV2(TYPE, -1, _Sat _Fract, -0.5r - 0.5r) \
   CONV2(TYPE, 1, _Sat long _Fract, 1.0lr) \
   CONV2(TYPE, -1, _Sat long _Fract, -0.5lr - 0.5lr) \
-  CONV2(TYPE, 1, _Sat long long _Fract, 1.0llr) \
-  CONV2(TYPE, -1, _Sat long long _Fract, -0.5llr - 0.5llr) \
+  LLFRACT_TEST (CONV2(TYPE, 1, _Sat long long _Fract, 1.0llr)) \
+  LLFRACT_TEST (CONV2(TYPE, -1, _Sat long long _Fract, -0.5llr - 0.5llr)) \
   CONV2(TYPE, 1, _Sat unsigned short _Fract, 1.0uhr) \
   CONV2(TYPE, -1, _Sat unsigned short _Fract, 0.0uhr) \
   CONV2(TYPE, 1, _Sat unsigned _Fract, 1.0ur) \
   CONV2(TYPE, -1, _Sat unsigned _Fract, 0.0ur) \
   CONV2(TYPE, 1, _Sat unsigned long _Fract, 1.0ulr) \
   CONV2(TYPE, -1, _Sat unsigned long _Fract, 0.0ulr) \
-  CONV2(TYPE, 1, _Sat unsigned long long _Fract, 1.0ullr) \
-  CONV2(TYPE, -1, _Sat unsigned long long _Fract, 0.0ullr)
+  ULLFRACT_TEST (CONV2(TYPE, 1, _Sat unsigned long long _Fract, 1.0ullr)) \
+  ULLFRACT_TEST (CONV2(TYPE, -1, _Sat unsigned long long _Fract, 0.0ullr))
 
 /* Unsigned integer to _Sat signed/unsigned fract.  */
 #define SAT_CONV5(TYPE) \
   CONV2(TYPE, 100, _Sat short _Fract, 1.0hr) \
   CONV2(TYPE, 100, _Sat _Fract, 1.0r) \
   CONV2(TYPE, 100, _Sat long _Fract, 1.0lr) \
-  CONV2(TYPE, 100, _Sat long long _Fract, 1.0llr) \
+  LLFRACT_TEST (CONV2(TYPE, 100, _Sat long long _Fract, 1.0llr)) \
   CONV2(TYPE, 100, _Sat unsigned short _Fract, 1.0uhr) \
   CONV2(TYPE, 100, _Sat unsigned _Fract, 1.0ur) \
   CONV2(TYPE, 100, _Sat unsigned long _Fract, 1.0ulr) \
-  CONV2(TYPE, 100, _Sat unsigned long long _Fract, 1.0ullr) \
+  ULLFRACT_TEST (CONV2(TYPE, 100, _Sat unsigned long long _Fract, 1.0ullr)) \
   CONV2(TYPE, 1, _Sat short _Fract, 1.0hr) \
   CONV2(TYPE, 1, _Sat _Fract, 1.0r) \
   CONV2(TYPE, 1, _Sat long _Fract, 1.0lr) \
-  CONV2(TYPE, 1, _Sat long long _Fract, 1.0llr) \
+  LLFRACT_TEST (CONV2(TYPE, 1, _Sat long long _Fract, 1.0llr)) \
   CONV2(TYPE, 1, _Sat unsigned short _Fract, 1.0uhr) \
   CONV2(TYPE, 1, _Sat unsigned _Fract, 1.0ur) \
   CONV2(TYPE, 1, _Sat unsigned long _Fract, 1.0ulr) \
-  CONV2(TYPE, 1, _Sat unsigned long long _Fract, 1.0ullr)
+  ULLFRACT_TEST (CONV2(TYPE, 1, _Sat unsigned long long _Fract, 1.0ullr))
 
 /* Floating-point to _Sat signed/unsigned fract.  */
 #define SAT_CONV6(TYPE) \
@@ -334,84 +336,84 @@  extern void abort (void);
   CONV2(TYPE, -100.0, _Sat _Fract, -0.5r - 0.5r) \
   CONV2(TYPE, 100.0, _Sat long _Fract, 1.0lr) \
   CONV2(TYPE, -100.0, _Sat long _Fract, -0.5lr - 0.5lr) \
-  CONV2(TYPE, 100.0, _Sat long long _Fract, 1.0llr) \
-  CONV2(TYPE, -100.0, _Sat long long _Fract, -0.5llr - 0.5llr) \
+  LLFRACT_TEST (CONV2(TYPE, 100.0, _Sat long long _Fract, 1.0llr)) \
+  LLFRACT_TEST (CONV2(TYPE, -100.0, _Sat long long _Fract, -0.5llr - 0.5llr)) \
   CONV2(TYPE, 100.0, _Sat unsigned short _Fract, 1.0uhr) \
   CONV2(TYPE, -100.0, _Sat unsigned short _Fract, 0.0uhr) \
   CONV2(TYPE, 100.0, _Sat unsigned _Fract, 1.0ur) \
   CONV2(TYPE, -100.0, _Sat unsigned _Fract, 0.0ur) \
   CONV2(TYPE, 100.0, _Sat unsigned long _Fract, 1.0ulr) \
   CONV2(TYPE, -100.0, _Sat unsigned long _Fract, 0.0ulr) \
-  CONV2(TYPE, 100.0, _Sat unsigned long long _Fract, 1.0ullr) \
-  CONV2(TYPE, -100.0, _Sat unsigned long long _Fract, 0.0ullr) \
+  ULLFRACT_TEST (CONV2(TYPE, 100.0, _Sat unsigned long long _Fract, 1.0ullr)) \
+  ULLFRACT_TEST (CONV2(TYPE, -100.0, _Sat unsigned long long _Fract, 0.0ullr)) \
   CONV2(TYPE, 1.0, _Sat short _Fract, 1.0hr) \
   CONV2(TYPE, -1.0, _Sat short _Fract, -0.5hr - 0.5hr) \
   CONV2(TYPE, 1.0, _Sat _Fract, 1.0r) \
   CONV2(TYPE, -1.0, _Sat _Fract, -0.5r - 0.5r) \
   CONV2(TYPE, 1.0, _Sat long _Fract, 1.0lr) \
   CONV2(TYPE, -1.0, _Sat long _Fract, -0.5lr - 0.5lr) \
-  CONV2(TYPE, 1.0, _Sat long long _Fract, 1.0llr) \
-  CONV2(TYPE, -1.0, _Sat long long _Fract, -0.5llr - 0.5llr) \
+  LLFRACT_TEST (CONV2(TYPE, 1.0, _Sat long long _Fract, 1.0llr)) \
+  LLFRACT_TEST (CONV2(TYPE, -1.0, _Sat long long _Fract, -0.5llr - 0.5llr)) \
   CONV2(TYPE, 1.0, _Sat unsigned short _Fract, 1.0uhr) \
   CONV2(TYPE, -1.0, _Sat unsigned short _Fract, 0.0uhr) \
   CONV2(TYPE, 1.0, _Sat unsigned _Fract, 1.0ur) \
   CONV2(TYPE, -1.0, _Sat unsigned _Fract, 0.0ur) \
   CONV2(TYPE, 1.0, _Sat unsigned long _Fract, 1.0ulr) \
   CONV2(TYPE, -1.0, _Sat unsigned long _Fract, 0.0ulr) \
-  CONV2(TYPE, 1.0, _Sat unsigned long long _Fract, 1.0ullr) \
-  CONV2(TYPE, -1.0, _Sat unsigned long long _Fract, 0.0ullr)
+  ULLFRACT_TEST (CONV2(TYPE, 1.0, _Sat unsigned long long _Fract, 1.0ullr)) \
+  ULLFRACT_TEST (CONV2(TYPE, -1.0, _Sat unsigned long long _Fract, 0.0ullr))
 
 int main ()
 {
   ALL_CONV (short _Fract, hr);
   ALL_CONV (_Fract, r);
   ALL_CONV (long _Fract, lr);
-  ALL_CONV (long long _Fract, llr);
+  LLFRACT_TEST (ALL_CONV (long long _Fract, llr));
   ALL_CONV (unsigned short _Fract, uhr);
   ALL_CONV (unsigned _Fract, ur);
   ALL_CONV (unsigned long _Fract, ulr);
-  ALL_CONV (unsigned long long _Fract, ullr);
+  ULLFRACT_TEST (ALL_CONV (unsigned long long _Fract, ullr));
   ALL_CONV (short _Accum, hk);
   ALL_CONV (_Accum, k);
   ALL_CONV (long _Accum, lk);
-  ALL_CONV (long long _Accum, llk);
+  LLACCUM_TEST (ALL_CONV (long long _Accum, llk));
   ALL_CONV (unsigned short _Accum, uhk);
   ALL_CONV (unsigned _Accum, uk);
   ALL_CONV (unsigned long _Accum, ulk);
-  ALL_CONV (unsigned long long _Accum, ullk);
+  ULLACCUM_TEST (ALL_CONV (unsigned long long _Accum, ullk));
 
   ALL_ACCUM_CONV (short _Accum, hk);
   ALL_ACCUM_CONV (_Accum, k);
   ALL_ACCUM_CONV (long _Accum, lk);
-  ALL_ACCUM_CONV (long long _Accum, llk);
+  LLACCUM_TEST (ALL_ACCUM_CONV (long long _Accum, llk));
   ALL_ACCUM_CONV (unsigned short _Accum, uhk);
   ALL_ACCUM_CONV (unsigned _Accum, uk);
   ALL_ACCUM_CONV (unsigned long _Accum, ulk);
-  ALL_ACCUM_CONV (unsigned long long _Accum, ullk);
+  ULLACCUM_TEST (ALL_ACCUM_CONV (unsigned long long _Accum, ullk));
 
   NEG_CONV (short _Fract, hr);
   NEG_CONV (_Fract, r);
   NEG_CONV (long _Fract, lr);
-  NEG_CONV (long long _Fract, llr);
+  LLFRACT_TEST (NEG_CONV (long long _Fract, llr));
   NEG_CONV (short _Accum, hk);
   NEG_CONV (_Accum, k);
   NEG_CONV (long _Accum, lk);
-  NEG_CONV (long long _Accum, llk);
+  LLACCUM_TEST (NEG_CONV (long long _Accum, llk));
 
   SAT_CONV1 (short _Accum, hk);
   SAT_CONV1 (_Accum, k);
   SAT_CONV1 (long _Accum, lk);
-  SAT_CONV1 (long long _Accum, llk);
+  LLACCUM_TEST (SAT_CONV1 (long long _Accum, llk));
 
   SAT_CONV2 (unsigned short _Accum, uhk);
   SAT_CONV2 (unsigned _Accum, uk);
   SAT_CONV2 (unsigned long _Accum, ulk);
-  SAT_CONV2 (unsigned long long _Accum, ullk);
+  LLACCUM_TEST (SAT_CONV2 (unsigned long long _Accum, ullk));
 
   SAT_CONV3 (short _Fract, hr);
   SAT_CONV3 (_Fract, r);
   SAT_CONV3 (long _Fract, lr);
-  SAT_CONV3 (long long _Fract, llr);
+  LLFRACT_TEST (SAT_CONV3 (long long _Fract, llr));
 
   SAT_CONV4 (signed char);
   SAT_CONV4 (short);
diff --git a/gcc/testsuite/gcc.dg/fixed-point/func-array.c b/gcc/testsuite/gcc.dg/fixed-point/func-array.c
index 0d0e8c1..21d61b4 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/func-array.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/func-array.c
@@ -5,6 +5,8 @@ 
    Test passing array elements involving fixed-point types.
    Based on the test from ../dfp/.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 
 /* A handful of functions that return the Nth argument of
@@ -21,35 +23,35 @@  TYPE NAME ## 5 (TYPE args[]) { return args[5]; }
 FUNC (short _Fract, sf)
 FUNC (_Fract, f)
 FUNC (long _Fract, lf)
-FUNC (long long _Fract, llf)
+LLFRACT_TEST (FUNC (long long _Fract, llf))
 FUNC (unsigned short _Fract, usf)
 FUNC (unsigned _Fract, uf)
 FUNC (unsigned long _Fract, ulf)
-FUNC (unsigned long long _Fract, ullf)
+ULLFRACT_TEST (FUNC (unsigned long long _Fract, ullf))
 FUNC (_Sat short _Fract, Ssf)
 FUNC (_Sat _Fract, Sf)
 FUNC (_Sat long _Fract, Slf)
-FUNC (_Sat long long _Fract, Sllf)
+LLFRACT_TEST (FUNC (_Sat long long _Fract, Sllf))
 FUNC (_Sat unsigned short _Fract, Susf)
 FUNC (_Sat unsigned _Fract, Suf)
 FUNC (_Sat unsigned long _Fract, Sulf)
-FUNC (_Sat unsigned long long _Fract, Sullf)
+ULLFRACT_TEST (FUNC (_Sat unsigned long long _Fract, Sullf))
 FUNC (short _Accum, sa)
 FUNC (_Accum, a)
 FUNC (long _Accum, la)
-FUNC (long long _Accum, lla)
+LLACCUM_TEST (FUNC (long long _Accum, lla))
 FUNC (unsigned short _Accum, usa)
 FUNC (unsigned _Accum, ua)
 FUNC (unsigned long _Accum, ula)
-FUNC (unsigned long long _Accum, ulla)
+ULLACCUM_TEST (FUNC (unsigned long long _Accum, ulla))
 FUNC (_Sat short _Accum, Ssa)
 FUNC (_Sat _Accum, Sa)
 FUNC (_Sat long _Accum, Sla)
-FUNC (_Sat long long _Accum, Slla)
+LLACCUM_TEST (FUNC (_Sat long long _Accum, Slla))
 FUNC (_Sat unsigned short _Accum, Susa)
 FUNC (_Sat unsigned _Accum, Sua)
 FUNC (_Sat unsigned long _Accum, Sula)
-FUNC (_Sat unsigned long long _Accum, Sulla)
+ULLACCUM_TEST (FUNC (_Sat unsigned long long _Accum, Sulla))
 
 int main()
 {
@@ -68,35 +70,35 @@  int main()
   TEST (short _Fract, sf, hr)
   TEST (_Fract, f, r)
   TEST (long _Fract, lf, lr)
-  TEST (long long _Fract, llf, llr)
+  LLFRACT_TEST (TEST (long long _Fract, llf, llr))
   TEST (unsigned short _Fract, usf, uhr)
   TEST (unsigned _Fract, uf, ur)
   TEST (unsigned long _Fract, ulf, ulr)
-  TEST (unsigned long long _Fract, ullf, ullr)
+  ULLFRACT_TEST (TEST (unsigned long long _Fract, ullf, ullr))
   TEST (_Sat short _Fract, Ssf, hr)
   TEST (_Sat _Fract, Sf, r)
   TEST (_Sat long _Fract, Slf, lr)
-  TEST (_Sat long long _Fract, Sllf, llr)
+  LLFRACT_TEST (TEST (_Sat long long _Fract, Sllf, llr))
   TEST (_Sat unsigned short _Fract, Susf, uhr)
   TEST (_Sat unsigned _Fract, Suf, ur)
   TEST (_Sat unsigned long _Fract, Sulf, ulr)
-  TEST (_Sat unsigned long long _Fract, Sullf, ullr)
+  ULLFRACT_TEST (TEST (_Sat unsigned long long _Fract, Sullf, ullr))
   TEST (short _Accum, sa, hk)
   TEST (_Accum, a, k)
   TEST (long _Accum, la, lk)
-  TEST (long long _Accum, lla, llk)
+  LLACCUM_TEST (TEST (long long _Accum, lla, llk))
   TEST (unsigned short _Accum, usa, uhk)
   TEST (unsigned _Accum, ua, uk)
   TEST (unsigned long _Accum, ula, ulk)
-  TEST (unsigned long long _Accum, ulla, ullk)
+  ULLACCUM_TEST (TEST (unsigned long long _Accum, ulla, ullk))
   TEST (_Sat short _Accum, Ssa, hk)
   TEST (_Sat _Accum, Sa, k)
   TEST (_Sat long _Accum, Sla, lk)
-  TEST (_Sat long long _Accum, Slla, llk)
+  LLACCUM_TEST (TEST (_Sat long long _Accum, Slla, llk))
   TEST (_Sat unsigned short _Accum, Susa, uhk)
   TEST (_Sat unsigned _Accum, Sua, uk)
   TEST (_Sat unsigned long _Accum, Sula, ulk)
-  TEST (_Sat unsigned long long _Accum, Sulla, ullk)
+  ULLACCUM_TEST (TEST (_Sat unsigned long long _Accum, Sulla, ullk))
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/func-mixed.c b/gcc/testsuite/gcc.dg/fixed-point/func-mixed.c
index 01930e4..0d25ab8 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/func-mixed.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/func-mixed.c
@@ -5,6 +5,8 @@ 
    Test scalar passing and return values involving fixed-point types.
    Based on the test from ../dfp/.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 
 /* A handful of functions that return the Nth argument of
@@ -25,35 +27,35 @@  TYPE NAME ## 4 (int arg0, unsigned arg1, float arg2, double arg3, TYPE arg4) \
 FUNC (short _Fract, sf)
 FUNC (_Fract, f)
 FUNC (long _Fract, lf)
-FUNC (long long _Fract, llf)
+LLFRACT_TEST (FUNC (long long _Fract, llf))
 FUNC (unsigned short _Fract, usf)
 FUNC (unsigned _Fract, uf)
 FUNC (unsigned long _Fract, ulf)
-FUNC (unsigned long long _Fract, ullf)
+ULLFRACT_TEST (FUNC (unsigned long long _Fract, ullf))
 FUNC (_Sat short _Fract, Ssf)
 FUNC (_Sat _Fract, Sf)
 FUNC (_Sat long _Fract, Slf)
-FUNC (_Sat long long _Fract, Sllf)
+LLFRACT_TEST (FUNC (_Sat long long _Fract, Sllf))
 FUNC (_Sat unsigned short _Fract, Susf)
 FUNC (_Sat unsigned _Fract, Suf)
 FUNC (_Sat unsigned long _Fract, Sulf)
-FUNC (_Sat unsigned long long _Fract, Sullf)
+ULLFRACT_TEST (FUNC (_Sat unsigned long long _Fract, Sullf))
 FUNC (short _Accum, sa)
 FUNC (_Accum, a)
 FUNC (long _Accum, la)
-FUNC (long long _Accum, lla)
+LLACCUM_TEST (FUNC (long long _Accum, lla))
 FUNC (unsigned short _Accum, usa)
 FUNC (unsigned _Accum, ua)
 FUNC (unsigned long _Accum, ula)
-FUNC (unsigned long long _Accum, ulla)
+ULLACCUM_TEST (FUNC (unsigned long long _Accum, ulla))
 FUNC (_Sat short _Accum, Ssa)
 FUNC (_Sat _Accum, Sa)
 FUNC (_Sat long _Accum, Sla)
-FUNC (_Sat long long _Accum, Slla)
+LLACCUM_TEST (FUNC (_Sat long long _Accum, Slla))
 FUNC (_Sat unsigned short _Accum, Susa)
 FUNC (_Sat unsigned _Accum, Sua)
 FUNC (_Sat unsigned long _Accum, Sula)
-FUNC (_Sat unsigned long long _Accum, Sulla)
+ULLACCUM_TEST (FUNC (_Sat unsigned long long _Accum, Sulla))
 
 int main()
 {
@@ -69,35 +71,35 @@  int main()
   TEST (short _Fract, sf, hr)
   TEST (_Fract, f, r)
   TEST (long _Fract, lf, lr)
-  TEST (long long _Fract, llf, llr)
+  LLFRACT_TEST (TEST (long long _Fract, llf, llr))
   TEST (unsigned short _Fract, usf, uhr)
   TEST (unsigned _Fract, uf, ur)
   TEST (unsigned long _Fract, ulf, ulr)
-  TEST (unsigned long long _Fract, ullf, ullr)
+  ULLFRACT_TEST (TEST (unsigned long long _Fract, ullf, ullr))
   TEST (_Sat short _Fract, Ssf, hr)
   TEST (_Sat _Fract, Sf, r)
   TEST (_Sat long _Fract, Slf, lr)
-  TEST (_Sat long long _Fract, Sllf, llr)
+  LLFRACT_TEST (TEST (_Sat long long _Fract, Sllf, llr))
   TEST (_Sat unsigned short _Fract, Susf, uhr)
   TEST (_Sat unsigned _Fract, Suf, ur)
   TEST (_Sat unsigned long _Fract, Sulf, ulr)
-  TEST (_Sat unsigned long long _Fract, Sullf, ullr)
+  ULLFRACT_TEST (TEST (_Sat unsigned long long _Fract, Sullf, ullr))
   TEST (short _Accum, sa, hk)
   TEST (_Accum, a, k)
   TEST (long _Accum, la, lk)
-  TEST (long long _Accum, lla, llk)
+  LLACCUM_TEST (TEST (long long _Accum, lla, llk))
   TEST (unsigned short _Accum, usa, uhk)
   TEST (unsigned _Accum, ua, uk)
   TEST (unsigned long _Accum, ula, ulk)
-  TEST (unsigned long long _Accum, ulla, ullk)
+  ULLACCUM_TEST (TEST (unsigned long long _Accum, ulla, ullk))
   TEST (_Sat short _Accum, Ssa, hk)
   TEST (_Sat _Accum, Sa, k)
   TEST (_Sat long _Accum, Sla, lk)
-  TEST (_Sat long long _Accum, Slla, llk)
+  LLACCUM_TEST (TEST (_Sat long long _Accum, Slla, llk))
   TEST (_Sat unsigned short _Accum, Susa, uhk)
   TEST (_Sat unsigned _Accum, Sua, uk)
   TEST (_Sat unsigned long _Accum, Sula, ulk)
-  TEST (_Sat unsigned long long _Accum, Sulla, ullk)
+  ULLACCUM_TEST (TEST (_Sat unsigned long long _Accum, Sulla, ullk))
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/func-scalar.c b/gcc/testsuite/gcc.dg/fixed-point/func-scalar.c
index 957b562..dacf64c 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/func-scalar.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/func-scalar.c
@@ -5,6 +5,8 @@ 
    Test scalar passing and return values involving fixed-point types.
    Based on the test from ../dfp/.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 
 /* A handful of functions that return the Nth argument of
@@ -25,35 +27,35 @@  TYPE NAME ## 4 (TYPE arg0, TYPE arg1, TYPE arg2, TYPE arg3, TYPE arg4) \
 FUNC (short _Fract, sf)
 FUNC (_Fract, f)
 FUNC (long _Fract, lf)
-FUNC (long long _Fract, llf)
+LLFRACT_TEST (FUNC (long long _Fract, llf))
 FUNC (unsigned short _Fract, usf)
 FUNC (unsigned _Fract, uf)
 FUNC (unsigned long _Fract, ulf)
-FUNC (unsigned long long _Fract, ullf)
+ULLFRACT_TEST (FUNC (unsigned long long _Fract, ullf))
 FUNC (_Sat short _Fract, Ssf)
 FUNC (_Sat _Fract, Sf)
 FUNC (_Sat long _Fract, Slf)
-FUNC (_Sat long long _Fract, Sllf)
+LLFRACT_TEST (FUNC (_Sat long long _Fract, Sllf))
 FUNC (_Sat unsigned short _Fract, Susf)
 FUNC (_Sat unsigned _Fract, Suf)
 FUNC (_Sat unsigned long _Fract, Sulf)
-FUNC (_Sat unsigned long long _Fract, Sullf)
+ULLFRACT_TEST (FUNC (_Sat unsigned long long _Fract, Sullf))
 FUNC (short _Accum, sa)
 FUNC (_Accum, a)
 FUNC (long _Accum, la)
-FUNC (long long _Accum, lla)
+LLACCUM_TEST (FUNC (long long _Accum, lla))
 FUNC (unsigned short _Accum, usa)
 FUNC (unsigned _Accum, ua)
 FUNC (unsigned long _Accum, ula)
-FUNC (unsigned long long _Accum, ulla)
+ULLACCUM_TEST (FUNC (unsigned long long _Accum, ulla))
 FUNC (_Sat short _Accum, Ssa)
 FUNC (_Sat _Accum, Sa)
 FUNC (_Sat long _Accum, Sla)
-FUNC (_Sat long long _Accum, Slla)
+LLACCUM_TEST (FUNC (_Sat long long _Accum, Slla))
 FUNC (_Sat unsigned short _Accum, Susa)
 FUNC (_Sat unsigned _Accum, Sua)
 FUNC (_Sat unsigned long _Accum, Sula)
-FUNC (_Sat unsigned long long _Accum, Sulla)
+ULLACCUM_TEST (FUNC (_Sat unsigned long long _Accum, Sulla))
 
 int main()
 {
@@ -74,35 +76,35 @@  int main()
   TEST (short _Fract, sf, hr)
   TEST (_Fract, f, r)
   TEST (long _Fract, lf, lr)
-  TEST (long long _Fract, llf, llr)
+  LLFRACT_TEST (TEST (long long _Fract, llf, llr))
   TEST (unsigned short _Fract, usf, uhr)
   TEST (unsigned _Fract, uf, ur)
   TEST (unsigned long _Fract, ulf, ulr)
-  TEST (unsigned long long _Fract, ullf, ullr)
+  ULLFRACT_TEST (TEST (unsigned long long _Fract, ullf, ullr))
   TEST (_Sat short _Fract, Ssf, hr)
   TEST (_Sat _Fract, Sf, r)
   TEST (_Sat long _Fract, Slf, lr)
-  TEST (_Sat long long _Fract, Sllf, llr)
+  LLFRACT_TEST (TEST (_Sat long long _Fract, Sllf, llr))
   TEST (_Sat unsigned short _Fract, Susf, uhr)
   TEST (_Sat unsigned _Fract, Suf, ur)
   TEST (_Sat unsigned long _Fract, Sulf, ulr)
-  TEST (_Sat unsigned long long _Fract, Sullf, ullr)
+  ULLFRACT_TEST (TEST (_Sat unsigned long long _Fract, Sullf, ullr))
   TEST (short _Accum, sa, hk)
   TEST (_Accum, a, k)
   TEST (long _Accum, la, lk)
-  TEST (long long _Accum, lla, llk)
+  LLACCUM_TEST (TEST (long long _Accum, lla, llk))
   TEST (unsigned short _Accum, usa, uhk)
   TEST (unsigned _Accum, ua, uk)
   TEST (unsigned long _Accum, ula, ulk)
-  TEST (unsigned long long _Accum, ulla, ullk)
+  ULLACCUM_TEST (TEST (unsigned long long _Accum, ulla, ullk))
   TEST (_Sat short _Accum, Ssa, hk)
   TEST (_Sat _Accum, Sa, k)
   TEST (_Sat long _Accum, Sla, lk)
-  TEST (_Sat long long _Accum, Slla, llk)
+  LLACCUM_TEST (TEST (_Sat long long _Accum, Slla, llk))
   TEST (_Sat unsigned short _Accum, Susa, uhk)
   TEST (_Sat unsigned _Accum, Sua, uk)
   TEST (_Sat unsigned long _Accum, Sula, ulk)
-  TEST (_Sat unsigned long long _Accum, Sulla, ullk)
+  ULLACCUM_TEST (TEST (_Sat unsigned long long _Accum, Sulla, ullk))
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/func-struct.c b/gcc/testsuite/gcc.dg/fixed-point/func-struct.c
index c753888..0ba04bc 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/func-struct.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/func-struct.c
@@ -5,6 +5,8 @@ 
    Test structure passing and return values involving fixed-point types.
    Based on the test from ../dfp/.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 
 struct example
@@ -15,96 +17,128 @@  struct example
   char dummy2;
   long _Fract lf;
   char dummy3;
+#if DO_LLFRACT_TESTS
   long long _Fract llf;
   char dummy4;
+#endif
   unsigned short _Fract usf;
   char dummy5;
   unsigned _Fract uf;
   char dummy6;
   unsigned long _Fract ulf;
   char dummy7;
+#if DO_ULLFRACT_TESTS
   unsigned long long _Fract ullf;
   char dummy8;
+#endif
   _Sat short _Fract Ssf;
   char dummy9;
   _Sat _Fract Sf;
   char dummy10;
   _Sat long _Fract Slf;
   char dummy11;
+#if DO_LLFRACT_TESTS
   _Sat long long _Fract Sllf;
   char dummy12;
+#endif
   _Sat unsigned short _Fract Susf;
   char dummy13;
   _Sat unsigned _Fract Suf;
   char dummy14;
   _Sat unsigned long _Fract Sulf;
   char dummy15;
+#if DO_ULLFRACT_TESTS
   _Sat unsigned long long _Fract Sullf;
   char dummy16;
+#endif
   short _Accum sa;
   char dummya1;
   _Accum a;
   char dummya2;
   long _Accum la;
   char dummya3;
+#if DO_LLACCUM_TESTS
   long long _Accum lla;
   char dummya4;
+#endif
   unsigned short _Accum usa;
   char dummya5;
   unsigned _Accum ua;
   char dummya6;
   unsigned long _Accum ula;
   char dummya7;
+#if DO_ULLACCUM_TESTS
   unsigned long long _Accum ulla;
   char dummya8;
+#endif
   _Sat short _Accum Ssa;
   char dummya9;
   _Sat _Accum Sa;
   char dummya10;
   _Sat long _Accum Sla;
   char dummya11;
+#if DO_LLACCUM_TESTS
   _Sat long long _Accum Slla;
   char dummya12;
+#endif
   _Sat unsigned short _Accum Susa;
   char dummya13;
   _Sat unsigned _Accum Sua;
   char dummya14;
   _Sat unsigned long _Accum Sula;
   char dummya15;
+#if DO_ULLACCUM_TESTS
   _Sat unsigned long long _Accum Sulla;
   char dummya16;
+#endif
 } nums = { 0.1hr, 'a',
 	   0.2r, 'b',
 	   0.3lr, 'c',
+#if DO_LLFRACT_TESTS
 	   0.4llr, 'd',
+#endif
 	   0.5uhr, 'e',
 	   0.6ur, 'f',
 	   0.7ulr, 'g',
+#if DO_ULLFRACT_TESTS
 	   0.8ullr, 'h',
+#endif
 	   0.11r, 'i',
 	   0.22r, 'j',
 	   0.33lr, 'k',
+#if DO_LLFRACT_TESTS
 	   0.44llr, 'l',
+#endif
 	   0.55uhr, 'm',
 	   0.66ur, 'n',
 	   0.77ulr, 'o',
+#if DO_ULLFRACT_TESTS
 	   0.88ullr, 'p',
+#endif
 	   0.1hk, 'q',
 	   0.2k, 'r',
 	   0.3lk, 's',
+#if DO_LLACCUM_TESTS
 	   0.4llk, 't',
+#endif
 	   0.5uhk, 'u',
 	   0.6uk, 'v',
 	   0.7ulk, 'w',
+#if DO_ULLACCUM_TESTS
 	   0.8ullk, 'x',
+#endif
 	   0.11k, 'y',
 	   0.22k, 'z',
 	   0.33lk, '0',
+#if DO_LLACCUM_TESTS
 	   0.44llk, '1',
+#endif
 	   0.55uhk, '2',
 	   0.66uk, '3',
 	   0.77ulk, '4',
+#if DO_ULLACCUM_TESTS
 	   0.88ullk, '5'
+#endif
 	 };
 
 /* A handful of functions that return the Nth argument of
@@ -117,35 +151,35 @@  TYPE NAME ## _func (struct example s) \
 FUNC (short _Fract, sf)
 FUNC (_Fract, f)
 FUNC (long _Fract, lf)
-FUNC (long long _Fract, llf)
+LLFRACT_TEST (FUNC (long long _Fract, llf))
 FUNC (unsigned short _Fract, usf)
 FUNC (unsigned _Fract, uf)
 FUNC (unsigned long _Fract, ulf)
-FUNC (unsigned long long _Fract, ullf)
+ULLFRACT_TEST (FUNC (unsigned long long _Fract, ullf))
 FUNC (_Sat short _Fract, Ssf)
 FUNC (_Sat _Fract, Sf)
 FUNC (_Sat long _Fract, Slf)
-FUNC (_Sat long long _Fract, Sllf)
+LLFRACT_TEST (FUNC (_Sat long long _Fract, Sllf))
 FUNC (_Sat unsigned short _Fract, Susf)
 FUNC (_Sat unsigned _Fract, Suf)
 FUNC (_Sat unsigned long _Fract, Sulf)
-FUNC (_Sat unsigned long long _Fract, Sullf)
+ULLFRACT_TEST (FUNC (_Sat unsigned long long _Fract, Sullf))
 FUNC (short _Accum, sa)
 FUNC (_Accum, a)
 FUNC (long _Accum, la)
-FUNC (long long _Accum, lla)
+LLACCUM_TEST (FUNC (long long _Accum, lla))
 FUNC (unsigned short _Accum, usa)
 FUNC (unsigned _Accum, ua)
 FUNC (unsigned long _Accum, ula)
-FUNC (unsigned long long _Accum, ulla)
+ULLACCUM_TEST (FUNC (unsigned long long _Accum, ulla))
 FUNC (_Sat short _Accum, Ssa)
 FUNC (_Sat _Accum, Sa)
 FUNC (_Sat long _Accum, Sla)
-FUNC (_Sat long long _Accum, Slla)
+LLACCUM_TEST (FUNC (_Sat long long _Accum, Slla))
 FUNC (_Sat unsigned short _Accum, Susa)
 FUNC (_Sat unsigned _Accum, Sua)
 FUNC (_Sat unsigned long _Accum, Sula)
-FUNC (_Sat unsigned long long _Accum, Sulla)
+ULLACCUM_TEST (FUNC (_Sat unsigned long long _Accum, Sulla))
 
 int main()
 {
@@ -157,35 +191,35 @@  int main()
   TEST (short _Fract, sf, 0.1hr)
   TEST (_Fract, f, 0.2r)
   TEST (long _Fract, lf, 0.3lr)
-  TEST (long long _Fract, llf, 0.4llr)
+  LLFRACT_TEST (TEST (long long _Fract, llf, 0.4llr))
   TEST (unsigned short _Fract, usf, 0.5uhr)
   TEST (unsigned _Fract, uf, 0.6ur)
   TEST (unsigned long _Fract, ulf, 0.7ulr)
-  TEST (unsigned long long _Fract, ullf, 0.8ullr)
+  ULLFRACT_TEST (TEST (unsigned long long _Fract, ullf, 0.8ullr))
   TEST (_Sat short _Fract, Ssf, 0.11hr)
   TEST (_Sat _Fract, Sf, 0.22r)
   TEST (_Sat long _Fract, Slf, 0.33lr)
-  TEST (_Sat long long _Fract, Sllf, 0.44llr)
+  LLFRACT_TEST (TEST (_Sat long long _Fract, Sllf, 0.44llr))
   TEST (_Sat unsigned short _Fract, Susf, 0.55uhr)
   TEST (_Sat unsigned _Fract, Suf, 0.66ur)
   TEST (_Sat unsigned long _Fract, Sulf, 0.77ulr)
-  TEST (_Sat unsigned long long _Fract, Sullf, 0.88ullr)
+  ULLFRACT_TEST (TEST (_Sat unsigned long long _Fract, Sullf, 0.88ullr))
   TEST (short _Accum, sa, 0.1hk)
   TEST (_Accum, a, 0.2k)
   TEST (long _Accum, la, 0.3lk)
-  TEST (long long _Accum, lla, 0.4llk)
+  LLACCUM_TEST (TEST (long long _Accum, lla, 0.4llk))
   TEST (unsigned short _Accum, usa, 0.5uhk)
   TEST (unsigned _Accum, ua, 0.6uk)
   TEST (unsigned long _Accum, ula, 0.7ulk)
-  TEST (unsigned long long _Accum, ulla, 0.8ullk)
+  ULLACCUM_TEST (TEST (unsigned long long _Accum, ulla, 0.8ullk))
   TEST (_Sat short _Accum, Ssa, 0.11hk)
   TEST (_Sat _Accum, Sa, 0.22k)
   TEST (_Sat long _Accum, Sla, 0.33lk)
-  TEST (_Sat long long _Accum, Slla, 0.44llk)
+  LLACCUM_TEST (TEST (_Sat long long _Accum, Slla, 0.44llk))
   TEST (_Sat unsigned short _Accum, Susa, 0.55uhk)
   TEST (_Sat unsigned _Accum, Sua, 0.66uk)
   TEST (_Sat unsigned long _Accum, Sula, 0.77ulk)
-  TEST (_Sat unsigned long long _Accum, Sulla, 0.88ullk)
+  ULLACCUM_TEST (TEST (_Sat unsigned long long _Accum, Sulla, 0.88ullk))
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/func-vararg-mixed.c b/gcc/testsuite/gcc.dg/fixed-point/func-vararg-mixed.c
index 61a30e7..6887521 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/func-vararg-mixed.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/func-vararg-mixed.c
@@ -5,6 +5,8 @@ 
    Test passing varargs of fixed-point types.
    Based on the test from ../dfp/.  */
 
+#include "longlong-support.h"
+
 #include <stdarg.h>
 
 extern void abort (void);
@@ -66,35 +68,35 @@  vararg_ ## NAME (unsigned arg, ...) \
 FUNC (short _Fract, sf)
 FUNC (_Fract, f)
 FUNC (long _Fract, lf)
-FUNC (long long _Fract, llf)
+LLFRACT_TEST (FUNC (long long _Fract, llf))
 FUNC (unsigned short _Fract, usf)
 FUNC (unsigned _Fract, uf)
 FUNC (unsigned long _Fract, ulf)
-FUNC (unsigned long long _Fract, ullf)
+ULLFRACT_TEST (FUNC (unsigned long long _Fract, ullf))
 FUNC (_Sat short _Fract, Ssf)
 FUNC (_Sat _Fract, Sf)
 FUNC (_Sat long _Fract, Slf)
-FUNC (_Sat long long _Fract, Sllf)
+LLFRACT_TEST (FUNC (_Sat long long _Fract, Sllf))
 FUNC (_Sat unsigned short _Fract, Susf)
 FUNC (_Sat unsigned _Fract, Suf)
 FUNC (_Sat unsigned long _Fract, Sulf)
-FUNC (_Sat unsigned long long _Fract, Sullf)
+ULLFRACT_TEST (FUNC (_Sat unsigned long long _Fract, Sullf))
 FUNC (short _Accum, sa)
 FUNC (_Accum, a)
 FUNC (long _Accum, la)
-FUNC (long long _Accum, lla)
+LLACCUM_TEST (FUNC (long long _Accum, lla))
 FUNC (unsigned short _Accum, usa)
 FUNC (unsigned _Accum, ua)
 FUNC (unsigned long _Accum, ula)
-FUNC (unsigned long long _Accum, ulla)
+ULLACCUM_TEST (FUNC (unsigned long long _Accum, ulla))
 FUNC (_Sat short _Accum, Ssa)
 FUNC (_Sat _Accum, Sa)
 FUNC (_Sat long _Accum, Sla)
-FUNC (_Sat long long _Accum, Slla)
+LLACCUM_TEST (FUNC (_Sat long long _Accum, Slla))
 FUNC (_Sat unsigned short _Accum, Susa)
 FUNC (_Sat unsigned _Accum, Sua)
 FUNC (_Sat unsigned long _Accum, Sula)
-FUNC (_Sat unsigned long long _Accum, Sulla)
+ULLACCUM_TEST (FUNC (_Sat unsigned long long _Accum, Sulla))
 
 int main()
 {
@@ -111,35 +113,35 @@  int main()
   TEST(sf, hr)
   TEST(f, r)
   TEST(lf, lr)
-  TEST(llf, llr)
+  LLFRACT_TEST (TEST(llf, llr))
   TEST(usf, uhr)
   TEST(uf, ur)
   TEST(ulf, ulr)
-  TEST(ullf, ullr)
+  ULLFRACT_TEST (TEST(ullf, ullr))
   TEST(Ssf, hr)
   TEST(Sf, r)
   TEST(Slf, lr)
-  TEST(Sllf, llr)
+  LLFRACT_TEST (TEST(Sllf, llr))
   TEST(Susf, uhr)
   TEST(Suf, ur)
   TEST(Sulf, ulr)
-  TEST(Sullf, ullr)
+  ULLFRACT_TEST (TEST(Sullf, ullr))
   TEST(sa, hk)
   TEST(a, k)
   TEST(la, lk)
-  TEST(lla, llk)
+  LLACCUM_TEST (TEST(lla, llk))
   TEST(usa, uhk)
   TEST(ua, uk)
   TEST(ula, ulk)
-  TEST(ulla, ullk)
+  ULLACCUM_TEST (TEST(ulla, ullk))
   TEST(Ssa, hk)
   TEST(Sa, k)
   TEST(Sla, lk)
-  TEST(Slla, llk)
+  LLACCUM_TEST (TEST(Slla, llk))
   TEST(Susa, uhk)
   TEST(Sua, uk)
   TEST(Sula, ulk)
-  TEST(Sulla, ullk)
+  ULLACCUM_TEST (TEST(Sulla, ullk))
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/func-vararg.c b/gcc/testsuite/gcc.dg/fixed-point/func-vararg.c
index 9f517ae..84dadff 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/func-vararg.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/func-vararg.c
@@ -6,6 +6,7 @@ 
    Based on the test from ../dfp/.  */
 
 #include <stdarg.h>
+#include "longlong-support.h"
 
 extern void abort (void);
 
@@ -26,35 +27,35 @@  vararg_ ## NAME (unsigned arg, ...) \
 FUNC (short _Fract, sf)
 FUNC (_Fract, f)
 FUNC (long _Fract, lf)
-FUNC (long long _Fract, llf)
+LLFRACT_TEST (FUNC (long long _Fract, llf))
 FUNC (unsigned short _Fract, usf)
 FUNC (unsigned _Fract, uf)
 FUNC (unsigned long _Fract, ulf)
-FUNC (unsigned long long _Fract, ullf)
+ULLFRACT_TEST (FUNC (unsigned long long _Fract, ullf))
 FUNC (_Sat short _Fract, Ssf)
 FUNC (_Sat _Fract, Sf)
 FUNC (_Sat long _Fract, Slf)
-FUNC (_Sat long long _Fract, Sllf)
+LLFRACT_TEST (FUNC (_Sat long long _Fract, Sllf))
 FUNC (_Sat unsigned short _Fract, Susf)
 FUNC (_Sat unsigned _Fract, Suf)
 FUNC (_Sat unsigned long _Fract, Sulf)
-FUNC (_Sat unsigned long long _Fract, Sullf)
+ULLFRACT_TEST (FUNC (_Sat unsigned long long _Fract, Sullf))
 FUNC (short _Accum, sa)
 FUNC (_Accum, a)
 FUNC (long _Accum, la)
-FUNC (long long _Accum, lla)
+LLACCUM_TEST (FUNC (long long _Accum, lla))
 FUNC (unsigned short _Accum, usa)
 FUNC (unsigned _Accum, ua)
 FUNC (unsigned long _Accum, ula)
-FUNC (unsigned long long _Accum, ulla)
+ULLACCUM_TEST (FUNC (unsigned long long _Accum, ulla))
 FUNC (_Sat short _Accum, Ssa)
 FUNC (_Sat _Accum, Sa)
 FUNC (_Sat long _Accum, Sla)
-FUNC (_Sat long long _Accum, Slla)
+LLACCUM_TEST (FUNC (_Sat long long _Accum, Slla))
 FUNC (_Sat unsigned short _Accum, Susa)
 FUNC (_Sat unsigned _Accum, Sua)
 FUNC (_Sat unsigned long _Accum, Sula)
-FUNC (_Sat unsigned long long _Accum, Sulla)
+ULLACCUM_TEST (FUNC (_Sat unsigned long long _Accum, Sulla))
 
 int main()
 {
@@ -81,35 +82,35 @@  int main()
   TEST(sf, hr)
   TEST(f, r)
   TEST(lf, lr)
-  TEST(llf, llr)
+  LLFRACT_TEST (TEST(llf, llr))
   TEST(usf, uhr)
   TEST(uf, ur)
   TEST(ulf, ulr)
-  TEST(ullf, ullr)
+  ULLFRACT_TEST (TEST(ullf, ullr))
   TEST(Ssf, hr)
   TEST(Sf, r)
   TEST(Slf, lr)
-  TEST(Sllf, llr)
+  LLFRACT_TEST (TEST(Sllf, llr))
   TEST(Susf, uhr)
   TEST(Suf, ur)
   TEST(Sulf, ulr)
-  TEST(Sullf, ullr)
+  ULLFRACT_TEST (TEST(Sullf, ullr))
   TEST(sa, hk)
   TEST(a, k)
   TEST(la, lk)
-  TEST(lla, llk)
+  LLACCUM_TEST (TEST(lla, llk))
   TEST(usa, uhk)
   TEST(ua, uk)
   TEST(ula, ulk)
-  TEST(ulla, ullk)
+  ULLACCUM_TEST (TEST(ulla, ullk))
   TEST(Ssa, hk)
   TEST(Sa, k)
   TEST(Sla, lk)
-  TEST(Slla, llk)
+  LLACCUM_TEST (TEST(Slla, llk))
   TEST(Susa, uhk)
   TEST(Sua, uk)
   TEST(Sula, ulk)
-  TEST(Sulla, ullk)
+  ULLACCUM_TEST (TEST(Sulla, ullk))
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/longlong-support.h b/gcc/testsuite/gcc.dg/fixed-point/longlong-support.h
new file mode 100644
index 0000000..a811d17
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fixed-point/longlong-support.h
@@ -0,0 +1,31 @@ 
+#if __LLFRACT_FBIT__ <= (__SIZEOF_LONG_LONG__ * 8)
+#define LLFRACT_TEST(X) X
+#define DO_LLFRACT_TESTS 1
+#else
+#define LLFRACT_TEST(X)
+#define DO_LLFRACT_TESTS 0
+#endif
+
+#if __ULLFRACT_FBIT__ <= (__SIZEOF_LONG_LONG__ * 8)
+#define ULLFRACT_TEST(X) X
+#define DO_ULLFRACT_TESTS 1
+#else
+#define ULLFRACT_TEST(X)
+#define DO_ULLFRACT_TESTS 0
+#endif
+
+#if (__LLACCUM_IBIT__ + __LLACCUM_FBIT__) <= (__SIZEOF_LONG_LONG__ * 8)
+#define LLACCUM_TEST(X) X
+#define DO_LLACCUM_TESTS 1
+#else
+#define LLACCUM_TEST(X)
+#define DO_LLACCUM_TESTS 0
+#endif
+
+#if (__ULLACCUM_IBIT__ + __ULLACCUM_FBIT__) <= (__SIZEOF_LONG_LONG__ * 8)
+#define ULLACCUM_TEST(X) X
+#define DO_ULLACCUM_TESTS 1
+#else
+#define ULLACCUM_TEST(X)
+#define DO_ULLACCUM_TESTS 0
+#endif
diff --git a/gcc/testsuite/gcc.dg/fixed-point/loop-index.c b/gcc/testsuite/gcc.dg/fixed-point/loop-index.c
index d7ed911..a3271a0 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/loop-index.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/loop-index.c
@@ -4,6 +4,8 @@ 
 /* C99 6.8.5.2: The for statement.
    Based on the test from ../dfp/.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 
 #define FUNC(TYPE,NAME,PF) \
@@ -21,35 +23,35 @@  NAME (void) \
 FUNC (short _Fract, sf, hr)
 FUNC (_Fract, f, r)
 FUNC (long _Fract, lf, lr)
-FUNC (long long _Fract, llf, llr)
+LLFRACT_TEST (FUNC (long long _Fract, llf, llr))
 FUNC (unsigned short _Fract, usf, uhr)
 FUNC (unsigned _Fract, uf, ur)
 FUNC (unsigned long _Fract, ulf, ulr)
-FUNC (unsigned long long _Fract, ullf, ullr)
+ULLFRACT_TEST (FUNC (unsigned long long _Fract, ullf, ullr))
 FUNC (_Sat short _Fract, Ssf, hr)
 FUNC (_Sat _Fract, Sf, r)
 FUNC (_Sat long _Fract, Slf, lr)
-FUNC (_Sat long long _Fract, Sllf, llr)
+LLFRACT_TEST (FUNC (_Sat long long _Fract, Sllf, llr))
 FUNC (_Sat unsigned short _Fract, Susf, uhr)
 FUNC (_Sat unsigned _Fract, Suf, ur)
 FUNC (_Sat unsigned long _Fract, Sulf, ulr)
-FUNC (_Sat unsigned long long _Fract, Sullf, ullr)
+ULLFRACT_TEST (FUNC (_Sat unsigned long long _Fract, Sullf, ullr))
 FUNC (short _Accum, sa, hk)
 FUNC (_Accum, a, k)
 FUNC (long _Accum, la, lk)
-FUNC (long long _Accum, lla, llk)
+LLACCUM_TEST (FUNC (long long _Accum, lla, llk))
 FUNC (unsigned short _Accum, usa, uhk)
 FUNC (unsigned _Accum, ua, uk)
 FUNC (unsigned long _Accum, ula, ulk)
-FUNC (unsigned long long _Accum, ulla, ullk)
+ULLACCUM_TEST (FUNC (unsigned long long _Accum, ulla, ullk))
 FUNC (_Sat short _Accum, Ssa, hk)
 FUNC (_Sat _Accum, Sa, k)
 FUNC (_Sat long _Accum, Sla, lk)
-FUNC (_Sat long long _Accum, Slla, llk)
+LLACCUM_TEST (FUNC (_Sat long long _Accum, Slla, llk))
 FUNC (_Sat unsigned short _Accum, Susa, uhk)
 FUNC (_Sat unsigned _Accum, Sua, uk)
 FUNC (_Sat unsigned long _Accum, Sula, ulk)
-FUNC (_Sat unsigned long long _Accum, Sulla, ullk)
+ULLACCUM_TEST (FUNC (_Sat unsigned long long _Accum, Sulla, ullk))
 
 int
 main ()
@@ -57,35 +59,35 @@  main ()
   sf ();
   f ();
   lf ();
-  llf ();
+  LLFRACT_TEST (llf ());
   usf ();
   uf ();
   ulf ();
-  ullf ();
+  ULLFRACT_TEST (ullf ());
   Ssf ();
   Sf ();
   Slf ();
-  Sllf ();
+  LLFRACT_TEST (Sllf ());
   Susf ();
   Suf ();
   Sulf ();
-  Sullf ();
+  ULLFRACT_TEST (Sullf ());
   sa ();
   a ();
   la ();
-  lla ();
+  LLACCUM_TEST (lla ());
   usa ();
   ua ();
   ula ();
-  ulla ();
+  ULLACCUM_TEST (ulla ());
   Ssa ();
   Sa ();
   Sla ();
-  Slla ();
+  LLACCUM_TEST (Slla ());
   Susa ();
   Sua ();
   Sula ();
-  Sulla ();
+  ULLACCUM_TEST (Sulla ());
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/muldiv-warning.c b/gcc/testsuite/gcc.dg/fixed-point/muldiv-warning.c
index 4ac5531..17781f8 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/muldiv-warning.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/muldiv-warning.c
@@ -1,72 +1,74 @@ 
 /* { dg-do compile } */
 /* { dg-options "-std=gnu99" } */
 
+#include "longlong-support.h"
+
 /* Check if GCC generates warnings when overflows for mul and div.  */
 
 short _Fract sf0 = __SFRACT_MIN__ * __SFRACT_MIN__; /* { dg-warning "overflow" } */
 _Fract f0 = __FRACT_MIN__ * __FRACT_MIN__; /* { dg-warning "overflow" } */
 long _Fract lf0 = __LFRACT_MIN__ * __LFRACT_MIN__; /* { dg-warning "overflow" } */
-long long _Fract llf0 = __LLFRACT_MIN__ * __LLFRACT_MIN__; /* { dg-warning "overflow" } */
+LLFRACT_TEST (long long _Fract llf0 = __LLFRACT_MIN__ * __LLFRACT_MIN__); /* { dg-warning "overflow" } */
 short _Fract sf1 = __SFRACT_MAX__ * __SFRACT_MIN__;
 _Fract f1 = __FRACT_MAX__ * __FRACT_MIN__;
 long _Fract lf1 = __LFRACT_MAX__ * __LFRACT_MIN__;
-long long _Fract llf1 = __LLFRACT_MAX__ * __LLFRACT_MIN__;
+LLFRACT_TEST (long long _Fract llf1 = __LLFRACT_MAX__ * __LLFRACT_MIN__);
 short _Fract sf2 = __SFRACT_MIN__ / __SFRACT_MIN__; /* { dg-warning "overflow" } */
 _Fract f2 = __FRACT_MIN__ / __FRACT_MIN__; /* { dg-warning "overflow" } */
 long _Fract lf2 = __LFRACT_MIN__ / __LFRACT_MIN__; /* { dg-warning "overflow" } */
-long long _Fract llf2 = __LLFRACT_MIN__ / __LLFRACT_MIN__; /* { dg-warning "overflow" } */
+LLFRACT_TEST (long long _Fract llf2 = __LLFRACT_MIN__ / __LLFRACT_MIN__); /* { dg-warning "overflow" } */
 short _Fract sf3 = __SFRACT_MAX__ / __SFRACT_MIN__;
 _Fract f3 = __FRACT_MAX__ / __FRACT_MIN__;
 long _Fract lf3 = __LFRACT_MAX__ / __LFRACT_MIN__;
-long long _Fract llf3 = __LLFRACT_MAX__ / __LLFRACT_MIN__;
+LLFRACT_TEST (long long _Fract llf3 = __LLFRACT_MAX__ / __LLFRACT_MIN__);
 
 unsigned short _Fract usf0 = __USFRACT_MIN__ * __USFRACT_MIN__;
 unsigned _Fract uf0 = __UFRACT_MIN__ * __UFRACT_MIN__;
 unsigned long _Fract ulf0 = __ULFRACT_MIN__ * __ULFRACT_MIN__;
-unsigned long long _Fract ullf0 = __ULLFRACT_MIN__ * __ULLFRACT_MIN__;
+ULLFRACT_TEST (unsigned long long _Fract ullf0 = __ULLFRACT_MIN__ * __ULLFRACT_MIN__);
 unsigned short _Fract usf1 = __USFRACT_MAX__ * __USFRACT_MIN__;
 unsigned _Fract uf1 = __UFRACT_MAX__ * __UFRACT_MIN__;
 unsigned long _Fract ulf1 = __ULFRACT_MAX__ * __ULFRACT_MIN__;
-unsigned long long _Fract ullf1 = __ULLFRACT_MAX__ * __ULLFRACT_MIN__;
+ULLFRACT_TEST (unsigned long long _Fract ullf1 = __ULLFRACT_MAX__ * __ULLFRACT_MIN__);
 unsigned short _Fract usf2 = __USFRACT_MAX__ / __USFRACT_MAX__; /* { dg-warning "overflow" } */
 unsigned _Fract uf2 = __UFRACT_MAX__ / __UFRACT_MAX__; /* { dg-warning "overflow" } */
 unsigned long _Fract ulf2 = __ULFRACT_MAX__ / __ULFRACT_MAX__; /* { dg-warning "overflow" } */
-unsigned long long _Fract ullf2 = __ULLFRACT_MAX__ / __ULLFRACT_MAX__; /* { dg-warning "overflow" } */
+ULLFRACT_TEST (unsigned long long _Fract ullf2 = __ULLFRACT_MAX__ / __ULLFRACT_MAX__); /* { dg-warning "overflow" } */
 unsigned short _Fract usf3 = __USFRACT_MIN__ / __USFRACT_MAX__;
 unsigned _Fract uf3 = __UFRACT_MIN__ / __UFRACT_MAX__;
 unsigned long _Fract ulf3 = __ULFRACT_MIN__ / __ULFRACT_MAX__;
-unsigned long long _Fract ullf3 = __ULLFRACT_MIN__ / __ULLFRACT_MAX__;
+ULLFRACT_TEST (unsigned long long _Fract ullf3 = __ULLFRACT_MIN__ / __ULLFRACT_MAX__);
 
 short _Accum sa0 = __SACCUM_MIN__ * __SACCUM_MIN__; /* { dg-warning "overflow" } */
 _Accum a0 = __ACCUM_MIN__ * __ACCUM_MIN__; /* { dg-warning "overflow" } */
 long _Accum la0 = __LACCUM_MIN__ * __LACCUM_MIN__; /* { dg-warning "overflow" } */
-long long _Accum lla0 = __LLACCUM_MIN__ * __LLACCUM_MIN__; /* { dg-warning "overflow" } */
+LLACCUM_TEST (long long _Accum lla0 = __LLACCUM_MIN__ * __LLACCUM_MIN__); /* { dg-warning "overflow" "" { xfail "arm*-*-*" } } */
 short _Accum sa1 = __SACCUM_MAX__ * 0.1hk;
 _Accum a1 = __ACCUM_MAX__ * 0.1k;
 long _Accum la1 = __LACCUM_MAX__ * 0.1lk;
-long long _Accum lla1 = __LLACCUM_MAX__ * 0.1llk;
+LLACCUM_TEST (long long _Accum lla1 = __LLACCUM_MAX__ * 0.1llk);
 short _Accum sa2 = __SACCUM_MIN__ / 0.1hk; /* { dg-warning "overflow" } */
 _Accum a2 = __ACCUM_MIN__ / 0.1k; /* { dg-warning "overflow" } */
 long _Accum la2 = __LACCUM_MIN__ / 0.1lk; /* { dg-warning "overflow" } */
-long long _Accum lla2 = __LLACCUM_MIN__ / 0.1llk; /* { dg-warning "overflow" } */
+LLACCUM_TEST (long long _Accum lla2 = __LLACCUM_MIN__ / 0.1llk); /* { dg-warning "overflow" "" { xfail "arm*-*-*" } } */
 short _Accum sa3 = __SACCUM_MAX__ / __SACCUM_MIN__;
 _Accum a3 = __ACCUM_MAX__ / __ACCUM_MIN__;
 long _Accum la3 = __LACCUM_MAX__ / __LACCUM_MIN__;
-long long _Accum lla3 = __LLACCUM_MAX__ / __LLACCUM_MIN__;
+LLACCUM_TEST (long long _Accum lla3 = __LLACCUM_MAX__ / __LLACCUM_MIN__);
 
 unsigned short _Accum usa0 = __USACCUM_MIN__ * __USACCUM_MIN__;
 unsigned _Accum ua0 = __UACCUM_MIN__ * __UACCUM_MIN__;
 unsigned long _Accum ula0 = __ULACCUM_MIN__ * __ULACCUM_MIN__;
-unsigned long long _Accum ulla0 = __ULLACCUM_MIN__ * __ULLACCUM_MIN__;
+ULLACCUM_TEST (unsigned long long _Accum ulla0 = __ULLACCUM_MIN__ * __ULLACCUM_MIN__);
 unsigned short _Accum usa1 = __USACCUM_MAX__ * __USACCUM_MAX__; /* { dg-warning "overflow" } */
 unsigned _Accum ua1 = __UACCUM_MAX__ * __UACCUM_MAX__; /* { dg-warning "overflow" } */
 unsigned long _Accum ula1 = __ULACCUM_MAX__ * __ULACCUM_MAX__; /* { dg-warning "overflow" } */
-unsigned long long _Accum ulla1 = __ULLACCUM_MAX__ * __ULLACCUM_MAX__; /* { dg-warning "overflow" } */
+ULLACCUM_TEST (unsigned long long _Accum ulla1 = __ULLACCUM_MAX__ * __ULLACCUM_MAX__); /* { dg-warning "overflow" "" { xfail "arm*-*-*" } } */
 unsigned short _Accum usa2 = __USACCUM_MAX__ / 0.5hk; /* { dg-warning "overflow" } */
 unsigned _Accum ua2 = __UACCUM_MAX__ / 0.5k; /* { dg-warning "overflow" } */
 unsigned long _Accum ula2 = __ULACCUM_MAX__ / 0.5lk; /* { dg-warning "overflow" } */
-unsigned long long _Accum ulla2 = __ULLACCUM_MAX__ / 0.5llk; /* { dg-warning "overflow" } */
+ULLACCUM_TEST (unsigned long long _Accum ulla2 = __ULLACCUM_MAX__ / 0.5llk); /* { dg-warning "overflow" "" { xfail "arm*-*-*" } } */
 unsigned short _Accum usa3 = __USACCUM_MIN__ / __USACCUM_MAX__;
 unsigned _Accum ua3 = __UACCUM_MIN__ / __UACCUM_MAX__;
 unsigned long _Accum ula3 = __ULACCUM_MIN__ / __ULACCUM_MAX__;
-unsigned long long _Accum ulla3 = __ULLACCUM_MIN__ / __ULLACCUM_MAX__;
+ULLACCUM_TEST (unsigned long long _Accum ulla3 = __ULLACCUM_MIN__ / __ULLACCUM_MAX__);
diff --git a/gcc/testsuite/gcc.dg/fixed-point/operator-comma.c b/gcc/testsuite/gcc.dg/fixed-point/operator-comma.c
index 2f1316c..2d38cf0 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/operator-comma.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/operator-comma.c
@@ -5,6 +5,8 @@ 
    Test with fixed-point operands.
    Based on the test from ../dfp/.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 
 #define FUNC(TYPE,NAME,PF) \
@@ -19,35 +21,35 @@  init_ ## NAME () \
 FUNC (short _Fract, sf, hr)
 FUNC (_Fract, f, r)
 FUNC (long _Fract, lf, lr)
-FUNC (long long _Fract, llf, llr)
+LLFRACT_TEST (FUNC (long long _Fract, llf, llr))
 FUNC (unsigned short _Fract, usf, uhr)
 FUNC (unsigned _Fract, uf, ur)
 FUNC (unsigned long _Fract, ulf, ulr)
-FUNC (long long _Fract, ullf, ullr)
+LLFRACT_TEST (FUNC (long long _Fract, ullf, ullr))
 FUNC (_Sat short _Fract, Ssf, hr)
 FUNC (_Sat _Fract, Sf, r)
 FUNC (_Sat long _Fract, Slf, lr)
-FUNC (_Sat long long _Fract, Sllf, llr)
+LLFRACT_TEST (FUNC (_Sat long long _Fract, Sllf, llr))
 FUNC (_Sat unsigned short _Fract, Susf, uhr)
 FUNC (_Sat unsigned _Fract, Suf, ur)
 FUNC (_Sat unsigned long _Fract, Sulf, ulr)
-FUNC (_Sat long long _Fract, Sullf, ullr)
+LLFRACT_TEST (FUNC (_Sat long long _Fract, Sullf, ullr))
 FUNC (short _Accum, sa, hk)
 FUNC (_Accum, a, k)
 FUNC (long _Accum, la, lk)
-FUNC (long long _Accum, lla, llk)
+LLACCUM_TEST (FUNC (long long _Accum, lla, llk))
 FUNC (unsigned short _Accum, usa, uhk)
 FUNC (unsigned _Accum, ua, uk)
 FUNC (unsigned long _Accum, ula, ulk)
-FUNC (long long _Accum, ulla, ullk)
+LLACCUM_TEST (FUNC (long long _Accum, ulla, ullk))
 FUNC (_Sat short _Accum, Ssa, hk)
 FUNC (_Sat _Accum, Sa, k)
 FUNC (_Sat long _Accum, Sla, lk)
-FUNC (_Sat long long _Accum, Slla, llk)
+LLACCUM_TEST (FUNC (_Sat long long _Accum, Slla, llk))
 FUNC (_Sat unsigned short _Accum, Susa, uhk)
 FUNC (_Sat unsigned _Accum, Sua, uk)
 FUNC (_Sat unsigned long _Accum, Sula, ulk)
-FUNC (_Sat long long _Accum, Sulla, ullk)
+LLACCUM_TEST (FUNC (_Sat long long _Accum, Sulla, ullk))
 
 int
 main ()
@@ -64,35 +66,35 @@  main ()
   TEST(sf)
   TEST(f)
   TEST(lf)
-  TEST(llf)
+  LLFRACT_TEST (TEST(llf))
   TEST(usf)
   TEST(uf)
   TEST(ulf)
-  TEST(ullf)
+  ULLFRACT_TEST (TEST(ullf))
   TEST(Ssf)
   TEST(Sf)
   TEST(Slf)
-  TEST(Sllf)
+  LLFRACT_TEST (TEST(Sllf))
   TEST(Susf)
   TEST(Suf)
   TEST(Sulf)
-  TEST(Sullf)
+  ULLFRACT_TEST (TEST(Sullf))
   TEST(sa)
   TEST(a)
   TEST(la)
-  TEST(lla)
+  LLACCUM_TEST (TEST(lla))
   TEST(usa)
   TEST(ua)
   TEST(ula)
-  TEST(ulla)
+  ULLACCUM_TEST (TEST(ulla))
   TEST(Ssa)
   TEST(Sa)
   TEST(Sla)
-  TEST(Slla)
+  LLACCUM_TEST (TEST(Slla))
   TEST(Susa)
   TEST(Sua)
   TEST(Sula)
-  TEST(Sulla)
+  ULLACCUM_TEST (TEST(Sulla))
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/operator-cond.c b/gcc/testsuite/gcc.dg/fixed-point/operator-cond.c
index 94b0de0..3629b0a 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/operator-cond.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/operator-cond.c
@@ -5,6 +5,8 @@ 
    Test with fixed-point operands.
    Based on the test from ../dfp/.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 volatile int yes, no;
 
@@ -22,35 +24,35 @@  init_ ## NAME () \
 FUNC (short _Fract, sf, hr)
 FUNC (_Fract, f, r)
 FUNC (long _Fract, lf, lr)
-FUNC (long long _Fract, llf, llr)
+LLFRACT_TEST (FUNC (long long _Fract, llf, llr))
 FUNC (unsigned short _Fract, usf, uhr)
 FUNC (unsigned _Fract, uf, ur)
 FUNC (unsigned long _Fract, ulf, ulr)
-FUNC (long long _Fract, ullf, ullr)
+LLFRACT_TEST (FUNC (long long _Fract, ullf, ullr))
 FUNC (_Sat short _Fract, Ssf, hr)
 FUNC (_Sat _Fract, Sf, r)
 FUNC (_Sat long _Fract, Slf, lr)
-FUNC (_Sat long long _Fract, Sllf, llr)
+LLFRACT_TEST (FUNC (_Sat long long _Fract, Sllf, llr))
 FUNC (_Sat unsigned short _Fract, Susf, uhr)
 FUNC (_Sat unsigned _Fract, Suf, ur)
 FUNC (_Sat unsigned long _Fract, Sulf, ulr)
-FUNC (_Sat long long _Fract, Sullf, ullr)
+LLFRACT_TEST (FUNC (_Sat long long _Fract, Sullf, ullr))
 FUNC (short _Accum, sa, hk)
 FUNC (_Accum, a, k)
 FUNC (long _Accum, la, lk)
-FUNC (long long _Accum, lla, llk)
+LLACCUM_TEST (FUNC (long long _Accum, lla, llk))
 FUNC (unsigned short _Accum, usa, uhk)
 FUNC (unsigned _Accum, ua, uk)
 FUNC (unsigned long _Accum, ula, ulk)
-FUNC (long long _Accum, ulla, ullk)
+LLACCUM_TEST (FUNC (long long _Accum, ulla, ullk))
 FUNC (_Sat short _Accum, Ssa, hk)
 FUNC (_Sat _Accum, Sa, k)
 FUNC (_Sat long _Accum, Sla, lk)
-FUNC (_Sat long long _Accum, Slla, llk)
+LLACCUM_TEST (FUNC (_Sat long long _Accum, Slla, llk))
 FUNC (_Sat unsigned short _Accum, Susa, uhk)
 FUNC (_Sat unsigned _Accum, Sua, uk)
 FUNC (_Sat unsigned long _Accum, Sula, ulk)
-FUNC (_Sat long long _Accum, Sulla, ullk)
+LLACCUM_TEST (FUNC (_Sat long long _Accum, Sulla, ullk))
 
 int
 main ()
@@ -67,35 +69,35 @@  main ()
   TEST(sf)
   TEST(f)
   TEST(lf)
-  TEST(llf)
+  LLFRACT_TEST (TEST(llf))
   TEST(usf)
   TEST(uf)
   TEST(ulf)
-  TEST(ullf)
+  ULLFRACT_TEST (TEST(ullf))
   TEST(Ssf)
   TEST(Sf)
   TEST(Slf)
-  TEST(Sllf)
+  LLFRACT_TEST (TEST(Sllf))
   TEST(Susf)
   TEST(Suf)
   TEST(Sulf)
-  TEST(Sullf)
+  ULLFRACT_TEST (TEST(Sullf))
   TEST(sa)
   TEST(a)
   TEST(la)
-  TEST(lla)
+  LLACCUM_TEST (TEST(lla))
   TEST(usa)
   TEST(ua)
   TEST(ula)
-  TEST(ulla)
+  ULLACCUM_TEST (TEST(ulla))
   TEST(Ssa)
   TEST(Sa)
   TEST(Sla)
-  TEST(Slla)
+  LLACCUM_TEST (TEST(Slla))
   TEST(Susa)
   TEST(Sua)
   TEST(Sula)
-  TEST(Sulla)
+  ULLACCUM_TEST (TEST(Sulla))
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/operator-logical.c b/gcc/testsuite/gcc.dg/fixed-point/operator-logical.c
index 3873b25..4734403 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/operator-logical.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/operator-logical.c
@@ -6,6 +6,8 @@ 
    Test with fixed-point operands.
    Based on the test from ../dfp/.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 
 #define OPERATE(OPRD1,OPRT,OPRD2,RLT)	\
@@ -46,70 +48,70 @@  main ()
   short _Fract sf;
   _Fract f;
   long _Fract lf;
-  long long _Fract llf;
+  LLFRACT_TEST (long long _Fract llf);
   unsigned short _Fract usf;
   unsigned _Fract uf;
   unsigned long _Fract ulf;
-  unsigned long long _Fract ullf;
+  ULLFRACT_TEST (unsigned long long _Fract ullf);
   _Sat short _Fract Ssf;
   _Sat _Fract Sf;
   _Sat long _Fract Slf;
-  _Sat long long _Fract Sllf;
+  LLFRACT_TEST (_Sat long long _Fract Sllf);
   _Sat unsigned short _Fract Susf;
   _Sat unsigned _Fract Suf;
   _Sat unsigned long _Fract Sulf;
-  _Sat unsigned long long _Fract Sullf;
+  ULLFRACT_TEST (_Sat unsigned long long _Fract Sullf);
   short _Accum sa;
   _Accum a;
   long _Accum la;
-  long long _Accum lla;
+  LLACCUM_TEST (long long _Accum lla);
   unsigned short _Accum usa;
   unsigned _Accum ua;
   unsigned long _Accum ula;
-  unsigned long long _Accum ulla;
+  ULLACCUM_TEST (unsigned long long _Accum ulla);
   _Sat short _Accum Ssa;
   _Sat _Accum Sa;
   _Sat long _Accum Sla;
-  _Sat long long _Accum Slla;
+  LLACCUM_TEST (_Sat long long _Accum Slla);
   _Sat unsigned short _Accum Susa;
   _Sat unsigned _Accum Sua;
   _Sat unsigned long _Accum Sula;
-  _Sat unsigned long long _Accum Sulla;
+  ULLACCUM_TEST (_Sat unsigned long long _Accum Sulla);
 
   /* C99 Section 6.5.{13,14} Logical operator.  Constraints Each of the
      operands shall have scalar type.  Fixed-point types would obey this.  */
   FIXED_POINT_LOGICAL (sf);
   FIXED_POINT_LOGICAL (f);
   FIXED_POINT_LOGICAL (lf);
-  FIXED_POINT_LOGICAL (llf);
+  LLFRACT_TEST (FIXED_POINT_LOGICAL (llf));
   FIXED_POINT_LOGICAL (usf);
   FIXED_POINT_LOGICAL (uf);
   FIXED_POINT_LOGICAL (ulf);
-  FIXED_POINT_LOGICAL (ullf);
+  ULLFRACT_TEST (FIXED_POINT_LOGICAL (ullf));
   FIXED_POINT_LOGICAL (Ssf);
   FIXED_POINT_LOGICAL (Sf);
   FIXED_POINT_LOGICAL (Slf);
-  FIXED_POINT_LOGICAL (Sllf);
+  LLFRACT_TEST (FIXED_POINT_LOGICAL (Sllf));
   FIXED_POINT_LOGICAL (Susf);
   FIXED_POINT_LOGICAL (Suf);
   FIXED_POINT_LOGICAL (Sulf);
-  FIXED_POINT_LOGICAL (Sullf);
+  ULLFRACT_TEST (FIXED_POINT_LOGICAL (Sullf));
   FIXED_POINT_LOGICAL (sa);
   FIXED_POINT_LOGICAL (a);
   FIXED_POINT_LOGICAL (la);
-  FIXED_POINT_LOGICAL (lla);
+  LLACCUM_TEST (FIXED_POINT_LOGICAL (lla));
   FIXED_POINT_LOGICAL (usa);
   FIXED_POINT_LOGICAL (ua);
   FIXED_POINT_LOGICAL (ula);
-  FIXED_POINT_LOGICAL (ulla);
+  ULLACCUM_TEST (FIXED_POINT_LOGICAL (ulla));
   FIXED_POINT_LOGICAL (Ssa);
   FIXED_POINT_LOGICAL (Sa);
   FIXED_POINT_LOGICAL (Sla);
-  FIXED_POINT_LOGICAL (Slla);
+  LLACCUM_TEST (FIXED_POINT_LOGICAL (Slla));
   FIXED_POINT_LOGICAL (Susa);
   FIXED_POINT_LOGICAL (Sua);
   FIXED_POINT_LOGICAL (Sula);
-  FIXED_POINT_LOGICAL (Sulla);
+  ULLACCUM_TEST (FIXED_POINT_LOGICAL (Sulla));
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/fixed-point/unary.c b/gcc/testsuite/gcc.dg/fixed-point/unary.c
index 4e09549..558be97 100644
--- a/gcc/testsuite/gcc.dg/fixed-point/unary.c
+++ b/gcc/testsuite/gcc.dg/fixed-point/unary.c
@@ -5,6 +5,8 @@ 
 
    Check unary operators ++ -- + - !.  */
 
+#include "longlong-support.h"
+
 extern void abort (void);
 
 #define INCDEC(TYPE,POSTFIX) \
@@ -109,148 +111,148 @@  int main ()
   FRACT_INCDEC(short _Fract, hr);
   FRACT_INCDEC(_Fract, r);
   FRACT_INCDEC(long _Fract, lr);
-  FRACT_INCDEC(long long _Fract, llr);
+  LLFRACT_TEST (FRACT_INCDEC(long long _Fract, llr));
   FRACT_INCDEC(_Sat short _Fract, hr);
   FRACT_INCDEC(_Sat _Fract, r);
   FRACT_INCDEC(_Sat long _Fract, lr);
-  FRACT_INCDEC(_Sat long long _Fract, llr);
+  LLFRACT_TEST (FRACT_INCDEC(_Sat long long _Fract, llr));
 
   INCDEC(short _Accum, hk);
   INCDEC(_Accum, k);
   INCDEC(long _Accum, lk);
-  INCDEC(long long _Accum, llk);
+  LLACCUM_TEST (INCDEC(long long _Accum, llk));
   INCDEC(unsigned short _Accum, uhk);
   INCDEC(unsigned _Accum, uk);
   INCDEC(unsigned long _Accum, ulk);
-  INCDEC(unsigned long long _Accum, ullk);
+  ULLACCUM_TEST (INCDEC(unsigned long long _Accum, ullk));
   INCDEC(_Sat short _Accum, hk);
   INCDEC(_Sat _Accum, k);
   INCDEC(_Sat long _Accum, lk);
-  INCDEC(_Sat long long _Accum, llk);
+  LLACCUM_TEST (INCDEC(_Sat long long _Accum, llk));
   INCDEC(_Sat unsigned short _Accum, uhk);
   INCDEC(_Sat unsigned _Accum, uk);
   INCDEC(_Sat unsigned long _Accum, ulk);
-  INCDEC(_Sat unsigned long long _Accum, ullk);
+  ULLACCUM_TEST (INCDEC(_Sat unsigned long long _Accum, ullk));
 
   FRACT_SAT_INCDEC(_Sat short _Fract, hr);
   FRACT_SAT_INCDEC(_Sat _Fract, r);
   FRACT_SAT_INCDEC(_Sat long _Fract, lr);
-  FRACT_SAT_INCDEC(_Sat long long _Fract, llr);
+  LLFRACT_TEST (FRACT_SAT_INCDEC(_Sat long long _Fract, llr));
 
   FRACT_SAT_UNS_INCDEC(_Sat unsigned short _Fract, uhr);
   FRACT_SAT_UNS_INCDEC(_Sat unsigned _Fract, ur);
   FRACT_SAT_UNS_INCDEC(_Sat unsigned long _Fract, ulr);
-  FRACT_SAT_UNS_INCDEC(_Sat unsigned long long _Fract, ullr);
+  ULLFRACT_TEST (FRACT_SAT_UNS_INCDEC(_Sat unsigned long long _Fract, ullr));
 
   PLUS(short _Fract, hr);
   PLUS(_Fract, r);
   PLUS(long _Fract, lr);
-  PLUS(long long _Fract, llr);
+  LLFRACT_TEST (PLUS(long long _Fract, llr));
   PLUS(unsigned short _Fract, uhr);
   PLUS(unsigned _Fract, ur);
   PLUS(unsigned long _Fract, ulr);
-  PLUS(unsigned long long _Fract, ullr);
+  ULLFRACT_TEST (PLUS(unsigned long long _Fract, ullr));
   PLUS(_Sat short _Fract, hr);
   PLUS(_Sat _Fract, r);
   PLUS(_Sat long _Fract, lr);
-  PLUS(_Sat long long _Fract, llr);
+  LLFRACT_TEST (PLUS(_Sat long long _Fract, llr));
   PLUS(_Sat unsigned short _Fract, uhr);
   PLUS(_Sat unsigned _Fract, ur);
   PLUS(_Sat unsigned long _Fract, ulr);
-  PLUS(_Sat unsigned long long _Fract, ullr);
+  ULLFRACT_TEST (PLUS(_Sat unsigned long long _Fract, ullr));
   PLUS(short _Accum, hk);
   PLUS(_Accum, k);
   PLUS(long _Accum, lk);
-  PLUS(long long _Accum, llk);
+  LLACCUM_TEST (PLUS(long long _Accum, llk));
   PLUS(unsigned short _Accum, uhk);
   PLUS(unsigned _Accum, uk);
   PLUS(unsigned long _Accum, ulk);
-  PLUS(unsigned long long _Accum, ullk);
+  ULLACCUM_TEST (PLUS(unsigned long long _Accum, ullk));
   PLUS(_Sat short _Accum, hk);
   PLUS(_Sat _Accum, k);
   PLUS(_Sat long _Accum, lk);
-  PLUS(_Sat long long _Accum, llk);
+  LLACCUM_TEST (PLUS(_Sat long long _Accum, llk));
   PLUS(_Sat unsigned short _Accum, uhk);
   PLUS(_Sat unsigned _Accum, uk);
   PLUS(_Sat unsigned long _Accum, ulk);
-  PLUS(_Sat unsigned long long _Accum, ullk);
+  ULLACCUM_TEST (PLUS(_Sat unsigned long long _Accum, ullk));
 
   NEG(short _Fract, hr);
   NEG(_Fract, r);
   NEG(long _Fract, lr);
-  NEG(long long _Fract, llr);
+  LLFRACT_TEST (NEG(long long _Fract, llr));
   NEG(_Sat short _Fract, hr);
   NEG(_Sat _Fract, r);
   NEG(_Sat long _Fract, lr);
-  NEG(_Sat long long _Fract, llr);
+  LLFRACT_TEST (NEG(_Sat long long _Fract, llr));
   NEG(short _Accum, hk);
   NEG(_Accum, k);
   NEG(long _Accum, lk);
-  NEG(long long _Accum, llk);
+  LLACCUM_TEST (NEG(long long _Accum, llk));
   NEG(_Sat short _Accum, hk);
   NEG(_Sat _Accum, k);
   NEG(_Sat long _Accum, lk);
-  NEG(_Sat long long _Accum, llk);
+  LLACCUM_TEST (NEG(_Sat long long _Accum, llk));
 
   FRACT_SAT_NEG(_Sat short _Fract, hr);
   FRACT_SAT_NEG(_Sat _Fract, r);
   FRACT_SAT_NEG(_Sat long _Fract, lr);
-  FRACT_SAT_NEG(_Sat long long _Fract, llr);
+  LLFRACT_TEST (FRACT_SAT_NEG(_Sat long long _Fract, llr));
 
   UNS_NEG(short _Fract, hr);
   UNS_NEG(_Fract, r);
   UNS_NEG(long _Fract, lr);
-  UNS_NEG(long long _Fract, llr);
+  LLFRACT_TEST (UNS_NEG(long long _Fract, llr));
   UNS_NEG(_Sat short _Fract, hr);
   UNS_NEG(_Sat _Fract, r);
   UNS_NEG(_Sat long _Fract, lr);
-  UNS_NEG(_Sat long long _Fract, llr);
+  LLFRACT_TEST (UNS_NEG(_Sat long long _Fract, llr));
   UNS_NEG(short _Accum, hk);
   UNS_NEG(_Accum, k);
   UNS_NEG(long _Accum, lk);
-  UNS_NEG(long long _Accum, llk);
+  LLACCUM_TEST (UNS_NEG(long long _Accum, llk));
   UNS_NEG(_Sat short _Accum, hk);
   UNS_NEG(_Sat _Accum, k);
   UNS_NEG(_Sat long _Accum, lk);
-  UNS_NEG(_Sat long long _Accum, llk);
+  LLACCUM_TEST (UNS_NEG(_Sat long long _Accum, llk));
 
   FRACT_SAT_UNS_NEG(_Sat unsigned short _Fract, uhr);
   FRACT_SAT_UNS_NEG(_Sat unsigned _Fract, ur);
   FRACT_SAT_UNS_NEG(_Sat unsigned long _Fract, ulr);
-  FRACT_SAT_UNS_NEG(_Sat unsigned long long _Fract, ullr);
+  ULLFRACT_TEST (FRACT_SAT_UNS_NEG(_Sat unsigned long long _Fract, ullr));
 
   LOGNEG(short _Fract, hr);
   LOGNEG(_Fract, r);
   LOGNEG(long _Fract, lr);
-  LOGNEG(long long _Fract, llr);
+  LLFRACT_TEST (LOGNEG(long long _Fract, llr));
   LOGNEG(unsigned short _Fract, uhr);
   LOGNEG(unsigned _Fract, ur);
   LOGNEG(unsigned long _Fract, ulr);
-  LOGNEG(unsigned long long _Fract, ullr);
+  ULLFRACT_TEST (LOGNEG(unsigned long long _Fract, ullr));
   LOGNEG(_Sat short _Fract, hr);
   LOGNEG(_Sat _Fract, r);
   LOGNEG(_Sat long _Fract, lr);
-  LOGNEG(_Sat long long _Fract, llr);
+  LLFRACT_TEST (LOGNEG(_Sat long long _Fract, llr));
   LOGNEG(_Sat unsigned short _Fract, uhr);
   LOGNEG(_Sat unsigned _Fract, ur);
   LOGNEG(_Sat unsigned long _Fract, ulr);
-  LOGNEG(_Sat unsigned long long _Fract, ullr);
+  ULLFRACT_TEST (LOGNEG(_Sat unsigned long long _Fract, ullr));
   LOGNEG(short _Accum, hk);
   LOGNEG(_Accum, k);
   LOGNEG(long _Accum, lk);
-  LOGNEG(long long _Accum, llk);
+  LLACCUM_TEST (LOGNEG(long long _Accum, llk));
   LOGNEG(unsigned short _Accum, uhk);
   LOGNEG(unsigned _Accum, uk);
   LOGNEG(unsigned long _Accum, ulk);
-  LOGNEG(unsigned long long _Accum, ullk);
+  ULLACCUM_TEST (LOGNEG(unsigned long long _Accum, ullk));
   LOGNEG(_Sat short _Accum, hk);
   LOGNEG(_Sat _Accum, k);
   LOGNEG(_Sat long _Accum, lk);
-  LOGNEG(_Sat long long _Accum, llk);
+  LLACCUM_TEST (LOGNEG(_Sat long long _Accum, llk));
   LOGNEG(_Sat unsigned short _Accum, uhk);
   LOGNEG(_Sat unsigned _Accum, uk);
   LOGNEG(_Sat unsigned long _Accum, ulk);
-  LOGNEG(_Sat unsigned long long _Accum, ullk);
+  ULLACCUM_TEST (LOGNEG(_Sat unsigned long long _Accum, ullk));
 
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/arm/fixed-point-exec.c b/gcc/testsuite/gcc.target/arm/fixed-point-exec.c
new file mode 100644
index 0000000..6bc3b07
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/fixed-point-exec.c
@@ -0,0 +1,301 @@ 
+/* { dg-do run { target { fixed_point } } } */
+/* { dg-options "-std=gnu99" } */
+
+/* Check basic arithmetic ops for ARM fixed-point/saturating operation support.
+   Not target-independent since we make various assumptions about precision and
+   magnitudes of various types.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdfix.h>
+
+#define TEST(TYPE, OP, NAME, SUFFIX)				\
+  TYPE NAME##SUFFIX (TYPE A, TYPE B)				\
+    {								\
+      return A OP B;						\
+    }
+
+#define VARIANTS(TYPE, OP, NAME)				\
+  TEST (short TYPE, OP, NAME, _short);				\
+  TEST (TYPE, OP, NAME, _regular);				\
+  TEST (long TYPE, OP, NAME, _long);				\
+  TEST (_Sat short TYPE, OP, NAME, _sat_short);			\
+  TEST (_Sat TYPE, OP, NAME, _sat_regular);			\
+  TEST (_Sat long TYPE, OP, NAME, _sat_long);			\
+  TEST (unsigned short TYPE, OP, NAME, _uns_short);		\
+  TEST (unsigned TYPE, OP, NAME, _uns_regular);			\
+  TEST (unsigned long TYPE, OP, NAME, _uns_long);		\
+  TEST (unsigned _Sat short TYPE, OP, NAME, _uns_sat_short);	\
+  TEST (unsigned _Sat TYPE, OP, NAME, _uns_sat_regular);	\
+  TEST (unsigned _Sat long TYPE, OP, NAME, _uns_sat_long)
+
+VARIANTS (_Fract, +, plus_fract);
+VARIANTS (_Accum, +, plus_accum);
+VARIANTS (_Fract, -, minus_fract);
+VARIANTS (_Accum, -, minus_accum);
+VARIANTS (_Fract, *, mult_fract);
+VARIANTS (_Accum, *, mult_accum);
+VARIANTS (_Accum, /, div_accum);
+
+/* Inputs for signed add, multiply fractional tests.  */
+short _Fract sf_a = 0.9hr;
+short _Fract sf_b = -0.8hr;
+_Fract f_a = 0.9r;
+_Fract f_b = -0.8r;
+long _Fract lf_a = 0.9lr;
+long _Fract lf_b = -0.8lr;
+
+/* Inputs for signed subtract fractional tests.  */
+short _Fract sf_c = 0.7hr;
+short _Fract sf_d = 0.9hr;
+_Fract f_c = 0.7r;
+_Fract f_d = 0.9r;
+long _Fract lf_c = 0.7lr;
+long _Fract lf_d = 0.9lr;
+
+/* Inputs for unsigned add, subtract, multiply fractional tests.  */
+unsigned short _Fract usf_a = 0.4uhr;
+unsigned short _Fract usf_b = 0.3uhr;
+unsigned _Fract uf_a = 0.4ur;
+unsigned _Fract uf_b = 0.3ur;
+unsigned long _Fract ulf_a = 0.4ulr;
+unsigned long _Fract ulf_b = 0.3ulr;
+
+/* Inputs for saturating signed add tests.  */
+short _Sat _Fract sf_e = 0.8hr;
+short _Sat _Fract sf_f = 0.8hr;
+_Sat _Fract f_e = 0.8r;
+_Sat _Fract f_f = 0.8r;
+long _Sat _Fract lf_e = 0.8r;
+long _Sat _Fract lf_f = 0.8r;
+
+short _Sat _Fract sf_g = -0.8hr;
+short _Sat _Fract sf_h = -0.8hr;
+_Sat _Fract f_g = -0.8r;
+_Sat _Fract f_h = -0.8r;
+long _Sat _Fract lf_g = -0.8r;
+long _Sat _Fract lf_h = -0.8r;
+
+/* Inputs for saturating unsigned subtract tests.  */
+unsigned short _Sat _Fract usf_c = 0.3uhr;
+unsigned short _Sat _Fract usf_d = 0.4uhr;
+unsigned _Sat _Fract uf_c = 0.3ur;
+unsigned _Sat _Fract uf_d = 0.4ur;
+unsigned long _Sat _Fract ulf_c = 0.3ulr;
+unsigned long _Sat _Fract ulf_d = 0.4ulr;
+
+/* Inputs for signed accumulator tests.  */
+
+short _Accum sa_a = 1.25hk;
+short _Accum sa_b = -1.5hk;
+_Accum a_a = 100.25k;
+_Accum a_b = -100.5k;
+long _Accum la_a = 1000.25lk;
+long _Accum la_b = -1000.5lk;
+
+/* Inputs for unsigned accumulator tests.  */
+
+unsigned short _Accum usa_a = 2.5uhk;
+unsigned short _Accum usa_b = 1.75uhk;
+unsigned _Accum ua_a = 255.5uk;
+unsigned _Accum ua_b = 170.25uk;
+unsigned long _Accum ula_a = 1550.5ulk;
+unsigned long _Accum ula_b = 999.5ulk;
+
+/* Inputs for signed saturating accumulator tests.  */
+
+short _Sat _Accum sa_c = 240.0hk;
+short _Sat _Accum sa_d = 250.0hk;
+short _Sat _Accum sa_e = -240.0hk;
+short _Sat _Accum sa_f = -250.0hk;
+short _Sat _Accum sa_g = 0.5hk;
+
+_Sat _Accum a_c = 65000.0k;
+_Sat _Accum a_d = 20000.0k;
+_Sat _Accum a_e = -65000.0k;
+_Sat _Accum a_f = -20000.0k;
+_Sat _Accum a_g = 0.5k;
+
+long _Sat _Accum la_c = 3472883712.0lk;
+long _Sat _Accum la_d = 3456106496.0lk;
+long _Sat _Accum la_e = -3472883712.0lk;
+long _Sat _Accum la_f = -3456106496.0lk;
+long _Sat _Accum la_g = 0.5lk;
+
+/* Inputs for unsigned saturating accumulator tests.  */
+
+unsigned short _Sat _Accum usa_c = 250.0uhk;
+unsigned short _Sat _Accum usa_d = 240.0uhk;
+unsigned short _Sat _Accum usa_e = 0.5uhk;
+
+unsigned _Sat _Accum ua_c = 65000.0uk;
+unsigned _Sat _Accum ua_d = 20000.0uk;
+unsigned _Sat _Accum ua_e = 0.5uk;
+
+unsigned long _Sat _Accum ula_c = 3472883712.0ulk;
+unsigned long _Sat _Accum ula_d = 3456106496.0ulk;
+unsigned long _Sat _Accum ula_e = 0.5ulk;
+
+#define CHECK(FN, EXP) do {						     \
+  if (fabs ((float) (FN) - (EXP)) > 0.05)				     \
+    {									     \
+      fprintf (stderr, "result for " #FN " (as float): %f\n", (double) (FN));\
+      abort ();								     \
+    }									     \
+  } while (0)
+
+#define CHECK_EXACT(FN, EXP) do {					     \
+  if ((FN) != (EXP))							     \
+    {									     \
+      fprintf (stderr, "result for " #FN " (as float): %f, should be %f\n",  \
+	       (double) (FN), (double) (EXP));				     \
+      abort ();								     \
+    }									     \
+  } while (0)
+
+int
+main (int argc, char *argv[])
+{
+  /* Fract/fract operations, non-saturating.  */
+
+  CHECK (plus_fract_short (sf_a, sf_b), 0.1);
+  CHECK (plus_fract_regular (f_a, f_b), 0.1);
+  CHECK (plus_fract_long (lf_a, lf_b), 0.1);
+
+  CHECK (plus_fract_uns_short (usf_a, usf_b), 0.7);
+  CHECK (plus_fract_uns_regular (uf_a, uf_b), 0.7);
+  CHECK (plus_fract_uns_long (ulf_a, ulf_b), 0.7);
+
+  CHECK (minus_fract_short (sf_c, sf_d), -0.2);
+  CHECK (minus_fract_regular (f_c, f_d), -0.2);
+  CHECK (minus_fract_long (lf_c, lf_d), -0.2);
+
+  CHECK (minus_fract_uns_short (usf_a, usf_b), 0.1);
+  CHECK (minus_fract_uns_regular (uf_a, uf_b), 0.1);
+  CHECK (minus_fract_uns_long (ulf_a, ulf_b), 0.1);
+
+  CHECK (mult_fract_short (sf_a, sf_b), -0.72);
+  CHECK (mult_fract_regular (f_a, f_b), -0.72);
+  CHECK (mult_fract_long (lf_a, lf_b), -0.72);
+
+  CHECK (mult_fract_uns_short (usf_a, usf_b), 0.12);
+  CHECK (mult_fract_uns_regular (uf_a, uf_b), 0.12);
+  CHECK (mult_fract_uns_long (ulf_a, ulf_b), 0.12);
+
+  /* Fract/fract operations, saturating.  */
+
+  CHECK (plus_fract_sat_short (sf_e, sf_f), 1.0);
+  CHECK (plus_fract_sat_regular (f_e, f_f), 1.0);
+  CHECK (plus_fract_sat_long (lf_e, lf_f), 1.0);
+
+  CHECK (plus_fract_sat_short (sf_g, sf_h), -1.0);
+  CHECK (plus_fract_sat_regular (f_g, f_h), -1.0);
+  CHECK (plus_fract_sat_long (lf_g, lf_h), -1.0);
+  
+  CHECK (plus_fract_uns_sat_short (sf_e, sf_f), 1.0);
+  CHECK (plus_fract_uns_sat_regular (f_e, f_f), 1.0);
+  CHECK (plus_fract_uns_sat_long (lf_e, lf_f), 1.0);
+
+  CHECK (plus_fract_sat_short (sf_a, sf_b), 0.1);
+  CHECK (plus_fract_sat_regular (f_a, f_b), 0.1);
+  CHECK (plus_fract_sat_long (lf_a, lf_b), 0.1);
+  
+  CHECK (plus_fract_uns_sat_short (usf_a, usf_b), 0.7);
+  CHECK (plus_fract_uns_sat_regular (uf_a, uf_b), 0.7);
+  CHECK (plus_fract_uns_sat_long (ulf_a, ulf_b), 0.7);
+
+  CHECK (minus_fract_uns_sat_short (usf_c, usf_d), 0.0);
+  CHECK (minus_fract_uns_sat_regular (uf_c, uf_d), 0.0);
+  CHECK (minus_fract_uns_sat_short (ulf_c, ulf_d), 0.0);
+  
+  CHECK (minus_fract_sat_short (sf_c, sf_d), -0.2);
+  CHECK (minus_fract_sat_regular (f_c, f_d), -0.2);
+  CHECK (minus_fract_sat_long (lf_c, lf_d), -0.2);
+
+  /* Accum/accum operations, non-saturating.  */
+
+  CHECK (plus_accum_short (sa_a, sa_b), -0.25);
+  CHECK (plus_accum_regular (a_a, a_b), -0.25);
+  CHECK (plus_accum_long (la_a, la_b), -0.25);
+
+  CHECK (minus_accum_short (sa_a, sa_b), 2.75);
+  CHECK (minus_accum_regular (a_a, a_b), 200.75);
+  CHECK (minus_accum_long (la_a, la_b), 2000.75);
+  
+  CHECK (mult_accum_short (sa_a, sa_b), -1.875);
+  CHECK (mult_accum_regular (a_a, a_b), -10075.125);
+  CHECK (mult_accum_long (la_a, la_b), -1000750.125);
+
+  CHECK (div_accum_short (sa_a, sa_b), -1.25/1.5);
+  CHECK (div_accum_regular (a_a, a_b), -100.25/100.5);
+  CHECK (div_accum_long (la_a, la_b), -1000.25/1000.5);
+
+  /* Unsigned accum/accum operations, non-saturating.  */
+  
+  CHECK (plus_accum_uns_short (usa_a, usa_b), 4.25);
+  CHECK (plus_accum_uns_regular (ua_a, ua_b), 425.75);
+  CHECK (plus_accum_uns_long (ula_a, ula_b), 2550.0);
+
+  CHECK (minus_accum_uns_short (usa_a, usa_b), 0.75);
+  CHECK (minus_accum_uns_regular (ua_a, ua_b), 85.25);
+  CHECK (minus_accum_uns_long (ula_a, ula_b), 551.0);
+  
+  CHECK (mult_accum_uns_short (usa_a, usa_b), 4.375);
+  CHECK (mult_accum_uns_regular (ua_a, ua_b), 43498.875);
+  CHECK (mult_accum_uns_long (ula_a, ula_b), 1549724.75);
+
+  CHECK (div_accum_uns_short (usa_a, usa_b), 2.5/1.75);
+  CHECK (div_accum_uns_regular (ua_a, ua_b), 255.5/170.25);
+  CHECK (div_accum_uns_long (ula_a, ula_b), 1550.5/999.5);
+
+  /* Signed accum/accum operations, saturating.  */
+  
+  CHECK_EXACT (plus_accum_sat_short (sa_c, sa_d), SACCUM_MAX);
+  CHECK_EXACT (plus_accum_sat_short (sa_e, sa_f), SACCUM_MIN);
+  CHECK_EXACT (plus_accum_sat_regular (a_c, a_d), ACCUM_MAX);
+  CHECK_EXACT (plus_accum_sat_regular (a_e, a_f), ACCUM_MIN);
+  CHECK_EXACT (plus_accum_sat_long (la_c, la_d), LACCUM_MAX);
+  CHECK_EXACT (plus_accum_sat_long (la_e, la_f), LACCUM_MIN);
+
+  CHECK_EXACT (minus_accum_sat_short (sa_e, sa_d), SACCUM_MIN);
+  CHECK_EXACT (minus_accum_sat_short (sa_c, sa_f), SACCUM_MAX);
+  CHECK_EXACT (minus_accum_sat_regular (a_e, a_d), ACCUM_MIN);
+  CHECK_EXACT (minus_accum_sat_regular (a_c, a_f), ACCUM_MAX);
+  CHECK_EXACT (minus_accum_sat_long (la_e, la_d), LACCUM_MIN);
+  CHECK_EXACT (minus_accum_sat_long (la_c, la_f), LACCUM_MAX);
+
+  CHECK_EXACT (mult_accum_sat_short (sa_c, sa_d), SACCUM_MAX);
+  CHECK_EXACT (mult_accum_sat_short (sa_c, sa_e), SACCUM_MIN);
+  CHECK_EXACT (mult_accum_sat_regular (a_c, a_d), ACCUM_MAX);
+  CHECK_EXACT (mult_accum_sat_regular (a_c, a_e), ACCUM_MIN);
+  CHECK_EXACT (mult_accum_sat_long (la_c, la_d), LACCUM_MAX);
+  CHECK_EXACT (mult_accum_sat_long (la_c, la_e), LACCUM_MIN);
+  
+  CHECK_EXACT (div_accum_sat_short (sa_d, sa_g), SACCUM_MAX);
+  CHECK_EXACT (div_accum_sat_short (sa_e, sa_g), SACCUM_MIN);
+  CHECK_EXACT (div_accum_sat_regular (a_c, a_g), ACCUM_MAX);
+  CHECK_EXACT (div_accum_sat_regular (a_e, a_g), ACCUM_MIN);
+  CHECK_EXACT (div_accum_sat_long (la_d, la_g), LACCUM_MAX);
+  CHECK_EXACT (div_accum_sat_long (la_e, la_g), LACCUM_MIN);
+
+  /* Unsigned accum/accum operations, saturating.  */
+
+  CHECK_EXACT (plus_accum_uns_sat_short (usa_c, usa_d), USACCUM_MAX);
+  CHECK_EXACT (plus_accum_uns_sat_regular (ua_c, ua_d), UACCUM_MAX);
+  CHECK_EXACT (plus_accum_uns_sat_long (ula_c, ula_d), ULACCUM_MAX);
+  
+  CHECK_EXACT (minus_accum_uns_sat_short (usa_d, usa_c), 0uhk);
+  CHECK_EXACT (minus_accum_uns_sat_regular (ua_d, ua_c), 0uk);
+  CHECK_EXACT (minus_accum_uns_sat_long (ula_d, ula_c), 0ulk);
+
+  CHECK_EXACT (mult_accum_uns_sat_short (usa_c, usa_d), USACCUM_MAX);
+  CHECK_EXACT (mult_accum_uns_sat_regular (ua_c, ua_d), UACCUM_MAX);
+  CHECK_EXACT (mult_accum_uns_sat_long (ula_c, ula_d), ULACCUM_MAX);
+
+  CHECK_EXACT (div_accum_uns_sat_short (usa_c, usa_e), USACCUM_MAX);
+  CHECK_EXACT (div_accum_uns_sat_regular (ua_c, ua_e), UACCUM_MAX);
+  CHECK_EXACT (div_accum_uns_sat_long (ula_c, ula_e), ULACCUM_MAX);
+
+  return 0;
+}
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 8f96d6c..55c1f53 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -681,6 +681,7 @@  copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
 	case COMPLEX_CST:
 	case VECTOR_CST:
 	case REAL_CST:
+	case FIXED_CST:
 	case CONSTRUCTOR:
 	case VAR_DECL:
 	case PARM_DECL:
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 7e2ab93..5874267 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -647,6 +647,16 @@  endif
 # Build fixed-point support.
 ifeq ($(fixed_point),yes)
 
+FIXED_BIT_MACHINE := fixed-bit-machine.h
+
+# Use default header if a machine-specific one is not defined.
+ifeq ($(fixed_bit_machine_header),)
+fixed_bit_machine_header := fixed-bit-mach-generic.h
+endif
+
+$(FIXED_BIT_MACHINE): $(gcc_srcdir)/config/$(fixed_bit_machine_header)
+	cp $(gcc_srcdir)/config/$(fixed_bit_machine_header) $(FIXED_BIT_MACHINE)
+
 # Generate permutations of function name and mode
 fixed-labels := $(shell $(SHELL) $(srcdir)/gen-fixed.sh arith labels)
 fixed-funcs := $(shell $(SHELL) $(srcdir)/gen-fixed.sh arith funcs)
diff --git a/libgcc/config.host b/libgcc/config.host
index e3c48bb..5f24004 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -207,12 +207,15 @@  arm*-*-freebsd*)
 arm*-*-netbsdelf*)
 	;;
 arm*-*-linux*)			# ARM GNU/Linux with ELF
+	tmake_file="${tmake_file} arm/t-fixed-point"
 	;;
 arm*-*-uclinux*)		# ARM ucLinux
+	tmake_file="${tmake_file} arm/t-fixed-point"
 	;;
 arm*-*-ecos-elf)
 	;;
 arm*-*-eabi* | arm*-*-symbianelf* )
+	tmake_file="${tmake_file} arm/t-fixed-point"
 	;;
 arm*-*-rtems*)
 	;;
diff --git a/libgcc/config/arm/t-fixed-point b/libgcc/config/arm/t-fixed-point
new file mode 100644
index 0000000..66346dd
--- /dev/null
+++ b/libgcc/config/arm/t-fixed-point
@@ -0,0 +1 @@ 
+fixed_bit_machine_header := arm/fixed-bit-machine.h
diff --git a/libgcc/fixed-obj.mk b/libgcc/fixed-obj.mk
index 3c7c2f3..1bc8220 100644
--- a/libgcc/fixed-obj.mk
+++ b/libgcc/fixed-obj.mk
@@ -22,10 +22,10 @@  endif
 
 #$(info $o$(objext): -DL$($o-label) $($o-opt))
 
-$o$(objext): %$(objext): $(gcc_srcdir)/config/fixed-bit.c
+$o$(objext): %$(objext): $(gcc_srcdir)/config/fixed-bit.c $(FIXED_BIT_MACHINE)
 	$(gcc_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c $(vis_hide)
 
 ifeq ($(enable_shared),yes)
-$(o)_s$(objext): %_s$(objext): $(gcc_srcdir)/config/fixed-bit.c
+$(o)_s$(objext): %_s$(objext): $(gcc_srcdir)/config/fixed-bit.c $(FIXED_BIT_MACHINE)
 	$(gcc_s_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c
 endif