[PATCH v2 5/6] Add nanoMIPS documentation.

"Tsing" <[email protected]> Fri, 24 Jul 2026 18:30:57 +0800
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
From: tsing <[email protected]>

binutils/
        * doc/binutils.texi: Add entries for nanomips.
gas/
        * doc/all.texi: Add entries for nanomips.
        * doc/as.texi: Likewise.
        * doc/c-nanomips-aliases.texi: New file.
        * doc/c-nanomips-macros.texi: New file.
        * doc/c-nanomips.texi: New file.
ld/
        * gen-doc.texi: Add entries for naonmips.
        * ld.texi: Likewise.
---
 binutils/doc/binutils.texi      |    7 +
 gas/doc/all.texi                |    1 +
 gas/doc/as.texi                 |  189 ++
 gas/doc/c-nanomips-aliases.texi | 1527 +++++++++++++++
 gas/doc/c-nanomips-macros.texi  | 3136 +++++++++++++++++++++++++++++++
 gas/doc/c-nanomips.texi         | 1499 +++++++++++++++
 ld/gen-doc.texi                 |    1 +
 ld/ld.texi                      |   37 +
 8 files changed, 6397 insertions(+)
 create mode 100644 gas/doc/c-nanomips-aliases.texi
 create mode 100644 gas/doc/c-nanomips-macros.texi
 create mode 100644 gas/doc/c-nanomips.texi

diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 198ae8244ef..7325743bade 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -2857,6 +2857,13 @@ rather than names, for the selected types of registers.
 You can list the available values of @var{ABI} and @var{ARCH} using
 the @option{--help} option.
 
+For nanoMIPS, all of the options specified above for the MIPS
+architecture are supported. The available values of @var{ABI}
+and @var{ARCH} are different from MIPS and can be listed with
+the @option{--help} option. In addition, the @option{-Mshow-arch-insn}
+option prints extended mnemonics in disassembly, including format
+suffixes, as used in the architecture reference manual.
+
 For VAX, you can specify function entry addresses with @option{-M
 entry:0xf00ba}.  You can use this multiple times to properly
 disassemble VAX binary files that don't contain symbol tables (like
diff --git a/gas/doc/all.texi b/gas/doc/all.texi
index 83418951b13..0501512edb4 100644
--- a/gas/doc/all.texi
+++ b/gas/doc/all.texi
@@ -57,6 +57,7 @@
 @set MMIX
 @set MS1
 @set MSP430
+@set NANOMIPS
 @set NDS32
 @set NS32K
 @set OPENRISC
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index 5d7772d62d3..9dbc7a453e1 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -500,6 +500,29 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
    [@b{--no-expand}] [@b{--no-merge-gregs}] [@b{-x}]
    [@b{--linker-allocated-gregs}]
 @end ifset
+@ifset NANOMIPS
+
+@emph{Target nanoMIPS options:}
+   [@b{-EL}] [@b{-EB}]
+   [@b{-g}[@var{debug level}]] [@b{-G} @var{num}]
+   [@b{-march}=@var{CPU}] [@b{-mtune}=@var{CPU}]
+   [@b{-m32}] [@b{-m64}]
+   [@b{-mcmodel=@var{MODEL}}]
+   [@b{-mpic}] [@b{-mno-pic}]
+   [@b{-mPIC}] [@b{-mno-PIC}]
+   [@b{-mpid}] [@b{-mno-pid}]
+   [@b{-mpcrel}] [@b{-mno-pcrel}]
+   [@b{-minsn32}] [@b{-mno-insn32}]
+   [@b{-mmt}] [@b{-mno-mt}]
+   [@b{-mvirt}] [@b{-mno-virt}]
+   [@b{-mhard-float}] [@b{-msoft-float}]
+   [@b{-msingle-float}] [@b{-mdouble-float}]
+   [@b{-construct-floats}] [@b{-no-construct-floats}]
+   [@b{-mbalc-stubs}] [@b{-mno-balc-stubs}]
+   [@b{-mlegacyregs}] [@b{-mno-legacyregs}]
+   [@b{--linkrelax}]
+   [@b{-trap}] [@b{-no-break}] [@b{-break}] [@b{-no-trap}]
+@end ifset
 @ifset NDS32
 
 @emph{Target NDS32 options:}
@@ -1889,6 +1912,146 @@ Meta processor.
 See the info pages for documentation of the MMIX-specific options.
 @end ifset
 
+@ifset NANOMIPS
+The following options are available when @value{AS} is configured for
+a nanoMIPS processor.
+
+@table @gcctabopt
+@item -G @var{num}
+This option sets the largest size of an object that can be referenced
+implicitly with the @code{gp} register.  The default value is 8.
+
+@cindex nanoMIPS endianness
+@cindex endianness, nanoMIPS
+@cindex big endian output, nanoMIPS
+@item -EB
+Generate ``big endian'' format output.
+
+@cindex little endian output, nanoMIPS
+@item -EL
+Generate ``little endian'' format output.
+
+@cindex nanoMIPS ISA
+@item -march=@var{cpu}
+Generate code for a particular nanoMIPS CPU or ISA level. The following
+ISA levels are recognized: @code{32r6}, @code{32r6s}, @code{64r6}. The following CPUs are
+recognized: @code{nms1}, @code{i7200}.
+
+@item -mtune=@var{cpu}
+Schedule and tune for a particular nanoMIPS CPU.
+
+@item -m32
+@itemx -32
+Generate code for the P32 ABI.
+
+@item -m64
+@itemx -64
+Generate code for the P64 ABI.
+
+@item -mcmodel=@var{mmodel}
+Generate code for a particular C Memory Model. The following memory models
+are supported: @code{auto}, @code{medium}, @code{large}
+
+@item -mpic
+@itemx -mno-pic
+Generate medium model SVR4-style PIC.  This option tells the assembler
+to generate SVR4-style position-independent macro expansions.  It also
+tells the assembler to mark the output file as PIC.
+@samp{-mno-pic} turns off this option.
+
+@item -mPIC
+@itemx -mno-PIC
+Generate large model SVR4-style PIC.  This option tells the assembler
+to generate SVR4-style position-independent macro expansions.  It also
+tells the assembler to mark the output file as PIC.
+@samp{-mno-PIC} turns off this option.
+
+@item -mpid
+@itemx -mno-pid
+Generate position independent data.  This option tells the assembler to
+generate data sections that can be repositioned independent of code placement.
+It also tells the assembler to mark the output file as PID.
+@samp{-mno-pid} turns off this option.
+
+@item -mpcrel
+@itemx -mno-pcrel
+Generate PC-relative expansions.  This option tells the assembler to
+avoid the use of absolute addresses for symbols even when those
+addresses may be known at link time.  It also tells the assembler to
+mark the output file as purely PC-relative.
+@samp{-mno-pcrel} turns off this option.
+
+@item -minsn32
+@itemx -mno-insn32
+Only use 32-bit instruction encodings when generating code for the
+nanoMIPS processor.  This option inhibits the use of any 16-bit
+instructions.  This is equivalent to putting @code{.set insn32} at
+the start of the assembly file.  @samp{-mno-insn32} turns off this
+option.  This is equivalent to putting @code{.set noinsn32} at the
+start of the assembly file.  By default @samp{-mno-insn32} is
+selected, allowing all instructions to be used.
+
+@item -mmt
+@itemx -mno-mt
+Generate code for the MT Application Specific Extension.
+This tells the assembler to accept MT instructions.
+@samp{-mno-mt} turns off this option.
+
+@item -mvirt
+@itemx -mno-virt
+Generate code for the Virtualization Application Specific Extension.
+This tells the assembler to accept virtualization instructions.
+@samp{-mno-virt} turns off this option.
+
+@item -msoft-float
+@itemx -mhard-float
+Disable or enable floating-point instructions.  Note that by default
+floating-point instructions are always allowed even with CPU targets
+that don't have support for these instructions.
+
+@item -msingle-float
+@itemx -mdouble-float
+Disable or enable double-precision floating-point operations.  Note
+that by default double-precision floating-point operations are always
+allowed even with CPU targets that don't have support for these
+operations.
+
+@item --construct-floats
+@itemx --no-construct-floats
+The @samp{--no-construct-floats} option disables the construction of
+double width floating point constants by loading the two halves of the
+value into the two single width floating point registers that make up
+the double width register.  By default @samp{--construct-floats} is
+selected, allowing construction of these floating point constants.
+
+@item -mbalc-stubs
+@itemx -mno-balc-stubs
+Control the BALC stub optimization. The @samp{-mbalc-stubs} option aggregates
+multiple out-of-range 16-bit branch-and-link instructions to use a
+non-conditional branch-stub with 32-bit range. This gives better code
+compression, but can have a negative effect on performance. By default,
+@samp{-mno-balc-stubs} is selected, disabling this optimization.
+
+@item -mlegacyregs
+@itemx -mno-legacyregs
+Allow the use of legacy MIPS style numeric register formats in assembly. This
+option is disabled by default.
+
+@item --linkrelax
+Enable support for link-time relaxations.
+
+@item --trap
+@itemx --no-trap
+@itemx --break
+@itemx --no-break
+Control how to deal with multiplication overflow and division by zero.
+@samp{--trap} or @samp{--no-break} (which are synonyms) take a trap exception;
+@samp{--break} or @samp{--no-trap} (also synonyms, and the default) take a
+break exception.
+
+@end table
+@end ifset
+
 @ifset NDS32
 
 @ifclear man
@@ -8162,6 +8325,25 @@ will be:
 
 @end table
 
+@subsection nanoMIPS Attributes
+
+@table @r
+@item Tag_nanoGNU_MIPS_ABI_FP (4)
+The floating-point ABI used by this object file.  The value will be:
+
+@itemize @bullet
+@item
+0 for files not affected by the floating-point ABI.
+@item
+1 for files using the hardware floating-point ABI with a standard
+double-precision FPU.
+@item
+2 for files using the hardware floating-point ABI with a single-precision FPU.
+@item
+3 for files using the software floating-point ABI.
+@end itemize
+@end table
+
 @subsection PowerPC Attributes
 
 @table @r
@@ -8363,6 +8545,9 @@ subject, see the hardware manufacturer's manual.
 @ifset MSP430
 * MSP430-Dependent::		MSP430 Dependent Features
 @end ifset
+@ifset NANOMIPS
+* nanoMIPS-Dependent::          nanoMIPS Dependent Features
+@end ifset
 @ifset NDS32
 * NDS32-Dependent::             Andes NDS32 Dependent Features
 @end ifset
@@ -8599,6 +8784,10 @@ family.
 @include c-msp430.texi
 @end ifset
 
+@ifset NANOMIPS
+@include c-nanomips.texi
+@end ifset
+
 @ifset NDS32
 @include c-nds32.texi
 @end ifset
diff --git a/gas/doc/c-nanomips-aliases.texi b/gas/doc/c-nanomips-aliases.texi
new file mode 100644
index 00000000000..71e0308ae00
--- /dev/null
+++ b/gas/doc/c-nanomips-aliases.texi
@@ -0,0 +1,1527 @@
+@c Copyright (C) 2017-2026 Free Software Foundation, CIP United Inc.
+@c Contributed by MIPS Tech LLC.
+@c Written by Faraz Shahbazker <[email protected]>
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@node nanoMIPS Aliases
+@section 1:1 Instruction Aliases
+
+The nanoMIPS assembler allows multiple mnemonics to select the same
+target instruction.  These aliases are provided as a convenience to the
+user, so that assembly programs can be written without paying too much
+attention to type and order of operands, specially where the ISA has
+eccentric restrictions.  Following is a complete list of the various 1:1
+aliases supported:
+
+@itemize
+@item Disassembly = N indicates that disassembly will show the target instruction instead of the alias form.
+@item Size = 16/32 indicates that both 16 and 32-bit aliases are available.
+@end itemize
+
+@multitable  @columnfractions 0.25 0.25 0.3 0.05 0.1
+@headitem Alias@tab Condition @tab Target@tab Dis@tab Size
+@item @tab @tab @tab @tab 
+@item
+@verbatim
+Implicit operand forms
+@end verbatim
+@tab  @tab @tab  @tab
+
+@item
+@verbatim
+break
+@end verbatim
+
+@tab @tab @verbatim
+break 0
+@end verbatim
+
+@tab Y @tab 16/32
+@item
+@verbatim
+sdbbp
+@end verbatim
+
+@tab @tab @verbatim
+sdbbp 0
+@end verbatim
+
+@tab Y @tab 16/32
+@item
+@verbatim
+mfc0 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mfc0 rt,crs,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mfc0 rt,crsname[,sel]
+@end verbatim
+
+@tab @tab @verbatim
+mfc0 rt,crs,sel
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mfhc0 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mfhc0 rt,crs,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mfhc0 rt,crsname[,sel]
+@end verbatim
+
+@tab @tab @verbatim
+mfhc0 rt,crs,sel
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mtc0 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mtc0 rt,crs,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mtc0 rt,crsname[,sel]
+@end verbatim
+
+@tab @tab @verbatim
+mtc0 rt,crs,sel
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mthc0 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mthc0 rt,crs,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mthc0 rt,crsname[,sel]
+@end verbatim
+
+@tab @tab @verbatim
+mthc0 rt,crs,sel
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+rddsp rt
+@end verbatim
+
+@tab @tab @verbatim
+rddsp rt,31
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+rdhwr rt,hrs
+@end verbatim
+
+@tab @tab @verbatim
+rdhwr rt,hrs,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+tne rt,rs
+@end verbatim
+
+@tab  @tab @verbatim
+tne rt,rs,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+teq rt,rs
+@end verbatim
+
+@tab  @tab @verbatim
+teq rt,rs,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+syscall
+@end verbatim
+
+@tab @tab @verbatim
+syscall 0
+@end verbatim
+
+@tab Y @tab 16/32
+@item
+@verbatim
+wait
+@end verbatim
+
+@tab @tab @verbatim
+wait 0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+wrdsp rt
+@end verbatim
+
+@tab @tab @verbatim
+wrdsp rt,31
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+yield rs
+@end verbatim
+
+@tab @tab @verbatim
+yield $zero, rs
+@end verbatim
+
+@tab Y @tab 32
+@item @tab @tab @tab @tab 
+@item
+@verbatim
+General aliases
+@end verbatim
+
+@tab  @tab @tab  @tab 
+@item
+@verbatim
+jrc rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc $zero,rs
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+jalrc $ra,rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc rs
+@end verbatim
+
+@tab N @tab 16
+@item
+@verbatim
+jalrc rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc $ra,rs
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+li rt,imm
+@end verbatim
+
+@tab 0 <= imm < 65535 @tab @verbatim
+addiu rt,rt,imm
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+li rt,imm
+@end verbatim
+
+@tab -4095 <= imm <= 0 @tab @verbatim
+addiu[neg] rt,rt,imm
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+li rt,imm
+@end verbatim
+
+@tab imm % 4096 == 0 @tab @verbatim
+lui rt,(imm >> 12)
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+li rt,0
+@end verbatim
+
+@tab  @tab @verbatim
+move rt,$zero
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+addiu rt,rt,imm
+@end verbatim
+
+@tab @tab @verbatim
+addiu rt,imm
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+addiu.b rt,gp,ofst
+@end verbatim
+
+@tab 0 <= offset < 2^18 @tab @verbatim
+addiu[gp.b] rt,gp,ofst
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+addiu.w rt,gp,ofst
+@end verbatim
+
+@tab 0 <= offset < 2^21
+&& offset % 4 == 0 @tab @verbatim
+addiu[gp.w] rt,gp,ofst
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+align rd,rs,rt,bp
+@end verbatim
+
+@tab bp == 0 @tab @verbatim
+move rd,rs
+@end verbatim
+
+@tab N @tab 16/32
+@item
+@verbatim
+align rd,rs,rt,bp
+@end verbatim
+
+@tab bp <> 0 @tab @verbatim
+extw rd,rs,rt,(4-bp)<<3
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+and rt,rt,rs
+@end verbatim
+
+@tab @tab @verbatim
+and rt,rs
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+and rt,rs,rt
+@end verbatim
+
+@tab @tab @verbatim
+and rt,rs
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+beqzc rt,label
+@end verbatim
+
+@tab @tab @verbatim
+beqc $zero,rt,label
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+beqc rt,$zero,label
+@end verbatim
+
+@tab @tab @verbatim
+beqzc rt,label
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+beqc $zero,rt,label
+@end verbatim
+
+@tab @tab @verbatim
+beqzc rt,label
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+beqc rs,rt,label
+@end verbatim
+
+@tab rs > rt @*
+&& non-NMS @tab @verbatim
+beqc rt,rs,label
+@end verbatim
+
+@tab N @tab 16
+@item
+@verbatim
+blezc rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bgec $zero,rt,label
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+bgezc rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bgec rt,$zero,label
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+bgtzc rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bltc $zero,rt,label
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+bltzc rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bltc rt,$zero,label
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+bnezc rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bnec $zero,rt,label
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+bnec rt,$zero,label
+@end verbatim
+
+@tab @tab @verbatim
+bnezc rt,label
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+bnec $zero,rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bnezc rt,label
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+bnec rs,rt,label
+@end verbatim
+
+@tab rs <= rt @*
+&& non-NMS @tab @verbatim
+bnec rt,rs,label
+@end verbatim
+
+@tab N @tab 16
+@item
+@verbatim
+cftc1 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,1,3,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+cftc1 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,1,3,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+cftc2 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,1,5 0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+cttc1 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,1,3,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+cttc1 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,1,3,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+cttc2 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,1,5,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+di
+@end verbatim
+
+@tab @tab @verbatim
+di $zero
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+dmt
+@end verbatim
+
+@tab @tab @verbatim
+dmt $zero
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+dvpe
+@end verbatim
+
+@tab @tab @verbatim
+dvpe $zero
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+dvp
+@end verbatim
+
+@tab @tab @verbatim
+dvp $zero
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+ei
+@end verbatim
+
+@tab @tab @verbatim
+ei $zero
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+emt
+@end verbatim
+
+@tab @tab @verbatim
+emt $zero
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+evpe
+@end verbatim
+
+@tab @tab @verbatim
+evpe $zero
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+evp
+@end verbatim
+
+@tab @tab @verbatim
+evp $zero
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+jrc.hb rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc.hb $zero,rs
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+jalrc.hb rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc.hb $zero,rs
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+mftc0 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,0,0,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mftc0 rt,crs,sel
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,0,sel,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mftc0 rt,crsname[,sel]
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,0,sel,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mfthc0 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,0,0,1
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mfthc0 rt,crs,sel
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,0,sel,1
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mfthc0 rt,crsname[,sel]
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,0,sel,1
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mftc1 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,1,2,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mftc2 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,1,4,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mftdsp rt
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,$16,1,1,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mftgpr rt,rs
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,rs,1,0,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mfthc1 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,1,2,1
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mfthc2 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,crs,1,4,1
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mfthi rt
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,$1,1,1,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mfthi rt,acc
+@end verbatim
+
+@tab @tab @verbatim
+rs = (acc * 4) + 1
+mftr rt,rs,1,1,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mftlo rt
+@end verbatim
+
+@tab @tab @verbatim
+mftr rt,$0,1,1,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mftlo rt,acc
+@end verbatim
+
+@tab @tab @verbatim
+rs = (acc * 4)
+mftr rt,rs,1,1,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+move rd,rs
+@end verbatim
+
+@tab @tab @verbatim
+or rd,rs,$zero
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+move rd,rs
+@end verbatim
+
+@tab  @tab @verbatim
+addu rd,rs,$zero
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mttc0 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,0,0,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mttc0 rt,crs,sel
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,0,sel,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mttc0 rt,crsname[,sel]
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,0,sel,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mtthc0 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,0,0,1
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mtthc0 rt,crs,sel
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,0,sel,1
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mtthc0 rt,crsname[,sel]
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,0,sel,1
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mttc1 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,1,2,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mttc2 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,1,4,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mttdsp rt
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,$16,1,1,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mttgpr rt,rs
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,rs,1,0,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mtthc1 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,1,2,1
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mtthc2 rt,crs
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,crs,1,4,1
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mtthi rt
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,$1,1,1,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mtthi rt,acc
+@end verbatim
+
+@tab @tab @verbatim
+rs = (acc * 4) + 1
+mttr rt,rs,1,1,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mttlo rt
+@end verbatim
+
+@tab @tab @verbatim
+mttr rt,$0,1,1,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+mttlo rt,acc
+@end verbatim
+
+@tab @tab @verbatim
+rs = (acc * 4)
+mttr rt,rs,1,1,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+neg rd,rs
+@end verbatim
+
+@tab non-NMS @tab @verbatim
+sub rd,$zero,rs
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+negu rd,rs
+@end verbatim
+
+@tab @tab @verbatim
+subu rd,$zero,rs
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+not rd,rs
+@end verbatim
+
+@tab @tab @verbatim
+nor rd,rs,$zero
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+or rt,rt,rs
+@end verbatim
+
+@tab @tab @verbatim
+or rt,rs
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+or rt,rs,rt
+@end verbatim
+
+@tab @tab @verbatim
+or rt,rs
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+rem rd,rs,rt
+@end verbatim
+
+@tab @tab @verbatim
+mod rd,rs,rt
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+jraddiusp imm
+@end verbatim
+
+@tab 0 <= imm < 4096
+&& (imm%16 == 0) @tab @verbatim
+restore.jrc imm
+@end verbatim
+
+@tab N @tab 16/32
+@item
+@verbatim
+rotr rd,rs,rt
+@end verbatim
+
+@tab @tab @verbatim
+rotrv rd,rs,rt
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+ror rd,rs,shift
+@end verbatim
+
+@tab @tab @verbatim
+rotr rd,rs,shift
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+ror rd,rs,rt
+@end verbatim
+
+@tab @tab @verbatim
+rotrv rd,rs,rt
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+rorv rd,rs,shift
+@end verbatim
+
+@tab @tab @verbatim
+rotr rd,rs,shift
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+rorv rd,rs,rt
+@end verbatim
+
+@tab @tab @verbatim
+rotrv rd,rs,rt
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+sll rd,rs,rt
+@end verbatim
+
+@tab @tab @verbatim
+sllv rd,rs,rt
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+sra rd,rs,rt
+@end verbatim
+
+@tab @tab @verbatim
+srav rd,rs,rt
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+srl rd,rs,rt
+@end verbatim
+
+@tab @tab @verbatim
+srlv rd,rs,rt
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+xor rt,rt,rs
+@end verbatim
+
+@tab @tab @verbatim
+xor rt,rs
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+xor rt,rs,rt
+@end verbatim
+
+@tab @tab @verbatim
+xor rt,rs
+@end verbatim
+
+@tab Y @tab 16
+@item
+@verbatim
+andi rt,rs,imm
+@end verbatim
+
+@tab imm = 2x -1,where 12 < x <= 32 @tab @verbatim
+ext rt,rs,0,x
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+nop
+@end verbatim
+
+@tab @tab @verbatim
+sll $zero,rs,0
+@end verbatim
+
+@tab Y @tab 32
+@item
+@verbatim
+ualw rt,ofst(rs)
+@end verbatim
+
+@tab non-NMS @tab @verbatim
+ualwm rt,ofst(rs),1
+@end verbatim
+
+@tab Y @tab 32
+@item @tab @tab @tab @tab 
+@item
+@verbatim
+Convert-to-compact branch aliases
+@end verbatim
+
+@tab  @tab @tab  @tab 
+@item
+@verbatim
+jr rs
+@end verbatim
+
+@tab @tab @verbatim
+jrc rs
+@end verbatim
+
+@tab N @tab 16
+@item
+@verbatim
+jr rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc $zero,rs
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+jalr rd,rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc rd,rs
+@end verbatim
+
+@tab N @tab 16/32
+@item
+@verbatim
+jalr rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc $ra,rs
+@end verbatim
+
+@tab N @tab 16/32
+@item
+@verbatim
+bal label
+@end verbatim
+
+@tab @tab @verbatim
+balc label
+@end verbatim
+
+@tab N @tab 16/32
+@item
+@verbatim
+b label
+@end verbatim
+
+@tab @tab @verbatim
+bc label
+@end verbatim
+
+@tab N @tab 16/32
+@item
+@verbatim
+beqz rt,label
+@end verbatim
+
+@tab @tab @verbatim
+beqc $zero,rt,label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+beqz $zero,rt,label
+@end verbatim
+
+@tab @tab @verbatim
+beqzc rt,label
+@end verbatim
+
+@tab N @tab 16
+@item
+@verbatim
+beqz rt,$zero,label
+@end verbatim
+
+@tab @tab @verbatim
+beqzc rt,label
+@end verbatim
+
+@tab N @tab 16
+@item
+@verbatim
+beq rs,rt,label
+@end verbatim
+
+@tab rs < rt @*
+&& non-NMS @tab @verbatim
+beqc rs,rt,label
+@end verbatim
+
+@tab N @tab 16
+@item
+@verbatim
+beq rs,rt,label
+@end verbatim
+
+@tab rs > rt @*
+&& non-NMS @tab @verbatim
+beqc rt,rs,label
+@end verbatim
+
+@tab N @tab 16
+@item
+@verbatim
+beq rs,rt,label
+@end verbatim
+
+@tab @tab @verbatim
+beqc rt,rs,label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+blez rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bgec $zero,rt,label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+bgez rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bgec rt,$zero,label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+bge rs,rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bgec rs,rt,label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+bgeu rs,rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bgeuc rs,rt,label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+bgtz rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bltc $zero,rt,label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+bltz rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bltc rt,$zero,label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+blt rs,rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bltc rs,rt,label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+bltu rs,rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bltuc rs,rt,label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+bnez rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bnec $zero,rt,label
+@end verbatim
+
+@tab N @tab 16/32
+@item
+@verbatim
+bne rs,rt,label
+@end verbatim
+
+@tab rs >= rt @*
+&& non-NMS @tab @verbatim
+bnec rs,rt,label
+@end verbatim
+
+@tab N @tab 16
+@item
+@verbatim
+bne rs,rt,label
+@end verbatim
+
+@tab rs <= rt @*
+&& non-NMS @tab @verbatim
+bnec rt,rs,label
+@end verbatim
+
+@tab N @tab 16
+@item
+@verbatim
+bne rs,rt,label
+@end verbatim
+
+@tab @tab @verbatim
+bnec rs,rt,label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+bposge32 imm
+@end verbatim
+
+@tab @tab @verbatim
+bposge32c imm
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+j label
+@end verbatim
+
+@tab @tab @verbatim
+bc label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+jr.hb rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc.hb $zero,rs
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+jalr.hb rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc.hb $zero,rs
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+jalr.hb rd,rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc.hb rd,rs
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+jal rd,rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc rd,rs
+@end verbatim
+
+@tab N @tab 16/32
+@item
+@verbatim
+jal rs
+@end verbatim
+
+@tab @tab @verbatim
+jalrc $ra,rs
+@end verbatim
+
+@tab N @tab 16/32
+@item
+@verbatim
+jal label
+@end verbatim
+
+@tab @tab @verbatim
+balc label
+@end verbatim
+
+@tab N @tab 32
+@item
+@verbatim
+move.bal rt,rt,label
+@end verbatim
+
+@tab @tab @verbatim
+move.balc rd,rt,label
+@end verbatim
+
+@tab N @tab 32
+
+@end multitable
diff --git a/gas/doc/c-nanomips-macros.texi b/gas/doc/c-nanomips-macros.texi
new file mode 100644
index 00000000000..7f4685f8d77
--- /dev/null
+++ b/gas/doc/c-nanomips-macros.texi
@@ -0,0 +1,3136 @@
+@c Copyright (C) 2017-2026 Free Software Foundation, CIP United Inc.
+@c Contributed by MIPS Tech LLC
+@c Written by Faraz Shahbazker <[email protected]>
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+@page
+
+@node nanoMIPS Macros
+@section High-level Assembly Macros
+
+MIPS assemblers have traditionally provided a wider range of
+instructions than the MIPS architecture itself.  These extra
+instructions are usually referred to as ``macro'' instructions
+@footnote{The term ``macro'' is somewhat overloaded here, since
+these macros have no relation to those defined by @code{.macro},
+@pxref{Macro,, @code{.macro}}.}.  nanoMIPS assembler continues
+support for many traditionally supported instructions.
+
+Some nanoMIPS macro instructions extend an underlying architectural
+instruction while others are entirely new.  An example of the former
+type is @code{and}, which allows the third operand to be either a
+register or an arbitrary immediate value.  Examples of the latter type
+include @code{bgt}, which branches to the third operand when the
+first operand is greater than the second operand.
+
+One of the most common extensions provided by macros is to expand memory
+offsets to the full address range (32 or 64 bits) and to allow symbolic
+offsets such as @samp{my_data + 4} to be used in place of integer
+constants.  For example, the architectural instruction @code{lbu} allows
+only an unsigned 12-bit offset, whereas the macro @code{lbu} allows code
+such as @samp{lbu $a0,array+32769}.  The implementation of these symbolic
+offsets depends on several factors, such as whether the assembler is
+generating SVR4-style PIC (selected by @option{-mpic}, @pxref{nanoMIPS
+Options,, Assembler options}), the size of symbols,
+and the small data limit (@pxref{nanoMIPS Small Data,, Controlling the
+use of small data accesses}).
+
+@table @code
+@item gprel_p(label)
+TRUE if label can be referenced relative to $gp
+@item local_p(label)
+TRUE if label is locally scoped
+@end table
+
+@table @code
+@item @r{Instruction}
+@multitable @columnfractions 0.3 0.4 0.3
+@item Condition
+@tab Expansion
+@tab Remarks
+@end multitable
+
+@item abs rd,rt
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rd <> rt
+@end verbatim
+
+@tab
+@verbatim
+move rd,rt
+bgezc rt,0f
+subu rd,0,rt
+0:
+@end verbatim
+@tab
+
+@item
+@verbatim
+rd == rt
+@end verbatim
+
+@tab
+@verbatim
+bgezc rd,0f
+subu rd,0,rd
+0:
+@end verbatim
+
+@tab
+@end multitable
+@item la rd,ofst(rs)
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+-4095 <= ofst <= 65535
+@end verbatim
+
+@tab
+@verbatim
+addiu rd,rs,ofst
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+li rd,ofst
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs <> 0
+&& rs <> rd
+@end verbatim
+
+@tab
+@verbatim
+li rd,ofst
+addu rd,rd,rs
+@end verbatim
+
+@tab
+@c FIXME: alternative expansion
+@c move rd,rs
+@c addiu48 rd,ofst8 bytes irrespective of rd/rs are gpr3 or gpr4
+@item
+@verbatim
+rs <> 0
+&& rs == rd
+&& NMS
+@end verbatim
+
+@tab
+@verbatim
+li $at,ofst
+addu rd,$at,rs
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs <> 0
+&& rs == rd
+@end verbatim
+
+@tab
+@verbatim
+addiu[48] rd,rd,ofst
+@end verbatim
+
+@tab
+@end multitable
+@anchor{x_la_label}
+@item la rd,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@tab
+@item
+@verbatim
+(no-PIC
+ || local_p(label))
+&& gprel_p(label)
+&& (cmodel=[medium|auto])
+@end verbatim
+
+@tab
+@verbatim
+addiu rd,gp,%gp_rel(label)
+@end verbatim
+
+@tab
+@item
+@verbatim
+(no-PIC
+ || local_p(label))
+&& NMS
+@end verbatim
+
+@tab
+@verbatim
+aluipc rd,%pcrel_hi(label)
+addiu rd,%pcrel_lo(label)
+@end verbatim
+
+@tab
+@item
+@verbatim
+no-PIC
+|| local_p(label)
+@end verbatim
+
+@tab
+@verbatim
+addiupc[48] rd,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& (cmodel=[medium|auto]
+   || linkrelax)
+@end verbatim
+
+@tab
+@verbatim
+lw rd,%got_disp(label)($gp)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& cmodel=large
+@end verbatim
+
+@tab
+@verbatim
+aluipc rd,%got_pcrel_hi(label)
+lw rd,%got_lo(label)(rd)
+@end verbatim
+
+@tab
+@item
+@tab
+@tab
+@end multitable
+@item jal label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+no-PIC
+@end verbatim
+
+@tab
+@verbatim
+balc label
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+@end verbatim
+
+@tab
+@verbatim
+lw $at,%got_disp(label)($gp)
+jalrc $at
+@end verbatim
+
+@tab
+@end multitable
+@item jraddiusp imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+-4095 <= imm <= 65535
+&& (imm%16 != 0)
+@end verbatim
+
+@tab
+@verbatim
+addiu $sp,$sp,imm
+jrc $ra
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li at,imm
+addu sp,sp,at
+jrc ra
+@end verbatim
+
+@tab
+@end multitable
+@anchor{x_macro_li}@item li rd,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+-1 <= imm <= 126
+@end verbatim
+
+@tab
+@verbatim
+li rd,imm
+@end verbatim
+
+@tab
+@item
+@verbatim
+-4095 <= imm <= 65535
+@end verbatim
+
+@tab
+@verbatim
+addiu rd,$0,imm
+@end verbatim
+
+@tab
+@item
+@verbatim
+NMS
+&& (imm & 0xfff) == 0
+@end verbatim
+
+@tab
+@verbatim
+lui rd,%hi(imm)
+@end verbatim
+
+@tab
+@item
+@verbatim
+NMS
+@end verbatim
+
+@tab
+@verbatim
+lui rd,%hi(imm)
+addiu rd,%lo(imm)
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li[48] rd,imm
+@end verbatim
+
+@tab
+@end multitable
+@item li.s rd,immfloat
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@xref{x_macro_li,,li}.
+@end multitable
+@item li.d rd,immdouble
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+not NMS
+@tab
+@verbatim
+li48 rd+1,%hi32(immdouble)
+li48 rd,%lo32(immdouble)
+@end verbatim
+@tab
+@item
+-Gx, x >=8
+@tab
+@verbatim
+  ld rd, label
+  .sdata:
+label:
+  .dword immdouble
+@end verbatim
+@tab
+@xref{x_ld_label,,ld from label}.
+@item
+-Gx, x < 8
+@tab
+@verbatim
+  ld rd, label
+  .rodata:
+label:
+  .dword immdouble
+@end verbatim
+@tab
+@xref{x_ld_label,,ld from label}.
+@end multitable
+@item nor rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+li $at,imm
+nor rt,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item rol rd,rs,rt
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rs == rt
+@end verbatim
+
+@tab
+@verbatim
+negu $at,rt
+rorv rd,rs,$at
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs <> rt
+@end verbatim
+
+@tab
+@verbatim
+negu rd,rt
+rorv rd,rs,rd
+@end verbatim
+
+@tab
+@end multitable
+@item rol rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+ror rd,rs,rot5
+@end verbatim
+
+@tab
+imm5 = imm & 0x1f@*
+rot5 = (32 - imm5) & 0x1f
+@end multitable
+@item ror rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+ror rd,rs,imm5
+@end verbatim
+
+@tab
+imm5 = imm & 0x1f
+@end multitable
+@item rotl rd,rs,rt
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rs == rt
+@end verbatim
+
+@tab
+@verbatim
+negu $at,rt
+rorv rd,rs,$at
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs <> rt
+@end verbatim
+
+@tab
+@verbatim
+negu rd,rt
+rorv rd,rs,rd
+@end verbatim
+
+@tab
+@end multitable
+@item rotl rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+ror rd,rs,rot5
+@end verbatim
+
+@tab
+imm5 = imm & 0x1f@*
+rot5 = (32 - imm5) & 0x1f
+@end multitable
+@item sge rd,rs,rt
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+slt rd,rs,rt
+xori rd,rd,1
+@end verbatim
+
+@tab
+@end multitable
+@item sge rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+0 <= imm <= 4095
+@end verbatim
+
+@tab
+@verbatim
+slti rd,rs,imm
+xori rd,rd,1
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+slt rd,rs,rt
+xori rd,rd,1
+@end verbatim
+
+@tab
+@end multitable
+@item sgeu rd,rs,rt
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+sltu rd,rs,rt
+xori rd,rd,1
+@end verbatim
+
+@tab
+@end multitable
+@item sgeu rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+0 <= imm <= 4095
+@end verbatim
+
+@tab
+@verbatim
+sltiu rd,rs,imm
+xori rd,rd,1
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+sltu rd,rs,rt
+xori rd,rd,1
+@end verbatim
+
+@tab
+@end multitable
+@item sgt rd,rs,rt
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+slt rd,rt,rs
+@end verbatim
+
+@tab
+@end multitable
+@item sgt rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+li $at,imm
+slt rd,$at,rs
+@end verbatim
+
+@tab
+@end multitable
+@item sgtu rd,rs,rt
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+sltu rd,rt,rs
+@end verbatim
+
+@tab
+@end multitable
+@item sgtu rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+li $at,imm
+sltu rd,$at,rs
+@end verbatim
+
+@tab
+@end multitable
+@item sle rd,rs,rt
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+slt rd,rt,rs
+xori rd,rd,1
+@end verbatim
+
+@tab
+@end multitable
+@item sle rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+li $at,imm
+slt rd,$at,rs
+xori rd,rd,1
+@end verbatim
+
+@tab
+@end multitable
+@item sleu rd,rs,rt
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+sltu rd,rt,rs
+xori rd,rd,1
+@end verbatim
+
+@tab
+@end multitable
+@item sleu rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+li $at,imm
+sltu rd,$at,rs
+xori rd,rd,1
+@end verbatim
+
+@tab
+@end multitable
+@item seq rd,rs,rt
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+sltiu rd,rt,1
+@end verbatim
+
+@tab
+@item
+@verbatim
+rt == 0
+@end verbatim
+
+@tab
+@verbatim
+sltiu rd,rs,1
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+xor rd,rs,rt
+sltiu rd,rd,1
+@end verbatim
+
+@tab
+@end multitable
+@item seq rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm == 0
+@end verbatim
+
+@tab
+@verbatim
+sltiu rd,rs,1
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+move rd,$0
+@end verbatim
+
+@tab
+Always CLEAR
+@item
+@verbatim
+imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+xori rd,rs,imm
+sltiu rd,rd,1
+@end verbatim
+
+@tab
+@item
+@verbatim
+-8192 < imm < 0
+@end verbatim
+
+@tab
+@verbatim
+addiu rd,rs,-imm
+sltiu rd,rd,1
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+xor rd,rs,$at
+sltiu rd,rd,1
+@end verbatim
+
+@tab
+@end multitable
+@item sne rd,rs,rt
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+sltu,rd,$0,rt
+@end verbatim
+
+@tab
+@item
+@verbatim
+rt == 0
+@end verbatim
+
+@tab
+@verbatim
+sltu rd,$0,rs
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+xor rd,rs,rt
+sltu rd,$0,rd
+@end verbatim
+
+@tab
+@end multitable
+@item sne rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm == 0
+@end verbatim
+
+@tab
+@verbatim
+sltu rd,$0,rs
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+addiu rd,$0,1
+@end verbatim
+
+@tab
+Always SET
+@item
+@verbatim
+imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+xori rd,rs,imm
+sltu rd,$0,rd
+@end verbatim
+
+@tab
+@item
+@verbatim
+-8192 < imm < 0
+@end verbatim
+
+@tab
+@verbatim
+addiu rd,rs,-imm
+sltu rd,$0,rd
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+xor rd,rs,$at
+sltu rd,$0,rd
+@end verbatim
+
+@tab
+@end multitable
+@item slt rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+0 < imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+slti rd,rs,imm
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+slt rd,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item sltu rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+sltiu rd,rs,imm
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+slt rd,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item bgt rs,rt,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rt == 0
+@end verbatim
+
+@tab
+@verbatim
+bgtzc rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+bltzc rt,label
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+slt $i,rs,rt
+bnezc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item bgt rs,imm,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm == -1
+@end verbatim
+
+@tab
+@verbatim
+beqzc rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm == 0
+@end verbatim
+
+@tab
+@verbatim
+bgtzc rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm > GPR_SMAX
+@end verbatim
+
+@tab
+@verbatim
+nop
+@end verbatim
+
+@tab
+Always false
+@item
+@verbatim
+imm == GPR_SMIN
+@end verbatim
+
+@tab
+@verbatim
+bc label
+@end verbatim
+
+@tab
+Always true
+@item
+@verbatim
+0 < imm < 127
+@end verbatim
+
+@tab
+@verbatim
+bgeic rs,imm+1,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 4095
+@end verbatim
+
+@tab
+@verbatim
+slti $at,rs,imm+1
+beqzc $at,label
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm+1
+slt $at,rs,$at
+beqzc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item bgtu rs,rt,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rt == 0
+@end verbatim
+
+@tab
+@verbatim
+bnezc $rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+nop
+@end verbatim
+
+@tab
+Always false
+@item else
+
+@tab
+@verbatim
+sltu $at,rs,rs
+bnezc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item bgtu rs,imm,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+nop
+@end verbatim
+
+@tab
+Always false
+@item
+@verbatim
+imm == -1
+&& 32-bit
+@end verbatim
+
+@tab
+@verbatim
+nop
+@end verbatim
+
+@tab
+Always false
+@item
+@verbatim
+imm == 0
+@end verbatim
+
+@tab
+@verbatim
+bnezc $rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+0 < imm < 127
+@end verbatim
+
+@tab
+@verbatim
+bgeiuc rs,imm+1,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 4095
+@end verbatim
+
+@tab
+@verbatim
+sltiu $at,rs,imm+1
+beqzc $at,label
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm+1
+sltu $at,rs,$at
+beqzc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item ble rs,rt,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rt == 0
+@end verbatim
+
+@tab
+@verbatim
+blezc rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+bgezc rt,label
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+slt $at,rs,rs
+beqzc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item ble rs,imm,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm > GPR_SMAX
+@end verbatim
+
+@tab
+@verbatim
+bc label
+@end verbatim
+
+@tab
+Always true
+@item
+@verbatim
+imm == -1
+@end verbatim
+
+@tab
+@verbatim
+bltzc rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm == 0
+@end verbatim
+
+@tab
+@verbatim
+blezc rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+0 < imm < 127
+@end verbatim
+
+@tab
+@verbatim
+bltic rs,imm+1,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 4095
+@end verbatim
+
+@tab
+@verbatim
+slti $at,rs,imm+1
+bnezc $at,label
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm+1
+slt $at,rs,$at
+bnezc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item bleu rs,rt,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rt == 0
+@end verbatim
+
+@tab
+@verbatim
+beqzc rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+bc label
+@end verbatim
+
+@tab
+Always true
+@item else
+
+@tab
+@verbatim
+sltu $at,rs,rt
+beqzc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item bleu rs,imm,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm == -1
+&& 32-bit
+@end verbatim
+
+@tab
+@verbatim
+bc label
+@end verbatim
+
+@tab
+Always true
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+bc label
+@end verbatim
+
+@tab
+Always true
+@item
+@verbatim
+imm == 0
+@end verbatim
+
+@tab
+@verbatim
+beqzc rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+0 < imm < 127
+@end verbatim
+
+@tab
+@verbatim
+bltiuc rs,imm+1,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 4095
+@end verbatim
+
+@tab
+@verbatim
+slti $at,rs,imm+1
+bnezc $at,label
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm+1
+slt $at,rs,$at
+bnezc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item bgezal rs,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+ bltzc rs,0fbalc label
+0:
+@end verbatim
+
+@tab
+@end multitable
+@item bltzal rs,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+bgezc rs,0fbalc label
+0:
+@end verbatim
+
+@tab
+@end multitable
+@item Immediate supported - if immediate doesn't fit, load to register
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@tab
+@end multitable
+@item add rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+non-NMS
+@end verbatim
+
+@tab
+@verbatim
+li $at,imm
+add rd,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item addu rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+-4095 <= imm <= 65535
+@end verbatim
+
+@tab
+@verbatim
+addiu rd,rs,imm
+@end verbatim
+
+@tab
+@item
+@verbatim
+non-NMS
+&& rd == rs
+@end verbatim
+
+@tab
+@verbatim
+addiu[48] rd,rd,imm
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+addu rd,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item and rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+0 <= imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+andi rd,rs,imm
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 0
+|| imm >= 4096
+@end verbatim
+
+@tab
+@verbatim
+li $at,imm
+and rd,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item sub rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+non-NMS
+@end verbatim
+
+@tab
+@verbatim
+li $at,imm
+sub rt,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item subu rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+-4095 <= imm <= 65535
+@end verbatim
+
+@tab
+@verbatim
+addiu rt,rs,-imm
+@end verbatim
+
+@tab
+@item
+@verbatim
+non-NMS
+&& rd == rs
+@end verbatim
+
+@tab
+@verbatim
+addiu[48] rt,rs,-imm
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+subu rt,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item beq rs,imm,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+0 < imm <= 127
+@end verbatim
+
+@tab
+@verbatim
+beqic rs,imm,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+else
+@end verbatim
+
+@tab
+@verbatim
+li $at,imm
+beq rs,$at,label
+@end verbatim
+
+@tab
+@end multitable
+@item bge rs,imm,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+0 < imm <= 127
+@end verbatim
+
+@tab
+@verbatim
+bgeic rs,imm,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+slti $at,rs,imm
+beqzc $at,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 0
+|| imm >= 4096
+@end verbatim
+
+@tab
+@verbatim
+li $at,imm
+slt $at,rs,$at
+beqzc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item bgeu rs,imm,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm <= 127
+@end verbatim
+
+@tab
+@verbatim
+bgeiuc rs,imm,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+sltiu $at,rs,imm
+beqzc $at,label
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+sltu $at,rs,$at
+beqzc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item blt rs,imm,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm == 0
+@end verbatim
+
+@tab
+@verbatim
+bltzc rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm == 1
+@end verbatim
+
+@tab
+@verbatim
+blezc rs,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+0 < imm <= 127
+@end verbatim
+
+@tab
+@verbatim
+bltic rs,imm,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+slti $at,rs,imm
+bnezc $at,label
+@end verbatim
+
+@tab
+@item else
+@verbatim
+imm < 0
+|| imm >= 4096
+@end verbatim
+
+@tab
+@verbatim
+li $at,imm
+slt $at,rs,$at
+bnezc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item bltu rs,imm,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm <= 127
+@end verbatim
+
+@tab
+@verbatim
+bltiuc rs,imm,label
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+sltiu $at,rs,imm
+bnezc $at,label
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+sltu $at,rs,$at
+bnezc $at,label
+@end verbatim
+
+@tab
+@end multitable
+@item bne rs,imm,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+0 < imm <= 127
+@end verbatim
+
+@tab
+@verbatim
+bneic rs,imm,label
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+bnec rs,$at,label
+@end verbatim
+
+@tab
+@end multitable
+@item or rt,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+0 <= imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+ori rt,rs,imm
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 0
+|| imm >= 4096
+@end verbatim
+
+@tab
+@verbatim
+li $at,imm
+or rt,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item slt rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+0 <= imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+slti rd,rs,imm
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+slt rd,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item sltu rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+sltiu rd,rs,imm
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+slt rd,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item xor rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+0 <= imm < 4096
+@end verbatim
+
+@tab
+@verbatim
+xori rt,rs,imm
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm < 0
+|| imm >= 4096
+@end verbatim
+
+@tab
+@verbatim
+li $at,imm
+xor rt,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item teq rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+non-NMS
+@end verbatim
+
+@tab
+@verbatim
+li $at,imm
+teq rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item tne rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+non-NMS
+@end verbatim
+
+@tab
+@verbatim
+li $at,imm
+tne rs,$at
+@end verbatim
+
+@tab
+@item
+@tab
+@tab
+@end multitable
+@anchor{x_cache_ofst}@item cache hint,ofst(rs)
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+-256 <= ofst <= 255
+@end verbatim
+
+@tab
+@verbatim
+cache op,ofst(rs)
+@end verbatim
+
+@tab
+@item
+@verbatim
+-4095 <= ofst <= 65535
+@end verbatim
+
+@tab
+@verbatim
+addiu $at,rs,ofst
+cache op,0($at)
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,ofst
+addu $at,$at,rs
+cache op,0(rs)
+@end verbatim
+
+@tab
+@end multitable
+@item cachee hint,ofst(rs)
+@multitable @columnfractions 1 0 0
+@item @xref{x_cache_ofst,,cache operation at offset}.
+@end multitable
+@anchor{x_pref_ofst}@item pref hint,ofst(rs)
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+-256 <= ofst <= 4095
+@end verbatim
+
+@tab
+@verbatim
+pref op,ofst(rs)
+@end verbatim
+
+@tab
+@item
+@verbatim
+-4095 <= ofst <= 65535
+@end verbatim
+
+@tab
+@verbatim
+addiu $at,rs,ofst
+pref op,0($at)
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,ofst
+addu $at,$at,rs
+pref op,0(rs)
+@end verbatim
+
+@tab
+@item
+@tab
+@tab
+@end multitable
+@item prefe hint,ofst(rs)
+@multitable @columnfractions 1
+@item @xref{x_pref_ofst,,pre-fetch operation at offset}.
+@end multitable
+@anchor{x_lw_ofst}@item lw rd,ofst(rs)
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+-255 <= ofst <= 4095
+@end verbatim
+
+@tab
+@verbatim
+lw rd,ofst(rs)
+@end verbatim
+
+@tab
+@item
+@verbatim
+-4095 <= ofst <= 65535
+&& rd <> rs
+@end verbatim
+
+@tab
+@verbatim
+addiu rd,rs,ofst
+lw rd,0(rd)
+@end verbatim
+
+@tab
+@item
+@verbatim
+-4095 <= ofst <= 65535
+&& rd == rs
+@end verbatim
+
+@tab
+@verbatim
+addiu rd,rd,ofst
+lw rd,0(rd)
+@end verbatim
+
+@tab
+@item
+@verbatim
+rd == rs
+@end verbatim
+@tab
+@verbatim
+addiu[48] rs,rs,ofst
+lw rd,0(rs)
+@end verbatim
+@tab
+@item
+@verbatim
+rd <> rs
+&& NMS
+@end verbatim
+
+@tab
+@verbatim
+lui rd,%hi(ofst)
+addu rd,rd,rs
+lw rd,%lo(ofst)(rd)
+@end verbatim
+@tab
+@item
+@verbatim
+else
+@end verbatim
+
+@tab
+@verbatim
+lui $at,%hi(ofst)
+addu $at,$at,rs
+lw rd,%lo(ofst)($at)
+@end verbatim
+
+@tab
+@end multitable
+@anchor{x_lw_label}@item lw rd,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+(no-PIC
+ || local_p(label))
+&& gprel_p(label)
+&& (cmodel=[medium|auto])
+@end verbatim
+
+@tab
+@verbatim
+lw rd,%gprel(label)($gp)
+@end verbatim
+
+@tab
+@item
+@verbatim
+(no-PIC
+ || local_p(label))
+&& rd == 0
+&& NMS
+@end verbatim
+
+@tab
+@verbatim
+aluipc $at,%pcrel_hi(label)
+lw rd,%lo(label)($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+(no-PIC
+ || local_p(label))
+&& rd <> 0
+&& NMS
+@end verbatim
+
+@tab
+@verbatim
+aluipc rd,%pcrel_hi(label)
+lw rd,%lo(label)(rd)
+@end verbatim
+
+@tab
+@item
+@verbatim
+no-PIC
+|| local_p(label)
+@end verbatim
+
+@tab
+@verbatim
+lwpc rd,label
+@end verbatim
+
+@tab
+LW only, not applicable for sub-word loads
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& rd == 0
+&& (cmodel=[auto|medium]
+   || linkrelax)
+@end verbatim
+
+@tab
+@verbatim
+lw $at,%got_disp(label)($gp)
+lw rd,0($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& rd == 0
+&& !local_p(label)
+&& cmodel=large
+&& NMS
+@end verbatim
+
+@tab
+@verbatim
+aluipc $at,%got_pcrel_hi(label)
+lw at,%got_lo(label)($at)
+lw rd,0($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& rd == 0
+&& cmodel=large
+@end verbatim
+
+@tab
+@verbatim
+lwpc $at,%got_pcrel32(label)
+lw rd,0($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& rd <> 0
+&& (cmodel=[auto|medium]
+   || linkrelax)
+@end verbatim
+
+@tab
+@verbatim
+lw rd,%got_disp(label)($gp)
+lw rd,0(rd)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& rd <> 0
+&& cmodel=large
+&& NMS
+@end verbatim
+
+@tab
+@verbatim
+aluipc rd,%got_pcrel_hi(label)
+lw rd,%got_lo(label)(rd)
+lw rd,0(rd)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& rd <> 0
+&& cmodel=large
+@end verbatim
+
+@tab
+@verbatim
+lwpc rd,%got_pcrel32(label)
+lw rd,0(rd)
+@end verbatim
+
+@tab
+@end multitable
+@item lwu rd,ofst(rs)
+@itemx lb rd,ofst(rs)
+@itemx lbu rd,ofst(rs)
+@itemx lh rd,ofst(rs)
+@itemx lhu rd,ofst(rs)
+@itemx ulh rd,ofst(rs)
+@itemx ulw rd,ofst(rs)
+@multitable @columnfractions 1
+@item @xref{x_lw_ofst,,lw from ofst}.
+@end multitable
+@item lwu rd,label
+@itemx lb rd,label
+@itemx lbu rd,label
+@itemx lh rd,label
+@itemx lhu rd,label
+@itemx ulh rd,label
+@itemx ulw rd,label
+@multitable @columnfractions 1
+@item @xref{x_lw_label,,lw from label}.
+@end multitable
+@item ld rd,ofst(rs)
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+-252 <= ofst < 4092
+&& rd == rs
+@end verbatim
+
+@tab
+@verbatim
+lw rd+1,ofst+4(rs)
+lw rd,ofst(rs)
+@end verbatim
+
+@tab
+@item
+@verbatim
+-252 <= ofst < 4092
+&& rd <> rs
+@end verbatim
+
+@tab
+@verbatim
+lw rd,ofst(rs)
+lw rd+1,ofst+4(rs)
+@end verbatim
+
+@tab
+@item
+@verbatim
+-4095 <= ofst <= 65535
+@end verbatim
+
+@tab
+@verbatim
+addiu $at,rs,ofst
+lw rd,0($at)
+lw rd+1,4($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+%hi(ofst) == %hi(ofst+4)
+&& rs == 0
+@end verbatim
+
+@tab
+@verbatim
+lui $at,%hi(ofst)
+lw rd,%lo(ofst)($at)
+lw rd+1,%lo(ofst+4)($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+%hi(ofst) == %hi(ofst+4)
+&& rs <> 0
+@end verbatim
+
+@tab
+@verbatim
+lui $at,%hi(ofst)
+addu $at,$at,rs
+lw rd,%lo(ofst)($at)
+lw rd+1,%lo(ofst+4)($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+li $at,ofst
+lw rd,0($at)
+lw rd+1,4($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs <> 0
+@end verbatim
+
+@tab
+@verbatim
+li $at,ofst
+addu $at,$at,rs
+lw rd,0($at)
+lw rd+1,4($at)
+@end verbatim
+
+@tab
+@end multitable
+@anchor{x_ld_label}@item ld rd,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+(non-PIC
+ || local_p(label))
+&& gprel_p(label)
+&& cmodel=[medium|auto]
+@end verbatim
+
+@tab
+@verbatim
+lw rd,%gprel(label)($gp)
+lw rd+1,%gprel(label+4)($gp)
+@end verbatim
+
+@tab
+@item
+@verbatim
+(non-PIC
+ || local_p(label))
+&& NMS
+@end verbatim
+
+@tab
+@verbatim
+aluipc $at,%pcrel_hi(label)
+lw rd,%lo(label)($at)
+lw rd+1,%lo(label+4)($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+(non-PIC
+ || local_p(label))
+@end verbatim
+
+@tab
+@verbatim
+lwpc rd,label
+lwpc rd+1,label+4
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& (cmodel=[auto|medium]
+   || linkrelax)
+@end verbatim
+
+@tab
+@verbatim
+lw $at,%got_disp(label)($gp)
+lw rd,0($at)
+lw rd+1,4($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& cmodel=large
+&& NMS
+@end verbatim
+
+@tab
+@verbatim
+lui $at,%got_pcrel_hi(label)
+lw rd,%got_lo(label)($at)
+lw rd+1,%got_lo(label+4)($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& cmodel=large
+@end verbatim
+
+@tab
+@verbatim
+lwpc rd,%got_pcrel32(label)($at)
+lwpc rd+1,%got_pcrel32(label+4)($at)
+@end verbatim
+
+@tab
+@item
+@tab
+@tab
+@end multitable
+@anchor{x_ll_ofst}@item ll rd,ofst(rs)
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+-256 <= ofst < 255
+@end verbatim
+
+@tab
+@verbatim
+ll rd,ofst(rs)
+@end verbatim
+
+@tab
+@item
+@verbatim
+-4095 <= ofst <= 65535
+&& rd <> rs
+@end verbatim
+
+@tab
+@verbatim
+addiu rd,rs,ofst
+ll rd,0(rd)
+@end verbatim
+
+@tab
+@item
+@verbatim
+-4095 <= ofst <= 65535
+&& rd == rs
+@end verbatim
+
+@tab
+@verbatim
+addiu rd,rd,ofst
+ll rd,0(rd)
+@end verbatim
+
+@tab
+@item
+@verbatim
+rd <> rs
+@end verbatim
+
+@tab
+@verbatim
+li rd,ofst
+addu rd,rd,rs
+ll rd,0(rd)
+@end verbatim
+
+@tab
+@item
+@verbatim
+rd == rs
+@end verbatim
+
+@tab
+@verbatim
+li $at,ofst
+addu $at,$at,rs
+ll rd,0($at)
+@end verbatim
+
+@tab
+@end multitable
+@anchor{x_ll_label}@item ll rd,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rd == 0
+@end verbatim
+
+@tab
+@verbatim
+la $at,label
+ll rd,0($at)
+@end verbatim
+
+@tab
+@xref{x_la_label,,la of label}.
+@item
+@verbatim
+rd <> 0
+@end verbatim
+
+@tab
+@verbatim
+la rd,label
+ll rd,0(rd)
+@end verbatim
+@tab
+@xref{x_la_label,,la of label}.
+@end multitable
+@item lle rd,ofst(rs)
+@multitable @columnfractions 1
+@item @xref{x_ll_ofst,,ll from offset}.
+@end multitable
+@item lle rd,label
+@multitable @columnfractions 1
+@item @xref{x_ll_label,,ll from label}.
+@end multitable
+@anchor{x_llwp_ofst}@item llwp rd,ru,ofst(rs)
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rs == 0 && rd != 0
+@end verbatim
+@tab
+@verbatim
+li rd,ofst
+llwp rd,ru,(rd)
+@end verbatim
+@tab
+@item
+@verbatim
+rs == 0 && ru != 0
+@end verbatim
+@tab
+@verbatim
+li ru,ofst
+llwp rd,ru,(ru)
+@end verbatim
+@tab
+@item
+@verbatim
+-4095 <= ofst <= 65535
+&& rd != 0
+@end verbatim
+@tab
+@verbatim
+addiu rd,rs,ofst
+llwp rd,ru,(rd)
+@end verbatim
+@tab
+@item
+@verbatim
+-4095 <= ofst <= 65535
+&& ru != 0
+@end verbatim
+@tab
+@verbatim
+addiu ru,rs,ofst
+llwp rd,ru,(ru)
+@end verbatim
+@tab
+@item
+@verbatim
+rd != 0
+@end verbatim
+@tab
+@verbatim
+li rd,ofst
+addiu rd,rd,rs
+llwp rd,ru,(rd)
+@end verbatim
+@tab
+@item
+@verbatim
+ru != 0
+@end verbatim
+@tab
+@verbatim
+li ru,ofst
+addiu ru,ru,rs
+llwp rd,ru,(ru)
+@end verbatim
+@tab
+@end multitable
+@anchor{x_llwp_label}@item llwp rd,ru,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rd != 0
+@end verbatim
+@tab
+@verbatim
+la rd,label
+llwp rd,ru,(rd)
+@end verbatim
+@tab
+@xref{x_la_label,,la of label}.
+@item
+@verbatim
+ru != 0
+@end verbatim
+@tab
+@verbatim
+la ru,label
+llwp rd,ru,(ru)
+@end verbatim
+@tab
+@xref{x_la_label,,la of label}.
+@end multitable
+@item llwpe rd,ru,ofst(rs)
+@multitable @columnfractions 1
+@item @xref{x_llwp_ofst,,llwp from offset}.
+@item
+@end multitable
+@item llwpe rd,ru,label
+@multitable @columnfractions 1
+@item @xref{x_llwp_label,,llwp from label}.
+@item
+@end multitable
+@anchor{x_sw_ofst}@item sw rd,ofst(rs)
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+-256 <= ofst < 4095
+@end verbatim
+
+@tab
+@verbatim
+sw rd,ofst(rs)
+@end verbatim
+
+@tab
+@item
+@verbatim
+-4095 <= ofst <= 65535
+&& rd <> rs
+@end verbatim
+
+@tab
+@verbatim
+addiu $at,rs,ofst
+sw rd,0($at)
+@end verbatim
+
+@tab
+@item
+@tab
+@verbatim
+li $at,%hi(ofst)
+addu $at,$at,rs
+sw rd,%lo(ofst)($at)
+@end verbatim
+
+@tab
+@item
+@tab
+@verbatim
+li $at,%hi(ofst)
+addu $at,$at,rs
+sw rd,%lo(ofst)($at)
+@end verbatim
+
+@tab
+@end multitable
+@anchor{x_sw_label}@item sw rd,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+(no-PIC
+ || local_p(label))
+&& gprel_p(label)
+&& cmodel=[medium|auto]
+@end verbatim
+
+@tab
+@verbatim
+sw rd,%gprel(label)($gp)
+@end verbatim
+
+@tab
+@item
+@verbatim
+(no-PIC
+ || local_p(label))
+&& NMS
+@end verbatim
+
+@tab
+@verbatim
+aluipc $at,%pcrel_hi(label)($gp)
+sw rd,%lo(label)($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+(no-PIC
+ || local_p(label))
+@end verbatim
+
+@tab
+@verbatim
+swpc rd,label
+@end verbatim
+
+@tab
+SW only, not applicable for sub-word stores
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& (cmodel=[auto|medium]
+   || linkrelax)
+@end verbatim
+
+@tab
+@verbatim
+lw $at,%got_disp(label)($gp)
+sw rd,0($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& cmodel=large
+&& NMS
+@end verbatim
+
+@tab
+@verbatim
+aluipc $at,%got_pcrel_hi(label)
+lw $at,%got_lo(label)($at)
+lw rd,0($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+&& cmodel=large
+@end verbatim
+
+@tab
+@verbatim
+lwpc $at,label
+lw rd,0($at)
+@end verbatim
+
+@tab
+@end multitable
+@item sb rd,ofst(rs)
+@itemx sh rd,ofst(rs)
+@itemx ush rd,ofst(rs)
+@itemx usw rd,ofst(rs)
+@multitable @columnfractions 1
+@item @xref{x_sw_ofst,,sw to offset}.
+@item
+@end multitable
+@item sc rd,ofst(rs)
+@itemx sce rd,ofst(rs)
+@multitable @columnfractions 1
+@item @xref{x_ll_ofst,,ll from offset}.
+@end multitable
+@item sb rd,label
+@itemx sh rd,label
+@itemx ush rd,label
+@itemx usw rd,label
+@multitable @columnfractions 1
+@item @xref{x_sw_label,,sw to label}.
+@item
+@end multitable
+@item sd rd,label
+@itemx uld rd,label
+@itemx usd rd,label
+@multitable @columnfractions 1
+@item @xref{x_ld_label,,ld from label}.
+@end multitable
+@item sc rd,label
+@itemx sce rd,label
+@multitable @columnfractions 1
+@item @xref{x_ll_label,,ll from label}.
+@end multitable
+@anchor{x_scwp_ofst}@item scwp rd,ru,ofst(rs)
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+rs == 0
+@end verbatim
+@tab
+@verbatim
+li $at,ofst
+scwp rd,ru,($at)
+@end verbatim
+@tab
+@item
+@verbatim
+-4095 <= ofst <= 65535
+@end verbatim
+@tab
+@verbatim
+addiu $at,rs,ofst
+scwp rd,ru,($at)
+@end verbatim
+@tab
+@item else
+@tab
+@verbatim
+li $at,ofst
+addiu $at,$at,rs
+scwp rd,ru,($at)
+@end verbatim
+@tab
+@end multitable
+@anchor{x_scwp_label}@item scwp rd,ru,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+la $at,label
+scwp rd,ru,($at)
+@end verbatim
+@tab
+@xref{x_la_label,,la of label}.
+@end multitable
+@item scwpe rd,ru,ofst(rs)
+@multitable @columnfractions 1
+@item @xref{x_scwp_ofst,,scwp to offset}.
+@item
+@end multitable
+@item scwpe rd,ru,label
+@multitable @columnfractions 1
+@item @xref{x_scwp_label,,scwp to label}.
+@end multitable
+@item Division & Multiplication
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@tab
+@end multitable
+@item div rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm == 0
+@end verbatim
+
+@tab
+@verbatim
+break
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm == 1
+@end verbatim
+
+@tab
+@verbatim
+move rd,rs
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm == -1
+@end verbatim
+
+@tab
+@verbatim
+negu rd,rs
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+div rd,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item divu rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm == 0
+@end verbatim
+
+@tab
+@verbatim
+break
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm == 1
+@end verbatim
+
+@tab
+@verbatim
+move rd,rs
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+divu rd,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item rem rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+imm == 0
+@end verbatim
+
+@tab
+@verbatim
+break
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm == 1
+@end verbatim
+
+@tab
+@verbatim
+move rd,$0
+@end verbatim
+
+@tab
+@item
+@verbatim
+imm == -1
+@end verbatim
+
+@tab
+@verbatim
+move rd,$0
+@end verbatim
+
+@tab
+@item else
+
+@tab
+@verbatim
+li $at,imm
+mod rd,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item mul rd,rs,imm
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@verbatim
+li $at,imm
+mul rd,rs,$at
+@end verbatim
+
+@tab
+@end multitable
+@item ofst operations
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@tab
+@end multitable
+@item ld rd,ofst(rs)
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+0 <= ofst < 4092
+&& rd == rs
+@end verbatim
+
+@tab
+@verbatim
+lw rd+1,ofst+4(rs)
+lw rd,ofst(rs)
+@end verbatim
+
+@tab
+@item
+@verbatim
+0 <= ofst < 4092
+&& rd <> rs
+@end verbatim
+
+@tab
+@verbatim
+lw rd,ofst(rs)
+lw rd+1,ofst+4(rs)
+@end verbatim
+
+@tab
+@item
+@verbatim
+-4095 <= ofst < 65536
+@end verbatim
+
+@tab
+@verbatim
+addiu $at,rs,ofst
+lw rd,0($at)
+lw rd+1,4($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+%hi(ofst) == %hi(ofst+4)
+&& rs == 0
+@end verbatim
+
+@tab
+@verbatim
+lui $at,%hi(ofst)
+lw rd,%lo(ofst)($at)
+lw rd+1,%lo(ofst+4)($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+%hi(ofst) == %hi(ofst+4)
+&& rs <> 0
+@end verbatim
+
+@tab
+@verbatim
+lui $at,%hi(ofst)
+addu $at,$at,rs
+lw rd,%lo(ofst)($at)
+lw rd+1,%lo(ofst+4)($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+li $at,ofst
+lw rd,0($at)
+lw rd+1,4($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+rs == 0
+@end verbatim
+
+@tab
+@verbatim
+li $at,ofst
+addu $at,$at,rs
+lw rd,0($at)
+lw rd+1,4($at)
+@end verbatim
+
+@tab
+@end multitable
+@item ld rd,label
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+no-PIC
+&& gprel_p(label)
+
+@tab
+@verbatim
+lw rd,%gprel(label)($gp)
+lw rd+1,%gprel(label+4)($gp)
+@end verbatim
+
+@tab
+@item
+@verbatim
+no-PIC
+@end verbatim
+
+@tab
+@verbatim
+lui $at,%hi(label)
+lw rd,%lo(label)($at)
+lw rd+1,%lo(labe+4)($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& local_p(label)
+@end verbatim
+
+@tab
+@verbatim
+lw $at,%got_page(label)($gp)
+lw rd,%got_ofst(label)($at)
+lw rd+1,%got_ofst(label+4)($at)
+@end verbatim
+
+@tab
+@item
+@verbatim
+PIC
+&& !local_p(label)
+@end verbatim
+
+@tab
+@verbatim
+lw $at,%got_disp(label)($gp)
+lw rd,0($at)
+lw rd+1,4($at)
+@end verbatim
+
+@tab
+@end multitable
+@item NMS expansions
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@tab
+@tab
+@end multitable
+@item Instruction
+@multitable @columnfractions 0.3 0.4 0.3
+@item
+@verbatim
+Conditions
+@end verbatim
+
+@tab
+@verbatim
+Expansion
+@end verbatim
+
+@tab
+Remarks and supplementary calculations
+@end multitable
+@item ext rt,rs,pos,size
+@multitable @columnfractions 0.3 0.4 0.3
+@item (pos + size) > 31
+@tab
+@verbatim
+srl rt,rs,pos
+@end verbatim
+@tab
+@item else
+@tab
+@verbatim
+sll rt,rs,(31-pos-size)
+srl rt,rt,(31-size)
+@end verbatim
+@tab
+@end multitable
+@item ins rt,rs,pos,size
+@multitable @columnfractions 0.3 0.4 0.3
+@item rt == rs
+@tab
+@verbatim
+extw $at,rt,rs,pos
+extw rt,$at,rt,(1+size-pos)
+extw rt,rt,rt,(31-size)
+@end verbatim
+@tab
+@item pos == 0 && size == 31
+@tab
+@verbatim
+move rt,rs
+@end verbatim
+@tab
+@item pos != 0
+@tab
+@verbatim
+extw rt,rt,rt,pos
+extw rt,rt,rs,(1+size-pos)
+extw rt,rt,rt,(31-size)
+@end verbatim
+@tab
+@item else
+@tab
+@verbatim
+extw rt,rt,rs,(1+size-pos)
+extw rt,rt,rt,(31-size)
+@end verbatim
+@tab
+@end multitable
+@end table
+
+Note that while the assembler provides these macros for
+compatibility, it does not make any attempt to optimize them with the
+surrounding code.
diff --git a/gas/doc/c-nanomips.texi b/gas/doc/c-nanomips.texi
new file mode 100644
index 00000000000..9b3295cf25f
--- /dev/null
+++ b/gas/doc/c-nanomips.texi
@@ -0,0 +1,1499 @@
+@c Copyright (C) 2017-2026 Free Software Foundation, CIP United Inc.
+@c Contributed by MIPS Tech LLC.
+@c Written by Faraz Shahbazker <[email protected]>
+@c This is part of the GAS manual.
+@c For copying conditions, see the file as.texinfo.
+
+@macro doleft{TEXT}
+@flushleft \TEXT\
+@end flushleft
+@end macro
+
+@ifset GENERIC
+@page
+@node nanoMIPS-Dependent
+@chapter nanoMIPS Dependent Features
+@end ifset
+@ifclear GENERIC
+@node Machine Dependencies
+@chapter nanoMIPS Dependent Features
+@end ifclear
+
+@cindex nanoMIPS processor
+
+@menu
+* nanoMIPS Options::            Assembler Options
+* nanoMIPS Directives::         Assembler Directives
+* nanoMIPS Reloc Operators::    Explicit Relocation Operators
+* nanoMIPS Macros::             High-level Assembly Macros
+* nanoMIPS Aliases::            1:1 Instruction Aliases
+* nanoMIPS Small Data::         Small Data Access
+* nanoMIPS Relocations::        Using relocation operators for different
+                                addressing modes
+* nanoMIPS Instruction Selection:: Controlling Instruction Selection
+* nanoMIPS Transformations:: Controlling Linker Relaxation
+* nanoMIPS Syntax::             Syntactical Considerations
+@end menu
+
+@node nanoMIPS Options
+@section Assembler Options
+
+The nanoMIPS configurations of @sc{gnu} @code{@value{AS}} support these
+special options:
+
+@table @code
+@cindex -G option (nanoMIPS)
+@item -G @var{num}
+Set the ``small data'' limit to @var{n} bytes.  The default limit is 8 bytes.
+@xref{nanoMIPS Small Data, , Controlling the use of small data accesses}.
+
+@cindex @code{-EB} option (nanoMIPS)
+@cindex @code{-EL} option (nanoMIPS)
+@cindex nanoMIPS big-endian output
+@cindex nanoMIPS little-endian output
+@cindex big-endian output, nanoMIPS
+@cindex little-endian output, nanoMIPS
+@item -EB
+@itemx -EL
+Any nanoMIPS configuration of @code{@value{AS}} can select big-endian or
+little-endian output at run time (unlike the other @sc{gnu} development
+tools, which must be configured for one or the other).  Use @samp{-EB}
+to select big-endian output, and @samp{-EL} for little-endian.
+
+@item -march=@var{arch}
+Generate code for a particular nanoMIPS @var{arch}, which can be the
+name of a generic nanoMIPS @var{ISA} or the name of a particular
+@var{CPU}.  Valid @var{ISA} value are:
+
+@quotation
+32r6,
+32r6s,
+64r6
+@end quotation
+
+Valid @var{CPU} value are:
+@quotation
+i7200,
+nms1
+@end quotation
+
+@item -mtune=@var{cpu}
+Schedule and tune for a particular nanoMIPS CPU.  Valid @var{cpu} values are
+identical to @samp{-march=@var{cpu}}.
+
+@item -m32
+Generate code for the p32 ABI.
+
+@item -m64
+Generate code for the p64 ABI.
+
+@item -mcmodel=@var{mmodel}
+Generate code for a particular C Memory Model.  The following memory models
+are supported: @code{auto}, @code{medium}, @code{large}
+
+@item -mpic
+@itemx -mno-pic
+Generate medium model SVR4-style PIC.  This option tells the assembler
+to generate SVR4-style position-independent macro expansions.  It also
+tells the assembler to mark the output file as PIC.
+@samp{-mno-pic} turns off this option.
+
+@item -mPIC
+@itemx -mno-PIC
+Generate large model SVR4-style PIC.  This option tells the assembler
+to generate SVR4-style position-independent macro expansions.  It also
+tells the assembler to mark the output file as PIC.
+@samp{-mno-PIC} turns off this option.
+
+@item -mpid
+@itemx -mno-pid
+Generate position independent data.  This option tells the assembler to
+generate data sections that can be repositioned independent of code placement.
+It also tells the assembler to mark the output file as PID.
+@samp{-mno-pid} turns off this option.
+
+@item -mpcrel
+@itemx -mno-pcrel
+Generate PC-relative expansions.  This option tells the assembler to
+avoid the use of absolute addresses for symbols even when those
+addresses may be known at link time.  It also tells the assembler to
+mark the output file as purely PC-relative.
+@samp{-mno-pcrel} turns off this option.
+
+@item --linkrelax
+Enable link-time relaxation features.  The assembler will generate
+additional relocations to allow the linker to expand/relax object
+code and preserve correctness.
+
+@item -minsn32
+@itemx -mno-insn32
+Only use 32-bit instruction encodings.  This option inhibits the use
+of 16-bit and 48-bit instructions.  This is equivalent to putting
+@code{.module insn32} at the start of the assembly file.
+@samp{-mno-insn32} turns off this option.  This is equivalent to
+putting @code{.module noinsn32} at the start of the assembly file.  By
+default @samp{-mno-insn32} is selected, allowing all instructions to
+be used.
+
+@item -mmt
+@itemx -mno-mt
+Generate code for the MT Application Specific Extension.
+This tells the assembler to accept MT instructions.
+@samp{-mno-mt} turns off this option.
+
+@item -mvirt
+@itemx -mno-virt
+Generate code for the Virtualization Application Specific Extension.
+This tells the assembler to accept Virtualization instructions.
+@samp{-mno-virt} turns off this option.
+
+@item -msoft-float
+@itemx -mhard-float
+Disable or enable floating-point instructions.  Note that by default
+floating-point instructions are always allowed even with CPU targets
+that don't have support for these instructions.
+
+@item -msingle-float
+@itemx -mdouble-float
+Disable or enable double-precision floating-point operations.  Note
+that by default double-precision floating-point operations are always
+allowed even with CPU targets that don't have support for these
+operations.
+
+@item --construct-floats
+@itemx --no-construct-floats
+The @code{--no-construct-floats} option disables the construction of
+floating point constants in code by loading the values from memory
+instead.
+
+By default @code{--construct-floats} is selected, allowing construction
+of these floating point constants.
+
+@item -mbalc-stubs
+@itemx -mno-balc-stubs
+Consolidate multiple out-of-range call instructions to a function to
+16-bit calls to a stub with transfers control to the function.  The
+@samp{-mbalc-stubs} option improves code compression at the cost
+of performance, since each transformed call requires two control
+transfers.
+
+This optimization is disabled by default.
+
+@item -mlegacyregs
+Allow the use of legacy MIPS style numeric register formats in
+nanoMIPS assembly.
+
+@item --trap
+@itemx --no-break
+@c FIXME!  (1) reflect these options (next item too) in option summaries;
+
+@item --break
+@itemx --no-trap
+Generate code to take a break exception rather than a trap exception when an
+error is detected.  This is the default.
+
+@end table
+
+@node nanoMIPS Directives
+@section Assembler Directives
+
+@menu
+* nanoMIPS Controls:: Directives to control assembler behaviour & state
+* nanoMIPS ISA:: Directives to override the ISA
+* nanoMIPS CodeGen Concepts:: Directives to control memory model and addressing
+* nanoMIPS CodeGen Specifics:: Directives to control code generation
+* nanoMIPS DataGen:: Directives for data sections
+* nanoMIPS Floating-Point:: Directives to override floating-point options
+* nanoMIPS ASE Overrides:: Directives for generation of ASE instructions
+* nanoMIPS Compatibility:: Directives for compatibility with MIPS assembly
+@end menu
+
+@node nanoMIPS Controls
+@subsection Directives to control assembler behaviour & state
+@table @code
+@item @code{.set}
+
+@cindex nanoMIPS option control
+The @code{.set} directive allows changing various options that control
+behaviour at any point within an assembly file.  The syntax is identical
+to the @code{.set} directive used to assign values to symbols.  The
+nanoMIPS assembler supports a number of built-in special symbols, which
+when set to certain values change the behaviour of the assembler from
+that point onwards.  The change in the behaviour remains in effect till
+the next @code{.set} directive which affects that particular behaviour.
+
+@item @code{.module}
+
+@cindex nanoMIPS module control
+@kindex @code{.module}
+The @code{.module} directive allows command line options to be set directly
+from assembly.  The format of the directive matches the @code{.set}
+directive but only those options which are relevant to a whole module are
+supported.  The effect of a @code{.module} directive is the same as the
+corresponding command line option.  Where @code{.set} directives support
+returning to a default then the @code{.module} directives do not as they
+define the defaults.
+
+Module-level directives must appear first in assembly, before any
+instructions.
+
+@item @code{.set push}
+@itemx @code{.set pop}
+
+@cindex nanoMIPS option stack
+@kindex @code{.set push}
+@kindex @code{.set pop}
+The directives @code{.set push} and @code{.set pop} may be used to save
+and restore the current settings for all the options which are
+controlled by @code{.set}.  The @code{.set push} directive saves the
+current settings on what can be considered a virtual assembler settings
+``stack''.  The @code{.set pop} directive pops the ``stack'' and restores
+the assembler state to what it was before the most recent @code{.set push}.
+
+These directives can be useful inside an macro which must change an
+option but does not want to change the state of the code which invoked
+the macro.
+@end table
+
+@node nanoMIPS ISA
+@subsection Directives to override the ISA
+@table @code
+@cindex nanoMIPS CPU override
+@item .set arch=@var{isa}
+@kindex .set arch=@var{isa}
+@itemx .set arch=@var{cpu}
+@item .module arch=@var{isa}
+@kindex .module arch=@var{isa}
+@itemx .module arch=@var{cpu}
+The @code{.set arch=@var{isa}} directive changes the effective CPU
+target and allows the assembler to use instructions specific to a
+particular ISA or CPU.  All ISA and CPUs supported by the
+@samp{-march} command line option are also selectable by this
+directive.  The original value is restored by @code{.set
+arch=default}.
+
+Valid @var{isa} value are:
+@quotation
+32r6,
+32r6s,
+64r6
+@end quotation
+
+Valid @var{cpu} value are:
+@quotation
+i7200,
+nms1
+@end quotation
+@end table
+
+@node nanoMIPS CodeGen Concepts
+@subsection Directives to control memory model and addressing
+These directives indirectly control how built-in macros are expanded.
+Some of them also set or clear corresponding flags in the ELF header.
+
+@table @code
+@item .set mcmodel=auto
+@itemx .set mcmodel=medium
+@itemx .set mcmodel=large
+@itemx .module mcmodel=auto
+@itemx .module mcmodel=medium
+@itemx .module mcmodel=large
+@cindex Control code/data memory models
+@kindex .set mcmodel=auto
+@kindex .set mcmodel=medium
+@kindex .set mcmodel=large
+These directives specify the memory model that the assembler uses for
+generating macro expansions.  The directive @code{.set mcmodel=auto}
+defers most decisions about the range of the code/data layout to
+link-time relaxation.  It requires linker relaxation to be enabled and
+a capable linker.  The directive @code{.set mcmodel=medium} assumes
+that the GP-relative region (which includes the GOT in PIC) must not
+exceed 2MiB and the total code size for a final link must not exceed
+32MiB.  The directive @code{.set mcmodel=large} implies no limits.
+@c FIXME: not true for 64-bits, perhaps specify a 2GB limit.
+
+@item .set pic[012]
+@itemx .module pic[012]
+@kindex .set pic0
+@kindex .set pic1
+@kindex .set pic2
+@kindex .module pic0
+@kindex .module pic1
+@kindex .module pic2
+The @code{.set pic1} directive enables position independent code(PIC)
+generation for built-in macros, using the medium memory model.  The
+@code{.set pic2} directive enables PIC generation, using the large
+memory model.  The @code{.set pic0} directive disables PIC generation.
+If PIC is enabled, the corresponding flag in the ELF header is also set.
+Position independent code generation is disabled by default.
+
+@item .set pid
+@itemx .set nopid
+@itemx .module pid
+@itemx .module nopid
+@kindex .set pid
+@kindex .set nopid
+@kindex .module pid
+@kindex .module nopid
+The @code{.set pid} directive enables the position independent
+expansion of data addresses for built-in macros.  It also sets the PID
+flag in the ELF header.  The @code{.set nopid} directive disables such
+expansions.
+
+An object with the PID flag is guaranteed to not contain any absolute
+or PC-relative references to data.  All data references are through the
+$gp register.  Data sections can be re-positioned independent of code
+sections by changing the value of @var{_gp}.  This is disabled by
+default.
+
+@item .set pcrel
+@itemx .set nopcrel
+@itemx .module pcrel
+@itemx .module nopcrel
+@kindex .set pcrel
+@kindex .set nopcrel
+@kindex .module pcrel
+@kindex .module nopcrel
+The @code{.set pcrel} directive enables the PC-relative expansion of
+address calculation for built-in macros.  It also sets the PC-relative
+flag in the ELF header.  The @code{.set pcrel} directive disables
+PC-relative expansions.  An object with the PC-relative flag is
+guaranteed to not contain any absolute address calculation.  This
+is disabled by default.
+
+@item .linkrelax
+@kindex .linkrelax
+The @code{.linkrelax} directive enable linker relaxations for an
+assembly unit.  It also sets the LINKRELAX flag in the ELF header.
+Linker relaxation is disabled by default.
+@end table
+
+
+@node nanoMIPS CodeGen Specifics
+@subsection Directives to control code generation
+@table @code
+
+@item .set insn32
+@itemx .set noinsn32
+@cindex nanoMIPS 32-bit instruction generation override
+@kindex @code{.set insn32}
+@kindex @code{.set noinsn32}
+The directive @code{.set insn32} makes the assembler use only 32-bit
+instruction encodings when generating code for the nanoMIPS processor.
+This directive inhibits the use of any 16-bit or 48-bit instructions
+from that point on in the assembly.  The @code{.set noinsn32} directive
+allows 16-bit and 48-bit instructions to be accepted.
+
+@item .set reorder
+@itemx .set noreorder
+@cindex Compatibility with MIPS instruction re-ordering
+@kindex @code{.set reorder}
+@kindex @code{.set noreorder}
+The traditional MIPS assembler uses re-ordering of instructions to fill
+delay slots in delayed branch instructions.  If reordering is enabled,
+the assembler can move an instruction above a delayed branch
+instructions in to the delay slot of the instruction.  If it is disabled,
+the assembler must insert a nop instruction in the delay slot, to
+satisfy pipeline constraints.  Where the assembler is not free to adjust
+the user-specified order of instructions, a NOP is inserted in the
+delay slot instead.
+
+The nanoMIPS architecture does not have delayed instructions.  The branch
+instructions are termed as compact (as opposed to delayed) branch
+instructions.  The assembler does provide aliases from delayed to compact
+branch mnemonics for portability, however it cannot simply gloss over
+semantic differences between the two.  The nanoMIPS assembler will
+attempt to convert a delayed branch to a compact branch.  With
+re-ordering enabled, this is simply interpreting one instruction
+mnemonic (bal) as another (balc).  With reordering disabled, the
+conversion is only possible if the instruction in the delay slot is a
+NOP instruction, since the NOP can be trivially dropped without changing
+the effect of an assembly fragment.
+
+The following table compares the behaviour of MIPS and nanoMIPS for
+commonly encountered input patterns:
+
+@multitable @columnfractions 0.2 0.2 0.2 0.2 0.2
+@headitem
+Input assembly
+@tab
+Generated MIPS object
+@tab
+Remarks
+@tab
+Generated nanoMIPS object
+@tab
+Remarks
+@item
+@item
+@smallformat
+@verbatim
+.set reorder
+move $a0,$s0
+bal $ra,foo
+@end verbatim
+@end smallformat
+@tab
+@smallformat
+@verbatim
+bal $ra,foo
+move $a0,$s0
+@end verbatim
+@end smallformat
+@tab
+Instructions re-ordered to fill delay slot.  Move happens before control
+transfer due to delayed branch semantics.
+@tab
+@smallformat
+@verbatim
+move $a0,$s0
+balc $ra,foo
+@end verbatim
+@end smallformat
+@tab
+Delayed branch converted to compact branch.
+@item
+@smallformat
+@verbatim
+.set reorder
+move $a0,$s0
+beq $a0,$a1,foo
+@end verbatim
+@end smallformat
+@tab
+@smallformat
+@verbatim
+move $a0,$s0
+beq $a0,$a1,foo
+nop
+@end verbatim
+@end smallformat
+@tab
+Re-ordering inhibited by dependency.  NOP inserted automatically to fill
+delay slot.
+@tab
+@smallformat
+@verbatim
+move $a0,$s0
+beqc $a0,$a1,foo
+@end verbatim
+@end smallformat
+@tab
+Delayed branch converted to compact branch.
+@item
+@smallformat
+@verbatim
+.set noreorder
+move $a0,$s0
+bal $ra, foo
+nop
+@end verbatim
+@end smallformat
+@tab
+@smallformat
+@verbatim
+move $a0,$s0
+bal $ra, foo
+nop
+@end verbatim
+@end smallformat
+@tab
+Explicit NOP in delay slot
+@tab
+@smallformat
+@verbatim
+move $a0,$s0
+balc $ra,foo
+@end verbatim
+@end smallformat
+@tab
+Delayed branch converted to compact branch,  NOP removed.
+@item
+@smallformat
+@verbatim
+.set noreorder
+bal $ra, foo
+move $a0,$s0
+@end verbatim
+@end smallformat
+@tab
+@smallformat
+@verbatim
+bal $ra, foo
+move $a0,$s0
+@end verbatim
+@end smallformat
+@tab
+Explicit instruction in delay slot.
+@tab
+-
+@tab
+Signal error.  Cannot convert to compact branch.
+@item
+@smallformat
+@verbatim
+.set noreorder
+move $a0,$s0
+bal $ra, foo
+@end verbatim
+@end smallformat
+@tab
+@smallformat
+@verbatim
+move $a0,$s0
+bal $ra, foo
+<xx>
+@end verbatim
+@end smallformat
+@tab
+Unpredictable or illegal instruction in delay slot
+@tab
+@smallformat
+@verbatim
+move $a0,$s0
+balc $ra,foo
+@end verbatim
+@end smallformat
+@tab
+Delayed branch converted to compact branch,  NOP removed.
+@end multitable
+
+Finding a useful operations to perform in delay slots is important to
+get the best performance from the execution pipeline on MIPS
+architecture.  Traditionally, MIPS assembly programmers have preferred to
+control the utilization of delay slots directly, rather than rely on the
+assembler.  A lot of handwritten MIPS assembly follows the pattern in row
+4 above.  Here reordering is disabled and the instruction in the delay
+slot is not a NOP.  The nanoMIPS assembler will fail to convert the
+delayed branch to a compact branch and will signal an error.
+
+Reversing the order of the branch and the subsequent instruction is
+sufficient for the nanoMIPS assembler, as in row 5 above.  However the
+output will behave unpredictably when assembled for MIPS, because
+whatever instruction or data happens to be in the delay slot position in
+the output will get executed before the branch.  The safest and most
+reliable alternative is row 1.  It delegates maximum control to the
+assembler and generates the most efficient code for both MIPS and
+nanoMIPS.  Note that re-ordering is enabled by default on both MIPS and
+nanoMIPS.  If it is not disabled any where preceding a branch fragment,
+it need not be explicitly re-enabled for each branch.
+
+@item @code{.set linkrelax}
+@itemx @code{.set nolinkrelax}
+@cindex Directives to control linker relaxation over a region
+@kindex @code{.set linkrelax}
+@kindex @code{.set nolinkrelax}
+The directive @code{.set linkrelax} emits a place-holder to indicate
+that linker relaxations are enabled in the following region.  When
+relaxation is enabled, the assembler will emit additional relocations
+to direct the linker.  The @code{.set nolinkrelax} directive emits
+a place-holder to indicate that linker relaxations are disabled in the
+following region.
+
+@item @code{.set legacyregs}
+@itemx @code{.set nolegacyregs}
+@cindex nanoMIPS legacy register names
+@kindex @code{.set legacyregs}
+@kindex @code{.set nolegacyregs}
+The directive @code{.set legacyregs} allows the use of MIPS-compatible
+numeric register formats.  The names and usage conventions of general
+purpose registers for the nanoMIPS ABI is different from the MIPS
+ABI.  The nanoMIPS assembler rejects numeric formats by default, to
+force the user to re-think register usage when porting MIPS code.  The
+@code{.set nolegacyregs} directive disables these register
+identifiers.
+
+@item @code{.set macro}
+@itemx @code{.set nomacro}
+@kindex @code{.set macro}
+@kindex @code{.set nomacro}
+Some times it is undesirable to have one assembly instruction expand
+to several machine instructions.  The directive @code{.set nomacro}
+tells the assembler to prohibit such expansions.  @code{.set macro}
+restores the default behavior.  Note that this behaviour is a departure
+from the MIPS assembler which only warns about generation of macros
+after @code{.set nomacro}.
+
+@item @code{.set at=@var{reg}}
+@cindex @code{at} register, nanoMIPS
+@kindex @code{.set at=@var{reg}}
+Some macro instructions need a temporary register to store intermediate
+results.  This register is usually @code{$r1}, also known as @code{$at},
+but it can be changed to any core register @var{reg} using
+@code{.set at=@var{reg}}.  Note that @code{$at} always refers
+to @code{$r1} regardless of which register is being used as the
+temporary register.
+
+@item @code{.set at}
+@itemx @code{.set noat}
+@kindex @code{.set at}
+@kindex @code{.set noat}
+Implicit uses of the temporary register in macros could interfere with
+explicit uses in the assembly code.  The assembler therefore warns
+whenever it sees an explicit use of the temporary register.  The directive
+@code{.set noat} silences this warning while @code{.set at} restores
+the default behavior.  It is safe to use @code{.set noat} while
+@code{.set nomacro} is in effect since single-instruction macros
+never need a temporary register.
+
+@item .cpsetup
+@cindex nanoMIPS GP-setup
+@kindex @code{cpsetup}
+
+This directive maps to the GP-setup sequence for position independent
+code.
+
+@example
+lapc.b $gp, _gp
+@end example
+
+@end table
+
+@node nanoMIPS DataGen
+@subsection Directives for data sections
+@table @code
+
+@item @code{.bss}
+@cindex Zero-initialized data
+@kindex @code{.bss}
+The @code{.bss} directive starts the declaration of a zero-initialized
+data section.  This can also be achieved using the @code{.section}
+directive.  It is provided for compatibility with MIPS.
+
+@item @code{.sbss}
+@cindex Zero-initialized data
+@kindex @code{.sbss}
+The @code{.sbss} directive starts the declaration of a zero-initialized
+small data section.  This can also be achieved using the @code{.section}
+directive.  It is provided for compatibility with MIPS.
+
+@item @code{.rdata}
+@cindex Read-only data
+@kindex @code{.rdata}
+The @code{.rdata} directive starts the declaration of a read-only data
+section.  This can also be achieved using the @code{.section}
+directive.  It is provided for compatibility with MIPS.
+
+@item @code{.sdata}
+@cindex Small data
+@kindex @code{.sdata}
+The @code{.sdata} directive starts the declaration of an initialized
+small data section.  This can also be achieved using the @code{.section}
+directive.  It is provided for compatibility with MIPS.
+
+@item @code{.sbyte}
+@cindex Signed byte expressions
+@kindex @code{.sbyte}
+@code{.sbyte} expects zero or more expressions, separated by commas.
+Each expression is assembled into the next byte, similar to @code{.byte}
+psuedo-op.  The GNU assembler interprets all expressions are unsigned by
+default.  If the expression for @code{.sbyte} consists of a
+label-difference, the assembler will emit necessary relocation to
+interpreted the result as a signed 8-bit value.
+
+@item @code{.shword}
+@cindex Signed half-word expressions
+@kindex @code{.shword}
+@code{.shword} expects zero or more expressions, separated by commas.
+Each expression is assembled into the next half-word, similar to
+@code{.hword} psuedo-op.  If the expression consists of a
+label-difference, the assembler will emit necessary relocation to
+interpreted the result as a signed 16-bit value.
+
+@item @code{.ehword}
+@cindex Exception handler address
+@kindex @code{.ehword} expects a symbol.  sThe directive allocates a
+word-sized memory region and emits a PC-relative relocation to
+calculate the address of that symbol.
+@end table
+
+@node nanoMIPS Floating-Point
+@subsection Directives to override floating-point options
+
+@table @code
+@item .gnu_attribute 4,[0123]
+The directives @code{.gnu_attribute 4,} selects one of the supported
+FP ABIs.  @xref{Supported FP ABIs}.
+
+@item .set softfloat
+@itemx .set hardfloat
+@itemx .module softfloat
+@itemx .module hardfloat
+@kindex @code{.set softfloat}
+@kindex @code{.set hardfloat}
+@kindex @code{.module softfloat}
+@kindex @code{.module hardfloat}
+The directives @code{.set softfloat} and @code{.set hardfloat} provide
+finer control of disabling and enabling float-point instructions.
+These directives always override the default (that hard-float
+instructions are accepted) or the command-line options
+(@samp{-msoft-float} and @samp{-mhard-float}).
+
+@item .set singlefloat
+@itemx .set doublefloat
+@itemx .module singlefloat
+@itemx .module doublefloat
+@kindex @code{.set singlefloat}
+@kindex @code{.set doublefloat}
+@kindex @code{.module singlefloat}
+@kindex @code{.module doublefloat}
+The directives @code{.set singlefloat} and @code{.set doublefloat}
+provide finer control of disabling and enabling double-precision
+float-point operations.  These directives always override the default
+(that double-precision operations are accepted) or the command-line
+options (@samp{-msingle-float} and @samp{-mdouble-float}).
+
+@end table
+
+@anchor{Supported FP ABIs} @subsubsection Supported FP ABIs
+The supported floating-point ABI variants are:
+
+@table @code
+@item 0 - No floating-point
+This variant is used to indicate that floating-point is not used within
+the module at all and therefore has no impact on the ABI.  This is the
+default.
+
+@item 1 - Double-precision
+This variant indicates that double-precision support is used.  This means
+that 64-bit wide floating-point registers are required.
+
+@item 2 - Single-precision
+This variant indicates that single-precision support is used.  Double
+precision operations will be supported via soft-float routines.
+
+@item 3 - Soft-float
+This variant indicates that although floating-point support is used all
+operations are emulated in software.  This means the ABI is modified to
+pass all floating-point data in general-purpose registers.
+
+@end table
+
+@node nanoMIPS ASE Overrides
+@subsection Directives for generation of ASE instructions
+
+@table @code
+
+@item .set mt
+@itemx .set nomt
+@itemx .module mt
+@itemx .module nomt
+@cindex nanoMIPS MT instruction generation override
+@kindex @code{.set mt}
+@kindex @code{.set nomt}
+@kindex @code{.module mt}
+@kindex @code{.module nomt}
+The directive @code{.set mt} makes the assembler accept instructions
+from the Multi Threading Application Specific Extension from that point
+on in the assembly.  The @code{.set nomt} directive prevents MT
+instructions from being accepted.
+
+@item .set virt
+@itemx .set novirt
+@itemx .module virt
+@itemx .module novirt
+@cindex Virtualization instruction generation override
+@kindex @code{.set virt}
+@kindex @code{.set novirt}
+@kindex @code{.module virt}
+@kindex @code{.module novirt}
+The directive @code{.set virt} makes the assembler accept instructions
+from the Virtualization Application Specific Extension from that point
+on in the assembly.  The @code{.set novirt} directive prevents Virtualization
+instructions from being accepted.
+
+@end table
+
+@node nanoMIPS Compatibility
+@subsection Directives for compatibility with MIPS assembly
+
+These assembler directives are accepted without any verification or
+effect, for compatibility with MIPS.
+@table @code
+@item .cpadd
+@item .cpload
+@item .cplocal
+@item .crestore
+@item .cpreturn
+@item .set nomips16
+@item .set noMIPS-16
+@item .set nomicromips
+@item .set move
+@item @code{.set nomove}
+@item .set volatile
+@item .set novolatile
+@item .set nobopt
+@item .set noforbidden-slots
+@item .set oddspreg
+@end table
+
+@node nanoMIPS Reloc Operators
+@section Explicit Relocation Operators
+@table @code
+@item %lo
+
+Unsigned 12-bit low-part of 32-bit value.
+@example
+%lo(@var{X}) = @var{X} & 0xfff
+@end example
+@item %hi
+
+Signed 20-bit high-part of 32-bit value.
+@example
+%hi(@var{X}) = @var{X} & 0xfffff000
+@end example
+@item %gprel
+
+GP-relative displacement, size depends on type of operation and data layout.
+@item %gprel_hi
+Signed 20-bit high part of a GP-relative displacement.
+@item %gprel_lo
+Unsigned 12-bit low part of a GP-relative displacement.
+@item %got_disp
+19-bit (scaled) GOT displacement for address calculation or data access.
+@item %got_call
+19-bit (scaled) GOT displacement to load address for a function call.
+@item %got_pcrel_hi
+Signed 20-bit high part of GOT displacement from next PC.
+@item %got_pcrel_lo
+Unsigned 12-bit low part of GOT displacement.
+@item %got_pcrel32
+Full 32-bit signed GOT displacement from next PC.
+@item %got_page
+Marks the first level of indirection for GOT-relative data access
+(either a load or a store).  This is relaxed out by the linker.
+@item %got_ofst
+Marks the second level of indirection for GOT-relative data access
+(either a load or a store).
+@item %pcrel_hi
+Signed 20-bit high part of PC-relative displacement.
+@item %pcrel_lo
+Unsigned 12-bit low part of PC-relative displacement.  Map to @code{%lo}.
+
+@item %tlsgd
+GP-relative displacement to global dynamic TLS slot, size depends on
+type of operation.
+
+@item %tlsld
+
+GP-relative displacement to local dynamic TLS slot, size depends on type
+of operation.
+
+@item %dtprel
+
+Unsigned offset to a thread-local dynamic variable from current thread
+pointer, size depends on type of operation.
+
+@item %tprel
+
+Unsigned offset to a thread-local static variable from current thread
+pointer, size depends on type of operation.
+
+@item %gottprel
+
+19-bit (scaled) GOT displacement to a TLS slot.
+
+@item %gottprel_pc32
+
+Full 32-bit signed GOT displacement to a TLS slot from next PC.
+
+@item %gp_rel
+
+Provided for compatibility with MIPS.  Map to @code{%gprel}.
+
+@item %call16
+
+Provided for compatibility with MIPS.  Map to @code{%got_call}.
+
+@item %got
+
+Provided for compatibility with MIPS.  Map to @code{%got_disp}.
+@end table
+
+@include c-nanomips-macros.texi
+
+@include c-nanomips-aliases.texi
+
+@node nanoMIPS Small Data
+@section Small Data Access
+
+@cindex small data, nanoMIPS
+@cindex @code{gp} register, nanoMIPS
+It often takes multiple instructions to load data from a symbol.
+For example, when @samp{addr} is a 32-bit symbol, the non-PIC expansion
+of @samp{lw $a0,addr} is usually:
+
+@example
+lui     $a0,%hi(addr)
+lw      $a0,%lo(addr)($a0)
+@end example
+
+The sequence is longer when @samp{addr} is a 64-bit symbol.
+
+In order to cut down on this overhead, nanoMIPS architecture allows the
+programmer to set aside a 2 megabyte ``small data'' area and guarantees
+that all data of size @var{n} and smaller will be placed in that area.
+The limit @var{n} is passed to both the assembler and the linker using
+the command-line option @option{-G @var{n}}, @pxref{nanoMIPS Options,,
+Assembler options}.  Note that the same value of @var{n} must be used
+when linking and when assembling all input files to the link; any
+inconsistency could cause a relocation overflow error.
+
+The size of an object in the @code{.bss} section is set by the
+@code{.comm} or @code{.lcomm} directive that defines it.  The size of
+an external object may be set with the @code{.extern} directive.  For
+example, @samp{.extern sym,4} declares that the object at @code{sym}
+is 4 bytes in length, while leaving @code{sym} otherwise undefined.
+
+When no @option{-G} option is given, the default limit is 8 bytes.
+The option @option{-G 0} prevents any data from being automatically
+classified as small.
+
+It is also possible to mark specific objects as small by putting them in
+the special sections @code{.sdata}, @code{.ssdata}, @code{.sbss} and
+@code{.ssbss}, which are ``small'' counterparts of @code{.data} and
+@code{.bss} respectively for different types of data.  The toolchain
+will treat such data as small regardless of the @option{-G} setting.
+
+On startup, systems that support a small data area are expected to
+initialize register @code{$r28}, also known as @code{$gp}, in such a
+way that small data can be accessed using a 21-bit offset from that
+register for word/double-word types. The offset restriction is 18-bits
+in the case of sub-word and floating point types.  For example, when
+@samp{addr} is small data, the @samp{lw $a0,addr} instruction above is
+equivalent to:
+
+@example
+lw  $a0,%gprel(addr)($gp)
+@end example
+
+Small data is also supported for SVR4-style PIC.
+
+@node nanoMIPS Relocations
+@section Using relocation operators for different addressing modes
+
+@menu
+* Optimized GP-relative access::
+* General GP-relative access::
+* 32-bit absolute addressing and immediate construction::
+* PC-relative addressing::
+* Indirect addressing for small PIC model::
+* Indirect addressing for large PIC model::
+@end menu
+
+@node Optimized GP-relative access
+@subsection Optimized GP-relative access
+
+The nanoMIPS architecture allows various fundamental data types, up to
+16 bytes in size, to be accessed directly relative to the designated
+Global Pointer ($gp) register.  GP-relative access allows for data
+load/store and address calculations to be performed in a single 16 or
+32-bit instruction, using an offset from the $gp register.  The range
+of the offset and hence the size of the reachable GP-relative region,
+also called the small data region, varies with the type, size and
+alignment of the data object being accessed.  These limits form the
+basis of the medium memory model.
+
+@multitable @columnfractions .4 .6
+@headitem Data type @tab GP-relative offset range
+@item aligned word	@tab 19-bit scaled (2MiB)
+@item aligned dword	@tab 18-bit scaled (2MiB)
+@item aligned half-word	@tab 17-bit scaled (512KiB)
+@item aligned float	@tab 16-bit scaled (512KiB)
+@item [word] aligned double	@tab 16-bit scaled (512KiB)
+@item unaligned word	@tab 18-bit (512KiB)
+@item unaligned dword	@tab 18-bit (512KiB)
+@item unaligned half-word	@tab 18-bit (512KiB)
+@item byte	@tab 18-bit (512KiB)
+@end multitable
+
+The object file contains relocations which the linker attempts to
+resolve when doing the data layout.  Even with the medium memory model,
+there is no guarantee that all GP-relative accesses will be
+optimized.  If the linker can not find a data layout that allows all
+GP-relative accesses to be optimized, it will either
+
+@itemize
+@item
+Expand some accesses to use multiple instructions: this indicates that
+although the total amount of small data is less than 2MB, the offset
+range requirements for all types/alignment cannot be satisfied.  The
+linker can rewrite some accesses to use multiple
+instructions.  However, if expansion is inhibited or not implemented,
+the link will fail.
+@item
+Fail to link: this indicates that the total amount of small data is
+greater than 2MB.  The solution is to recompile using either the
+large or the automatic memory model.
+@end itemize
+
+Thus, the linker has final control of whether optimized GP-relative
+access is viable.  Assembler directives can be used to disallow
+expansions at either module-level or per-access.
+@xref{nanoMIPS Transformations, ,Controlling Linker Relaxation}.
+Assembly language syntax for requesting GP-relative access consists
+of 2 elements:
+@subsubsection Explicitly requested GP-relative access
+
+The user can explicitly request GP-relative access with the %gprel
+relocation operator.  This operator can only be used for load/store
+instructions with $gp as the base register or address calculation with
+$gp as a source operand.  The assembler will match the operation and
+select the an appropriate relocation for each access.  Examples:
+@example
+    lw $a0, %gprel(foo)($gp)
+    l.s $f0, %gprel(bar)($gp)
+    addiu $a0, $gp, %gprel(foo)
+@end example
+
+By itself, this does not guarantee that foo will end up within the
+small data region.  If the layout is such that it happens to be within
+range, the link will succeed.  Otherwise the linker may fail or expand
+the operation to multiple instructions, as explained above.
+@subsubsection Implicit GP-relative access through canonical named sections
+
+Small data sections are typically named `.sbss'/`.ssbss'
+(zero-initialized) or `.sdata'/`.ssdata'.  The linker places these
+sections close to $gp and complains if they are outside the GP-relative
+range.  If access to an object within a small data sections is made by
+assembler macros, where the addressing mode is unspecified, the
+assembler will choose a GP-relative expansion.
+
+@example
+    lw $a0, foo
+    @expansion{} lw $a0, %gprel(foo) ($gp)
+
+    la $a0, bar
+    @expansion{} addiu $a0, $gp, %gprel(foo)
+@end example
+Declaration of data in small data sections can be achieved by naming
+sections using the @code{.section} directive or by
+@code{comm/lcomm/extern} declarations, provided the declared size of the
+object is less than the small data limit specified by @code{-Gnum}.
+
+Compiler generated code uses a combination of data declaration in named
+small data sections and explicitly requested GP-relative access in
+instructions in order to guarantee GP-relative access.
+
+@node General GP-relative access
+@subsection General GP-relative access
+
+If optimized access is not an objective, the full 32-bit address space
+is reachable by GP-relative addressing.  This corresponds to the large
+memory model.  For address calculation with full nanoMIPS ISA, use the
+48-bit instruction
+
+@example
+    lui $a0, %gprel_hi (foo)
+    ori $a0, $a0, %gprel_lo(foo)
+    addu $a0, $a0, $gp
+@end example
+
+For loads/stores use the following sequence:
+
+@example
+    lui $a0, %gprel_hi (foo)
+    addu $a0, $a0, $gp
+    lw $a0, %gprel_lo(foo) ($a0)
+@end example
+
+With a linker capable of doing expansions, the preferred approach is
+to use the automatic memory model with optimized GP-relative
+sequences.  The linker will convert select accesses to non-optimized
+sequences where necessary.
+
+
+@node 32-bit absolute addressing and immediate construction
+@subsection 32-bit absolute addressing and immediate construction
+
+The nanoMIPS assembler provides macros which automatically find the
+best way to materialize an address of immediate value in a
+register.  The macros are called li and la for constants and addresses
+respectively.  This section demonstrates explicit coding methods for
+predictable code size and addressing modes.
+
+Address calculation for full nanoMIPS ISA with 48-bit instructions can
+trivially be done with
+
+@example
+    li $a0, foo
+@end example
+
+With only 32-bit instructions or when restricted to the nanoMIPS
+subset, use the following combination:
+
+@example
+    lui $a0, %hi(foo)
+    ori $a0, %lo(foo)
+@end example
+
+Immediate construction for full nanoMIPS ISA can be trivially done with:
+
+@example
+    li $a0, @var{imm}
+@end example
+
+Here, depending on the immediate value, the assembler will pick a
+16-bit, 32-bit or 48-bit instruction.
+
+For immediate construction using only 32-bit instructions, or when
+restricted to the nanoMIPS subset, the preferred option is:
+
+@example
+    lui $a0, %hi(@var{imm})
+    ori $a0, %lo(@var{imm})
+@end example
+
+This sequence breaks the immediate value in to a 20-bit high part and
+a 12-bit unsigned low part.  However, the traditional (16-bit high +
+16-bit signed-low) form, typical to MIPS, is also supported:
+
+@example
+    lui $a0, @code{imm_hi16}
+    addiu $a0,  @code{imm_lo16}
+@end example
+
+Here,
+@display
+@code{imm_lo16} = (short) @code{imm} and @code{imm_hi16} = ((@code{imm} - @code{imm_lo16}) >> 16)
+@end display
+These interpretations borrow from the definition of %hi & %lo on
+MIPS, so that MIPS code can continue to work correctly on
+nanoMIPS.  Note the use of ADDIU instruction for the signed low-part.
+
+@node PC-relative addressing
+@subsection PC-relative addressing
+
+Address calculation within a +-1MB region of current PC can be done
+with a single 32-bit instruction:
+
+@example
+    lapc.h $a0, foo
+@end example
+
+For full nanoMIPS ISA, the example below selects a 48-bit instruction
+which can reach any address within 32-bits (+-2GB) of the PC.
+
+@example
+    lapc.b $a0, foo
+@end example
+
+For address calculation using only 32-bit instructions, or when
+restricted to the nanoMIPS subset, use:
+
+@example
+    aluipc $a0, %pcrel_hi (foo)
+    ori $a0, $a0, %lo(foo)
+@end example
+
+The ALUIPC instruction generates a 4k-aligned address, unlike
+MIPS.  This can be considered as the address of the 4k page that
+contains the address foo.  The subsequent ORI introduces the offset
+within that 4k page and is not really PC-relative.  The user can insert
+any number of instructions between the high & low part calculations
+above, without having to adjust the addend for the low part.  Owing to
+these differences, the typical MIPS PC-relative address calculation
+fragment below will NOT work correctly on nanoMIPS:
+
+@example
+    aluipc $a0, %pcrel_hi (foo) ; not 4k-aligned
+    ori $a0, $a0, %pcrel_lo(foo+4) ; addend reflects difference in
+                                   ; PC of high and low steps
+@end example
+
+PC-relative address calculation typically needs more power than the
+corresponding absolute address calculation.  The latter should be
+preferred for low-power applications, whenever possible.
+
+@node Indirect addressing for small PIC model
+@subsection Indirect addressing for small PIC model (-fpic)
+
+The linker places the GOT section in the small data area.  GOT entries
+can be directly accessed as:
+
+@example
+    lw $a0, %got_disp (foo) ($gp)
+@end example
+
+This mechanism is agnostic to symbol visibility or preemption.  A
+capable linker will relax or expand the sequence to optimized the
+access.  The linker may also place small data directly in the
+GP-relative region, so even when the GOT section is less than 2MiB, it
+may be too big to satisfy medium memory model constraints.
+
+@node Indirect addressing for large PIC model
+@subsection Indirect addressing for large PIC model (-fPIC)
+
+When the GOT spills out of the GP-relative range, 32-bit displacements
+are required.  Calculating displacements relative to the PC instead of
+GP is preferred, since it gives shorter load sequences.  For the full
+nanoMIPS ISA, this can be done with a single 48-bit instruction:
+
+@example
+    lwpc $a0, %got_pcrel32 (foo)
+@end example
+
+For address calculation using only 32-bit instructions, or when
+restricted to the nanoMIPS subset, use:
+
+@example
+    aluipc $a0, %got_pcrel_hi (foo)
+    lw $a0, %got_lo (foo) ($a0)
+@end example
+
+As with GP-relative access, the preferred approach is to use small PIC
+sequences and let the linker convert select accesses to large PIC
+sequences where necessary.
+
+@node nanoMIPS Instruction Selection
+@section Controlling Instruction Selection
+
+@subsection Syntax for instruction selection
+
+The nanoMIPS ISA can use the same primary mnemonic to denote multiple
+target instructions.  This happens when the ISA has encodings of an
+instruction with different instruction sizes, or of same instruction
+size but with different operand types.  The assembler syntax allows 2
+ways for the user to specify the target instruction for such a
+mnemonic:
+
+@enumerate
+@item
+Size-suffixes (16/32/48) can be used to force the instruction size.  If
+there is no instruction of the specified size of if the operands do
+not match for that size, the instruction will be rejected.  It is
+guaranteed that neither the assembler nor the linker will expand an
+explicitly sized instruction in to multiple instructions.  The linker
+may still translate this instruction to another, more efficient
+instruction of the same size.
+
+@example
+    balc16 foo     # 16-bit call, fails if foo is outside
+                   # 11-bit signed range
+    li32 $a0, 100  # force 32-bit instruction even though
+                   # 16-bit encoding is possible
+    addiu48 $a0, $a1, 1000  # force 48-bit instruction even
+                      # though 32-bit encoding is possible
+@end example
+
+By default, the assembler will always select the smallest sized
+instruction for the given operands.  Size suffixes are useful when
+constructing branch tables, to ensure that all blocks within the table
+have the same size.
+
+@item
+Format suffixes from the architecture reference manual can also be
+used to select a specific encoding.  Suffixes are enclosed in square
+brackets, matching the convention used in the architecture
+reference.  If the operands do not match the format suffix, the
+instruction will be rejected.  It is guaranteed that neither the
+assembler nor the linker will expand an explicitly selected
+instruction in to multiple instructions or translate it in to any
+other instruction.
+
+@example
+    addiu[gp.w] $a0, $gp, %gprel(foo) # word-aligned GP-relative
+                                      # address calculation
+    lw[s9] $a0, 128($a1)  # load word with signed 9-bit offset even
+                          # when unsigned 12-bit is possible
+    addu[4x4] $s2, $s3, $s2  # select  4-bit register encoding
+@end example
+
+The ability to specify format suffixes serves little practical
+purpose, since the tools will try to find the most efficient encoding
+for an operation.  It is provided as an aid for development and
+testing.  For example, the @code{[4x4]} suffix in the case above forces the
+assembler to check whether the operands satisfy the requested
+encoding.
+@end enumerate
+
+@subsection Options to control instruction disassembly
+
+The assembler provides multiple instruction formats and mnemonics to
+target the same instruction encoding by means of 1:1 aliases.  There
+are 2 disassembler options that control how instructions may be
+disassembled:
+
+@table @code
+@item -Mno-aliases
+Disassembles all variants of an instruction to its most generic
+representation
+
+@item -Mshow-arch-insn
+Prints the format suffix for each instruction in square brackets
+according to the architecture reference manual.  This only affects the
+disassembly of those instructions that have format suffixes.
+@end table
+
+@node nanoMIPS Transformations
+@section Controlling Linker Relaxation
+
+nanoMIPS ABI provides support for linker relaxations and
+expansions.  Relaxation means that the linker can remove a group of
+instructions (typically, 1 or 2) or translate them in to more
+efficient sequences.  Expansion is the translation of an instruction
+which would be out-of-range due to code or data layout, in to a
+sequence capable of expressing the necessary extended range.  The
+assembler provides directives and command-line options to control
+linker transformations.
+
+@menu
+* nanoMIPS relax modules:: Module level control
+* nanoMIPS relax fragments:: Controlling relaxation of code fragments
+* nanoMIPS relax special:: Special handling of assembly constructs
+@end menu
+
+@node nanoMIPS relax modules
+@subsection Module level control
+
+Linker relaxations is disabled by default in the assembler.  It can be
+enabled for an assembly unit using the command-line option
+@option{--linkrelax} The assembly directive @code{.linkrelax'} also
+has the same effect.  It must be specified before any instruction in
+the assembly file.
+
+@node nanoMIPS relax fragments
+@subsection Controlling relaxation of code fragments
+
+@subsubsection Control by blocks
+
+The directive @code{.set nolinkrelax} can be used to inhibit relaxation
+within an assembly file, until a corresponding @code{.set linkrelax}
+directive is encountered.  This is only effective when linker
+relaxation is enabled for the assembly unit.  This can be used for
+low-level code which employs fixed PC-relative offsets or for vectored
+tables where each code element must be of the same fixed size.  These
+directives cause the assembler to emit relocations to mark the point
+where relaxation is to be enabled or disabled.
+
+For example, the following fragment disables linker relaxation only
+for the setup and call to foo:
+
+@example
+    .set nolinkrelax
+    beq $a0, $a1, 8
+    move $a0, $t8
+    sw $a4, 0($t8)
+    balc foo
+    .set linkrelax
+@end example
+
+The following fragment disables linker relaxation for the function foo:
+@example
+        .text
+        .set nolinkrelax
+        .type    foo,@@function
+    foo:
+        ...
+        jr $ra
+        .set linkrelax
+@end example
+
+@subsubsection One instruction at a time
+
+Each instruction can be marked to say that no relaxation or
+transformation is to be performed on this instruction.  This is done
+the creating an explicit @samp{R_NANOMIPS_FIXED} relocation for
+it.  This is automatically extended to cases where the user requests an
+instruction with a specific encoding.  For example, both fragments
+below have the same effect, which is to disallow any kind of
+transformation by the linker, even as the PC-relative relocation gets
+fixed up correctly.
+
+@example
+        .reloc    1f, R_NANOMIPS_FIXED
+    1:    lapc $a0, foo
+@end example
+
+@example
+    lapc[32] $a0, foo
+@end example
+@subsubsection By instruction size
+
+It is possible to let the linker perform translations while keeping
+the instruction size fixed.  The assembler does this automatically when
+an instruction has a size-suffix.  This is useful for creating branch
+tables or vector tables, where each element is required to have the
+same size, specified at assembly time.  For example,
+@example
+    vtable:
+        bc32 foo
+        bc32 bar
+        bc32 baz
+@end example
+@node nanoMIPS relax special
+@subsection Special handling of assembly constructs
+
+Certain assembly constructs need special handling by way of marker
+relocations to allow linker translations to happen correctly.  The
+objective is to capture all the information necessary to preserve
+correctness, that is available at assembly time but not available at
+link time.
+
+@subsubsection Alignment Directives
+
+Alignment directives have the effect of padding the location counter
+to a specific boundary.  The GNU assembler also accepts a fill pattern
+to be used for the padding and the maximum amount of padding to be
+inserted.  When the linker expands or relaxes instructions, any
+alignment point following those instructions is liable to move.  If the
+alignment point moves backwards, some of the padding inserted by the
+assembler can be removed.  If it move forward, more padding, possibly
+of a user-specified pattern needs to be inserted.  In this case, the
+total amount of padding, including what is inserted by the assembler
+and the linker, must not exceed the user-specified maximum
+padding.  The assembler will emit an @samp{R_NANOMIPS_ALIGN} relocation
+for each alignment point and an @samp{R_NANOMIPS_FILL} relocation
+where user-specified padding is required.  The exact details of the
+alignment and padding relocations are covered in the nanoMIPS P32 psABI
+supplement.
+
+@subsubsection Save/restore markers
+
+The nanoMIPS ABI allows SAVE & RESTORE instructions to be relaxed from
+32-bit to 16-bit encodings as a consequence of GP-setup
+optimization.  These instructions are not relocated, so the linker
+needs additional markers to be emitted in order to find these
+instructions.  These markers are needed only when generating position
+independent code, if the assembler selects a 32-bit encoding for a
+SAVE or RESTORE operation and saves $gp.  These markers are emitted
+automatically by the assembler when relaxations are enabled.
+
+@subsubsection Label-difference expressions
+
+Label difference expressions are used to create jump tables and
+calculate code offsets.  If any code between 2 labels undergoes
+relaxation or expansion, the difference between the labels can
+change.  On the other hand, if there is no relocation or relaxable code
+between 2 labels, then their difference can be considered as constant,
+or fixed at assembly.  A label difference that can change due to
+relaxation must be represented by relocations so that it may be
+re-calculated after relaxation.  The assembler takes care of deciding
+if label difference relocations are needed and emitting them, so the
+user can use label differences in assembly code even in the presence
+of linker relaxation.
+
+@node nanoMIPS Syntax
+@section Syntactical Considerations
+@menu
+* nanoMIPS-Chars::                Special Characters
+@end menu
+
+@node nanoMIPS-Chars
+@subsection Special Characters
+
+@cindex line comment character, nanoMIPS
+@cindex nanoMIPS line comment character
+The presence of a @samp{#} on a line indicates the start of a comment
+that extends to the end of the current line.
+
+If a @samp{#} appears as the first character of a line, the whole line
+is treated as a comment, but in this case the line can also be a
+logical line number directive (@pxref{Comments}) or a
+preprocessor control command (@pxref{Preprocessing}).
+
+@cindex line separator, nanoMIPS
+@cindex statement separator, nanoMIPS
+@cindex nanoMIPS line separator
+The @samp{;} character can be used to separate statements on the same
+line.
diff --git a/ld/gen-doc.texi b/ld/gen-doc.texi
index 561869f485a..2c98698482a 100644
--- a/ld/gen-doc.texi
+++ b/ld/gen-doc.texi
@@ -15,6 +15,7 @@
 @set M68HC11
 @set M68K
 @set MIPS
+@set nanoMIPS
 @set MMIX
 @set MSP430
 @set NDS32
diff --git a/ld/ld.texi b/ld/ld.texi
index 9d6618a4307..caf4d7e4a8e 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -27,6 +27,7 @@
 @set M68HC11
 @set M68K
 @set MIPS
+@set nanoMIPS
 @set MMIX
 @set MSP430
 @set NDS32
@@ -152,6 +153,9 @@ in the section entitled ``GNU Free Documentation License''.
 @ifset MIPS
 * MIPS::                        ld and MIPS family
 @end ifset
+@ifset nanoMIPS
+* nanoMIPS::                    ld and nanoMIPS family
+@end ifset
 @ifset POWERPC
 * PowerPC ELF32::               ld and PowerPC 32-bit ELF Support
 @end ifset
@@ -3990,6 +3994,39 @@ executables.  If a shared library is generated with a DSBT index of 0, the
 The @samp{--no-merge-exidx-entries} switch disables the merging of adjacent
 exidx entries in frame unwind info.
 
+@kindex --compact-branches
+@item --compact-branches
+@kindex --no-compact-branches
+@item --compact-branches
+These options control the generation of compact instructions by the linker
+in the PLT entries for MIPS R6.
+
+@end table
+
+@c man end
+@end ifset
+
+@ifset nanoMIPS
+@subsection Options specific to nanoMIPS targets
+
+@c man begin OPTIONS
+
+The following options are supported to control link time expansion and
+relaxation rules.
+
+@table @gcctabopt
+
+@kindex --insn32
+@item --insn32
+@kindex --no-insn32
+@itemx --no-insn32
+These options control the choice of nanoMIPS instructions used in code
+generated by the linker, such as that in the PLT or lazy binding stubs,
+or in relaxation.  If @samp{--insn32} is used, then the linker only uses
+32-bit instruction encodings.  By default or if @samp{--no-insn32} is
+used, all instruction encodings are used, including 16-bit ones where
+possible.
+
 @end table
 
 @c man end
-- 
2.39.5