about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs25
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_mir/src/const_eval/fn_queries.rs2
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/validation.rs3
-rw-r--r--compiler/rustc_passes/src/stability.rs38
-rw-r--r--compiler/rustc_session/src/lint/builtin.rs11
-rw-r--r--compiler/rustc_session/src/session.rs3
-rw-r--r--compiler/rustc_span/src/hygiene.rs4
-rw-r--r--compiler/rustc_target/src/asm/mips.rs132
-rw-r--r--compiler/rustc_target/src/asm/mod.rs25
10 files changed, 228 insertions, 16 deletions
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index a468d09c2d9..f801f845ac1 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -259,6 +259,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                 InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {}
                 InlineAsmArch::Nvptx64 => {}
                 InlineAsmArch::Hexagon => {}
+                InlineAsmArch::Mips => {}
             }
         }
         if !options.contains(InlineAsmOptions::NOMEM) {
@@ -505,6 +506,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>)
             InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
             | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "w",
             InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r",
+            InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "r",
+            InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f",
             InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
             InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => "r",
             InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => "l",
@@ -551,6 +554,7 @@ fn modifier_to_llvm(
             }
         }
         InlineAsmRegClass::Hexagon(_) => None,
+        InlineAsmRegClass::Mips(_) => None,
         InlineAsmRegClass::Nvptx(_) => None,
         InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg)
         | InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => None,
@@ -603,6 +607,8 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll
             cx.type_vector(cx.type_i64(), 2)
         }
         InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
+        InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
+        InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
         InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),
         InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => cx.type_i32(),
         InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => cx.type_i64(),
@@ -700,6 +706,12 @@ fn llvm_fixup_input(
                 value
             }
         }
+        (InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => match s.value {
+            // MIPS only supports register-length arithmetics.
+            Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()),
+            Primitive::F32 => bx.bitcast(value, bx.cx.type_i32()),
+            _ => value,
+        },
         _ => value,
     }
 }
@@ -768,6 +780,13 @@ fn llvm_fixup_output(
                 value
             }
         }
+        (InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => match s.value {
+            // MIPS only supports register-length arithmetics.
+            Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()),
+            Primitive::Int(Integer::I16, _) => bx.trunc(value, bx.cx.type_i16()),
+            Primitive::F32 => bx.bitcast(value, bx.cx.type_f32()),
+            _ => value,
+        },
         _ => value,
     }
 }
@@ -831,6 +850,12 @@ fn llvm_fixup_output_type(
                 layout.llvm_type(cx)
             }
         }
+        (InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => match s.value {
+            // MIPS only supports register-length arithmetics.
+            Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(),
+            Primitive::F32 => cx.type_i32(),
+            _ => layout.llvm_type(cx),
+        },
         _ => layout.llvm_type(cx),
     }
 }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 7f7472d9283..33caedfc198 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -305,6 +305,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
     add_lint_group!(
         "rustdoc",
         BROKEN_INTRA_DOC_LINKS,
+        PRIVATE_INTRA_DOC_LINKS,
         INVALID_CODEBLOCK_ATTRIBUTES,
         MISSING_DOC_CODE_EXAMPLES,
         PRIVATE_DOC_TESTS
diff --git a/compiler/rustc_mir/src/const_eval/fn_queries.rs b/compiler/rustc_mir/src/const_eval/fn_queries.rs
index 9ef63b3322d..1db1f6ceeda 100644
--- a/compiler/rustc_mir/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_mir/src/const_eval/fn_queries.rs
@@ -50,7 +50,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
             None => {
                 if let Some(stab) = tcx.lookup_stability(def_id) {
                     if stab.level.is_stable() {
-                        tcx.sess.span_err(
+                        tcx.sess.delay_span_bug(
                             tcx.def_span(def_id),
                             "stable const functions must have either `rustc_const_stable` or \
                              `rustc_const_unstable` attribute",
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index 73725c7b98e..ee6adbc7a45 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -204,9 +204,6 @@ impl Validator<'mir, 'tcx> {
     pub fn check_body(&mut self) {
         let ConstCx { tcx, body, def_id, .. } = *self.ccx;
 
-        // HACK: This function has side-effects???? Make sure we call it.
-        let _ = crate::const_eval::is_min_const_fn(tcx, def_id.to_def_id());
-
         // The local type and predicate checks are not free and only relevant for `const fn`s.
         if self.const_kind() == hir::ConstContext::ConstFn {
             // Prevent const trait methods from being annotated as `stable`.
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index b807dff5fd2..1378b0d5705 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -459,6 +459,21 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
             self.tcx.sess.span_err(span, &format!("{} has missing stability attribute", descr));
         }
     }
+
+    fn check_missing_const_stability(&self, hir_id: HirId, span: Span) {
+        let stab_map = self.tcx.stability();
+        let stab = stab_map.local_stability(hir_id);
+        if stab.map_or(false, |stab| stab.level.is_stable()) {
+            let const_stab = stab_map.local_const_stability(hir_id);
+            if const_stab.is_none() {
+                self.tcx.sess.span_err(
+                    span,
+                    "`#[stable]` const functions must also be either \
+                    `#[rustc_const_stable]` or `#[rustc_const_unstable]`",
+                );
+            }
+        }
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
@@ -469,14 +484,23 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
     }
 
     fn visit_item(&mut self, i: &'tcx Item<'tcx>) {
-        match i.kind {
-            // Inherent impls and foreign modules serve only as containers for other items,
-            // they don't have their own stability. They still can be annotated as unstable
-            // and propagate this unstability to children, but this annotation is completely
-            // optional. They inherit stability from their parents when unannotated.
-            hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => {}
+        // Inherent impls and foreign modules serve only as containers for other items,
+        // they don't have their own stability. They still can be annotated as unstable
+        // and propagate this unstability to children, but this annotation is completely
+        // optional. They inherit stability from their parents when unannotated.
+        if !matches!(
+            i.kind,
+            hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..)
+        ) {
+            self.check_missing_stability(i.hir_id, i.span);
+        }
 
-            _ => self.check_missing_stability(i.hir_id, i.span),
+        // Ensure `const fn` that are `stable` have one of `rustc_const_unstable` or
+        // `rustc_const_stable`.
+        if self.tcx.features().staged_api
+            && matches!(&i.kind, hir::ItemKind::Fn(sig, ..) if sig.header.is_const())
+        {
+            self.check_missing_const_stability(i.hir_id, i.span);
         }
 
         intravisit::walk_item(self, i)
diff --git a/compiler/rustc_session/src/lint/builtin.rs b/compiler/rustc_session/src/lint/builtin.rs
index 13a4057a35b..0cc97fb4541 100644
--- a/compiler/rustc_session/src/lint/builtin.rs
+++ b/compiler/rustc_session/src/lint/builtin.rs
@@ -1827,6 +1827,17 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// This is a subset of `broken_intra_doc_links` that warns when linking from
+    /// a public item to a private one. This is a `rustdoc` only lint, see the
+    /// documentation in the [rustdoc book].
+    ///
+    /// [rustdoc book]: ../../../rustdoc/lints.html#private_intra_doc_links
+    pub PRIVATE_INTRA_DOC_LINKS,
+    Warn,
+    "linking from a public item to a private one"
+}
+
+declare_lint! {
     /// The `invalid_codeblock_attributes` lint detects code block attributes
     /// in documentation examples that have potentially mis-typed values. This
     /// is a `rustdoc` only lint, see the documentation in the [rustdoc book].
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index ff67d3cb107..ff5e6156d84 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1103,9 +1103,6 @@ impl Session {
         self.used_attrs.lock().is_marked(attr)
     }
 
-    /// Returns `true` if the attribute's path matches the argument. If it matches, then the
-    /// attribute is marked as used.
-
     /// Returns `true` if the attribute's path matches the argument. If it
     /// matches, then the attribute is marked as used.
     ///
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 942c6648340..fb80dcb7561 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -702,7 +702,7 @@ pub struct ExpnData {
     /// The `DefId` of the macro being invoked,
     /// if this `ExpnData` corresponds to a macro invocation
     pub macro_def_id: Option<DefId>,
-    /// The crate that originally created this `ExpnData. During
+    /// The crate that originally created this `ExpnData`. During
     /// metadata serialization, we only encode `ExpnData`s that were
     /// created locally - when our serialized metadata is decoded,
     /// foreign `ExpnId`s will have their `ExpnData` looked up
@@ -759,7 +759,7 @@ impl ExpnData {
 
     #[inline]
     pub fn is_root(&self) -> bool {
-        if let ExpnKind::Root = self.kind { true } else { false }
+        matches!(self.kind, ExpnKind::Root)
     }
 }
 
diff --git a/compiler/rustc_target/src/asm/mips.rs b/compiler/rustc_target/src/asm/mips.rs
new file mode 100644
index 00000000000..638c52d97f1
--- /dev/null
+++ b/compiler/rustc_target/src/asm/mips.rs
@@ -0,0 +1,132 @@
+use super::{InlineAsmArch, InlineAsmType};
+use rustc_macros::HashStable_Generic;
+use std::fmt;
+
+def_reg_class! {
+    Mips MipsInlineAsmRegClass {
+        reg,
+        freg,
+    }
+}
+
+impl MipsInlineAsmRegClass {
+    pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
+        &[]
+    }
+
+    pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
+        None
+    }
+
+    pub fn suggest_modifier(
+        self,
+        _arch: InlineAsmArch,
+        _ty: InlineAsmType,
+    ) -> Option<(char, &'static str)> {
+        None
+    }
+
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+        None
+    }
+
+    pub fn supported_types(
+        self,
+        _arch: InlineAsmArch,
+    ) -> &'static [(InlineAsmType, Option<&'static str>)] {
+        match self {
+            Self::reg => types! { _: I8, I16, I32, F32; },
+            Self::freg => types! { _: F32; },
+        }
+    }
+}
+
+// The reserved registers are somewhat taken from <https://git.io/JUR1k#L150>.
+def_regs! {
+    Mips MipsInlineAsmReg MipsInlineAsmRegClass {
+        v0: reg = ["$2", "$v0"],
+        v1: reg = ["$3", "$v1"],
+        a0: reg = ["$4", "$a0"],
+        a1: reg = ["$5", "$a1"],
+        a2: reg = ["$6", "$a2"],
+        a3: reg = ["$7", "$a3"],
+        // FIXME: Reserve $t0, $t1 if in mips16 mode.
+        t0: reg = ["$8", "$t0"],
+        t1: reg = ["$9", "$t1"],
+        t2: reg = ["$10", "$t2"],
+        t3: reg = ["$11", "$t3"],
+        t4: reg = ["$12", "$t4"],
+        t5: reg = ["$13", "$t5"],
+        t6: reg = ["$14", "$t6"],
+        t7: reg = ["$15", "$t7"],
+        s0: reg = ["$16", "$s0"],
+        s1: reg = ["$17", "$s1"],
+        s2: reg = ["$18", "$s2"],
+        s3: reg = ["$19", "$s3"],
+        s4: reg = ["$20", "$s4"],
+        s5: reg = ["$21", "$s5"],
+        s6: reg = ["$22", "$s6"],
+        s7: reg = ["$23", "$s7"],
+        t8: reg = ["$24", "$t8"],
+        t9: reg = ["$25", "$t9"],
+        f0: freg = ["$f0"],
+        f1: freg = ["$f1"],
+        f2: freg = ["$f2"],
+        f3: freg = ["$f3"],
+        f4: freg = ["$f4"],
+        f5: freg = ["$f5"],
+        f6: freg = ["$f6"],
+        f7: freg = ["$f7"],
+        f8: freg = ["$f8"],
+        f9: freg = ["$f9"],
+        f10: freg = ["$f10"],
+        f11: freg = ["$f11"],
+        f12: freg = ["$f12"],
+        f13: freg = ["$f13"],
+        f14: freg = ["$f14"],
+        f15: freg = ["$f15"],
+        f16: freg = ["$f16"],
+        f17: freg = ["$f17"],
+        f18: freg = ["$f18"],
+        f19: freg = ["$f19"],
+        f20: freg = ["$f20"],
+        f21: freg = ["$f21"],
+        f22: freg = ["$f22"],
+        f23: freg = ["$f23"],
+        f24: freg = ["$f24"],
+        f25: freg = ["$f25"],
+        f26: freg = ["$f26"],
+        f27: freg = ["$f27"],
+        f28: freg = ["$f28"],
+        f29: freg = ["$f29"],
+        f30: freg = ["$f30"],
+        f31: freg = ["$f31"],
+        #error = ["$0", "$zero"] =>
+            "constant zero cannot be used as an operand for inline asm",
+        #error = ["$1", "$at"] =>
+            "reserved for assembler (Assembler Temp)",
+        #error = ["$26", "$k0"] =>
+            "OS-reserved register cannot be used as an operand for inline asm",
+        #error = ["$27", "$k1"] =>
+            "OS-reserved register cannot be used as an operand for inline asm",
+        #error = ["$28", "$gp"] =>
+            "the global pointer cannot be used as an operand for inline asm",
+        #error = ["$29", "$sp"] =>
+            "the stack pointer cannot be used as an operand for inline asm",
+        #error = ["$30", "$s8", "$fp"] =>
+            "the frame pointer cannot be used as an operand for inline asm",
+        #error = ["$31", "$ra"] =>
+            "the return address register cannot be used as an operand for inline asm",
+    }
+}
+
+impl MipsInlineAsmReg {
+    pub fn emit(
+        self,
+        out: &mut dyn fmt::Write,
+        _arch: InlineAsmArch,
+        _modifier: Option<char>,
+    ) -> fmt::Result {
+        out.write_str(self.name())
+    }
+}
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index c22644bf813..e2f8e91fa95 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -152,6 +152,7 @@ macro_rules! types {
 mod aarch64;
 mod arm;
 mod hexagon;
+mod mips;
 mod nvptx;
 mod riscv;
 mod x86;
@@ -159,6 +160,7 @@ mod x86;
 pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass};
 pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass};
 pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass};
+pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass};
 pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass};
 pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass};
 pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass};
@@ -173,6 +175,7 @@ pub enum InlineAsmArch {
     RiscV64,
     Nvptx64,
     Hexagon,
+    Mips,
 }
 
 impl FromStr for InlineAsmArch {
@@ -188,6 +191,7 @@ impl FromStr for InlineAsmArch {
             "riscv64" => Ok(Self::RiscV64),
             "nvptx64" => Ok(Self::Nvptx64),
             "hexagon" => Ok(Self::Hexagon),
+            "mips" => Ok(Self::Mips),
             _ => Err(()),
         }
     }
@@ -201,6 +205,7 @@ pub enum InlineAsmReg {
     RiscV(RiscVInlineAsmReg),
     Nvptx(NvptxInlineAsmReg),
     Hexagon(HexagonInlineAsmReg),
+    Mips(MipsInlineAsmReg),
 }
 
 impl InlineAsmReg {
@@ -211,6 +216,7 @@ impl InlineAsmReg {
             Self::AArch64(r) => r.name(),
             Self::RiscV(r) => r.name(),
             Self::Hexagon(r) => r.name(),
+            Self::Mips(r) => r.name(),
         }
     }
 
@@ -221,6 +227,7 @@ impl InlineAsmReg {
             Self::AArch64(r) => InlineAsmRegClass::AArch64(r.reg_class()),
             Self::RiscV(r) => InlineAsmRegClass::RiscV(r.reg_class()),
             Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()),
+            Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
         }
     }
 
@@ -252,6 +259,9 @@ impl InlineAsmReg {
             InlineAsmArch::Hexagon => {
                 Self::Hexagon(HexagonInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
+            InlineAsmArch::Mips => {
+                Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, &name)?)
+            }
         })
     }
 
@@ -269,6 +279,7 @@ impl InlineAsmReg {
             Self::AArch64(r) => r.emit(out, arch, modifier),
             Self::RiscV(r) => r.emit(out, arch, modifier),
             Self::Hexagon(r) => r.emit(out, arch, modifier),
+            Self::Mips(r) => r.emit(out, arch, modifier),
         }
     }
 
@@ -279,6 +290,7 @@ impl InlineAsmReg {
             Self::AArch64(_) => cb(self),
             Self::RiscV(_) => cb(self),
             Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
+            Self::Mips(_) => cb(self),
         }
     }
 }
@@ -291,6 +303,7 @@ pub enum InlineAsmRegClass {
     RiscV(RiscVInlineAsmRegClass),
     Nvptx(NvptxInlineAsmRegClass),
     Hexagon(HexagonInlineAsmRegClass),
+    Mips(MipsInlineAsmRegClass),
 }
 
 impl InlineAsmRegClass {
@@ -302,6 +315,7 @@ impl InlineAsmRegClass {
             Self::RiscV(r) => r.name(),
             Self::Nvptx(r) => r.name(),
             Self::Hexagon(r) => r.name(),
+            Self::Mips(r) => r.name(),
         }
     }
 
@@ -316,6 +330,7 @@ impl InlineAsmRegClass {
             Self::RiscV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::RiscV),
             Self::Nvptx(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Nvptx),
             Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon),
+            Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
         }
     }
 
@@ -337,6 +352,7 @@ impl InlineAsmRegClass {
             Self::RiscV(r) => r.suggest_modifier(arch, ty),
             Self::Nvptx(r) => r.suggest_modifier(arch, ty),
             Self::Hexagon(r) => r.suggest_modifier(arch, ty),
+            Self::Mips(r) => r.suggest_modifier(arch, ty),
         }
     }
 
@@ -354,6 +370,7 @@ impl InlineAsmRegClass {
             Self::RiscV(r) => r.default_modifier(arch),
             Self::Nvptx(r) => r.default_modifier(arch),
             Self::Hexagon(r) => r.default_modifier(arch),
+            Self::Mips(r) => r.default_modifier(arch),
         }
     }
 
@@ -370,6 +387,7 @@ impl InlineAsmRegClass {
             Self::RiscV(r) => r.supported_types(arch),
             Self::Nvptx(r) => r.supported_types(arch),
             Self::Hexagon(r) => r.supported_types(arch),
+            Self::Mips(r) => r.supported_types(arch),
         }
     }
 
@@ -391,6 +409,7 @@ impl InlineAsmRegClass {
                 InlineAsmArch::Hexagon => {
                     Self::Hexagon(HexagonInlineAsmRegClass::parse(arch, name)?)
                 }
+                InlineAsmArch::Mips => Self::Mips(MipsInlineAsmRegClass::parse(arch, name)?),
             })
         })
     }
@@ -405,6 +424,7 @@ impl InlineAsmRegClass {
             Self::RiscV(r) => r.valid_modifiers(arch),
             Self::Nvptx(r) => r.valid_modifiers(arch),
             Self::Hexagon(r) => r.valid_modifiers(arch),
+            Self::Mips(r) => r.valid_modifiers(arch),
         }
     }
 }
@@ -545,5 +565,10 @@ pub fn allocatable_registers(
             hexagon::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
+        InlineAsmArch::Mips => {
+            let mut map = mips::regclass_map();
+            mips::fill_reg_map(arch, has_feature, target, &mut map);
+            map
+        }
     }
 }