[committed] Add -mgnu-asm to pdp11 target, change -mdec-asm

Message ID 95454E22-3C76-47B5-8E64-E5120ABF7330@comcast.net
State New
Headers show
Series
  • [committed] Add -mgnu-asm to pdp11 target, change -mdec-asm
Related show

Commit Message

Paul Koning July 1, 2018, 7:21 p.m.
The pdp11 target has long had -mdec-asm which was documented to generate DEC compatible assembly language output but actually produces GNU assembler output.  This patch adds -mgnu-asm to do what -mdec-asm used to do, and -mdec-asm now does produces output acceptable to DEC Macro-11.

Committed.

	paul

ChangeLog:

2018-07-01  Paul Koning  <ni1d@arrl.net>

	* common/config/pdp11/pdp11-common.c (pdp11_handle_option): Handle
	-munit-asm, -mgnu-asm, -mdec-asm.
	* config/pdp11/pdp11-protos.h (pdp11_gen_int_label): New.
	(pdp11_output_labelref): New.
	(pdp11_output_def): New.
	(pdp11_output_addr_vec_elt): New.
	* config/pdp11/pdp11.c: Use tab between opcode and operands.  Use
	%# and %@ format codes.
	(pdp11_option_override): New.
	(TARGET_ASM_FILE_START_FILE_DIRECTIVE): Define.
	(pdp11_output_ident): New.
	(pdp11_asm_named_section): New.
	(pdp11_asm_init_sections): New.
	(pdp11_file_start): New.
	(pdp11_file_end): New.
	(output_ascii): Use .ascii/.asciz for -mdec-asm.
	(pdp11_asm_print_operand): Update %# and %$ for -mdec-asm.  Add
	%o, like %c but octal.
	(pdp11_option_override): New.
	* config/pdp11/pdp11.h (TEXT_SECTION_ASM_OP): Update for
	-mdec-asm.
	(DATA_SECTION_ASM_OP): Ditto.
	(READONLY_DATA_SECTION_ASM_OP): New.
	(IS_ASM_LOGICAL_LINE_SEPARATOR): New.
	(ASM_GENERATE_INTERNAL_LABEL): Use new function.
	(ASM_OUTPUT_LABELREF): Ditto.
	(ASM_OUTPUT_DEF): Ditto.
	(ASM_OUTPUT_EXTERNAL): New.
	(ASM_OUTPUT_SOURCE_FILENAME): New.
	(ASM_OUTPUT_ADDR_VEC_ELT): Use new function.
	(ASM_OUTPUT_SKIP): Update for -mdec-asm.
	* config/pdp11/pdp11.md: Use tab between opcode and operands.  Use
	%# and %@ format codes.
	* config/pdp11/pdp11.opt (mgnu-asm): New.
	(mdec-asm): Conflicts with -mgnu-asm and -munix-asm.
	(munix-asm): Conflicts with -mdec-asm and -mgnu-asm.
	* doc/invoke.txt (PDP-11 Options): Add -mgnu-asm.

Patch

Index: common/config/pdp11/pdp11-common.c
===================================================================
--- common/config/pdp11/pdp11-common.c	(revision 262287)
+++ common/config/pdp11/pdp11-common.c	(working copy)
@@ -59,7 +59,16 @@  pdp11_handle_option (struct gcc_options *opts,
       opts->x_target_flags &= ~MASK_40;
       opts->x_target_flags |= MASK_45;
       return true;
-      
+
+    case OPT_munix_asm:
+    case OPT_mgnu_asm:
+      targetm_common.have_named_sections = false;
+      return true;
+
+    case OPT_mdec_asm:
+      targetm_common.have_named_sections = true;
+      return true;
+
     default:
       return true;
     }
Index: config/pdp11/pdp11-protos.h
===================================================================
--- config/pdp11/pdp11-protos.h	(revision 262287)
+++ config/pdp11/pdp11-protos.h	(working copy)
@@ -51,3 +51,7 @@  extern void pdp11_asm_output_var (FILE *, const ch
 extern void pdp11_expand_prologue (void);
 extern void pdp11_expand_epilogue (void);
 extern poly_int64 pdp11_push_rounding (poly_int64);
+extern void pdp11_gen_int_label (char *, const char *, int);
+extern void pdp11_output_labelref (FILE *, const char *);
+extern void pdp11_output_def (FILE *, const char *, const char *);
+extern void pdp11_output_addr_vec_elt (FILE *, int);
Index: config/pdp11/pdp11.c
===================================================================
--- config/pdp11/pdp11.c	(revision 262287)
+++ config/pdp11/pdp11.c	(working copy)
@@ -212,7 +212,7 @@  static bool pdp11_scalar_mode_supported_p (scalar_
 #undef  TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS pdp11_preferred_output_reload_class
 
-#undef TARGET_LRA_P
+#undef  TARGET_LRA_P
 #define TARGET_LRA_P hook_bool_void_false
 
 #undef  TARGET_LEGITIMATE_ADDRESS_P
@@ -221,9 +221,30 @@  static bool pdp11_scalar_mode_supported_p (scalar_
 #undef  TARGET_CONDITIONAL_REGISTER_USAGE
 #define TARGET_CONDITIONAL_REGISTER_USAGE pdp11_conditional_register_usage
 
+#undef  TARGET_OPTION_OVERRIDE
+#define TARGET_OPTION_OVERRIDE pdp11_option_override
+
+#undef  TARGET_ASM_FILE_START_FILE_DIRECTIVE
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
+
+#undef  TARGET_ASM_OUTPUT_IDENT
+#define TARGET_ASM_OUTPUT_IDENT pdp11_output_ident
+
 #undef  TARGET_ASM_FUNCTION_SECTION
 #define TARGET_ASM_FUNCTION_SECTION pdp11_function_section
 
+#undef  TARGET_ASM_NAMED_SECTION
+#define	TARGET_ASM_NAMED_SECTION pdp11_asm_named_section
+
+#undef  TARGET_ASM_INIT_SECTIONS
+#define TARGET_ASM_INIT_SECTIONS pdp11_asm_init_sections
+
+#undef  TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START pdp11_file_start
+
+#undef  TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END pdp11_file_end
+
 #undef  TARGET_PRINT_OPERAND
 #define TARGET_PRINT_OPERAND pdp11_asm_print_operand
 
@@ -238,6 +259,7 @@  static bool pdp11_scalar_mode_supported_p (scalar_
 
 #undef  TARGET_HARD_REGNO_NREGS
 #define TARGET_HARD_REGNO_NREGS pdp11_hard_regno_nregs
+
 #undef  TARGET_HARD_REGNO_MODE_OK
 #define TARGET_HARD_REGNO_MODE_OK pdp11_hard_regno_mode_ok
 
@@ -477,9 +499,9 @@  static const char *
 singlemove_string (rtx *operands)
 {
   if (operands[1] != const0_rtx)
-    return "mov %1,%0";
+    return "mov\t%1,%0";
 
-  return "clr %0";
+  return "clr\t%0";
 }
 
 
@@ -664,12 +686,12 @@  output_move_multiple (rtx *operands)
   if (action[0] == dec_before)
     {
       operands[0] = XEXP (operands[0], 0);
-      output_asm_insn ("sub $4,%0", operands);
+      output_asm_insn ("sub\t%#4,%0", operands);
     }
   if (action[1] == dec_before)
     {
       operands[1] = XEXP (operands[1], 0);
-      output_asm_insn ("sub $4,%1", operands);
+      output_asm_insn ("sub\t%#4,%1", operands);
     }
 
   /* Do the words.  */
@@ -680,46 +702,86 @@  output_move_multiple (rtx *operands)
   if (action[0] == inc_after)
     {
       operands[0] = XEXP (operands[0], 0);
-      output_asm_insn ("add $4,%0", operands);
+      output_asm_insn ("add\t%#4,%0", operands);
     }
   if (action[1] == inc_after)
     {
       operands[1] = XEXP (operands[1], 0);
-      output_asm_insn ("add $4,%1", operands);
+      output_asm_insn ("add\t%#4,%1", operands);
     }
 
   return "";
 }
 
+/* Build an internal label.  */
+void
+pdp11_gen_int_label (char *label, const char *prefix, int num)
+{
+  if (TARGET_DEC_ASM)
+    /* +1 because GCC numbers labels starting at zero.  */
+    sprintf (label, "*%lu$", num + 1);
+  else
+    sprintf (label, "*%s_%lu", prefix, num);
+}
+  
 /* Output an ascii string.  */
 void
 output_ascii (FILE *file, const char *p, int size)
 {
-  int i;
-
-  /* This used to output .byte "string", which doesn't work with the UNIX
-     assembler and I think not with DEC ones either.  */
-  fprintf (file, "\t.byte ");
-
-  for (i = 0; i < size; i++)
+  int i, c;
+  const char *pseudo = "\t.ascii\t";
+  bool delim = false;
+  
+  if (TARGET_DEC_ASM)
     {
-      register int c = p[i];
-      if (c < 0)
-	c += 256;
-      fprintf (file, "%#o", c);
-      if (i < size - 1)
-	putc (',', file);
+      if (p[size - 1] == '\0')
+	{
+	  pseudo = "\t.asciz\t";
+	  size--;
+	}
+      fputs (pseudo, file);
+      for (i = 0; i < size; i++)
+	{
+	  c = *p++ & 0xff;
+	  if (c < 32 || c == '"' || c > 126)
+	    {
+	      if (delim)
+		putc ('"', file);
+	      fprintf (file, "<%o%>", c);
+	      delim = false;
+	    }
+	  else
+	    {
+	      if (!delim)
+		putc ('"', file);
+	      delim = true;
+	      putc (c, file);
+	    }
+	}
+      if (delim)
+	putc ('"', file);
+      putc ('\n', file);
     }
-  putc ('\n', file);
+  else
+    {
+      fprintf (file, "\t.byte ");
+
+      for (i = 0; i < size; i++)
+	{
+	  fprintf (file, "%#o", *p++ & 0xff);
+	  if (i < size - 1)
+	    putc (',', file);
+	}
+      putc ('\n', file);
+    }
 }
 
-
 void
 pdp11_asm_output_var (FILE *file, const char *name, int size,
 		      int align, bool global)
 {
   if (align > 8)
-    fprintf (file, "\n\t.even\n");
+    fprintf (file, "\t.even\n");
   if (global)
     {
       fprintf (file, ".globl ");
@@ -727,9 +789,16 @@  pdp11_asm_output_var (FILE *file, const char *name
     }
   fprintf (file, "\n");
   assemble_name (file, name);
-  fprintf (file, ": .=.+ %#ho\n", (unsigned short)size);
+  fputs (":", file);
+  ASM_OUTPUT_SKIP (file, size);
 }
 
+/* Special format operators handled here:
+   # -- output the correct immediate operand marker for the assembler
+        dialect.
+   @ -- output the correct indirect marker for the assembler dialect.
+   C -- emit a constant value as a number (not an immediate operand)
+        in assembler syntax.  */
 static void
 pdp11_asm_print_operand (FILE *file, rtx x, int code)
 {
@@ -736,7 +805,12 @@  pdp11_asm_print_operand (FILE *file, rtx x, int co
   long sval[2];
  
   if (code == '#')
-    fprintf (file, "#");
+    {
+      if (TARGET_DEC_ASM)
+	putc ('#', file);
+      else
+	putc ('$', file);
+    }
   else if (code == '@')
     {
       if (TARGET_UNIX_ASM)
@@ -751,11 +825,20 @@  pdp11_asm_print_operand (FILE *file, rtx x, int co
   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != SImode)
     {
       REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), sval);
-      fprintf (file, "$%#lo", sval[0] >> 16);
+      if (TARGET_DEC_ASM)
+	fprintf (file, "#%lo", (sval[0] >> 16) & 0xffff);
+      else
+	fprintf (file, "$%#lo", (sval[0] >> 16) & 0xffff);
     }
   else
     {
-      putc ('$', file);
+      if (code != 'o')
+	{
+	  if (TARGET_DEC_ASM)
+	    putc ('#', file);
+	  else
+	    putc ('$', file);
+	}
       output_addr_const_pdp11 (file, x);
     }
 }
@@ -851,7 +934,9 @@  print_operand_address (FILE *file, register rtx ad
       if (!again && GET_CODE (addr) == CONST_INT)
 	{
 	  /* Absolute (integer number) address.  */
-	  if (!TARGET_UNIX_ASM)
+	  if (TARGET_DEC_ASM)
+	    fprintf (file, "@#");
+	  else if (!TARGET_UNIX_ASM)
 	    fprintf (file, "@$");
 	}
       output_addr_const_pdp11 (file, addr);
@@ -1088,13 +1173,13 @@  output_jump (rtx *operands, int ccnz, int length)
   switch (length)
     {
     case 2:
-      sprintf (buf, "%s %%l1", pos);
+      sprintf (buf, "%s\t%%l1", pos);
       return buf;
     case 6:
       tmpop[0] = gen_label_rtx ();
-      sprintf (buf, "%s %%l0", neg);
+      sprintf (buf, "%s\t%%l0", neg);
       output_asm_insn (buf, tmpop);
-      output_asm_insn ("jmp %l1", operands);
+      output_asm_insn ("jmp\t%l1", operands);
       output_asm_label (tmpop[0]);
       fputs (":\n", asm_out_file);
       return "";
@@ -1290,7 +1375,7 @@  output_block_move(rtx *operands)
 	    register int i;
 	    
 	    for (i = 1; i <= INTVAL (operands[2]); i++)
-		output_asm_insn("movb (%1)+, (%0)+", operands);
+		output_asm_insn("movb\t(%1)+,(%0)+", operands);
 
 	    return "";
 	}
@@ -1301,9 +1386,9 @@  output_block_move(rtx *operands)
 	    register int i;
 	    
 	    for (i = 1; i <= INTVAL (operands[2]) / 2; i++)
-		output_asm_insn ("mov (%1)+, (%0)+", operands);
+		output_asm_insn ("mov\t(%1)+,(%0)+", operands);
 	    if (INTVAL (operands[2]) & 1)
-	      output_asm_insn ("movb (%1), (%0)", operands);
+	      output_asm_insn ("movb\t(%1),(%0)", operands);
 	    
 	    return "";
 	}
@@ -1335,7 +1420,7 @@  output_block_move(rtx *operands)
       
       /* Loop count is byte count scaled by unroll.  */
       operands[2] = GEN_INT (INTVAL (operands[2]) >> unroll);
-      output_asm_insn ("mov %2, %4", operands);
+      output_asm_insn ("mov\t%2,%4", operands);
     }
     else
     {
@@ -1348,12 +1433,12 @@  output_block_move(rtx *operands)
 	if (TARGET_40_PLUS && INTVAL (operands[3]) > 1)
 	  {
 	    unroll = 1;
-	    output_asm_insn ("asr %4", operands);
+	    output_asm_insn ("asr\t%4", operands);
 	  }
 	else
 	  {
 	    unroll = 0;
-	    output_asm_insn ("tst %4", operands);
+	    output_asm_insn ("tst\t%4", operands);
 	  }
 	sprintf (buf, "beq movestrhi%d", count + 1);
 	output_asm_insn (buf, NULL);
@@ -1367,23 +1452,23 @@  output_block_move(rtx *operands)
     switch (unroll)
     {
       case 0:
-	output_asm_insn ("movb (%1)+, (%0)+", operands);
+	output_asm_insn ("movb\t(%1)+,(%0)+", operands);
 	break;
 	
       case 1:
-	output_asm_insn ("mov (%1)+, (%0)+", operands);
+	output_asm_insn ("mov\t(%1)+,(%0)+", operands);
 	break;
 	
       case 2:
-	output_asm_insn ("mov (%1)+, (%0)+", operands);
-	output_asm_insn ("mov (%1)+, (%0)+", operands);
+	output_asm_insn ("mov\t(%1)+,(%0)+", operands);
+	output_asm_insn ("mov\t(%1)+,(%0)+", operands);
 	break;
 	
       default:
-	output_asm_insn ("mov (%1)+, (%0)+", operands);
-	output_asm_insn ("mov (%1)+, (%0)+", operands);
-	output_asm_insn ("mov (%1)+, (%0)+", operands);
-	output_asm_insn ("mov (%1)+, (%0)+", operands);
+	output_asm_insn ("mov\t(%1)+,(%0)+", operands);
+	output_asm_insn ("mov\t(%1)+,(%0)+", operands);
+	output_asm_insn ("mov\t(%1)+,(%0)+", operands);
+	output_asm_insn ("mov\t(%1)+,(%0)+", operands);
 	break;
     }
 
@@ -1390,12 +1475,12 @@  output_block_move(rtx *operands)
     /* Output the decrement and test.  */
     if (TARGET_40_PLUS)
       {
-	sprintf (buf, "sob %%4, movestrhi%d", count);
+	sprintf (buf, "sob\t%%4, movestrhi%d", count);
 	output_asm_insn (buf, operands);
       }
     else
       {
-	output_asm_insn ("dec %4", operands);
+	output_asm_insn ("dec\t%4", operands);
 	sprintf (buf, "bgt movestrhi%d", count);
 	output_asm_insn (buf, NULL);
       }
@@ -1403,7 +1488,7 @@  output_block_move(rtx *operands)
 
     /* If constant odd byte count, move the last byte.  */
     if (lastbyte)
-      output_asm_insn ("movb (%1), (%0)", operands);
+      output_asm_insn ("movb\t(%1),(%0)", operands);
     else if (!CONSTANT_P (operands[2]))
       {
 	/* Output the destination label for the zero byte count check.  */
@@ -1416,7 +1501,7 @@  output_block_move(rtx *operands)
 	  {
 	    sprintf (buf, "bcc movestrhi%d", count);
 	    output_asm_insn (buf, NULL);
-	    output_asm_insn ("movb (%1), (%0)", operands);
+	    output_asm_insn ("movb\t(%1),(%0)", operands);
 	    sprintf (buf, "\nmovestrhi%d:", count);
 	    output_asm_insn (buf, NULL);
 	    count++;
@@ -1764,12 +1849,13 @@  output_addr_const_pdp11 (FILE *file, rtx x)
 	  i = -i;
 	  fprintf (file, "-");
 	}
-      fprintf (file, "%#o", i & 0xffff);
+      if (TARGET_DEC_ASM)
+	fprintf (file, "%o", i & 0xffff);
+      else
+	fprintf (file, "%#o", i & 0xffff);
       break;
 
     case CONST:
-      /* This used to output parentheses around the expression,
-	 but that does not work on the 386 (either ATT or BSD assembler).  */
       output_addr_const_pdp11 (file, XEXP (x, 0));
       break;
 
@@ -1778,7 +1864,10 @@  output_addr_const_pdp11 (FILE *file, rtx x)
 	{
 	  /* We can use %o if the number is one word and positive.  */
 	  gcc_assert (!CONST_DOUBLE_HIGH (x));
-	  fprintf (file, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x));
+	  if (TARGET_DEC_ASM)
+	    fprintf (file, "%ho", CONST_DOUBLE_LOW (x) & 0xffff);
+	  else
+	    fprintf (file, "%#ho", CONST_DOUBLE_LOW (x) & 0xffff);
 	}
       else
 	/* We can't handle floating point constants;
@@ -1888,8 +1977,8 @@  bool
 pdp11_expand_shift (rtx *operands, rtx (*shift_sc) (rtx, rtx, rtx),
 		    rtx (*shift_base) (rtx, rtx, rtx))
 {
-  rtx dest, n, r, test;
-  rtx_code_label *lb, *lb2;
+  rtx r, test;
+  rtx_code_label *lb;
   
   if (CONSTANT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
     emit_insn ((*shift_sc) (operands[0], operands[1], operands[2]));
@@ -1956,14 +2045,14 @@  pdp11_assemble_shift (rtx *operands, machine_mode
       switch (m)
 	{
 	case E_QImode:
-	  output_asm_insn ("rorb %0", operands);
+	  output_asm_insn ("rorb\t%0", operands);
 	  break;
 	case E_HImode:
-	  output_asm_insn ("ror %0", operands);
+	  output_asm_insn ("ror\t%0", operands);
 	  break;
 	case E_SImode:
-	  output_asm_insn ("ror %0", exops[0]);
-	  output_asm_insn ("ror %0", exops[1]);
+	  output_asm_insn ("ror\t%0", exops[0]);
+	  output_asm_insn ("ror\t%0", exops[1]);
 	  break;
 	default:
 	  gcc_unreachable ();
@@ -1979,14 +2068,14 @@  pdp11_assemble_shift (rtx *operands, machine_mode
 	  switch (m)
 	    {
 	    case E_QImode:
-	      output_asm_insn ("asrb %0", operands);
+	      output_asm_insn ("asrb\t%0", operands);
 	      break;
 	    case E_HImode:
-	      output_asm_insn ("asr %0", operands);
+	      output_asm_insn ("asr\t%0", operands);
 	      break;
 	    case E_SImode:
-	      output_asm_insn ("asr %0", exops[0]);
-	      output_asm_insn ("ror %0", exops[1]);
+	      output_asm_insn ("asr\t%0", exops[0]);
+	      output_asm_insn ("ror\t%0", exops[1]);
 	      break;
 	    default:
 	      gcc_unreachable ();
@@ -1996,14 +2085,14 @@  pdp11_assemble_shift (rtx *operands, machine_mode
 	  switch (m)
 	    {
 	    case E_QImode:
-	      output_asm_insn ("aslb %0", operands);
+	      output_asm_insn ("aslb\t%0", operands);
 	      break;
 	    case E_HImode:
-	      output_asm_insn ("asl %0", operands);
+	      output_asm_insn ("asl\t%0", operands);
 	      break;
 	    case E_SImode:
-	      output_asm_insn ("asl %0", exops[1]);
-	      output_asm_insn ("rol %0", exops[0]);
+	      output_asm_insn ("asl\t%0", exops[1]);
+	      output_asm_insn ("rol\t%0", exops[0]);
 	      break;
 	    default:
 	      gcc_unreachable ();
@@ -2014,8 +2103,8 @@  pdp11_assemble_shift (rtx *operands, machine_mode
   if (!small)
     {
       /* Loop case, emit the count-down and branch if not done.  */
-      output_asm_insn ("dec %2", operands);
-      output_asm_insn ("bne %l0", lb);
+      output_asm_insn ("dec\t%2", operands);
+      output_asm_insn ("bne\t%l0", lb);
     }
   return "";
 }
@@ -2159,6 +2248,114 @@  pdp11_function_section (tree decl ATTRIBUTE_UNUSED
   return NULL;
 }
 
+/* Support #ident for DEC assembler, but don't process the
+   auto-generated ident string that names the compiler (since its
+   syntax is not correct for DEC .ident).  */
+static void pdp11_output_ident (const char *ident)
+{
+  if (TARGET_DEC_ASM)
+    {
+      if (strncmp (ident, "GCC:", 4) != 0)
+	fprintf (asm_out_file, "\t.ident\t\"%s\"\n", ident);
+    }
+  
+}
+
+/* This emits a (user) label, which gets a "_" prefix except for DEC
+   assembler output.  */
+void
+pdp11_output_labelref (FILE *file, const char *name)
+{
+  if (!TARGET_DEC_ASM)
+    fputs (USER_LABEL_PREFIX, file);
+  fputs (name, file);
+}
+
+/* This equates name with value.  */
+void
+pdp11_output_def (FILE *file, const char *label1, const char *label2)
+{
+  if (TARGET_DEC_ASM)
+    {
+      assemble_name (file, label1);
+      putc ('=', file);
+      assemble_name (file, label2);
+    }
+  else
+    {
+      fputs (".set", file);
+      assemble_name (file, label1);
+      putc (',', file);
+      assemble_name (file, label2);
+    } 
+  putc ('\n', file);
+}
+
+void
+pdp11_output_addr_vec_elt (FILE *file, int value)
+{
+  char buf[256];
+
+  pdp11_gen_int_label (buf, "L", value);
+  if (!TARGET_UNIX_ASM)
+    fprintf (file, "\t.word");
+  fprintf (file, "\t%s\n", buf + 1);
+}
+
+/* This overrides some target hooks that are initializer elements so
+   they can't be variables in the #define.  */
+static void
+pdp11_option_override (void)
+{
+  if (TARGET_DEC_ASM)
+    {
+      targetm.asm_out.open_paren  = "<";
+      targetm.asm_out.close_paren = ">";
+    }
+}
+
+static void
+pdp11_asm_named_section (const char *name, unsigned int flags,
+			 tree decl ATTRIBUTE_UNUSED)
+{
+  const char *rwro = (flags & SECTION_WRITE) ? "rw" : "ro";
+  const char *insdat = (flags & SECTION_CODE) ? "i" : "d";
+  
+  gcc_assert (TARGET_DEC_ASM);
+  fprintf (asm_out_file, "\t.psect\t%s,con,%s,%s\n", name, insdat, rwro);
+}
+
+static void
+pdp11_asm_init_sections (void)
+{
+  if (TARGET_DEC_ASM)
+    {
+      bss_section = data_section;
+    }
+  else if (TARGET_GNU_ASM)
+    {
+      bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
+					 output_section_asm_op,
+					 ".bss");
+    }
+}
+  
+static void
+pdp11_file_start (void)
+{
+  default_file_start ();
+  
+  if (TARGET_DEC_ASM)
+    fprintf (asm_out_file, "\t.enabl\tlsb,reg\n\n");
+}
+
+static void
+pdp11_file_end (void)
+{
+  if (TARGET_DEC_ASM)
+    fprintf (asm_out_file, "\t.end\n");
+}
+
 /* Implement TARGET_LEGITIMATE_CONSTANT_P.  */
 
 static bool
Index: config/pdp11/pdp11.h
===================================================================
--- config/pdp11/pdp11.h	(revision 262287)
+++ config/pdp11/pdp11.h	(working copy)
@@ -45,6 +45,10 @@  along with GCC; see the file COPYING3.  If not see
 
 #define TARGET_UNIX_ASM_DEFAULT	0
 
+/* "Dialect" just distinguishes between standard DEC mnemonics, which
+   are also used by the GNU assembler, vs. Unix mnemonics and float
+   register names.  So it is tied to the -munit-asm option, and treats
+   -mgnu-asm and -mdec-asm as equivalent (both are dialect zero).  */
 #define ASSEMBLER_DIALECT	(TARGET_UNIX_ASM ? 1 : 0)
 
 
@@ -489,12 +493,20 @@  extern int may_call_alloca;
 
 /* Output before read-only data.  */
 
-#define TEXT_SECTION_ASM_OP "\t.text\n"
+#define TEXT_SECTION_ASM_OP \
+  ((TARGET_DEC_ASM) ? "\t.psect\tcode,i,ro,con" : "\t.text")
 
 /* Output before writable data.  */
 
-#define DATA_SECTION_ASM_OP "\t.data\n"
+#define DATA_SECTION_ASM_OP \
+  ((TARGET_DEC_ASM) ? "\t.psect\tdata,d,rw,con" : "\t.data")
 
+/* Output before read-only data.  Same as read-write data for non-DEC
+   assemblers because they don't know about .rodata.  */
+
+#define READONLY_DATA_SECTION_ASM_OP \
+  ((TARGET_DEC_ASM) ? "\t.psect\trodata,d,ro,con" : "\t.data")
+
 /* How to refer to registers in assembler output.
    This sequence is indexed by compiler's hard-register-number (see above).  */
 
@@ -504,38 +516,59 @@  extern int may_call_alloca;
  "cc", "fcc" }
 
 /* Globalizing directive for a label.  */
-#define GLOBAL_ASM_OP "\t.globl "
+#define GLOBAL_ASM_OP "\t.globl\t"
 
-/* The prefix to add to user-visible assembler symbols.  */
+/* The prefix to add to user-visible assembler symbols.  For the DEC
+   assembler case, this is not used.  */
 
 #define USER_LABEL_PREFIX "_"
 
+/* Line separators.  */
+
+#define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) \
+  ((C) == '\n' || (!TARGET_DEC_ASM && (C) == ';'))
+
 /* This is how to store into the string LABEL
    the symbol_ref name of an internal numbered label where
    PREFIX is the class of label and NUM is the number within the class.
    This is suitable for output with `assemble_name'.  */
 
-#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)	\
-  sprintf (LABEL, "*%s_%lu", PREFIX, (unsigned long)(NUM))
+#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
+  pdp11_gen_int_label ((LABEL), (PREFIX), (NUM))
 
+/* Emit a string.  */
+
 #define ASM_OUTPUT_ASCII(FILE, P, SIZE)  \
   output_ascii (FILE, P, SIZE)
 
+/* Print a label reference, with _ prefix if not DEC.  */
+
+#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
+  pdp11_output_labelref ((STREAM), (NAME))
+
+/* Equate a symbol to an expression.  */
+
+#define ASM_OUTPUT_DEF(STREAM, NAME, VALUE) \
+  pdp11_output_def (STREAM, NAME, VALUE)
+
+/* Mark a reference to an external symbol.  Needed for DEC assembler.  */
+
+#define ASM_OUTPUT_EXTERNAL(STREAM, DECL, NAME) \
+  if (TARGET_DEC_ASM) \
+    fprintf ((STREAM), "\t.globl\t%s\n", (NAME))
+
+#define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME) \
+  if (TARGET_DEC_ASM) \
+    fprintf ((STREAM), ".title\t%s\n", (NAME))
+
 /* This is how to output an element of a case-vector that is absolute.  */
 
 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
-  fprintf (FILE, "\t%sL_%d\n", TARGET_UNIX_ASM ? "" : ".word ", VALUE)
+  pdp11_output_addr_vec_elt (FILE, VALUE)
 
-/* This is how to output an element of a case-vector that is relative.
-   Don't define this if it is not supported.  */
-
-/* #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) */
-
 /* This is how to output an assembler line
    that says to advance the location counter
    to a multiple of 2**LOG bytes. 
-
-   who needs this????
 */
 
 #define ASM_OUTPUT_ALIGN(FILE,LOG)	\
@@ -551,13 +584,16 @@  extern int may_call_alloca;
     }
 
 #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
-  fprintf (FILE, "\t.=.+ %#ho\n", (unsigned short)(SIZE))
+  if (TARGET_DEC_ASM) \
+    fprintf (FILE, "\t.blkb\t%ho\n", (SIZE) & 0xffff);	\
+  else							\
+    fprintf (FILE, "\t.=.+ %#ho\n", (SIZE) & 0xffff);
 
 /* This says how to output an assembler line
    to define a global common symbol.  */
 
 #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)  \
-    pdp11_asm_output_var (FILE, NAME, SIZE, ALIGN, true)
+  pdp11_asm_output_var (FILE, NAME, SIZE, ALIGN, true)
 
 
 /* This says how to output an assembler line
@@ -564,22 +600,18 @@  extern int may_call_alloca;
    to define a local common symbol.  */
 
 #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
-    pdp11_asm_output_var (FILE, NAME, SIZE, ALIGN, false)
+  pdp11_asm_output_var (FILE, NAME, SIZE, ALIGN, false)
 
 /* Print a memory address as an operand to reference that memory location.  */
 
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
- print_operand_address (FILE, ADDR)
+  print_operand_address (FILE, ADDR)
 
-#define ASM_OUTPUT_REG_PUSH(FILE,REGNO)			\
-(							\
-  fprintf (FILE, "\tmov %s, -(sp)\n", reg_names[REGNO])	\
-)
+#define ASM_OUTPUT_REG_PUSH(FILE,REGNO)	\
+  fprintf (FILE, "\tmov\t%s,-(sp)\n", reg_names[REGNO])
 
-#define ASM_OUTPUT_REG_POP(FILE,REGNO)                 		\
-(                                                       	\
-  fprintf (FILE, "\tmov (sp)+, %s\n", reg_names[REGNO])     	\
-)
+#define ASM_OUTPUT_REG_POP(FILE,REGNO)	\
+  fprintf (FILE, "\tmov\t(sp)+,%s\n", reg_names[REGNO])
 
 #define TRAMPOLINE_SIZE 8
 #define TRAMPOLINE_ALIGNMENT 16
@@ -588,6 +620,7 @@  extern int may_call_alloca;
 
 #define COMPARE_FLAG_MODE HImode
 
+/* May be overridden by command option processing.  */
 #define TARGET_HAVE_NAMED_SECTIONS false
 
 /* pdp11-unknown-aout target has no support of C99 runtime */
Index: config/pdp11/pdp11.md
===================================================================
--- config/pdp11/pdp11.md	(revision 262287)
+++ config/pdp11/pdp11.md	(working copy)
@@ -212,9 +212,9 @@ 
   "*
 {
   if (which_alternative == 0 || which_alternative == 2)
-    return \"{tstd|tstf} %0\";
+    return \"{tstd|tstf}\t%0\";
   else
-    return \"{cmpd|cmpf} %0, %1\";
+    return \"{cmpd|cmpf}\t%0,%1\";
 }"
   [(set_attr "length" "2,2,4,4")
    (set_attr "type" "fp")]) 
@@ -232,12 +232,12 @@ 
 		    (match_operand:PDPint 1 "general_operand" "N,rR,Qi,N,rR,Qi")))]
   ""
   "@
-   tst<PDPint:isfx> %0
-   cmp<PDPint:isfx> %0,%1
-   cmp<PDPint:isfx> %0,%1
-   tst<PDPint:isfx> %0
-   cmp<PDPint:isfx> %0,%1
-   cmp<PDPint:isfx> %0,%1"
+   tst<PDPint:isfx>\t%0
+   cmp<PDPint:isfx>\t%0,%1
+   cmp<PDPint:isfx>\t%0,%1
+   tst<PDPint:isfx>\t%0
+   cmp<PDPint:isfx>\t%0,%1
+   cmp<PDPint:isfx>\t%0,%1"
   [(set_attr "length" "2,2,4,4,4,6")])
 
 ;; sob instruction - FIXME: this doesn't do anything, need to use doloop_end.
@@ -257,13 +257,13 @@ 
   "*
 {
  if (get_attr_length (insn) == 2)
-    return \"sob %0, %l1\";
+    return \"sob\t%0,%l1\";
 
  /* emulate sob */
  operands[2] = gen_label_rtx ();
- output_asm_insn (\"dec %0\", operands);
- output_asm_insn (\"beq %l2\", operands);
- output_asm_insn (\"jmp %l1\", operands);
+ output_asm_insn (\"dec\t%0\", operands);
+ output_asm_insn (\"beq\t%l2\", operands);
+ output_asm_insn (\"jmp\t%l1\", operands);
  
  output_asm_label (operands[2]);
  fputs (\":\\n\", asm_out_file);
@@ -432,9 +432,9 @@ 
   "*
 {
   if (operands[1] == const0_rtx)
-    return \"clr<PDPint:isfx> %0\";
+    return \"clr<PDPint:isfx>\t%0\";
 
-  return \"mov<PDPint:isfx> %1, %0\";
+  return \"mov<PDPint:isfx>\t%1,%0\";
 }"
   [(set_attr "length" "2,4,4,6")])
 
@@ -462,7 +462,7 @@ 
   "TARGET_FPU"
   "*
   gcc_assert (which_alternative < 2);
-  return \"std %1, %0\";
+  return \"std\t%1,%0\";
   "
   "&& reload_completed"
   [(parallel [(set (match_dup 0)
@@ -482,9 +482,9 @@ 
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
   "@
-  ldd %1, %0
-  ldd %1, %0
-  clrd %0"
+  ldd\t%1,%0
+  ldd\t%1,%0
+  clrd\t%0"
   [(set_attr "length" "2,4,2")])
 
 ;; SFmode is easier because that uses convert load/store, which
@@ -513,11 +513,11 @@ 
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
   "@
-  {ldcfd|movof} %1, %0
-  {stcdf|movfo} %1, %0
-  {ldcfd|movof} %1, %0
-  {stcdf|movfo} %1, %0
-  clrf %0"
+  {ldcfd|movof}\t%1,%0
+  {stcdf|movfo}\t%1,%0
+  {ldcfd|movof}\t%1,%0
+  {stcdf|movfo}\t%1,%0
+  clrf\t%0"
   [(set_attr "length" "2,2,4,4,2")])
 
 ;; maybe fiddle a bit with move_ratio, then 
@@ -594,7 +594,7 @@ 
 	(float_truncate:SF (match_operand:DF 1 "register_operand" "a,a")))
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
-   "{stcdf|movfo} %1, %0"
+   "{stcdf|movfo}\t%1,%0"
   [(set_attr "length" "2,4")])
 
 
@@ -615,7 +615,7 @@ 
 		   (zero_extend:HI (match_operand:QI 1 "general_operand" "0,0")))
 	      (clobber (reg:CC CC_REGNUM))])]
   "reload_completed"
-  "bic $0177400, %0"
+  "bic\t%#0177400,%0"
   [(set_attr "length" "4,6")])
 			 
 (define_expand "zero_extendhisi2"
@@ -662,7 +662,7 @@ 
 	(float_extend:DF (match_operand:SF 1 "float_operand" "R,Q")))
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
-  "{ldcfd|movof} %1, %0"
+  "{ldcfd|movof}\t%1,%0"
   [(set_attr "length" "2,4")])
 
 ;; movb sign extends if destination is a register
@@ -682,7 +682,7 @@ 
 	(sign_extend:HI (match_operand:QI 1 "general_operand" "rR,Q")))
    (clobber (reg:CC CC_REGNUM))]
   "reload_completed"
-  "movb %1, %0"
+  "movb\t%1,%0"
   [(set_attr "length" "2,4")])
 
 (define_insn_and_split "extendhisi2"
@@ -713,8 +713,8 @@ 
       latehalf[0] = operands[0];
       operands[0] = adjust_address(operands[0], HImode, 2);
   
-      output_asm_insn(\"mov %1, %0\", operands);
-      output_asm_insn(\"sxt %0\", latehalf);
+      output_asm_insn(\"mov\t%1,%0\", operands);
+      output_asm_insn(\"sxt\t%0\", latehalf);
 
       return \"\";
 
@@ -721,8 +721,8 @@ 
     case 1:
 
       /* - auto-decrement - right direction ;-) */
-      output_asm_insn(\"mov %1, %0\", operands);
-      output_asm_insn(\"sxt %0\", operands);
+      output_asm_insn(\"mov\t%1,%0\", operands);
+      output_asm_insn(\"sxt\t%0\", operands);
 
       return \"\";
 
@@ -732,8 +732,8 @@ 
       latehalf[0] = operands[0];
       operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
 
-      output_asm_insn(\"mov %1, %0\", operands);
-      output_asm_insn(\"sxt %0\", latehalf);
+      output_asm_insn(\"mov\t%1,%0\", operands);
+      output_asm_insn(\"sxt\t%0\", latehalf);
 
       return \"\";
 
@@ -773,16 +773,16 @@ 
  
        latehalf[0] = NULL; 
        latehalf[1] = gen_rtx_REG (HImode, REGNO (operands[1]) + 1);
-       output_asm_insn(\"mov %1, -(sp)\", latehalf);
-       output_asm_insn(\"mov %1, -(sp)\", operands);
+       output_asm_insn(\"mov\t%1,-(sp)\", latehalf);
+       output_asm_insn(\"mov\t%1,-(sp)\", operands);
        
        output_asm_insn(\"setl\", operands);
-       output_asm_insn(\"{ldcld|movif} (sp)+, %0\", operands);
+       output_asm_insn(\"{ldcld|movif}\t(sp)+,%0\", operands);
        output_asm_insn(\"seti\", operands);
        return \"\";
      }
      else 
-       return \"setl\;{ldcld|movif} %1, %0\;seti\";
+       return \"setl\;{ldcld|movif}\t%1,%0\;seti\";
   "
   [(set_attr "length" "10,6,8")])
 
@@ -801,7 +801,7 @@ 
 	(float:DF (match_operand:HI 1 "general_operand" "rR,Qi")))
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
-  "{ldcid|movif} %1, %0"
+  "{ldcid|movif}\t%1,%0"
   [(set_attr "length" "2,4")])
 	
 ;; cut float to int
@@ -831,15 +831,15 @@ 
   "* if (which_alternative ==0)
      {
        output_asm_insn(\"setl\", operands);
-       output_asm_insn(\"{stcdl|movfi} %1, -(sp)\", operands);
+       output_asm_insn(\"{stcdl|movfi}\t%1,-(sp)\", operands);
        output_asm_insn(\"seti\", operands);
-       output_asm_insn(\"mov (sp)+, %0\", operands);
+       output_asm_insn(\"mov\t(sp)+,%0\", operands);
        operands[0] = gen_rtx_REG (HImode, REGNO (operands[0]) + 1);
-       output_asm_insn(\"mov (sp)+, %0\", operands);
+       output_asm_insn(\"mov\t(sp)+,%0\", operands);
        return \"\";
      }
      else 
-       return \"setl\;{stcdl|movfi} %1, %0\;seti\";
+       return \"setl\;{stcdl|movfi}\t%1,%0\;seti\";
   "
   [(set_attr "length" "10,6,8")])
 
@@ -861,7 +861,7 @@ 
    (clobber (reg:CC CC_REGNUM))
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
-  "{stcdi|movfi} %1, %0"
+  "{stcdi|movfi}\t%1,%0"
   [(set_attr "length" "2,4")])
 
 
@@ -887,7 +887,7 @@ 
 	      (match_operand:DF 2 "general_operand" "fR,QF")))
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
-  "{addd|addf} %2, %0"
+  "{addd|addf}\t%2,%0"
   [(set_attr "length" "2,4")])
 
 (define_insn_and_split "adddi3"
@@ -917,24 +917,24 @@ 
   pdp11_expand_operands (inops, exops, 2, NULL, either);
   
   if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
-    output_asm_insn (\"add %1, %0\", exops[0]);
+    output_asm_insn (\"add\t%1,%0\", exops[0]);
   if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
   {
-    output_asm_insn (\"add %1, %0\", exops[1]);
-    output_asm_insn (\"adc %0\", exops[0]);
+    output_asm_insn (\"add\t%1,%0\", exops[1]);
+    output_asm_insn (\"adc\t%0\", exops[0]);
   }
   if (!CONSTANT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
   {
-    output_asm_insn (\"add %1, %0\", exops[2]);
-    output_asm_insn (\"adc %0\", exops[1]);
-    output_asm_insn (\"adc %0\", exops[0]);
+    output_asm_insn (\"add\t%1,%0\", exops[2]);
+    output_asm_insn (\"adc\t%0\", exops[1]);
+    output_asm_insn (\"adc\t%0\", exops[0]);
   }
   if (!CONSTANT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
   {
-    output_asm_insn (\"add %1, %0\", exops[3]);
-    output_asm_insn (\"adc %0\", exops[2]);
-    output_asm_insn (\"adc %0\", exops[1]);
-    output_asm_insn (\"adc %0\", exops[0]);
+    output_asm_insn (\"add\t%1,%0\", exops[3]);
+    output_asm_insn (\"adc\t%0\", exops[2]);
+    output_asm_insn (\"adc\t%0\", exops[1]);
+    output_asm_insn (\"adc\t%0\", exops[0]);
   }
 
   return \"\";
@@ -977,11 +977,11 @@ 
   pdp11_expand_operands (inops, exops, 2, NULL, either);
   
   if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
-    output_asm_insn (\"add %1, %0\", exops[0]);
+    output_asm_insn (\"add\t%1,%0\", exops[0]);
   if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
   {
-    output_asm_insn (\"add %1, %0\", exops[1]);
-    output_asm_insn (\"adc %0\", exops[0]);
+    output_asm_insn (\"add\t%1,%0\", exops[1]);
+    output_asm_insn (\"adc\t%0\", exops[0]);
   }
 
   return \"\";
@@ -1012,12 +1012,12 @@ 
   if (GET_CODE (operands[2]) == CONST_INT)
     {
       if (INTVAL(operands[2]) == 1)
-	return \"inc %0\";
+	return \"inc\t%0\";
       else if (INTVAL(operands[2]) == -1)
-        return \"dec %0\";
+        return \"dec\t%0\";
     }
 
-  return \"add %2, %0\";
+  return \"add\t%2,%0\";
 }"
   [(set_attr "length" "2,4,4,6")])
 
@@ -1045,7 +1045,7 @@ 
 	          (match_operand:DF 2 "general_operand" "fR,QF")))
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
-  "{subd|subf} %2, %0"
+  "{subd|subf}\t%2,%0"
   [(set_attr "length" "2,4")])
 
 (define_insn_and_split "subdi3"
@@ -1075,24 +1075,24 @@ 
   pdp11_expand_operands (inops, exops, 2, NULL, either);
   
   if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
-    output_asm_insn (\"sub %1, %0\", exops[0]);
+    output_asm_insn (\"sub\t%1,%0\", exops[0]);
   if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
   {
-    output_asm_insn (\"sub %1, %0\", exops[1]);
-    output_asm_insn (\"sbc %0\", exops[0]);
+    output_asm_insn (\"sub\t%1,%0\", exops[1]);
+    output_asm_insn (\"sbc\t%0\", exops[0]);
   }
   if (!CONSTANT_P (exops[2][1]) || INTVAL (exops[2][1]) != 0)
   {
-    output_asm_insn (\"sub %1, %0\", exops[2]);
-    output_asm_insn (\"sbc %0\", exops[1]);
-    output_asm_insn (\"sbc %0\", exops[0]);
+    output_asm_insn (\"sub\t%1,%0\", exops[2]);
+    output_asm_insn (\"sbc\t%0\", exops[1]);
+    output_asm_insn (\"sbc\t%0\", exops[0]);
   }
   if (!CONSTANT_P (exops[3][1]) || INTVAL (exops[3][1]) != 0)
   {
-    output_asm_insn (\"sub %1, %0\", exops[3]);
-    output_asm_insn (\"sbc %0\", exops[2]);
-    output_asm_insn (\"sbc %0\", exops[1]);
-    output_asm_insn (\"sbc %0\", exops[0]);
+    output_asm_insn (\"sub\t%1,%0\", exops[3]);
+    output_asm_insn (\"sbc\t%0\", exops[2]);
+    output_asm_insn (\"sbc\t%0\", exops[1]);
+    output_asm_insn (\"sbc\t%0\", exops[0]);
   }
 
   return \"\";
@@ -1126,11 +1126,11 @@ 
   pdp11_expand_operands (inops, exops, 2, NULL, either);
   
   if (!CONSTANT_P (exops[0][1]) || INTVAL (exops[0][1]) != 0)
-    output_asm_insn (\"sub %1, %0\", exops[0]);
+    output_asm_insn (\"sub\t%1,%0\", exops[0]);
   if (!CONSTANT_P (exops[1][1]) || INTVAL (exops[1][1]) != 0)
   {
-    output_asm_insn (\"sub %1, %0\", exops[1]);
-    output_asm_insn (\"sbc %0\", exops[0]);
+    output_asm_insn (\"sub\t%1,%0\", exops[1]);
+    output_asm_insn (\"sbc\t%0\", exops[0]);
   }
 
   return \"\";
@@ -1164,12 +1164,12 @@ 
   if (GET_CODE (operands[2]) == CONST_INT)
     {
       if (INTVAL(operands[2]) == 1)
-	return \"dec %0\";
+	return \"dec\t%0\";
       else if (INTVAL(operands[2]) == -1)
-        return \"inc %0\";
+        return \"inc\t%0\";
     }
 
-  return \"sub %2, %0\";
+  return \"sub\t%2,%0\";
 }"
   [(set_attr "length" "2,4,4,6")])
 
@@ -1222,7 +1222,7 @@ 
 			  (match_operand:PDPint 2 "general_operand" "0,0,0,0")))
    (clobber (reg:CC CC_REGNUM))]
   "reload_completed"
-  "bic<PDPint:isfx> %1, %0"
+  "bic<PDPint:isfx>\t%1,%0"
   [(set_attr "length" "2,4,4,6")])
 
 ;;- Bit set (inclusive or) instructions
@@ -1244,7 +1244,7 @@ 
 	     (match_operand:PDPint 2 "general_operand" "rR,Qi,rR,Qi")))
    (clobber (reg:CC CC_REGNUM))]
   "reload_completed"
-  "bis<PDPint:isfx> %2, %0"
+  "bis<PDPint:isfx>\t%2,%0"
   [(set_attr "length" "2,4,4,6")])
 
 ;;- xor instructions
@@ -1266,7 +1266,7 @@ 
 	     (match_operand:HI 2 "register_operand" "r,r")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_40_PLUS && reload_completed"
-  "xor %2, %0"
+  "xor\t%2,%0"
   [(set_attr "length" "2,4")])
 
 ;;- one complement instructions
@@ -1287,7 +1287,7 @@ 
 	(not:PDPint (match_operand:PDPint 1 "general_operand" "0,0")))
    (clobber (reg:CC CC_REGNUM))]
   "reload_completed"
-  "com<PDPint:isfx> %0"
+  "com<PDPint:isfx>\t%0"
   [(set_attr "length" "2,4")])
 
 ;;- arithmetic shift instructions
@@ -1329,7 +1329,7 @@ 
 	(ashift:HI (match_operand:HI 1 "general_operand" "0,0")
 	               (match_operand:HI 2 "general_operand" "rR,Q")))]
   "TARGET_40_PLUS"
-  "ash %2, %0"
+  "ash\t%2,%0"
   [(set_attr "length" "2,4")])
 
 (define_insn "aslsi_op"
@@ -1337,7 +1337,7 @@ 
 	(ashift:SI (match_operand:SI 1 "general_operand" "0,0")
 	           (match_operand:HI 2 "general_operand" "rR,Q")))]
   "TARGET_40_PLUS"
-  "ashc %2, %0"
+  "ashc\t%2,%0"
   [(set_attr "length" "2,4")])
 
 ;; Now the expanders that produce the insns defined above. 
@@ -1444,7 +1444,7 @@ 
 	(abs:DF (match_operand:DF 1 "general_operand" "0,0")))
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
-  "{absd|absf} %0"
+  "{absd|absf}\t%0"
   [(set_attr "length" "2,4")])
 
 ;; negate insns
@@ -1464,7 +1464,7 @@ 
 	(neg:DF (match_operand:DF 1 "general_operand" "0,0")))
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
-  "{negd|negf} %0"
+  "{negd|negf}\t%0"
   [(set_attr "length" "2,4")])
 
 (define_insn_and_split "negdi2"
@@ -1488,14 +1488,14 @@ 
   
   pdp11_expand_operands (operands, exops, 1, NULL, either);
 
-  output_asm_insn (\"com %0\", exops[3]);
-  output_asm_insn (\"com %0\", exops[2]);
-  output_asm_insn (\"com %0\", exops[1]);
-  output_asm_insn (\"com %0\", exops[0]);
-  output_asm_insn (\"add $1, %0\", exops[3]);
-  output_asm_insn (\"adc %0\", exops[2]);
-  output_asm_insn (\"adc %0\", exops[1]);
-  output_asm_insn (\"adc %0\", exops[0]);
+  output_asm_insn (\"com\t%0\", exops[3]);
+  output_asm_insn (\"com\t%0\", exops[2]);
+  output_asm_insn (\"com\t%0\", exops[1]);
+  output_asm_insn (\"com\t%0\", exops[0]);
+  output_asm_insn (\"add\t%#1,%0\", exops[3]);
+  output_asm_insn (\"adc\t%0\", exops[2]);
+  output_asm_insn (\"adc\t%0\", exops[1]);
+  output_asm_insn (\"adc\t%0\", exops[0]);
 
   return \"\";
 }
@@ -1522,10 +1522,10 @@ 
   
   pdp11_expand_operands (operands, exops, 1, NULL, either);
 
-  output_asm_insn (\"com %0\", exops[1]);
-  output_asm_insn (\"com %0\", exops[0]);
-  output_asm_insn (\"add $1, %0\", exops[1]);
-  output_asm_insn (\"adc %0\", exops[0]);
+  output_asm_insn (\"com\t%0\", exops[1]);
+  output_asm_insn (\"com\t%0\", exops[0]);
+  output_asm_insn (\"add\t%#1,%0\", exops[1]);
+  output_asm_insn (\"adc\t%0\", exops[0]);
 
   return \"\";
 }
@@ -1546,7 +1546,7 @@ 
 	(neg:PDPint (match_operand:PDPint 1 "general_operand" "0,0")))
    (clobber (reg:CC CC_REGNUM))]
   ""
-  "neg<PDPint:isfx> %0"
+  "neg<PDPint:isfx>\t%0"
   [(set_attr "length" "2,4")])
 
 
@@ -1558,8 +1558,8 @@ 
   "*
 {
   if (get_attr_length (insn) == 2)
-    return \"br %l0\";
-  return \"jmp %l0\";
+    return \"br\t%l0\";
+  return \"jmp\t%l0\";
 }"
   [(set (attr "length") (if_then_else (ior (lt (minus (match_dup 0)
 						      (pc))
@@ -1575,9 +1575,9 @@ 
    (use (label_ref (match_operand 1 "" "")))]
   ""
   "@
-  jmp (%0)
-  jmp %@%0
-  jmp %@%0"
+  jmp\t(%0)
+  jmp\t%@%0
+  jmp\t%@%0"
   [(set_attr "length" "2,2,4")])
 
 ;; indirect jump.  TODO: this needs a constraint that allows memory
@@ -1596,7 +1596,7 @@ 
 	 (match_operand:HI 1 "general_operand" "g,g"))]
   ;;- Don't use operand 1 for most machines.
   ""
-  "jsr pc, %0"
+  "jsr pc,%0"
   [(set_attr "length" "2,4")])
 
 ;;- jump to subroutine
@@ -1606,7 +1606,7 @@ 
 	      (match_operand:HI 2 "general_operand" "g,g")))]
   ;;- Don't use operand 2 for most machines.
   ""
-  "jsr pc, %1"
+  "jsr pc,%1"
   [(set_attr "length" "2,4")])
 
 (define_expand "untyped_call"
@@ -1661,7 +1661,7 @@ 
 	      (match_operand:DF 2 "float_operand" "fR,QF")))
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
-  "{muld|mulf} %2, %0"
+  "{muld|mulf}\t%2,%0"
   [(set_attr "length" "2,4")])
 
 ;; 16 bit result multiply.  This uses odd numbered registers.
@@ -1683,7 +1683,7 @@ 
 	      (match_operand:HI 2 "general_operand" "rR,Qi")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_40_PLUS && reload_completed"
-  "mul %2, %0"
+  "mul\t%2,%0"
   [(set_attr "length" "2,4")])
 
 ;; 32 bit result from 16 bit operands
@@ -1706,7 +1706,7 @@ 
 	      (sign_extend:SI (match_operand:HI 2 "general_operand" "rR,Qi"))))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_40_PLUS && reload_completed"
-  "mul %2, %0"
+  "mul\t%2,%0"
   [(set_attr "length" "2,4")])
 
 ;;- divide
@@ -1727,7 +1727,7 @@ 
 	     (match_operand:DF 2 "general_operand" "fR,QF")))
    (clobber (reg:CC FCC_REGNUM))]
   "TARGET_FPU && reload_completed"
-  "{divd|divf} %2, %0"
+  "{divd|divf}\t%2,%0"
   [(set_attr "length" "2,4")])
 
 (define_expand "divmodhi4"
@@ -1773,5 +1773,5 @@ 
 	(mod:HI (match_dup 1) (match_dup 2)))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_40_PLUS"
-   "div %2,%0"
+   "div\t%2,%0"
   [(set_attr "length" "2,4")])
Index: config/pdp11/pdp11.opt
===================================================================
--- config/pdp11/pdp11.opt	(revision 262287)
+++ config/pdp11/pdp11.opt	(working copy)
@@ -35,9 +35,13 @@  Target Report Mask(AC0)
 Return floating-point results in ac0 (fr0 in Unix assembler syntax).
 
 mdec-asm
-Target RejectNegative Report InverseMask(UNIX_ASM)
+Target RejectNegative Report Mask(DEC_ASM) Negative(mgnu-asm)
 Use the DEC assembler syntax.
 
+mgnu-asm
+Target RejectNegative Report Mask(GNU_ASM) Negative(munix-asm)
+Use the GNU assembler syntax.
+
 mfloat32
 Target Report Mask(FLOAT32)
 Use 32 bit float.
@@ -67,5 +71,5 @@  Target Report Mask(SPLIT)
 Target has split I&D.
 
 munix-asm
-Target RejectNegative Report Mask(UNIX_ASM)
+Target RejectNegative Report Mask(UNIX_ASM) Negative(mdec-asm)
 Use UNIX assembler syntax.
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 262287)
+++ doc/invoke.texi	(working copy)
@@ -972,7 +972,7 @@  Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-mfpu  -msoft-float  -mac0  -mno-ac0  -m40  -m45  -m10 @gol
 -mint32  -mno-int16 -mint16  -mno-int32 @gol
 -mfloat32  -mno-float64 -mfloat64  -mno-float32 @gol
--msplit -munix-asm  -mdec-asm}
+-msplit -munix-asm  -mdec-asm -mgnu-asm}
 
 @emph{picoChip Options}
 @gccoptlist{-mae=@var{ae_type}  -mvliw-lookahead=@var{N} @gol
@@ -22080,7 +22080,11 @@  Use Unix assembler syntax.
 
 @item -mdec-asm
 @opindex mdec-asm
-Use DEC assembler syntax.  This is the default.
+Use DEC assembler syntax.
+
+@item -mgnu-asm
+@opindex mgnu-asm
+Use GNU assembler syntax.  This is the default.
 @end table
 
 @node picoChip Options