+2018-05-24  Jim Wilson  <jimw@sifive.com>
+
+       PR gas/23219
+       * config/tc-riscv.c (riscv_frag_align_code): Move frag_more call after
+       !riscv_opts.relax check.
+       (riscv_handle_align): Rewrite !riscv_opts.relax support.
+       * config/tc-riscv (MAX_MEM_FOR_RS_ALIGN_CODE): Update.
+       * testsuite/gas/riscv/no-relax-align.d: New
+       * testsuite/gas/riscv/no-relax-align.s: New
+       * testsuite/gas/riscv/no-relax-align-2.d: New
+       * testsuite/gas/riscv/no-relax-align-2.s: New
+
 2018-05-21  Peter Bergner  <bergner@vnet.ibm.com.com>
 
        * config/tc-ppc.c (md_assemble): Delete handling of fake operands.
 
   if (bytes <= insn_alignment)
     return TRUE;
 
-  nops = frag_more (worst_case_bytes);
-
   /* When not relaxing, riscv_handle_align handles code alignment.  */
   if (!riscv_opts.relax)
     return FALSE;
 
+  nops = frag_more (worst_case_bytes);
+
   ex.X_op = O_constant;
   ex.X_add_number = worst_case_bytes;
 
       /* When relaxing, riscv_frag_align_code handles code alignment.  */
       if (!riscv_opts.relax)
        {
-         bfd_signed_vma count = fragP->fr_next->fr_address
-                                - fragP->fr_address - fragP->fr_fix;
-
-         if (count <= 0)
+         bfd_signed_vma bytes = (fragP->fr_next->fr_address
+                                 - fragP->fr_address - fragP->fr_fix);
+         /* We have 4 byte uncompressed nops.  */
+         bfd_signed_vma size = 4;
+         bfd_signed_vma excess = bytes % size;
+         char *p = fragP->fr_literal + fragP->fr_fix;
+
+         if (bytes <= 0)
            break;
 
-         count &= MAX_MEM_FOR_RS_ALIGN_CODE;
-         riscv_make_nops (fragP->fr_literal + fragP->fr_fix, count);
-         fragP->fr_var = count;
+         /* Insert zeros or compressed nops to get 4 byte alignment.  */
+         if (excess)
+           {
+             riscv_make_nops (p, excess);
+             fragP->fr_fix += excess;
+             p += excess;
+           }
+
+         /* Insert variable number of 4 byte uncompressed nops.  */
+         riscv_make_nops (p, size);
+         fragP->fr_var = size;
        }
       break;
 
 
 extern void riscv_handle_align (fragS *);
 #define HANDLE_ALIGN riscv_handle_align
 
-#define MAX_MEM_FOR_RS_ALIGN_CODE 7
+#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
 
 /* The ISA of the target may change based on command-line arguments.  */
 #define TARGET_FORMAT riscv_target_format()
 
--- /dev/null
+#as:
+#objdump: -dr
+
+.*:[   ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[      ]+0:[   ]+0000[         ]+unimp
+[      ]+2:[   ]+0001[         ]+nop
+[      ]+4:[   ]+00000013[     ]+nop
+[      ]+8:[   ]+00000013[     ]+nop
+[      ]+c:[   ]+00000013[     ]+nop
+[      ]+10:[  ]+0001[         ]+nop
+[      ]+12:[  ]+0001[         ]+nop
+[      ]+14:[  ]+00000013[     ]+nop
+[      ]+18:[  ]+00000013[     ]+nop
+[      ]+1c:[  ]+00000013[     ]+nop
 
--- /dev/null
+       .option norelax
+       .option rvc
+       .byte 0
+       .align 4
+       nop
 
--- /dev/null
+#as:
+#objdump: -dr
+
+.*:[   ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[      ]+0:[   ]+00000013[     ]+nop
+[      ]+4:[   ]+00000013[     ]+nop
+[      ]+8:[   ]+00000013[     ]+nop
+[      ]+c:[   ]+00000013[     ]+nop
 
--- /dev/null
+       .option norelax
+       .align 4
+       nop
+       nop