This adds a target hook to avoid doing register allocation or reload and
changes some code not to crash in such a case.

	gcc/
	* target.def (no_register_allocation): New data hook.
	* doc/tm.texi.in: Add @hook TARGET_NO_REGISTER_ALLOCATION.
	* doc/tm.texi: Regenerate.
	* ira.c (gate_ira): New function.
	(pass_data_ira): Set has_gate.
	(pass_ira): Add a gate function.
	(pass_data_reload): Likewise.
	(pass_reload): Add a gate function.
	(pass_ira): Use it.
	* reload1.c (eliminate_regs): If reg_eliminte_is NULL, assert that
	no register allocation happens on the target and return.
	* final.c (alter_subreg): Ensure register is not a pseudo before
	calling simplify_subreg.
	(output_operand): Assert that x isn't a pseudo only if doing
	register allocation.

------------------------------------------------------------------------
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 422351)
+++ gcc/doc/tm.texi	(revision 422352)
@@ -9457,11 +9457,19 @@ True if the @code{DW_AT_comp_dir} attrib
 @end deftypevr
 
 @deftypevr {Target Hook} bool TARGET_DELAY_SCHED2
-True if sched2 is not to be run at its normal place.  This usually means it will be run as part of machine-specific reorg.
+True if sched2 is not to be run at its normal place.
+This usually means it will be run as part of machine-specific reorg.
 @end deftypevr
 
 @deftypevr {Target Hook} bool TARGET_DELAY_VARTRACK
-True if vartrack is not to be run at its normal place.  This usually means it will be run as part of machine-specific reorg.
+True if vartrack is not to be run at its normal place.
+This usually means it will be run as part of machine-specific reorg.
+@end deftypevr
+
+@deftypevr {Target Hook} bool TARGET_NO_REGISTER_ALLOCATION
+True if register allocation and the passes
+following it should not be run.  Usually true only for virtual assembler
+targets.
 @end deftypevr
 
 @defmac ASM_OUTPUT_DWARF_DELTA (@var{stream}, @var{size}, @var{label1}, @var{label2})
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 422351)
+++ gcc/doc/tm.texi.in	(revision 422352)
@@ -7159,6 +7159,8 @@ tables, and hence is desirable if it wor
 
 @hook TARGET_DELAY_VARTRACK
 
+@hook TARGET_NO_REGISTER_ALLOCATION
+
 @defmac ASM_OUTPUT_DWARF_DELTA (@var{stream}, @var{size}, @var{label1}, @var{label2})
 A C statement to issue assembly directives that create a difference
 @var{lab1} minus @var{lab2}, using an integer of the given @var{size}.
Index: gcc/target.def
===================================================================
--- gcc/target.def	(revision 422351)
+++ gcc/target.def	(revision 422352)
@@ -5231,15 +5231,21 @@ DEFHOOKPOD
  bool, false)
 
 DEFHOOKPOD
-(delay_sched2, "True if sched2 is not to be run at its normal place.  \
+(delay_sched2, "True if sched2 is not to be run at its normal place.\n\
 This usually means it will be run as part of machine-specific reorg.",
 bool, false)
 
 DEFHOOKPOD
-(delay_vartrack, "True if vartrack is not to be run at its normal place.  \
+(delay_vartrack, "True if vartrack is not to be run at its normal place.\n\
 This usually means it will be run as part of machine-specific reorg.",
 bool, false)
 
+DEFHOOKPOD
+(no_register_allocation, "True if register allocation and the passes\n\
+following it should not be run.  Usually true only for virtual assembler\n\
+targets.",
+bool, false)
+
 /* Leave the boolean fields at the end.  */
 
 /* Close the 'struct gcc_target' definition.  */
Index: gcc/final.c
===================================================================
--- gcc/final.c	(revision 422351)
+++ gcc/final.c	(revision 422352)
@@ -3125,7 +3125,7 @@ alter_subreg (rtx *xp, bool final_p)
       else
 	*xp = adjust_address_nv (y, GET_MODE (x), offset);
     }
-  else
+  else if (REG_P (y) && HARD_REGISTER_P (y))
     {
       rtx new_rtx = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
 				     SUBREG_BYTE (x));
@@ -3812,7 +3812,8 @@ output_operand (rtx x, int code ATTRIBUT
     x = alter_subreg (&x, true);
 
   /* X must not be a pseudo reg.  */
-  gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);
+  if (!targetm.no_register_allocation)
+    gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);
 
   targetm.asm_out.print_operand (asm_out_file, x, code);
 
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	(revision 422351)
+++ gcc/reload1.c	(revision 422352)
@@ -2963,6 +2963,11 @@ eliminate_regs_1 (rtx x, enum machine_mo
 rtx
 eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
 {
+  if (reg_eliminate == NULL)
+    {
+      gcc_assert (targetm.no_register_allocation);
+      return x;
+    }
   return eliminate_regs_1 (x, mem_mode, insn, false, false);
 }
 
Index: gcc/ira.c
===================================================================
--- gcc/ira.c.orig
+++ gcc/ira.c
@@ -5507,6 +5507,13 @@ rest_of_handle_ira (void)
   return 0;
 }
 
+static bool
+gate_ira (void)
+{
+  return !targetm.no_register_allocation;
+}
+
+
 namespace {
 
 const pass_data pass_data_ira =
@@ -5514,7 +5521,7 @@ const pass_data pass_data_ira =
   RTL_PASS, /* type */
   "ira", /* name */
   OPTGROUP_NONE, /* optinfo_flags */
-  false, /* has_gate */
+  true, /* has_gate */
   true, /* has_execute */
   TV_IRA, /* tv_id */
   0, /* properties_required */
@@ -5532,6 +5539,7 @@ public:
   {}
 
   /* opt_pass methods: */
+  bool gate () { return gate_ira (); }
   unsigned int execute () { return rest_of_handle_ira (); }
 
 }; // class pass_ira
@@ -5558,7 +5566,7 @@ const pass_data pass_data_reload =
   RTL_PASS, /* type */
   "reload", /* name */
   OPTGROUP_NONE, /* optinfo_flags */
-  false, /* has_gate */
+  true, /* has_gate */
   true, /* has_execute */
   TV_RELOAD, /* tv_id */
   0, /* properties_required */
@@ -5576,6 +5584,7 @@ public:
   {}
 
   /* opt_pass methods: */
+  bool gate () { return gate_ira (); }
   unsigned int execute () { return rest_of_handle_reload (); }
 
 }; // class pass_reload
