[PATCH/RFC/RFA] Machine modes for address printing (all targets)
diff mbox

Message ID 20151104125418.5b15143a@octopus
State New
Headers show

Commit Message

Julian Brown Nov. 4, 2015, 12:54 p.m. UTC
Hi,

Depending on assembler syntax and supported addressing modes, several
targets need to know the machine mode for a memory access when printing
an address (i.e. for automodify addresses that need to know the size
of their access), but it is not available with the current
TARGET_PRINT_OPERAND_ADDRESS hook. This leads to an ugly corner in the
operand output mechanism, where address printing gets split between
different parts of a backend, or some other hack (e.g. a global
variable) is used to communicate the machine mode to the address
printing hook.

Using a global variable also leads to a latent (?) bug on at least
AArch64: attempts to use the 'a' operand printing code cause final.c
to call output_address (in turn invoking the PRINT_OPERAND_ADDRESS
macro) *without* first setting the magic global
aarch64_memory_reference_mode, which means a stale value will be used
instead.

The full list of targets that use some form of workaround for the lack
of machine mode in the address printing hook is (E&OE):

aarch64: uses magic global.
arc: pre/post inc/dec handled in print_operand.
arm: uses magic global.
c6x
epiphany: offsets handled in print_operand.
m32r: hard-wires 4 for access size.
nds32
tilegx: uses magic global.
tilepro: uses magic global.

That's not all targets by any means, but may be enough to warrant a
change in the interface. I propose that:

* The output_address function should have a machine_mode argument
  added. Bare addresses (e.g. the 'a' case in final.c) should pass
  "VOIDmode" for this argument.

* Other callers of output_address -- actually all in backends -- can
  pass the machine mode for the memory access in question.

* The TARGET_PRINT_OPERAND_ADDRESS hook shall also have a machine_mode
  argument added. The legacy PRINT_OPERAND_ADDRESS hook can be left
  alone. (The documentation for the operand-printing hooks needs fixing
  too, incidentally.)

The attached patch makes this change, fairly mechanically. This removes
(most of) the magic globals for address printing, but I haven't tried
to refactor the targets that use other hacks to print correct
auto-modify addresses (that can be done by their respective
maintainers, hopefully, and should result in a nice cleanup).

Unfortunately I can't hope to test all the targets affected, though the
subset of targets that it's relatively easy for me to build, build
fine. I also ran regression tests for AArch64.

OK to apply, or any comments, or any further testing required?

Thanks,

Julian

ChangeLog

    gcc/
    * final.c (output_asm_insn): Pass VOIDmode to output_address.
    (output_address): Add MODE argument. Pass to print_operand_address
    hook.
    * targhooks.c (default_print_operand_address): Add MODE argument.
    * targhooks.h (default_print_operand_address): Update prototype.
    * output.h (output_address): Update prototype.
    * target.def (print_operand_address): Add MODE argument.
    * config/vax/vax.c (print_operand_address): Pass VOIDmode to
    output_address.
    (print_operand): Pass access mode to output_address.
    * config/mcore/mcore.c (mcore_print_operand_address): Add MODE
    argument.
    (mcore_print_operand): Update calls to mcore_print_operand_address.
    * config/fr30/fr30.c (fr30_print_operand): Pass VOIDmode to
    output_address.
    * config/lm32/lm32.c (lm32_print_operand): Pass mode in calls to
    output_address.
    * config/tilegx/tilegx.c (output_memory_reference_mode): Remove
    global.
    (tilegx_print_operand): Don't set above global. Update calls to
    output_address.
    (tilegx_print_operand_address): Add MODE argument. Use instead of
    output_memory_reference_mode global.
    * config/frv/frv.c (frv_print_operand_address): Add MODE argument.
    * config/mn10300/mn10300.c (mn10300_print_operand): Pass mode to
    output_address.
    * config/cris/cris.c (cris_print_operand_address): Add MODE
    argument.
    (cris_print_operand): Pass mode to output_address calls.
    * config/spu/spu.c (print_operand): Pass mode to output_address
    calls.
    * config/aarch64/aarch64.h (aarch64_print_operand)
    (aarch64_print_operand_address): Remove prototypes.
    * config/aarch64/aarch64.c (aarch64_memory_reference_mode): Delete
    global.
    (aarch64_print_operand): Make static. Update calls to
    output_address.
    (aarch64_print_operand_address): Add MODE argument. Use instead of
    aarch64_memory_reference_mode global.
    (TARGET_PRINT_OPERAND, TARGET_PRINT_OPERAND_ADDRESS): Define target
    hooks.
    * config/aarch64/aarch64.h (PRINT_OPERAND, PRINT_OPERAND_ADDRESS):
    Delete macro definitions.
    * config/pa/pa.c (pa_print_operand): Pass mode in output_address
    calls.
    * config/xtensa/xtensa.c (print_operand): Pass mode in
    output_address calls.
    * config/h8300/h8300.c (h8300_print_operand_address): Add MODE
    argument.
    (h83000_print_operand): Update calls to h8300_print_operand_address
    and output_address.
    * config/ia64/ia64.c (ia64_print_operand_address): Add MODE
    argument.
    * config/tilepro/tilepro.c (output_memory_reference_mode): Delete
    global.
    (tilepro_print_operand): Pass mode to output_address.
    (tilepro_print_operand_address): Add MODE argument. Use instead of
    output_memory_reference_mode.
    * config/nvptx/nvptx.c (output_decl_chunk, nvptx_assemble_integer)
    (nvptx_output_call_insn, nvptx_print_address_operand): Pass VOIDmode
    to output_address calls.
    (nvptx_print_operand_address): Add MODE argument.
    * config/alpha/alpha.c (print_operand): Pass mode argument in
    output_address calls.
    * config/m68k/m68k.c (print_operand): Pass mode argument in
    output_address call.
    * config/avr/avr.c (avr_print_operand_address): Add MODE argument.
    * config/sparc/sparc.c (sparc_print_operand_address): Add MODE
    argument. Update calls to output_address.
    (sparc_print_operand): Pass mode to output_address.
    * config/iq2000/iq2000.c (iq2000_print_operand_address): Add MODE
    argument.
    (iq2000_print_operand): Pass mode in output_address calls.
    * config/stormy16/stormy16.c (xstormy16_print_operand_address): Add
    MODE argument.
    * config/mips/mips.c (mips_print_operand): Update calls to
    output_address.
    (mips_print_operand_address): Add MODE argument.
    * config/epiphany/epiphany.c (epiphany_print_operand): Update calls
    to output_address.
    (epiphany_print_operand_address): Add MODE argument. Add FIXME note.
    * config/pdp11/pdp11.c (pdp11_asm_print_operand): Update call to
    output_address.
    * config/rx/rx.c (rx_print_operand_address): Add MODE argument.
    (rx_print_operand): Update calls to output_address.
    * config/nds32/nds32.c (nds32_print_operand): Update calls to
    output_address.
    (nds32_print_operand_address): Add MODE argument.
    * config/rs6000/rs6000.c (print_operand): Pass mem mode to
    output_address calls.
    * config/c6x/c6x.c (print_address_offset): Pass mem mode to
    output_address call.
    (c6x_print_address_operand): Update calls to output_address.
    (c6x_print_operand_address): Pass mode to above.
    * config/v850/v850.c (v850_print_operand_address): Add MODE
    argument.
    (v850_print_operand): Pass mode to v850_print_operand_address,
    output_address.
    * config/mmix/mmix.c (mmix_print_operand_address): Add MODE
    argument.
    (mmix_print_operand): Pass mode in output_address calls.
    * config/sh/sh.c (sh_print_operand_address): Add MODE argument.
    (sh_print_operand): Pass mem mode to output_address.
    * config/cr16/cr16.c (cr16_print_operand_address): Add MODE
    argument.
    (cr16_print_operand): Pass mode to output_address,
    cr16_print_operand_address.
    * config/bfin/bfin.c (print_address_operand): Pass VOIDmode to
    output_address.
    * config/microblaze/microblaze.c (print_operand): Pass mode to
    output_address.
    * config/nios2/nios2.c (nios2_print_operand): Pass VOIDmode to
    output_address.
    (nios2_print_operand_address): Add MODE argument. Update call to
    nios2_print_operand_address.
    * config/s390/s390.c (print_operand): Pass mode to output_address.
    * config/m32c/m32c.c (m32c_print_operand_address): Add MODE
    argument.
    * config/arc/arc.c (arc_print_operand): Pass VOIDmode to
    output_address.
    * config/arm/arm.c (arm_print_operand_address): Add MODE argument.
    Use instead of output_memory_reference_mode.
    (output_memory_reference_mode): Delete global.
    (arm_print_operand): Pass mem mode to output_address.
    * config/m32r/m32r.c (m32r_print_operand_address): Add MODE
    argument.
    (m32r_print_operand): Pass mode to output_address.
    * config/msp430/msp430.c (msp430_print_operand_addr): Add MODE
    argument.
    (msp430_print_operand): Pass mode to msp430_print_operand_addr.
    * config/i386/i386.c (ix86_print_operand): Pass mode to
    output_address calls.
    (ix86_print_operand_address): Add MODE argument.

Comments

Bernd Schmidt Nov. 5, 2015, 10:22 a.m. UTC | #1
On 11/04/2015 01:54 PM, Julian Brown wrote:
> That's not all targets by any means, but may be enough to warrant a
> change in the interface. I propose that:
>
> * The output_address function should have a machine_mode argument
>    added. Bare addresses (e.g. the 'a' case in final.c) should pass
>    "VOIDmode" for this argument.
>
> * Other callers of output_address -- actually all in backends -- can
>    pass the machine mode for the memory access in question.
>
> * The TARGET_PRINT_OPERAND_ADDRESS hook shall also have a machine_mode
>    argument added. The legacy PRINT_OPERAND_ADDRESS hook can be left
>    alone. (The documentation for the operand-printing hooks needs fixing
>    too, incidentally.)

I think this approach seems fine.

>  static void
> -mcore_print_operand_address (FILE * stream, rtx x)
> +mcore_print_operand_address (FILE * stream, machine_mode mode ATTRIBUTE_UNUSED,
> +			     rtx x)

So apparently we're settling on writing the unused arg as just 
"machine_mode" without a name. Please change everywhere.

> @@ -1754,7 +1754,7 @@ mmix_print_operand_punct_valid_p (unsign
>  /* TARGET_PRINT_OPERAND_ADDRESS.  */
>
>  static void
> -mmix_print_operand_address (FILE *stream, rtx x)
> +mmix_print_operand_address (FILE *stream, machine_mode mode, rtx x)
>  {
>    if (REG_P (x))
>      {

The arg appears to be unused - I'd expect to see a warning here.

Other thank that it looks OK. I'm not going to require that you test 
every target, but it would be good to have the full set built to cc1 
before and after, and please be on the lookout for fallout.


Bernd

Patch
diff mbox

Index: gcc/config/vax/vax.c
===================================================================
--- gcc/config/vax/vax.c	(revision 229706)
+++ gcc/config/vax/vax.c	(working copy)
@@ -472,7 +472,7 @@  print_operand_address (FILE * file, rtx 
 
 	    }
 
-	  output_address (offset);
+	  output_address (VOIDmode, offset);
 	}
 
       if (breg != 0)
@@ -527,7 +527,7 @@  print_operand (FILE *file, rtx x, int co
   else if (REG_P (x))
     fprintf (file, "%s", reg_names[REGNO (x)]);
   else if (MEM_P (x))
-    output_address (XEXP (x, 0));
+    output_address (GET_MODE (x), XEXP (x, 0));
   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
     {
       char dstr[30];
Index: gcc/config/mcore/mcore.c
===================================================================
--- gcc/config/mcore/mcore.c	(revision 229706)
+++ gcc/config/mcore/mcore.c	(working copy)
@@ -309,7 +309,8 @@  calc_live_regs (int * count)
 /* Print the operand address in x to the stream.  */
 
 static void
-mcore_print_operand_address (FILE * stream, rtx x)
+mcore_print_operand_address (FILE * stream, machine_mode mode ATTRIBUTE_UNUSED,
+			     rtx x)
 {
   switch (GET_CODE (x))
     {
@@ -401,7 +402,7 @@  mcore_print_operand (FILE * stream, rtx 
 	  break;
 	case MEM:
 	  mcore_print_operand_address
-	    (stream, XEXP (adjust_address (x, SImode, 4), 0));
+	    (stream, GET_MODE (x), XEXP (adjust_address (x, SImode, 4), 0));
 	  break;
 	default:
 	  gcc_unreachable ();
@@ -425,7 +426,7 @@  mcore_print_operand (FILE * stream, rtx 
 	  fputs (reg_names[REGNO (x)], (stream));
 	  break;
 	case MEM:
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), XEXP (x, 0));
 	  break;
 	default:
 	  output_addr_const (stream, x);
Index: gcc/config/fr30/fr30.c
===================================================================
--- gcc/config/fr30/fr30.c	(revision 229706)
+++ gcc/config/fr30/fr30.c	(working copy)
@@ -662,7 +662,7 @@  fr30_print_operand (FILE *file, rtx x, i
 	  break;
 	  
 	case SYMBOL_REF:
-	  output_address (x0);
+	  output_address (VOIDmode, x0);
 	  break;
 	  
 	default:
Index: gcc/config/lm32/lm32.c
===================================================================
--- gcc/config/lm32/lm32.c	(revision 229706)
+++ gcc/config/lm32/lm32.c	(working copy)
@@ -498,7 +498,7 @@  lm32_print_operand (FILE * file, rtx op,
   else if (code == HIGH)
     output_addr_const (file, XEXP (op, 0));  
   else if (code == MEM)
-    output_address (XEXP (op, 0));
+    output_address (GET_MODE (op), XEXP (op, 0));
   else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
     fprintf (file, "%s", reg_names[0]);
   else if (GET_CODE (op) == CONST_DOUBLE)
@@ -551,7 +551,7 @@  lm32_print_operand_address (FILE * file,
       break;
 
     case MEM:
-      output_address (XEXP (addr, 0));
+      output_address (VOIDmode, XEXP (addr, 0));
       break;
 
     case PLUS:
Index: gcc/config/tilegx/tilegx.c
===================================================================
--- gcc/config/tilegx/tilegx.c	(revision 229706)
+++ gcc/config/tilegx/tilegx.c	(working copy)
@@ -59,11 +59,6 @@ 
 /* SYMBOL_REF for GOT */
 static GTY(()) rtx g_got_symbol = NULL;
 
-/* In case of a POST_INC or POST_DEC memory reference, we must report
-   the mode of the memory reference from TARGET_PRINT_OPERAND to
-   TARGET_PRINT_OPERAND_ADDRESS.  */
-static machine_mode output_memory_reference_mode;
-
 /* Report whether we're printing out the first address fragment of a
    POST_INC or POST_DEC memory reference, from TARGET_PRINT_OPERAND to
    TARGET_PRINT_OPERAND_ADDRESS.  */
@@ -5268,10 +5263,8 @@  tilegx_print_operand (FILE *file, rtx x,
 	  return;
 	}
 
-      output_memory_reference_mode = GET_MODE (x);
       output_memory_autoinc_first = true;
-      output_address (XEXP (x, 0));
-      output_memory_reference_mode = VOIDmode;
+      output_address (GET_MODE (x), XEXP (x, 0));
       return;
 
     case 'i':
@@ -5282,10 +5275,8 @@  tilegx_print_operand (FILE *file, rtx x,
 	  return;
 	}
 
-      output_memory_reference_mode = GET_MODE (x);
       output_memory_autoinc_first = false;
-      output_address (XEXP (x, 0));
-      output_memory_reference_mode = VOIDmode;
+      output_address (GET_MODE (x), XEXP (x, 0));
       return;
 
     case 'j':
@@ -5404,8 +5395,7 @@  tilegx_print_operand (FILE *file, rtx x,
 	}
       else if (MEM_P (x))
 	{
-	  output_memory_reference_mode = VOIDmode;
-	  output_address (XEXP (x, 0));
+	  output_address (VOIDmode, XEXP (x, 0));
 	  return;
 	}
       else
@@ -5423,14 +5413,14 @@  tilegx_print_operand (FILE *file, rtx x,
 
 /* Implement TARGET_PRINT_OPERAND_ADDRESS.  */
 static void
-tilegx_print_operand_address (FILE *file, rtx addr)
+tilegx_print_operand_address (FILE *file, machine_mode mode, rtx addr)
 {
   if (GET_CODE (addr) == POST_DEC
       || GET_CODE (addr) == POST_INC)
     {
-      int offset = GET_MODE_SIZE (output_memory_reference_mode);
+      int offset = GET_MODE_SIZE (mode);
 
-      gcc_assert (output_memory_reference_mode != VOIDmode);
+      gcc_assert (mode != VOIDmode);
 
       if (output_memory_autoinc_first)
 	fprintf (file, "%s", reg_names[REGNO (XEXP (addr, 0))]);
@@ -5440,7 +5430,7 @@  tilegx_print_operand_address (FILE *file
     }
   else if (GET_CODE (addr) == POST_MODIFY)
     {
-      gcc_assert (output_memory_reference_mode != VOIDmode);
+      gcc_assert (mode != VOIDmode);
 
       gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
 
Index: gcc/config/frv/frv.c
===================================================================
--- gcc/config/frv/frv.c	(revision 229706)
+++ gcc/config/frv/frv.c	(working copy)
@@ -262,7 +262,7 @@  static int frv_default_flags_for_cpu		(v
 static int frv_string_begins_with		(const char *, const char *);
 static FRV_INLINE bool frv_small_data_reloc_p	(rtx, int);
 static void frv_print_operand			(FILE *, rtx, int);
-static void frv_print_operand_address		(FILE *, rtx);
+static void frv_print_operand_address		(FILE *, machine_mode, rtx);
 static bool frv_print_operand_punct_valid_p	(unsigned char code);
 static void frv_print_operand_memory_reference_reg
 						(FILE *, rtx);
@@ -2470,7 +2470,8 @@  frv_index_memory (rtx memref, machine_mo
 
 /* Print a memory address as an operand to reference that memory location.  */
 static void
-frv_print_operand_address (FILE * stream, rtx x)
+frv_print_operand_address (FILE * stream, machine_mode mode ATTRIBUTE_UNUSED,
+			   rtx x)
 {
   if (GET_CODE (x) == MEM)
     x = XEXP (x, 0);
Index: gcc/config/mn10300/mn10300.c
===================================================================
--- gcc/config/mn10300/mn10300.c	(revision 229706)
+++ gcc/config/mn10300/mn10300.c	(working copy)
@@ -239,7 +239,7 @@  mn10300_print_operand (FILE *file, rtx x
 	{
 	case MEM:
 	  fputc ('(', file);
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), XEXP (x, 0));
 	  fputc (')', file);
 	  break;
 
@@ -258,7 +258,7 @@  mn10300_print_operand (FILE *file, rtx x
 	{
 	case MEM:
 	  fputc ('(', file);
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), XEXP (x, 0));
 	  fputc (')', file);
 	  break;
 
@@ -317,7 +317,7 @@  mn10300_print_operand (FILE *file, rtx x
 	case MEM:
 	  fputc ('(', file);
 	  x = adjust_address (x, SImode, 4);
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), XEXP (x, 0));
 	  fputc (')', file);
 	  break;
 
@@ -369,9 +369,10 @@  mn10300_print_operand (FILE *file, rtx x
     case 'A':
       fputc ('(', file);
       if (REG_P (XEXP (x, 0)))
-	output_address (gen_rtx_PLUS (SImode, XEXP (x, 0), const0_rtx));
+	output_address (VOIDmode, gen_rtx_PLUS (SImode,
+						XEXP (x, 0), const0_rtx));
       else
-	output_address (XEXP (x, 0));
+	output_address (VOIDmode, XEXP (x, 0));
       fputc (')', file);
       break;
 
@@ -402,12 +403,12 @@  mn10300_print_operand (FILE *file, rtx x
 	{
 	case MEM:
 	  fputc ('(', file);
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), XEXP (x, 0));
 	  fputc (')', file);
 	  break;
 
 	case PLUS:
-	  output_address (x);
+	  output_address (VOIDmode, x);
 	  break;
 
 	case REG:
Index: gcc/config/cris/cris.c
===================================================================
--- gcc/config/cris/cris.c	(revision 229706)
+++ gcc/config/cris/cris.c	(working copy)
@@ -114,7 +114,7 @@  static int cris_reg_saved_in_regsave_are
 
 static void cris_print_operand (FILE *, rtx, int);
 
-static void cris_print_operand_address (FILE *, rtx);
+static void cris_print_operand_address (FILE *, machine_mode, rtx);
 
 static bool cris_print_operand_punct_valid_p (unsigned char code);
 
@@ -803,7 +803,7 @@  cris_print_operand (FILE *file, rtx x, i
 		return;
 	      }
 	  }
-	output_address (addr);
+	output_address (VOIDmode, addr);
       }
       return;
 
@@ -942,7 +942,7 @@  cris_print_operand (FILE *file, rtx x, i
 	      adj_mem
 		= adjust_address (adj_mem, GET_MODE (adj_mem), size / 2);
 
-	    output_address (XEXP (adj_mem, 0));
+	    output_address (VOIDmode, XEXP (adj_mem, 0));
 	    return;
 	  }
 
@@ -1129,7 +1129,7 @@  cris_print_operand (FILE *file, rtx x, i
       return;
 
     case MEM:
-      output_address (XEXP (operand, 0));
+      output_address (GET_MODE (operand), XEXP (operand, 0));
       return;
 
     case CONST_DOUBLE:
@@ -1200,7 +1200,8 @@  cris_print_operand_punct_valid_p (unsign
 /* The PRINT_OPERAND_ADDRESS worker.  */
 
 static void
-cris_print_operand_address (FILE *file, rtx x)
+cris_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED,
+			    rtx x)
 {
   /* All these were inside MEM:s so output indirection characters.  */
   putc ('[', file);
Index: gcc/config/spu/spu.c
===================================================================
--- gcc/config/spu/spu.c	(revision 229706)
+++ gcc/config/spu/spu.c	(working copy)
@@ -1339,7 +1339,7 @@  print_operand (FILE * file, rtx x, int c
 	    /* Used in indirect function calls. */
 	    fprintf (file, "%s", reg_names[REGNO (XEXP (x, 0))]);
 	  else
-	    output_address (XEXP (x, 0));
+	    output_address (GET_MODE (x), XEXP (x, 0));
 	}
       return;
 
@@ -1432,7 +1432,7 @@  print_operand (FILE * file, rtx x, int c
       if (xcode == REG)
 	fprintf (file, "%s", reg_names[REGNO (x)]);
       else if (xcode == MEM)
-	output_address (XEXP (x, 0));
+	output_address (GET_MODE (x), XEXP (x, 0));
       else if (xcode == CONST_VECTOR)
 	print_operand (file, CONST_VECTOR_ELT (x, 0), 0);
       else
Index: gcc/config/aarch64/aarch64-protos.h
===================================================================
--- gcc/config/aarch64/aarch64-protos.h	(revision 229706)
+++ gcc/config/aarch64/aarch64-protos.h	(working copy)
@@ -345,8 +345,6 @@  void aarch64_init_cumulative_args (CUMUL
 				   const_tree, unsigned);
 void aarch64_init_expanders (void);
 void aarch64_init_simd_builtins (void);
-void aarch64_print_operand (FILE *, rtx, char);
-void aarch64_print_operand_address (FILE *, rtx);
 void aarch64_emit_call_insn (rtx);
 void aarch64_register_pragmas (void);
 void aarch64_relayout_simd_types (void);
Index: gcc/config/aarch64/aarch64.c
===================================================================
--- gcc/config/aarch64/aarch64.c	(revision 229706)
+++ gcc/config/aarch64/aarch64.c	(working copy)
@@ -556,10 +556,6 @@  static const struct aarch64_option_exten
   {NULL, 0, 0}
 };
 
-/* Used to track the size of an address when generating a pre/post
-   increment address.  */
-static machine_mode aarch64_memory_reference_mode;
-
 typedef enum aarch64_cond_code
 {
   AARCH64_EQ = 0, AARCH64_NE, AARCH64_CS, AARCH64_CC, AARCH64_MI, AARCH64_PL,
@@ -4131,8 +4127,8 @@  aarch64_ccmp_mode_to_code (enum machine_
 }
 
 
-void
-aarch64_print_operand (FILE *f, rtx x, char code)
+static void
+aarch64_print_operand (FILE *f, rtx x, int code)
 {
   switch (code)
     {
@@ -4362,8 +4358,7 @@  aarch64_print_operand (FILE *f, rtx x, c
 	  break;
 
 	case MEM:
-	  aarch64_memory_reference_mode = GET_MODE (x);
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), XEXP (x, 0));
 	  break;
 
 	case CONST:
@@ -4553,13 +4548,12 @@  aarch64_print_operand (FILE *f, rtx x, c
     }
 }
 
-void
-aarch64_print_operand_address (FILE *f, rtx x)
+static void
+aarch64_print_operand_address (FILE *f, machine_mode mode, rtx x)
 {
   struct aarch64_address_info addr;
 
-  if (aarch64_classify_address (&addr, x, aarch64_memory_reference_mode,
-			     MEM, true))
+  if (aarch64_classify_address (&addr, x, mode, MEM, true))
     switch (addr.type)
       {
       case ADDRESS_REG_IMM:
@@ -4602,19 +4596,19 @@  aarch64_print_operand_address (FILE *f, 
 	  {
 	  case PRE_INC:
 	    asm_fprintf (f, "[%s, %d]!", reg_names [REGNO (addr.base)],
-			 GET_MODE_SIZE (aarch64_memory_reference_mode));
+			 GET_MODE_SIZE (mode));
 	    return;
 	  case POST_INC:
 	    asm_fprintf (f, "[%s], %d", reg_names [REGNO (addr.base)],
-			 GET_MODE_SIZE (aarch64_memory_reference_mode));
+			 GET_MODE_SIZE (mode));
 	    return;
 	  case PRE_DEC:
 	    asm_fprintf (f, "[%s, -%d]!", reg_names [REGNO (addr.base)],
-			 GET_MODE_SIZE (aarch64_memory_reference_mode));
+			 GET_MODE_SIZE (mode));
 	    return;
 	  case POST_DEC:
 	    asm_fprintf (f, "[%s], -%d", reg_names [REGNO (addr.base)],
-			 GET_MODE_SIZE (aarch64_memory_reference_mode));
+			 GET_MODE_SIZE (mode));
 	    return;
 	  case PRE_MODIFY:
 	    asm_fprintf (f, "[%s, %wd]!", reg_names [REGNO (addr.base)],
@@ -13693,6 +13687,12 @@  aarch64_promoted_type (const_tree t)
 #undef TARGET_USE_PSEUDO_PIC_REG
 #define TARGET_USE_PSEUDO_PIC_REG aarch64_use_pseudo_pic_reg
 
+#undef TARGET_PRINT_OPERAND
+#define TARGET_PRINT_OPERAND aarch64_print_operand
+
+#undef TARGET_PRINT_OPERAND_ADDRESS
+#define TARGET_PRINT_OPERAND_ADDRESS aarch64_print_operand_address
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-aarch64.h"
Index: gcc/config/aarch64/aarch64.h
===================================================================
--- gcc/config/aarch64/aarch64.h	(revision 229706)
+++ gcc/config/aarch64/aarch64.h	(working copy)
@@ -792,11 +792,6 @@  do {									     \
 /* Jump table alignment is explicit in ASM_OUTPUT_CASE_LABEL.  */
 #define ADDR_VEC_ALIGN(JUMPTABLE) 0
 
-#define PRINT_OPERAND(STREAM, X, CODE) aarch64_print_operand (STREAM, X, CODE)
-
-#define PRINT_OPERAND_ADDRESS(STREAM, X) \
-  aarch64_print_operand_address (STREAM, X)
-
 #define MCOUNT_NAME "_mcount"
 
 #define NO_PROFILE_COUNTERS 1
Index: gcc/config/pa/pa.c
===================================================================
--- gcc/config/pa/pa.c	(revision 229706)
+++ gcc/config/pa/pa.c	(working copy)
@@ -5413,10 +5413,10 @@  pa_print_operand (FILE *file, rtx x, int
 		       reg_names [REGNO (index)], reg_names [REGNO (base)]);
 	    }
 	  else
-	    output_address (XEXP (x, 0));
+	    output_address (GET_MODE (x), XEXP (x, 0));
 	  break;
 	default:
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), XEXP (x, 0));
 	  break;
 	}
     }
Index: gcc/config/xtensa/xtensa.c
===================================================================
--- gcc/config/xtensa/xtensa.c	(revision 229706)
+++ gcc/config/xtensa/xtensa.c	(working copy)
@@ -2318,7 +2318,7 @@  print_operand (FILE *file, rtx x, int le
 	  && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode))
 	{
 	  x = adjust_address (x, GET_MODE (x) == DFmode ? SFmode : SImode, 4);
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), XEXP (x, 0));
 	}
       else
 	output_operand_lossage ("invalid %%N value");
@@ -2429,7 +2429,7 @@  print_operand (FILE *file, rtx x, int le
       if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
 	fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
       else if (GET_CODE (x) == MEM)
-	output_address (XEXP (x, 0));
+	output_address (GET_MODE (x), XEXP (x, 0));
       else if (GET_CODE (x) == CONST_INT)
 	fprintf (file, "%ld", INTVAL (x));
       else
Index: gcc/config/h8300/h8300.c
===================================================================
--- gcc/config/h8300/h8300.c	(revision 229706)
+++ gcc/config/h8300/h8300.c	(working copy)
@@ -95,7 +95,7 @@  static unsigned int h8300_asm_insn_count
 static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree h8300_handle_eightbit_data_attribute (tree *, tree, tree, int, bool *);
 static tree h8300_handle_tiny_data_attribute (tree *, tree, tree, int, bool *);
-static void h8300_print_operand_address (FILE *, rtx);
+static void h8300_print_operand_address (FILE *, machine_mode, rtx);
 static void h8300_print_operand (FILE *, rtx, int);
 static bool h8300_print_operand_punct_valid_p (unsigned char code);
 #ifndef OBJECT_FORMAT_ELF
@@ -1647,7 +1647,7 @@  h8300_print_operand (FILE *file, rtx x, 
 	}
       break;
     case 'o':
-      h8300_print_operand_address (file, x);
+      h8300_print_operand_address (file, VOIDmode, x);
       break;
     case 's':
       if (GET_CODE (x) == CONST_INT)
@@ -1719,7 +1719,7 @@  h8300_print_operand (FILE *file, rtx x, 
 	    rtx addr = XEXP (x, 0);
 
 	    fprintf (file, "@");
-	    output_address (addr);
+	    output_address (GET_MODE (x), addr);
 
 	    /* Add a length suffix to constant addresses.  Although this
 	       is often unnecessary, it helps to avoid ambiguity in the
@@ -1764,7 +1764,7 @@  h8300_print_operand (FILE *file, rtx x, 
 	case CONST:
 	case LABEL_REF:
 	  fprintf (file, "#");
-	  h8300_print_operand_address (file, x);
+	  h8300_print_operand_address (file, VOIDmode, x);
 	  break;
 	case CONST_DOUBLE:
 	  {
@@ -1790,7 +1790,7 @@  h8300_print_operand_punct_valid_p (unsig
 /* Output assembly language output for the address ADDR to FILE.  */
 
 static void
-h8300_print_operand_address (FILE *file, rtx addr)
+h8300_print_operand_address (FILE *file, machine_mode mode, rtx addr)
 {
   rtx index;
   int size;
@@ -1824,12 +1824,12 @@  h8300_print_operand_address (FILE *file,
       if (GET_CODE (index) == REG)
 	{
 	  /* reg,foo */
-	  h8300_print_operand_address (file, XEXP (addr, 1));
+	  h8300_print_operand_address (file, mode, XEXP (addr, 1));
 	  fprintf (file, ",");
 	  switch (size)
 	    {
 	    case 0:
-	      h8300_print_operand_address (file, index);
+	      h8300_print_operand_address (file, mode, index);
 	      break;
 
 	    case 1:
@@ -1852,9 +1852,9 @@  h8300_print_operand_address (FILE *file,
       else
 	{
 	  /* foo+k */
-	  h8300_print_operand_address (file, XEXP (addr, 0));
+	  h8300_print_operand_address (file, mode, XEXP (addr, 0));
 	  fprintf (file, "+");
-	  h8300_print_operand_address (file, XEXP (addr, 1));
+	  h8300_print_operand_address (file, mode, XEXP (addr, 1));
 	}
       fprintf (file, ")");
       break;
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	(revision 229706)
+++ gcc/config/ia64/ia64.c	(working copy)
@@ -236,7 +236,7 @@  static void ia64_output_function_epilogu
 static void ia64_output_function_end_prologue (FILE *);
 
 static void ia64_print_operand (FILE *, rtx, int);
-static void ia64_print_operand_address (FILE *, rtx);
+static void ia64_print_operand_address (FILE *, machine_mode, rtx);
 static bool ia64_print_operand_punct_valid_p (unsigned char code);
 
 static int ia64_issue_rate (void);
@@ -5239,6 +5239,7 @@  ia64_output_dwarf_dtprel (FILE *file, in
 
 static void
 ia64_print_operand_address (FILE * stream ATTRIBUTE_UNUSED,
+			    machine_mode mode ATTRIBUTE_UNUSED,
 			    rtx address ATTRIBUTE_UNUSED)
 {
 }
Index: gcc/config/tilepro/tilepro.c
===================================================================
--- gcc/config/tilepro/tilepro.c	(revision 229706)
+++ gcc/config/tilepro/tilepro.c	(working copy)
@@ -59,11 +59,6 @@ 
 /* SYMBOL_REF for GOT */
 static GTY(()) rtx g_got_symbol = NULL;
 
-/* In case of a POST_INC or POST_DEC memory reference, we must report
-   the mode of the memory reference from TARGET_PRINT_OPERAND to
-   TARGET_PRINT_OPERAND_ADDRESS.  */
-static machine_mode output_memory_reference_mode;
-
 /* Report whether we're printing out the first address fragment of a
    POST_INC or POST_DEC memory reference, from TARGET_PRINT_OPERAND to
    TARGET_PRINT_OPERAND_ADDRESS.  */
@@ -4594,10 +4589,8 @@  tilepro_print_operand (FILE *file, rtx x
 	  return;
 	}
 
-      output_memory_reference_mode = GET_MODE (x);
       output_memory_autoinc_first = true;
-      output_address (XEXP (x, 0));
-      output_memory_reference_mode = VOIDmode;
+      output_address (GET_MODE (x), XEXP (x, 0));
       return;
 
     case 'i':
@@ -4608,10 +4601,8 @@  tilepro_print_operand (FILE *file, rtx x
 	  return;
 	}
 
-      output_memory_reference_mode = GET_MODE (x);
       output_memory_autoinc_first = false;
-      output_address (XEXP (x, 0));
-      output_memory_reference_mode = VOIDmode;
+      output_address (GET_MODE (x), XEXP (x, 0));
       return;
 
     case 'j':
@@ -4810,8 +4801,7 @@  tilepro_print_operand (FILE *file, rtx x
 	}
       else if (MEM_P (x))
 	{
-	  output_memory_reference_mode = VOIDmode;
-	  output_address (XEXP (x, 0));
+	  output_address (VOIDmode, XEXP (x, 0));
 	  return;
 	}
       else
@@ -4830,14 +4820,14 @@  tilepro_print_operand (FILE *file, rtx x
 
 /* Implement TARGET_PRINT_OPERAND_ADDRESS.  */
 static void
-tilepro_print_operand_address (FILE *file, rtx addr)
+tilepro_print_operand_address (FILE *file, machine_mode mode, rtx addr)
 {
   if (GET_CODE (addr) == POST_DEC
       || GET_CODE (addr) == POST_INC)
     {
-      int offset = GET_MODE_SIZE (output_memory_reference_mode);
+      int offset = GET_MODE_SIZE (mode);
 
-      gcc_assert (output_memory_reference_mode != VOIDmode);
+      gcc_assert (mode != VOIDmode);
 
       if (output_memory_autoinc_first)
 	fprintf (file, "%s", reg_names[REGNO (XEXP (addr, 0))]);
@@ -4847,7 +4837,7 @@  tilepro_print_operand_address (FILE *fil
     }
   else if (GET_CODE (addr) == POST_MODIFY)
     {
-      gcc_assert (output_memory_reference_mode != VOIDmode);
+      gcc_assert (mode != VOIDmode);
 
       gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
 
Index: gcc/config/nvptx/nvptx.c
===================================================================
--- gcc/config/nvptx/nvptx.c	(revision 229706)
+++ gcc/config/nvptx/nvptx.c	(working copy)
@@ -1560,7 +1560,7 @@  static void
 output_decl_chunk (void)
 {
   begin_decl_field ();
-  output_address (gen_int_mode (init_part, decl_chunk_mode));
+  output_address (VOIDmode, gen_int_mode (init_part, decl_chunk_mode));
   init_part = 0;
 }
 
@@ -1617,7 +1617,7 @@  nvptx_assemble_integer (rtx x, unsigned 
 	{
 	  nvptx_record_needed_fndecl (SYMBOL_REF_DECL (x));
 	  fprintf (asm_out_file, "generic(");
-	  output_address (x);
+	  output_address (VOIDmode, x);
 	  fprintf (asm_out_file, ")");
 	}
       if (off != 0)
@@ -1875,7 +1875,7 @@  nvptx_output_call_insn (rtx_insn *insn, 
       assemble_name (asm_out_file, name);
     }
   else
-    output_address (callee);
+    output_address (VOIDmode, callee);
 
   if (arg_end > 1 || (decl && DECL_STATIC_CHAIN (decl)))
     {
@@ -1935,9 +1935,9 @@  nvptx_print_address_operand (FILE *file,
     {
     case PLUS:
       off = XEXP (x, 1);
-      output_address (XEXP (x, 0));
+      output_address (VOIDmode, XEXP (x, 0));
       fprintf (file, "+");
-      output_address (off);
+      output_address (VOIDmode, off);
       break;
 
     case SYMBOL_REF:
@@ -1955,9 +1955,9 @@  nvptx_print_address_operand (FILE *file,
 /* Write assembly language output for the address ADDR to FILE.  */
 
 static void
-nvptx_print_operand_address (FILE *file, rtx addr)
+nvptx_print_operand_address (FILE *file, machine_mode mode, rtx addr)
 {
-  nvptx_print_address_operand (file, addr, VOIDmode);
+  nvptx_print_address_operand (file, addr, mode);
 }
 
 /* Print an operand, X, to FILE, with an optional modifier in CODE.
Index: gcc/config/alpha/alpha.c
===================================================================
--- gcc/config/alpha/alpha.c	(revision 229706)
+++ gcc/config/alpha/alpha.c	(working copy)
@@ -5327,7 +5327,7 @@  print_operand (FILE *file, rtx x, int co
       if (REG_P (x))
 	fprintf (file, "%s", reg_names[REGNO (x)]);
       else if (MEM_P (x))
-	output_address (XEXP (x, 0));
+	output_address (GET_MODE (x), XEXP (x, 0));
       else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
 	{
 	  switch (XINT (XEXP (x, 0), 1))
Index: gcc/config/m68k/m68k.c
===================================================================
--- gcc/config/m68k/m68k.c	(revision 229706)
+++ gcc/config/m68k/m68k.c	(working copy)
@@ -4470,7 +4470,7 @@  print_operand (FILE *file, rtx op, int l
     }
   else if (GET_CODE (op) == MEM)
     {
-      output_address (XEXP (op, 0));
+      output_address (GET_MODE (op), XEXP (op, 0));
       if (letter == 'd' && ! TARGET_68020
 	  && CONSTANT_ADDRESS_P (XEXP (op, 0))
 	  && !(GET_CODE (XEXP (op, 0)) == CONST_INT
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c	(revision 229706)
+++ gcc/config/avr/avr.c	(working copy)
@@ -2158,7 +2158,8 @@  cond_string (enum rtx_code code)
 /* Output ADDR to FILE as address.  */
 
 static void
-avr_print_operand_address (FILE *file, rtx addr)
+avr_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED,
+			   rtx addr)
 {
   switch (GET_CODE (addr))
     {
Index: gcc/config/sparc/sparc.c
===================================================================
--- gcc/config/sparc/sparc.c	(revision 229706)
+++ gcc/config/sparc/sparc.c	(working copy)
@@ -617,7 +617,7 @@  static machine_mode sparc_preferred_simd
 static reg_class_t sparc_preferred_reload_class (rtx x, reg_class_t rclass);
 static bool sparc_print_operand_punct_valid_p (unsigned char);
 static void sparc_print_operand (FILE *, rtx, int);
-static void sparc_print_operand_address (FILE *, rtx);
+static void sparc_print_operand_address (FILE *, machine_mode, rtx);
 static reg_class_t sparc_secondary_reload (bool, rtx, reg_class_t,
 					   machine_mode,
 					   secondary_reload_info *);
@@ -8802,7 +8802,7 @@  sparc_print_operand (FILE *file, rtx x, 
       return;
     case 'm':
       /* Print the operand's address only.  */
-      output_address (XEXP (x, 0));
+      output_address (GET_MODE (x), XEXP (x, 0));
       return;
     case 'r':
       /* In this case we need a register.  Use %g0 if the
@@ -8895,7 +8895,7 @@  sparc_print_operand (FILE *file, rtx x, 
       /* Operand must be a MEM; write its address.  */
       if (GET_CODE (x) != MEM)
 	output_operand_lossage ("invalid %%f operand");
-      output_address (XEXP (x, 0));
+      output_address (GET_MODE (x), XEXP (x, 0));
       return;
 
     case 's':
@@ -8933,7 +8933,7 @@  sparc_print_operand (FILE *file, rtx x, 
 	/* Poor Sun assembler doesn't understand absolute addressing.  */
       if (CONSTANT_P (XEXP (x, 0)))
 	fputs ("%g0+", file);
-      output_address (XEXP (x, 0));
+      output_address (GET_MODE (x), XEXP (x, 0));
       fputc (']', file);
     }
   else if (GET_CODE (x) == HIGH)
@@ -8972,7 +8972,8 @@  sparc_print_operand (FILE *file, rtx x, 
 /* Implement TARGET_PRINT_OPERAND_ADDRESS.  */
 
 static void
-sparc_print_operand_address (FILE *file, rtx x)
+sparc_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED,
+			     rtx x)
 {
   register rtx base, index = 0;
   int offset = 0;
@@ -8995,7 +8996,7 @@  sparc_print_operand_address (FILE *file,
 		      && ! TARGET_CM_MEDMID);
 	  output_operand (XEXP (base, 0), 0);
 	  fputs ("+%lo(", file);
-	  output_address (XEXP (base, 1));
+	  output_address (VOIDmode, XEXP (base, 1));
 	  fprintf (file, ")+%d", offset);
 	}
       else
@@ -9027,7 +9028,7 @@  sparc_print_operand_address (FILE *file,
         fputs ("+%l44(", file);
       else
         fputs ("+%lo(", file);
-      output_address (XEXP (addr, 1));
+      output_address (VOIDmode, XEXP (addr, 1));
       fputc (')', file);
     }
   else if (flag_pic
Index: gcc/config/iq2000/iq2000.c
===================================================================
--- gcc/config/iq2000/iq2000.c	(revision 229706)
+++ gcc/config/iq2000/iq2000.c	(working copy)
@@ -2896,7 +2896,7 @@  iq2000_setup_incoming_varargs (cumulativ
    reference whose address is ADDR.  ADDR is an RTL expression.  */
 
 static void
-iq2000_print_operand_address (FILE * file, rtx addr)
+iq2000_print_operand_address (FILE * file, machine_mode mode, rtx addr)
 {
   if (!addr)
     error ("PRINT_OPERAND_ADDRESS, null pointer");
@@ -2921,7 +2921,7 @@  iq2000_print_operand_address (FILE * fil
 			     "PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG.");
 
 	  fprintf (file, "%%lo(");
-	  iq2000_print_operand_address (file, arg1);
+	  iq2000_print_operand_address (file, mode, arg1);
 	  fprintf (file, ")(%s)", reg_names [REGNO (arg0)]);
 	}
 	break;
@@ -3169,10 +3169,12 @@  iq2000_print_operand (FILE *file, rtx op
 
   else if (code == MEM)
     {
+      machine_mode mode = GET_MODE (op);
+
       if (letter == 'D')
-	output_address (plus_constant (Pmode, XEXP (op, 0), 4));
+	output_address (mode, plus_constant (Pmode, XEXP (op, 0), 4));
       else
-	output_address (XEXP (op, 0));
+	output_address (mode, XEXP (op, 0));
     }
 
   else if (code == CONST_DOUBLE
Index: gcc/config/stormy16/stormy16.c
===================================================================
--- gcc/config/stormy16/stormy16.c	(revision 229706)
+++ gcc/config/stormy16/stormy16.c	(working copy)
@@ -1662,7 +1662,8 @@  xstormy16_asm_out_constructor (rtx symbo
    Print a memory address as an operand to reference that memory location.  */
 
 static void
-xstormy16_print_operand_address (FILE *file, rtx address)
+xstormy16_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED,
+				 rtx address)
 {
   HOST_WIDE_INT offset;
   int pre_dec, post_inc;
@@ -1769,7 +1770,7 @@  xstormy16_print_operand (FILE *file, rtx
       else if (LABEL_P (x))
 	output_asm_label (x);
       else
-	xstormy16_print_operand_address (file, x);
+	xstormy16_print_operand_address (file, VOIDmode, x);
       return;
 
     case 'o':
@@ -1825,7 +1826,7 @@  xstormy16_print_operand (FILE *file, rtx
       break;
 
     case MEM:
-      xstormy16_print_operand_address (file, XEXP (x, 0));
+      xstormy16_print_operand_address (file, GET_MODE (x), XEXP (x, 0));
       break;
 
     default:
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	(revision 229706)
+++ gcc/config/mips/mips.c	(working copy)
@@ -8595,7 +8595,8 @@  mips_print_operand (FILE *file, rtx op, 
 
 	case MEM:
 	  if (letter == 'D')
-	    output_address (plus_constant (Pmode, XEXP (op, 0), 4));
+	    output_address (GET_MODE (op), plus_constant (Pmode,
+							  XEXP (op, 0), 4));
 	  else if (letter == 'b')
 	    {
 	      gcc_assert (REG_P (XEXP (op, 0)));
@@ -8604,7 +8605,7 @@  mips_print_operand (FILE *file, rtx op, 
 	  else if (letter && letter != 'z')
 	    output_operand_lossage ("invalid use of '%%%c'", letter);
 	  else
-	    output_address (XEXP (op, 0));
+	    output_address (GET_MODE (op), XEXP (op, 0));
 	  break;
 
 	default:
@@ -8624,7 +8625,8 @@  mips_print_operand (FILE *file, rtx op, 
 /* Implement TARGET_PRINT_OPERAND_ADDRESS.  */
 
 static void
-mips_print_operand_address (FILE *file, rtx x)
+mips_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED,
+			    rtx x)
 {
   struct mips_address_info addr;
 
Index: gcc/config/epiphany/epiphany.c
===================================================================
--- gcc/config/epiphany/epiphany.c	(revision 229706)
+++ gcc/config/epiphany/epiphany.c	(working copy)
@@ -1317,7 +1317,7 @@  epiphany_print_operand (FILE *file, rtx 
 	    offset = 0;
 	    break;
 	}
-      output_address (addr);
+      output_address (GET_MODE (x), addr);
       fputc (']', file);
       if (offset)
 	{
@@ -1338,7 +1338,7 @@  epiphany_print_operand (FILE *file, rtx 
 	      case 1:
 		break;
 	    }
-	  output_address (offset);
+	  output_address (GET_MODE (x), offset);
 	}
       break;
     case CONST_DOUBLE :
@@ -1370,7 +1370,8 @@  epiphany_print_operand (FILE *file, rtx 
 /* Print a memory address as an operand to reference that memory location.  */
 
 static void
-epiphany_print_operand_address (FILE *file, rtx addr)
+epiphany_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED,
+				rtx addr)
 {
   register rtx base, index = 0;
   int offset = 0;
@@ -1424,7 +1425,9 @@  epiphany_print_operand_address (FILE *fi
       break;
     case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC: case POST_MODIFY:
       /* We shouldn't get here as we've lost the mode of the memory object
-	 (which says how much to inc/dec by.  */
+	 (which says how much to inc/dec by.
+	 FIXME: We have the mode now, address printing can be moved into this
+	 function.  */
       gcc_unreachable ();
       break;
     default:
Index: gcc/config/pdp11/pdp11.c
===================================================================
--- gcc/config/pdp11/pdp11.c	(revision 229706)
+++ gcc/config/pdp11/pdp11.c	(working copy)
@@ -724,7 +724,7 @@  pdp11_asm_print_operand (FILE *file, rtx
   else if (GET_CODE (x) == REG)
     fprintf (file, "%s", reg_names[REGNO (x)]);
   else if (GET_CODE (x) == MEM)
-    output_address (XEXP (x, 0));
+    output_address (GET_MODE (x), XEXP (x, 0));
   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != SImode)
     {
       REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), sval);
Index: gcc/config/rx/rx.c
===================================================================
--- gcc/config/rx/rx.c	(revision 229706)
+++ gcc/config/rx/rx.c	(working copy)
@@ -379,7 +379,8 @@  rx_mode_dependent_address_p (const_rtx a
    reference whose address is ADDR.  */
 
 static void
-rx_print_operand_address (FILE * file, rtx addr)
+rx_print_operand_address (FILE * file, machine_mode mode ATTRIBUTE_UNUSED,
+			  rtx addr)
 {
   switch (GET_CODE (addr))
     {
@@ -690,7 +691,7 @@  rx_print_operand (FILE * file, rtx op, i
 	case MEM:
 	  if (! WORDS_BIG_ENDIAN)
 	    op = adjust_address (op, SImode, 4);
-	  output_address (XEXP (op, 0));
+	  output_address (GET_MODE (op), XEXP (op, 0));
 	  break;
 	default:
 	  gcc_unreachable ();
@@ -714,7 +715,7 @@  rx_print_operand (FILE * file, rtx op, i
 	case MEM:
 	  if (WORDS_BIG_ENDIAN)
 	    op = adjust_address (op, SImode, 4);
-	  output_address (XEXP (op, 0));
+	  output_address (GET_MODE (op), XEXP (op, 0));
 	  break;
 	default:
 	  gcc_unreachable ();
@@ -846,11 +847,11 @@  rx_print_operand (FILE * file, rtx op, i
 	  }
 
 	case MEM:
-	  output_address (XEXP (op, 0));
+	  output_address (GET_MODE (op), XEXP (op, 0));
 	  break;
 
 	case PLUS:
-	  output_address (op);
+	  output_address (VOIDmode, op);
 	  break;
 
 	case REG:
@@ -915,7 +916,7 @@  rx_print_operand (FILE * file, rtx op, i
 	case SYMBOL_REF:
 	case LABEL_REF:
 	case CODE_LABEL:
-	  rx_print_operand_address (file, op);
+	  rx_print_operand_address (file, VOIDmode, op);
 	  break;
 
 	default:
Index: gcc/config/nds32/nds32.c
===================================================================
--- gcc/config/nds32/nds32.c	(revision 229706)
+++ gcc/config/nds32/nds32.c	(working copy)
@@ -2311,7 +2311,7 @@  nds32_print_operand (FILE *stream, rtx x
       break;
 
     case MEM:
-      output_address (XEXP (x, 0));
+      output_address (GET_MODE (x), XEXP (x, 0));
       break;
 
     case CODE_LABEL:
@@ -2331,7 +2331,8 @@  nds32_print_operand (FILE *stream, rtx x
 }
 
 static void
-nds32_print_operand_address (FILE *stream, rtx x)
+nds32_print_operand_address (FILE *stream, machine_mode mode ATTRIBUTE_UNUSED,
+			     rtx x)
 {
   rtx op0, op1;
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 229706)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -19259,18 +19259,19 @@  print_operand (FILE *file, rtx x, int co
 	fputs (reg_names[REGNO (x) + 1], file);
       else if (MEM_P (x))
 	{
+	  machine_mode mode = GET_MODE (x);
 	  /* Handle possible auto-increment.  Since it is pre-increment and
 	     we have already done it, we can just use an offset of word.  */
 	  if (GET_CODE (XEXP (x, 0)) == PRE_INC
 	      || GET_CODE (XEXP (x, 0)) == PRE_DEC)
-	    output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0),
-					   UNITS_PER_WORD));
+	    output_address (mode, plus_constant (Pmode, XEXP (XEXP (x, 0), 0),
+						 UNITS_PER_WORD));
 	  else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
-	    output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0),
-					   UNITS_PER_WORD));
+	    output_address (mode, plus_constant (Pmode, XEXP (XEXP (x, 0), 0),
+						 UNITS_PER_WORD));
 	  else
-	    output_address (XEXP (adjust_address_nv (x, SImode,
-						     UNITS_PER_WORD),
+	    output_address (mode, XEXP (adjust_address_nv (x, SImode,
+							   UNITS_PER_WORD),
 				  0));
 
 	  if (small_data_operand (x, GET_MODE (x)))
@@ -19506,13 +19507,16 @@  print_operand (FILE *file, rtx x, int co
 	fputs (reg_names[REGNO (x) + 2], file);
       else if (MEM_P (x))
 	{
+	  machine_mode mode = GET_MODE (x);
 	  if (GET_CODE (XEXP (x, 0)) == PRE_INC
 	      || GET_CODE (XEXP (x, 0)) == PRE_DEC)
-	    output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 8));
+	    output_address (mode, plus_constant (Pmode,
+						 XEXP (XEXP (x, 0), 0), 8));
 	  else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
-	    output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 8));
+	    output_address (mode, plus_constant (Pmode,
+						 XEXP (XEXP (x, 0), 0), 8));
 	  else
-	    output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
+	    output_address (mode, XEXP (adjust_address_nv (x, SImode, 8), 0));
 	  if (small_data_operand (x, GET_MODE (x)))
 	    fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
 		     reg_names[SMALL_DATA_REG]);
@@ -19551,13 +19555,16 @@  print_operand (FILE *file, rtx x, int co
 	fputs (reg_names[REGNO (x) + 3], file);
       else if (MEM_P (x))
 	{
+	  machine_mode mode = GET_MODE (x);
 	  if (GET_CODE (XEXP (x, 0)) == PRE_INC
 	      || GET_CODE (XEXP (x, 0)) == PRE_DEC)
-	    output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 12));
+	    output_address (mode, plus_constant (Pmode,
+						 XEXP (XEXP (x, 0), 0), 12));
 	  else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
-	    output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 12));
+	    output_address (mode, plus_constant (Pmode,
+						 XEXP (XEXP (x, 0), 0), 12));
 	  else
-	    output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
+	    output_address (mode, XEXP (adjust_address_nv (x, SImode, 12), 0));
 	  if (small_data_operand (x, GET_MODE (x)))
 	    fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
 		     reg_names[SMALL_DATA_REG]);
@@ -19645,9 +19652,9 @@  print_operand (FILE *file, rtx x, int co
 	    fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
 		     reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
 	  else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
-	    output_address (XEXP (XEXP (x, 0), 1));
+	    output_address (GET_MODE (x), XEXP (XEXP (x, 0), 1));
 	  else
-	    output_address (XEXP (x, 0));
+	    output_address (GET_MODE (x), XEXP (x, 0));
 	}
       else
 	{
Index: gcc/config/c6x/c6x.c
===================================================================
--- gcc/config/c6x/c6x.c	(revision 229706)
+++ gcc/config/c6x/c6x.c	(working copy)
@@ -1854,7 +1854,7 @@  print_address_offset (FILE *file, rtx of
 	}
     }
   fputs ("(", file);
-  output_address (off);
+  output_address (mem_mode, off);
   fputs (")", file);
 }
 
@@ -1877,7 +1877,7 @@  c6x_print_address_operand (FILE *file, r
     case PRE_MODIFY:
     case POST_MODIFY:
       if (GET_CODE (x) == POST_MODIFY)
-	output_address (XEXP (x, 0));
+	output_address (mem_mode, XEXP (x, 0));
       off = XEXP (XEXP (x, 1), 1);
       if (XEXP (x, 0) == stack_pointer_rtx)
 	{
@@ -1894,7 +1894,7 @@  c6x_print_address_operand (FILE *file, r
       else
 	fprintf (file, "++");
       if (GET_CODE (x) == PRE_MODIFY)
-	output_address (XEXP (x, 0));
+	output_address (mem_mode, XEXP (x, 0));
       print_address_offset (file, off, mem_mode);
       break;
 
@@ -1907,28 +1907,28 @@  c6x_print_address_operand (FILE *file, r
 	}
       else
 	fprintf (file, "+");
-      output_address (XEXP (x, 0));
+      output_address (mem_mode, XEXP (x, 0));
       print_address_offset (file, off, mem_mode);
       break;
 
     case PRE_DEC:
       gcc_assert (XEXP (x, 0) != stack_pointer_rtx);
       fprintf (file, "--");
-      output_address (XEXP (x, 0));
+      output_address (mem_mode, XEXP (x, 0));
       fprintf (file, "[1]");
       break;
     case PRE_INC:
       fprintf (file, "++");
-      output_address (XEXP (x, 0));
+      output_address (mem_mode, XEXP (x, 0));
       fprintf (file, "[1]");
       break;
     case POST_INC:
       gcc_assert (XEXP (x, 0) != stack_pointer_rtx);
-      output_address (XEXP (x, 0));
+      output_address (mem_mode, XEXP (x, 0));
       fprintf (file, "++[1]");
       break;
     case POST_DEC:
-      output_address (XEXP (x, 0));
+      output_address (mem_mode, XEXP (x, 0));
       fprintf (file, "--[1]");
       break;
 
@@ -2042,9 +2042,9 @@  c6x_print_unit_specifier_field (FILE *fi
 
 /* Output assembly language output for the address ADDR to FILE.  */
 static void
-c6x_print_operand_address (FILE *file, rtx addr)
+c6x_print_operand_address (FILE *file, machine_mode mode, rtx addr)
 {
-  c6x_print_address_operand (file, addr, VOIDmode);
+  c6x_print_address_operand (file, addr, mode);
 }
 
 /* Print an operand, X, to FILE, with an optional modifier in CODE.
Index: gcc/config/v850/v850.c
===================================================================
--- gcc/config/v850/v850.c	(revision 229706)
+++ gcc/config/v850/v850.c	(working copy)
@@ -50,7 +50,7 @@ 
 #define streq(a,b) (strcmp (a, b) == 0)
 #endif
 
-static void v850_print_operand_address (FILE *, rtx);
+static void v850_print_operand_address (FILE *, machine_mode, rtx);
 
 /* Names of the various data areas used on the v850.  */
 const char * GHS_default_section_names [(int) COUNT_OF_GHS_SECTION_KINDS];
@@ -540,10 +540,13 @@  v850_print_operand (FILE * file, rtx x, 
 	  fprintf (file, reg_names[REGNO (x) + 1]);
 	  break;
 	case MEM:
-	  x = XEXP (adjust_address (x, SImode, 4), 0);
-	  v850_print_operand_address (file, x);
-	  if (GET_CODE (x) == CONST_INT)
-	    fprintf (file, "[r0]");
+	  {
+	    machine_mode mode = GET_MODE (x);
+	    x = XEXP (adjust_address (x, SImode, 4), 0);
+	    v850_print_operand_address (file, mode, x);
+	    if (GET_CODE (x) == CONST_INT)
+	      fprintf (file, "[r0]");
+	  }
 	  break;
 	  
 	case CONST_INT:
@@ -617,10 +620,11 @@  v850_print_operand (FILE * file, rtx x, 
 	{
 	case MEM:
 	  if (GET_CODE (XEXP (x, 0)) == CONST_INT)
-	    output_address (gen_rtx_PLUS (SImode, gen_rtx_REG (SImode, 0),
+	    output_address (GET_MODE (x),
+			    gen_rtx_PLUS (SImode, gen_rtx_REG (SImode, 0),
 					  XEXP (x, 0)));
 	  else
-	    output_address (XEXP (x, 0));
+	    output_address (GET_MODE (x), XEXP (x, 0));
 	  break;
 
 	case REG:
@@ -638,7 +642,7 @@  v850_print_operand (FILE * file, rtx x, 
 	case CONST:
 	case LABEL_REF:
 	case CODE_LABEL:
-	  v850_print_operand_address (file, x);
+	  v850_print_operand_address (file, VOIDmode, x);
 	  break;
 	default:
 	  gcc_unreachable ();
@@ -652,7 +656,8 @@  v850_print_operand (FILE * file, rtx x, 
 /* Output assembly language output for the address ADDR to FILE.  */
 
 static void
-v850_print_operand_address (FILE * file, rtx addr)
+v850_print_operand_address (FILE * file, machine_mode mode ATTRIBUTE_UNUSED,
+			    rtx addr)
 {
   switch (GET_CODE (addr))
     {
Index: gcc/config/mmix/mmix.c
===================================================================
--- gcc/config/mmix/mmix.c	(revision 229706)
+++ gcc/config/mmix/mmix.c	(working copy)
@@ -162,7 +162,7 @@  static bool mmix_frame_pointer_required 
 static void mmix_asm_trampoline_template (FILE *);
 static void mmix_trampoline_init (rtx, tree, rtx);
 static void mmix_print_operand (FILE *, rtx, int);
-static void mmix_print_operand_address (FILE *, rtx);
+static void mmix_print_operand_address (FILE *, machine_mode, rtx);
 static bool mmix_print_operand_punct_valid_p (unsigned char);
 static void mmix_conditional_register_usage (void);
 
@@ -1697,7 +1697,7 @@  mmix_print_operand (FILE *stream, rtx x,
       return;
 
     case MEM:
-      output_address (XEXP (modified_x, 0));
+      output_address (GET_MODE (modified_x), XEXP (modified_x, 0));
       return;
 
     case CONST_INT:
@@ -1754,7 +1754,7 @@  mmix_print_operand_punct_valid_p (unsign
 /* TARGET_PRINT_OPERAND_ADDRESS.  */
 
 static void
-mmix_print_operand_address (FILE *stream, rtx x)
+mmix_print_operand_address (FILE *stream, machine_mode mode, rtx x)
 {
   if (REG_P (x))
     {
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c	(revision 229706)
+++ gcc/config/sh/sh.c	(working copy)
@@ -212,7 +212,7 @@  static tree sh_handle_sp_switch_attribut
 static tree sh_handle_trap_exit_attribute (tree *, tree, tree, int, bool *);
 static tree sh_handle_renesas_attribute (tree *, tree, tree, int, bool *);
 static void sh_print_operand (FILE *, rtx, int);
-static void sh_print_operand_address (FILE *, rtx);
+static void sh_print_operand_address (FILE *, machine_mode, rtx);
 static bool sh_print_operand_punct_valid_p (unsigned char code);
 static bool sh_asm_output_addr_const_extra (FILE *file, rtx x);
 static void sh_output_function_epilogue (FILE *, HOST_WIDE_INT);
@@ -1144,7 +1144,8 @@  sh_override_options_after_change (void)
 
 /* Print the operand address in x to the stream.  */
 static void
-sh_print_operand_address (FILE *stream, rtx x)
+sh_print_operand_address (FILE *stream, machine_mode mode ATTRIBUTE_UNUSED,
+			  rtx x)
 {
   switch (GET_CODE (x))
     {
@@ -1562,7 +1563,7 @@  sh_print_operand (FILE *stream, rtx x, i
 	  break;
 
 	case MEM:
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), XEXP (x, 0));
 	  break;
 
 	default:
Index: gcc/config/cr16/cr16.c
===================================================================
--- gcc/config/cr16/cr16.c	(revision 229706)
+++ gcc/config/cr16/cr16.c	(working copy)
@@ -122,7 +122,7 @@  static enum data_model_type data_model =
 
 /* TARGETM Function Prototypes and forward declarations  */
 static void cr16_print_operand (FILE *, rtx, int);
-static void cr16_print_operand_address (FILE *, rtx);
+static void cr16_print_operand_address (FILE *, machine_mode, rtx);
 
 /* Stack layout and calling conventions.  */
 #undef  TARGET_STRUCT_VALUE_RTX
@@ -1494,7 +1494,7 @@  cr16_print_operand (FILE * file, rtx x, 
 	  return;
 
 	case MEM:
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), XEXP (x, 0));
 	  return;
 
 	case CONST_DOUBLE:
@@ -1524,7 +1524,7 @@  cr16_print_operand (FILE * file, rtx x, 
 	    {
 	      putc ('$', file);
 	    }
-	  cr16_print_operand_address (file, x);
+	  cr16_print_operand_address (file, VOIDmode, x);
 	  return;
 	}
     default:
@@ -1537,7 +1537,8 @@  cr16_print_operand (FILE * file, rtx x, 
 /* Implements the macro PRINT_OPERAND_ADDRESS defined in cr16.h.  */
 
 static void
-cr16_print_operand_address (FILE * file, rtx addr)
+cr16_print_operand_address (FILE * file, machine_mode mode ATTRIBUTE_UNUSED,
+			    rtx addr)
 {
   enum cr16_addrtype addrtype;
   struct cr16_address address;
Index: gcc/config/bfin/bfin.c
===================================================================
--- gcc/config/bfin/bfin.c	(revision 229706)
+++ gcc/config/bfin/bfin.c	(working copy)
@@ -1300,21 +1300,21 @@  print_address_operand (FILE *file, rtx x
   switch (GET_CODE (x))
     {
     case PLUS:
-      output_address (XEXP (x, 0));
+      output_address (VOIDmode, XEXP (x, 0));
       fprintf (file, "+");
-      output_address (XEXP (x, 1));
+      output_address (VOIDmode, XEXP (x, 1));
       break;
 
     case PRE_DEC:
       fprintf (file, "--");
-      output_address (XEXP (x, 0));    
+      output_address (VOIDmode, XEXP (x, 0));    
       break;
     case POST_INC:
-      output_address (XEXP (x, 0));
+      output_address (VOIDmode, XEXP (x, 0));
       fprintf (file, "++");
       break;
     case POST_DEC:
-      output_address (XEXP (x, 0));
+      output_address (VOIDmode, XEXP (x, 0));
       fprintf (file, "--");
       break;
 
Index: gcc/config/microblaze/microblaze.c
===================================================================
--- gcc/config/microblaze/microblaze.c	(revision 229706)
+++ gcc/config/microblaze/microblaze.c	(working copy)
@@ -2317,7 +2317,7 @@  print_operand (FILE * file, rtx op, int 
     if (letter == 'o')
       {
 	rtx op4 = adjust_address (op, GET_MODE (op), 4);
-	output_address (XEXP (op4, 0));
+	output_address (GET_MODE (op), XEXP (op4, 0));
       }
     else if (letter == 'y')
       {
@@ -2329,7 +2329,7 @@  print_operand (FILE * file, rtx op, int 
         }
       }
     else
-      output_address (XEXP (op, 0));
+      output_address (GET_MODE (op), XEXP (op, 0));
 
   else if (letter == 'h' || letter == 'j')
     {
Index: gcc/config/nios2/nios2.c
===================================================================
--- gcc/config/nios2/nios2.c	(revision 229706)
+++ gcc/config/nios2/nios2.c	(working copy)
@@ -2622,7 +2622,7 @@  nios2_print_operand (FILE *file, rtx op,
 	}
       if (letter == 0)
         {
-          output_address (op);
+          output_address (VOIDmode, op);
           return;
         }
       break;
@@ -2705,7 +2705,7 @@  nios2_output_addr_const_extra (FILE *fil
 
 /* Implement TARGET_PRINT_OPERAND_ADDRESS.  */
 static void
-nios2_print_operand_address (FILE *file, rtx op)
+nios2_print_operand_address (FILE *file, machine_mode mode, rtx op)
 {
   switch (GET_CODE (op))
     {
@@ -2751,7 +2751,7 @@  nios2_print_operand_address (FILE *file,
     case MEM:
       {
         rtx base = XEXP (op, 0);
-        nios2_print_operand_address (file, base);
+        nios2_print_operand_address (file, mode, base);
         return;
       }
     default:
Index: gcc/config/s390/s390.c
===================================================================
--- gcc/config/s390/s390.c	(revision 229706)
+++ gcc/config/s390/s390.c	(working copy)
@@ -7031,7 +7031,7 @@  print_operand (FILE *file, rtx x, int co
       break;
 
     case MEM:
-      output_address (XEXP (x, 0));
+      output_address (GET_MODE (x), XEXP (x, 0));
       break;
 
     case CONST:
Index: gcc/config/m32c/m32c.c
===================================================================
--- gcc/config/m32c/m32c.c	(revision 229706)
+++ gcc/config/m32c/m32c.c	(working copy)
@@ -2795,7 +2795,8 @@  m32c_print_operand_punct_valid_p (unsign
 #define TARGET_PRINT_OPERAND_ADDRESS m32c_print_operand_address
 
 static void
-m32c_print_operand_address (FILE * stream, rtx address)
+m32c_print_operand_address (FILE * stream, machine_mode mode ATTRIBUTE_UNUSED,
+			    rtx address)
 {
   if (GET_CODE (address) == MEM)
     address = XEXP (address, 0);
Index: gcc/config/arc/arc.c
===================================================================
--- gcc/config/arc/arc.c	(revision 229706)
+++ gcc/config/arc/arc.c	(working copy)
@@ -2929,19 +2929,22 @@  arc_print_operand (FILE *file, rtx x, in
 	      || GET_CODE (XEXP (x, 0)) == POST_INC
 	      || GET_CODE (XEXP (x, 0)) == POST_DEC
 	      || GET_CODE (XEXP (x, 0)) == POST_MODIFY)
-	    output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
+	    output_address (VOIDmode,
+			    plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
 	  else if (output_scaled)
 	    {
 	      rtx addr = XEXP (x, 0);
 	      int size = GET_MODE_SIZE (GET_MODE (x));
 
-	      output_address (plus_constant (Pmode, XEXP (addr, 0),
+	      output_address (VOIDmode,
+			      plus_constant (Pmode, XEXP (addr, 0),
 					     ((INTVAL (XEXP (addr, 1)) + 4)
 					      >> (size == 2 ? 1 : 2))));
 	      output_scaled = 0;
 	    }
 	  else
-	    output_address (plus_constant (Pmode, XEXP (x, 0), 4));
+	    output_address (VOIDmode,
+			    plus_constant (Pmode, XEXP (x, 0), 4));
 	  fputc (']', file);
 	}
       else
@@ -3132,28 +3135,31 @@  arc_print_operand (FILE *file, rtx x, in
 	switch (GET_CODE (addr))
 	  {
 	  case PRE_INC: case POST_INC:
-	    output_address (plus_constant (Pmode, XEXP (addr, 0), size)); break;
+	    output_address (VOIDmode,
+			    plus_constant (Pmode, XEXP (addr, 0), size)); break;
 	  case PRE_DEC: case POST_DEC:
-	    output_address (plus_constant (Pmode, XEXP (addr, 0), -size));
+	    output_address (VOIDmode,
+			    plus_constant (Pmode, XEXP (addr, 0), -size));
 	    break;
 	  case PRE_MODIFY: case POST_MODIFY:
-	    output_address (XEXP (addr, 1)); break;
+	    output_address (VOIDmode, XEXP (addr, 1)); break;
 	  case PLUS:
 	    if (output_scaled)
 	      {
-		output_address (plus_constant (Pmode, XEXP (addr, 0),
+		output_address (VOIDmode,
+				plus_constant (Pmode, XEXP (addr, 0),
 					       (INTVAL (XEXP (addr, 1))
 						>> (size == 2 ? 1 : 2))));
 		output_scaled = 0;
 	      }
 	    else
-	      output_address (addr);
+	      output_address (VOIDmode, addr);
 	    break;
 	  default:
 	    if (flag_pic && CONSTANT_ADDRESS_P (addr))
 	      arc_output_pic_addr_const (file, addr, code);
 	    else
-	      output_address (addr);
+	      output_address (VOIDmode, addr);
 	    break;
 	  }
 	fputc (']', file);
@@ -3239,7 +3245,7 @@  arc_print_operand_address (FILE *file , 
 	gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF);
 	gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT);
 
-	output_address(XEXP(addr,0));
+	output_address (VOIDmode, XEXP (addr, 0));
 
 	break;
       }
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 229706)
+++ gcc/config/arm/arm.c	(working copy)
@@ -100,7 +100,7 @@  static bool thumb_force_lr_save (void);
 static unsigned arm_size_return_regs (void);
 static bool arm_assemble_integer (rtx, unsigned int, int);
 static void arm_print_operand (FILE *, rtx, int);
-static void arm_print_operand_address (FILE *, rtx);
+static void arm_print_operand_address (FILE *, machine_mode, rtx);
 static bool arm_print_operand_punct_valid_p (unsigned char code);
 static const char *fp_const_from_val (REAL_VALUE_TYPE *);
 static arm_cc get_arm_condition_code (rtx);
@@ -869,11 +869,6 @@  int prefer_neon_for_64bits = 0;
 /* Nonzero if we shouldn't use literal pools.  */
 bool arm_disable_literal_pool = false;
 
-/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference,
-   we must report the mode of the memory reference from
-   TARGET_PRINT_OPERAND to TARGET_PRINT_OPERAND_ADDRESS.  */
-machine_mode output_memory_reference_mode;
-
 /* The register number to be used for the PIC offset register.  */
 unsigned arm_pic_register = INVALID_REGNUM;
 
@@ -22434,8 +22429,7 @@  arm_print_operand (FILE *stream, rtx x, 
 	  break;
 
 	case MEM:
-	  output_memory_reference_mode = GET_MODE (x);
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), XEXP (x, 0));
 	  break;
 
 	case CONST_DOUBLE:
@@ -22464,7 +22458,7 @@  arm_print_operand (FILE *stream, rtx x, 
 
 /* Target hook for printing a memory address.  */
 static void
-arm_print_operand_address (FILE *stream, rtx x)
+arm_print_operand_address (FILE *stream, machine_mode mode, rtx x)
 {
   if (TARGET_32BIT)
     {
@@ -22522,20 +22516,18 @@  arm_print_operand_address (FILE *stream,
       else if (GET_CODE (x) == PRE_INC || GET_CODE (x) == POST_INC
 	       || GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_DEC)
 	{
-	  extern machine_mode output_memory_reference_mode;
-
 	  gcc_assert (REG_P (XEXP (x, 0)));
 
 	  if (GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC)
 	    asm_fprintf (stream, "[%r, #%s%d]!",
 			 REGNO (XEXP (x, 0)),
 			 GET_CODE (x) == PRE_DEC ? "-" : "",
-			 GET_MODE_SIZE (output_memory_reference_mode));
+			 GET_MODE_SIZE (mode));
 	  else
 	    asm_fprintf (stream, "[%r], #%s%d",
 			 REGNO (XEXP (x, 0)),
 			 GET_CODE (x) == POST_DEC ? "-" : "",
-			 GET_MODE_SIZE (output_memory_reference_mode));
+			 GET_MODE_SIZE (mode));
 	}
       else if (GET_CODE (x) == PRE_MODIFY)
 	{
Index: gcc/config/m32r/m32r.c
===================================================================
--- gcc/config/m32r/m32r.c	(revision 229706)
+++ gcc/config/m32r/m32r.c	(working copy)
@@ -66,7 +66,7 @@  static rtx   m32r_legitimize_address (rt
 static bool  m32r_mode_dependent_address_p (const_rtx, addr_space_t);
 static tree  m32r_handle_model_attribute (tree *, tree, tree, int, bool *);
 static void  m32r_print_operand (FILE *, rtx, int);
-static void  m32r_print_operand_address (FILE *, rtx);
+static void  m32r_print_operand_address (FILE *, machine_mode, rtx);
 static bool  m32r_print_operand_punct_valid_p (unsigned char code);
 static void  m32r_output_function_prologue (FILE *, HOST_WIDE_INT);
 static void  m32r_output_function_epilogue (FILE *, HOST_WIDE_INT);
@@ -2086,6 +2086,8 @@  m32r_print_operand (FILE * file, rtx x, 
 	fputs (reg_names[REGNO (x)+1], file);
       else if (MEM_P (x))
 	{
+	  machine_mode mode = GET_MODE (x);
+
 	  fprintf (file, "@(");
 	  /* Handle possible auto-increment.  Since it is pre-increment and
 	     we have already done it, we can just use an offset of four.  */
@@ -2093,9 +2095,10 @@  m32r_print_operand (FILE * file, rtx x, 
 	     currently necessary, but keep it around.  */
 	  if (GET_CODE (XEXP (x, 0)) == PRE_INC
 	      || GET_CODE (XEXP (x, 0)) == PRE_DEC)
-	    output_address (plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
+	    output_address (mode, plus_constant (Pmode,
+						 XEXP (XEXP (x, 0), 0), 4));
 	  else
-	    output_address (plus_constant (Pmode, XEXP (x, 0), 4));
+	    output_address (mode, plus_constant (Pmode, XEXP (x, 0), 4));
 	  fputc (')', file);
 	}
       else
@@ -2255,7 +2258,7 @@  m32r_print_operand (FILE * file, rtx x, 
       else
 	{
 	  fputs ("@(", file);
-	  output_address (XEXP (x, 0));
+	  output_address (GET_MODE (x), addr);
 	  fputc (')', file);
 	}
       break;
@@ -2282,7 +2285,8 @@  m32r_print_operand (FILE * file, rtx x, 
 /* Print a memory address as an operand to reference that memory location.  */
 
 static void
-m32r_print_operand_address (FILE * file, rtx addr)
+m32r_print_operand_address (FILE * file, machine_mode mode ATTRIBUTE_UNUSED,
+			    rtx addr)
 {
   rtx base;
   rtx index = 0;
Index: gcc/config/msp430/msp430.c
===================================================================
--- gcc/config/msp430/msp430.c	(revision 229706)
+++ gcc/config/msp430/msp430.c	(working copy)
@@ -3287,7 +3287,8 @@  msp430_print_operand_raw (FILE * file, r
    is ADDR.  */
 
 static void
-msp430_print_operand_addr (FILE * file, rtx addr)
+msp430_print_operand_addr (FILE * file, machine_mode mode ATTRIBUTE_UNUSED,
+			   rtx addr)
 {
   switch (GET_CODE (addr))
     {
@@ -3531,7 +3532,7 @@  msp430_print_operand (FILE * file, rtx o
 
     case MEM:
       addr = XEXP (op, 0);
-      msp430_print_operand_addr (file, addr);
+      msp430_print_operand_addr (file, GET_MODE (op), addr);
       break;
 
     case CONST:
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 229706)
+++ gcc/config/i386/i386.c	(working copy)
@@ -16595,7 +16595,7 @@  ix86_print_operand (FILE *file, rtx x, i
 	  if (TARGET_64BIT)
 	    x = gen_rtx_UNSPEC (DImode, gen_rtvec (1, x), UNSPEC_LEA_ADDR);
 
-	  output_address (x);
+	  output_address (VOIDmode, x);
 	  return;
 
 	case 'L':
@@ -17112,9 +17112,11 @@  ix86_print_operand (FILE *file, rtx x, i
 
   else if (MEM_P (x))
     {
+      machine_mode mode = GET_MODE (x);
+
       /* No `byte ptr' prefix for call instructions or BLKmode operands.  */
       if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P'
-	  && GET_MODE (x) != BLKmode)
+	  && mode != BLKmode)
 	{
 	  const char * size;
 	  switch (GET_MODE_SIZE (GET_MODE (x)))
@@ -17125,7 +17127,7 @@  ix86_print_operand (FILE *file, rtx x, i
 	    case 8: size = "QWORD"; break;
 	    case 12: size = "TBYTE"; break;
 	    case 16:
-	      if (GET_MODE (x) == XFmode)
+	      if (mode == XFmode)
 		size = "TBYTE";
               else
 		size = "XMMWORD";
@@ -17161,7 +17163,7 @@  ix86_print_operand (FILE *file, rtx x, i
       else if (this_is_asm_operands && ! address_operand (x, VOIDmode))
 	output_operand_lossage ("invalid constraints for operand");
       else
-	output_address (x);
+	output_address (mode, x);
     }
 
   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == SFmode)
@@ -17246,7 +17248,8 @@  ix86_print_operand_punct_valid_p (unsign
 /* Print a memory operand whose address is ADDR.  */
 
 static void
-ix86_print_operand_address (FILE *file, rtx addr)
+ix86_print_operand_address (FILE *file, machine_mode mode ATTRIBUTE_UNUSED,
+			    rtx addr)
 {
   struct ix86_address parts;
   rtx base, index, disp;
Index: gcc/final.c
===================================================================
--- gcc/final.c	(revision 229706)
+++ gcc/final.c	(working copy)
@@ -3713,7 +3713,7 @@  output_asm_insn (const char *templ, rtx 
 	    else if (letter == 'l')
 	      output_asm_label (operands[opnum]);
 	    else if (letter == 'a')
-	      output_address (operands[opnum]);
+	      output_address (VOIDmode, operands[opnum]);
 	    else if (letter == 'c')
 	      {
 		if (CONSTANT_ADDRESS_P (operands[opnum]))
@@ -3848,11 +3848,11 @@  output_operand (rtx x, int code ATTRIBUT
    machine-dependent assembler syntax.  */
 
 void
-output_address (rtx x)
+output_address (machine_mode mode, rtx x)
 {
   bool changed = false;
   walk_alter_subreg (&x, &changed);
-  targetm.asm_out.print_operand_address (asm_out_file, x);
+  targetm.asm_out.print_operand_address (asm_out_file, mode, x);
 }
 
 /* Print an integer constant expression in assembler syntax.
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c	(revision 229706)
+++ gcc/targhooks.c	(working copy)
@@ -345,6 +345,7 @@  default_print_operand (FILE *stream ATTR
 
 void
 default_print_operand_address (FILE *stream ATTRIBUTE_UNUSED,
+			       machine_mode mode ATTRIBUTE_UNUSED,
 			       rtx x ATTRIBUTE_UNUSED)
 {
 #ifdef PRINT_OPERAND_ADDRESS
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h	(revision 229706)
+++ gcc/targhooks.h	(working copy)
@@ -67,7 +67,7 @@  extern bool hook_callee_copies_named
   (cumulative_args_t ca, machine_mode, const_tree, bool);
 
 extern void default_print_operand (FILE *, rtx, int);
-extern void default_print_operand_address (FILE *, rtx);
+extern void default_print_operand_address (FILE *, machine_mode, rtx);
 extern bool default_print_operand_punct_valid_p (unsigned char);
 extern tree default_mangle_assembler_name (const char *);
 
Index: gcc/output.h
===================================================================
--- gcc/output.h	(revision 229706)
+++ gcc/output.h	(working copy)
@@ -108,9 +108,9 @@  extern void output_asm_label (rtx);
 /* Marks SYMBOL_REFs in x as referenced through use of assemble_external.  */
 extern void mark_symbol_refs_as_used (rtx);
 
-/* Print a memory reference operand for address X
+/* Print a memory reference operand for address X with access mode MODE
    using machine-dependent assembler syntax.  */
-extern void output_address (rtx);
+extern void output_address (machine_mode, rtx);
 
 /* Print an integer constant expression in assembler syntax.
    Addition and subtraction are the only arithmetic
Index: gcc/target.def
===================================================================
--- gcc/target.def	(revision 229706)
+++ gcc/target.def	(working copy)
@@ -893,7 +893,7 @@  DEFHOOK_UNDOC
 DEFHOOK_UNDOC
 (print_operand_address,
  "",
- void, (FILE *file, rtx addr),
+ void, (FILE *file, machine_mode mode, rtx addr),
  default_print_operand_address)
 
 /* Determine whether CODE is a valid punctuation character for the