Address review feedback: update docs and clarify comments for 128-bit support

- Document the new 128-bit UInt/Int limits (and the platform-support
  caveat) in the language reference, and note the unchanged 64-bit limit
  on bits types, including anonymous bits.
- Move the bits-size note out of testdata/int128_sizes.emb into the docs.
- Reword test comments (drop "now"; -(2**120) instead of ambiguous
  -2**120) and use a hex literal in the text-format test so the value is
  easy to relate to the expected shifted constant.
- Explain the LeastWidthInteger rounding-up recursion in a comment and
  make the no-int128 static_assert message say why the width is
  unsupported.
diff --git a/compiler/back_end/cpp/testcode/int128_sizes_test.cc b/compiler/back_end/cpp/testcode/int128_sizes_test.cc
index 33091fd..3e18f87 100644
--- a/compiler/back_end/cpp/testcode/int128_sizes_test.cc
+++ b/compiler/back_end/cpp/testcode/int128_sizes_test.cc
@@ -385,10 +385,11 @@
   EXPECT_TRUE(::emboss::UpdateFromText(writer, "{nine_byte: -12345}"));
   EXPECT_EQ(static_cast<__int128_t>(-12345), writer.nine_byte().Read());
 
-  // A large negative 128-bit value (-2**120) does not fit in 64 bits; it must
-  // round-trip through the decimal text format.
+  // A large negative 128-bit value, -(2**120), does not fit in 64 bits.  (The
+  // WriteToString round-trip below covers the equivalent decimal text,
+  // -1329227995784915872903807060280344576.)
   EXPECT_TRUE(::emboss::UpdateFromText(
-      writer, "{sixteen_byte: -1329227995784915872903807060280344576}"));
+      writer, "{sixteen_byte: -0x1000000000000000000000000000000}"));
   EXPECT_EQ(-(static_cast<__int128_t>(1) << 120), writer.sixteen_byte().Read());
 
   // Round-trip through WriteToString and back.
diff --git a/compiler/front_end/constraints_test.py b/compiler/front_end/constraints_test.py
index eaba409..16385cb 100644
--- a/compiler/front_end/constraints_test.py
+++ b/compiler/front_end/constraints_test.py
@@ -235,7 +235,7 @@
         )
 
     def test_bits_field_too_big_for_type(self):
-        # UInt now supports up to 128 bits, so test with 129 bits (17 bytes)
+        # UInt supports up to 128 bits, so test with 129 bits (17 bytes)
         ir = _make_ir_from_emb(
             "struct Foo:\n"
             "  0 [+17]  UInt  uint136\n"
@@ -468,7 +468,7 @@
         )
 
     def test_explicit_size_too_big(self):
-        # UInt now supports up to 128 bits, so test with 256 bits (32 bytes)
+        # UInt supports up to 128 bits, so test with 256 bits (32 bytes)
         # to ensure we get the "Requirements of UInt not met" error
         ir = _make_ir_from_emb(
             "struct Foo:\n"
diff --git a/doc/language-reference.md b/doc/language-reference.md
index db8682e..5b28e40 100644
--- a/doc/language-reference.md
+++ b/doc/language-reference.md
@@ -873,6 +873,10 @@
 as other `bits`, `UInt`, `Bcd`, `Flag`).  Byte-oriented types, such as
 `struct`s, may not be embedded in a `bits`.
 
+A `bits` must be fixed size, and may be no more than 64 bits in total size.
+Note that this limit is smaller than the 128-bit maximum size of a `UInt` or
+`Int` field in a `struct`.
+
 For example:
 
 ```
@@ -950,6 +954,11 @@
 In this case, the fields of the `bits` will be treated as though they are fields
 of the outer struct.
 
+Like any other `bits`, an anonymous `bits` is limited to 64 bits in total size,
+even though the enclosing `struct` may contain integer fields of up to 128
+bits.  Supporting larger `bits` would require additional implementation work in
+the compiler and runtime.
+
 
 #### Inline `bits`
 
@@ -1078,17 +1087,29 @@
 
 ### `UInt`
 
-A `UInt` is an unsigned integer.  `UInt` can be anywhere from 1 to 64 bits in
+A `UInt` is an unsigned integer.  `UInt` can be anywhere from 1 to 128 bits in
 size, and may be used both in `struct`s and in `bits`.  `UInt` fields may be
 referenced in integer expressions.
 
+`UInt`s larger than 64 bits require 128-bit integer support from the target
+platform: for the C++ backend, a compiler that provides `__uint128_t` (detected
+via `EMBOSS_HAS_INT128`).  On platforms without 128-bit integer support,
+generated code for fields larger than 64 bits will fail to compile.  Since
+`bits` types are limited to 64 bits in total size, `UInt`s larger than 64 bits
+can only be used in `struct`s.  `UInt` fields larger than 64 bits cannot be
+referenced in integer expressions.
+
 
 ### `Int`
 
 An `Int` is a signed two's-complement integer.  `Int` can be anywhere from 1 to
-64 bits in size, and may be used both in `struct`s and in `bits`.  `Int` fields
+128 bits in size, and may be used both in `struct`s and in `bits`.  `Int` fields
 may be referenced in integer expressions.
 
+Like `UInt`, `Int`s larger than 64 bits require 128-bit integer support from
+the target platform (for the C++ backend, `__int128_t`), can only be used in
+`struct`s, and cannot be referenced in integer expressions.
+
 
 ### `Bcd`
 
diff --git a/runtime/cpp/emboss_cpp_types.h b/runtime/cpp/emboss_cpp_types.h
index 1ef0b58..a9dd9f7 100644
--- a/runtime/cpp/emboss_cpp_types.h
+++ b/runtime/cpp/emboss_cpp_types.h
@@ -53,6 +53,14 @@
 // LeastWidthInteger<n_bits>::Unsigned is the smallest uintNN_t type that can
 // hold n_bits or more.  LeastWidthInteger<n_bits>::Signed is the corresponding
 // signed type.
+//
+// The exact-width specializations below always take precedence, so the
+// unspecialized template is only ever instantiated for widths with no
+// exact-width integer type.  It recursively "rounds up" such widths to the
+// next supported width: for example, LeastWidthInteger<12>::Unsigned
+// instantiates LeastWidthInteger<13> through LeastWidthInteger<16>, yielding
+// ::std::uint16_t.  The static_assert bounds the recursion for widths above
+// the maximum supported width.
 #if EMBOSS_HAS_INT128
 template <int kBits>
 struct LeastWidthInteger final {
@@ -68,7 +76,9 @@
 #else
 template <int kBits>
 struct LeastWidthInteger final {
-  static_assert(kBits <= 64, "Only bit sizes up to 64 are supported.");
+  static_assert(kBits <= 64,
+                "Bit widths over 64 require 128-bit integer support, which is "
+                "not available on this platform (EMBOSS_HAS_INT128 is 0).");
   using Unsigned = typename LeastWidthInteger<kBits + 1>::Unsigned;
   using Signed = typename LeastWidthInteger<kBits + 1>::Signed;
 };
diff --git a/testdata/int128_sizes.emb b/testdata/int128_sizes.emb
index 692df0b..5bb0b04 100644
--- a/testdata/int128_sizes.emb
+++ b/testdata/int128_sizes.emb
@@ -78,8 +78,3 @@
   110 [+28]  UInt:112[2]  fourteen_byte
   138 [+30]  UInt:120[2]  fifteen_byte
   168 [+32]  UInt:128[2]  sixteen_byte
-
-
-# Note: Anonymous `bits` types are still constrained to 64 bits maximum.
-# Supporting 128-bit `bits` types would require additional implementation
-# work in the OffsetBitBlock class and the constraints checker.