2024-06-16 13:25:50

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH fixes 0/4] MIPS: MT ASE fixes

Hi all,

This series fixed multiple problems for MT ASE handling in current
kernel code.

PATCH 1 is critical, although it's not causing problems on MT kernel,
we are risking clobbering register here.

Rest are usual build fixes for adopting toolcahins.

Please apply it to fixes tree.

Thanks.
- Jiaxun

Signed-off-by: Jiaxun Yang <[email protected]>
---
Jiaxun Yang (4):
MIPS: mipsmtregs: Fix target register for MFTC0
MIPS: asmmacro: Fix MT ASE macros
MIPS: cps-vec: Replace MT instructions with macros
MIPS: Use toolchain MT ASE support whenever possible

arch/mips/Makefile | 2 +
arch/mips/include/asm/asmmacro.h | 241 +++++++++++++++++++++++++++++++++----
arch/mips/include/asm/mipsmtregs.h | 42 ++++++-
arch/mips/kernel/cps-vec.S | 62 ++++------
4 files changed, 287 insertions(+), 60 deletions(-)
---
base-commit: 6906a84c482f098d31486df8dc98cead21cce2d0
change-id: 20240616-mips-mt-fixes-50eb56d2159c

Best regards,
--
Jiaxun Yang <[email protected]>



2024-06-16 13:25:59

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH fixes 1/4] MIPS: mipsmtregs: Fix target register for MFTC0

Target register of mftc0 should be __res instead of $1, this is
a leftover from old .insn code.

Fixes: dd6d29a61489 ("MIPS: Implement microMIPS MT ASE helpers")
Cc: [email protected]
Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/include/asm/mipsmtregs.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h
index 30e86861c206..b1ee3c48e84b 100644
--- a/arch/mips/include/asm/mipsmtregs.h
+++ b/arch/mips/include/asm/mipsmtregs.h
@@ -322,7 +322,7 @@ static inline void ehb(void)
" .set push \n" \
" .set "MIPS_ISA_LEVEL" \n" \
_ASM_SET_MFTC0 \
- " mftc0 $1, " #rt ", " #sel " \n" \
+ " mftc0 %0, " #rt ", " #sel " \n" \
_ASM_UNSET_MFTC0 \
" .set pop \n" \
: "=r" (__res)); \

--
2.43.0


2024-06-16 13:26:17

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH fixes 2/4] MIPS: asmmacro: Fix MT ASE macros

Introduce and use parse_r from C inline assembly equivalent to parse
assembly register names properly.

Fix MTTR macro to include h parameter, also mark parameters besides
h mandatory.

Implement MFTC0, MTTC0, MFTGPR, MTTGPR with MTTR.

Rename all macros to prefix with _, as assmbly macros are case
insensitive, we are risking clash with assembler instructions
if we just use capitalized instruction name as macro name.

Cc: [email protected]
Signed-off-by: Jiaxun Yang <[email protected]>
---
This patch has two over long lines on raw instruction words (104),
I don't think it's a good idea to split it into multiple lines
as it only cause difficulties on reading the code.
---
arch/mips/include/asm/asmmacro.h | 166 ++++++++++++++++++++++++++++++++++-----
1 file changed, 148 insertions(+), 18 deletions(-)

diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
index 18c2ae58cdf3..6eadd59f53e9 100644
--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -44,6 +44,112 @@
.endm
#endif

+/*
+ * parse_r var, r - Helper assembler macro for parsing register names.
+ */
+.macro parse_r var r
+ \var = -1
+ .ifc \r, $0
+ \var = 0
+ .endif
+ .ifc \r, $1
+ \var = 1
+ .endif
+ .ifc \r, $2
+ \var = 2
+ .endif
+ .ifc \r, $3
+ \var = 3
+ .endif
+ .ifc \r, $4
+ \var = 4
+ .endif
+ .ifc \r, $5
+ \var = 5
+ .endif
+ .ifc \r, $6
+ \var = 6
+ .endif
+ .ifc \r, $7
+ \var = 7
+ .endif
+ .ifc \r, $8
+ \var = 8
+ .endif
+ .ifc \r, $9
+ \var = 9
+ .endif
+ .ifc \r, $10
+ \var = 10
+ .endif
+ .ifc \r, $11
+ \var = 11
+ .endif
+ .ifc \r, $12
+ \var = 12
+ .endif
+ .ifc \r, $13
+ \var = 13
+ .endif
+ .ifc \r, $14
+ \var = 14
+ .endif
+ .ifc \r, $15
+ \var = 15
+ .endif
+ .ifc \r, $16
+ \var = 16
+ .endif
+ .ifc \r, $17
+ \var = 17
+ .endif
+ .ifc \r, $18
+ \var = 18
+ .endif
+ .ifc \r, $19
+ \var = 19
+ .endif
+ .ifc \r, $20
+ \var = 20
+ .endif
+ .ifc \r, $21
+ \var = 21
+ .endif
+ .ifc \r, $22
+ \var = 22
+ .endif
+ .ifc \r, $23
+ \var = 23
+ .endif
+ .ifc \r, $24
+ \var = 24
+ .endif
+ .ifc \r, $25
+ \var = 25
+ .endif
+ .ifc \r, $26
+ \var = 26
+ .endif
+ .ifc \r, $27
+ \var = 27
+ .endif
+ .ifc \r, $28
+ \var = 28
+ .endif
+ .ifc \r, $29
+ \var = 29
+ .endif
+ .ifc \r, $30
+ \var = 30
+ .endif
+ .ifc \r, $31
+ \var = 31
+ .endif
+ .iflt \var
+ .error "Unable to parse register name \r"
+ .endif
+.endm
+
#ifdef CONFIG_CPU_HAS_DIEI
.macro local_irq_enable
ei
@@ -215,34 +321,58 @@
/*
* Temporary until all gas have MT ASE support
*/
- .macro DMT reg=0
- insn_if_mips 0x41600bc1 | (\reg << 16)
- insn32_if_mm 0x0000057C | (\reg << 21)
+ .macro _dmt reg = $0
+ parse_r __reg, \reg
+ insn_if_mips 0x41600bc1 | (__reg << 16)
+ insn32_if_mm 0x0000057C | (__reg << 21)
+ .endm
+
+ .macro _emt reg = $0
+ parse_r __reg, \reg
+ insn_if_mips 0x41600be1 | (__reg << 16)
+ insn32_if_mm 0x0000257C | (__reg << 21)
+ .endm
+
+ .macro _dvpe reg = $0
+ parse_r __reg, \reg
+ insn_if_mips 0x41600001 | (__reg << 16)
+ insn32_if_mm 0x0000157C | (__reg << 21)
+ .endm
+
+ .macro _evpe reg = $0
+ parse_r __reg, \reg
+ insn_if_mips 0x41600021 | (__reg << 16)
+ insn32_if_mm 0x0000357C | (__reg << 21)
+ .endm
+
+ .macro _mftr rs, rt, u, sel, h = 0
+ parse_r __rs, \rs
+ parse_r __rt, \rt
+ insn_if_mips 0x41000000 | (__rt << 16) | (__rs << 11) | (\u << 5) | (\h << 3) | (\sel)
+ insn32_if_mm 0x0000000E | (__rt << 21) | (__rs << 16) | (\u << 10) | (\h << 9) | (\sel << 4)
.endm

- .macro EMT reg=0
- insn_if_mips 0x41600be1 | (\reg << 16)
- insn32_if_mm 0x0000257C | (\reg << 21)
+ .macro _mttr rt, rs, u, sel, h = 0
+ parse_r __rs, \rs
+ parse_r __rt, \rt
+ insn_if_mips 0x41800000 | (__rt << 16) | (__rs << 11) | (\u << 5) | (\h << 3) | (\sel)
+ insn32_if_mm 0x00000006 | (__rt << 21) | (__rs << 16) | (\u << 10) | (\h << 9) | (\sel << 4)
.endm

- .macro DVPE reg=0
- insn_if_mips 0x41600001 | (\reg << 16)
- insn32_if_mm 0x0000157C | (\reg << 21)
+ .macro _mftc0 rs, rt, sel = 0
+ _mftr \rs, \rt, 0, \sel, 0
.endm

- .macro EVPE reg=0
- insn_if_mips 0x41600021 | (\reg << 16)
- insn32_if_mm 0x0000357C | (\reg << 21)
+ .macro _mttc0 rt, rs, sel = 0
+ _mttr \rt, \rs, 0, \sel, 0
.endm

- .macro MFTR rs=0, rt=0, u=0, sel=0
- insn_if_mips 0x41000000 | (\rt << 16) | (\rs << 11) | (\u << 5) | (\sel)
- insn32_if_mm 0x0000000E | (\rt << 21) | (\rs << 16) | (\u << 10) | (\sel << 4)
+ .macro _mftgpr rs, rt
+ _mftr \rs, \rt, 1, 0, 0
.endm

- .macro MTTR rt=0, rs=0, u=0, sel=0
- insn_if_mips 0x41800000 | (\rt << 16) | (\rs << 11) | (\u << 5) | (\sel)
- insn32_if_mm 0x00000006 | (\rt << 21) | (\rs << 16) | (\u << 10) | (\sel << 4)
+ .macro _mttgpr rs, rt
+ _mttr \rt, \rs, 1, 0, 0
.endm

#ifdef TOOLCHAIN_SUPPORTS_MSA

--
2.43.0


2024-06-16 13:26:39

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH fixes 3/4] MIPS: cps-vec: Replace MT instructions with macros

Replace MT instructions with macros to deal with assemblers
not supporting MT ASE properly.

Remove all .set mt as they are going to be handled in macros.

Cc: [email protected]
Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/kernel/cps-vec.S | 62 ++++++++++++++++++----------------------------
1 file changed, 24 insertions(+), 38 deletions(-)

diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index f876309130ad..5a4120ce4a56 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -195,15 +195,11 @@ LEAF(mips_cps_core_init)
/* Check that the core implements the MT ASE */
has_mt t0, 3f

- .set push
- .set MIPS_ISA_LEVEL_RAW
- .set mt
-
/* Only allow 1 TC per VPE to execute... */
- dmt
+ _dmt

/* ...and for the moment only 1 VPE */
- dvpe
+ _dvpe
PTR_LA t1, 1f
jr.hb t1
nop
@@ -231,20 +227,20 @@ LEAF(mips_cps_core_init)
ehb

/* Bind TC to VPE (1:1 TC:VPE mapping) */
- mttc0 ta1, CP0_TCBIND
+ _mttc0 ta1, CP0_TCBIND

/* Set exclusive TC, non-active, master */
li t0, VPECONF0_MVP
sll t1, ta1, VPECONF0_XTC_SHIFT
or t0, t0, t1
- mttc0 t0, CP0_VPECONF0
+ _mttc0 t0, CP0_VPECONF0

/* Set TC non-active, non-allocatable */
- mttc0 zero, CP0_TCSTATUS
+ _mttc0 zero, CP0_TCSTATUS

/* Set TC halted */
li t0, TCHALT_H
- mttc0 t0, CP0_TCHALT
+ _mttc0 t0, CP0_TCHALT

/* Next VPE */
addiu ta1, ta1, 1
@@ -257,7 +253,7 @@ LEAF(mips_cps_core_init)
xori t0, t0, MVPCONTROL_VPC
mtc0 t0, CP0_MVPCONTROL

-3: .set pop
+3:
#endif
jr ra
nop
@@ -353,11 +349,7 @@ LEAF(mips_cps_boot_vpes)
has_mt t0, 5f

/* Enter VPE configuration state */
- .set push
- .set MIPS_ISA_LEVEL_RAW
- .set mt
- dvpe
- .set pop
+ _dvpe

PTR_LA t1, 1f
jr.hb t1
@@ -384,12 +376,8 @@ LEAF(mips_cps_boot_vpes)
mtc0 t0, CP0_VPECONTROL
ehb

- .set push
- .set MIPS_ISA_LEVEL_RAW
- .set mt
-
/* Skip the VPE if its TC is not halted */
- mftc0 t0, CP0_TCHALT
+ _mftc0 t0, CP0_TCHALT
beqz t0, 2f
nop

@@ -400,19 +388,19 @@ LEAF(mips_cps_boot_vpes)

/* Set the TC restart PC */
lw t1, VPEBOOTCFG_PC(t0)
- mttc0 t1, CP0_TCRESTART
+ _mttc0 t1, CP0_TCRESTART

/* Set the TC stack pointer */
lw t1, VPEBOOTCFG_SP(t0)
- mttgpr t1, sp
+ _mttgpr t1, sp

/* Set the TC global pointer */
lw t1, VPEBOOTCFG_GP(t0)
- mttgpr t1, gp
+ _mttgpr t1, gp

/* Copy config from this VPE */
mfc0 t0, CP0_CONFIG
- mttc0 t0, CP0_CONFIG
+ _mttc0 t0, CP0_CONFIG

/*
* Copy the EVA config from this VPE if the CPU supports it.
@@ -423,30 +411,30 @@ LEAF(mips_cps_boot_vpes)
beqz t0, 3f
nop
mfc0 t0, CP0_SEGCTL0
- mttc0 t0, CP0_SEGCTL0
+ _mttc0 t0, CP0_SEGCTL0
mfc0 t0, CP0_SEGCTL1
- mttc0 t0, CP0_SEGCTL1
+ _mttc0 t0, CP0_SEGCTL1
mfc0 t0, CP0_SEGCTL2
- mttc0 t0, CP0_SEGCTL2
+ _mttc0 t0, CP0_SEGCTL2
3:
/* Ensure no software interrupts are pending */
- mttc0 zero, CP0_CAUSE
- mttc0 zero, CP0_STATUS
+ _mttc0 zero, CP0_CAUSE
+ _mttc0 zero, CP0_STATUS

/* Set TC active, not interrupt exempt */
- mftc0 t0, CP0_TCSTATUS
+ _mftc0 t0, CP0_TCSTATUS
li t1, ~TCSTATUS_IXMT
and t0, t0, t1
ori t0, t0, TCSTATUS_A
- mttc0 t0, CP0_TCSTATUS
+ _mttc0 t0, CP0_TCSTATUS

/* Clear the TC halt bit */
- mttc0 zero, CP0_TCHALT
+ _mttc0 zero, CP0_TCHALT

/* Set VPE active */
- mftc0 t0, CP0_VPECONF0
+ _mftc0 t0, CP0_VPECONF0
ori t0, t0, VPECONF0_VPA
- mttc0 t0, CP0_VPECONF0
+ _mttc0 t0, CP0_VPECONF0

/* Next VPE */
2: srl ta2, ta2, 1
@@ -459,9 +447,7 @@ LEAF(mips_cps_boot_vpes)
xori t1, t1, MVPCONTROL_VPC
mtc0 t1, CP0_MVPCONTROL
ehb
- evpe
-
- .set pop
+ _evpe

/* Check whether this VPE is meant to be running */
li t0, 1

--
2.43.0


2024-06-16 13:26:46

by Jiaxun Yang

[permalink] [raw]
Subject: [PATCH fixes 4/4] MIPS: Use toolchain MT ASE support whenever possible

Probe toolchain support to MT ASE and use it in code whenever
possible.

Fix build on MIPS downstream toolchain that is not really happy
with our .insn usage.

Cc: [email protected]
Signed-off-by: Jiaxun Yang <[email protected]>
---
arch/mips/Makefile | 2 +
arch/mips/include/asm/asmmacro.h | 75 ++++++++++++++++++++++++++++++++++++--
arch/mips/include/asm/mipsmtregs.h | 40 ++++++++++++++++++++
3 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 80aecba24892..e3d1c5a0e8e9 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -257,6 +257,8 @@ toolchain-dsp := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mdsp)
cflags-$(toolchain-dsp) += -DTOOLCHAIN_SUPPORTS_DSP
toolchain-ginv := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mginv)
cflags-$(toolchain-ginv) += -DTOOLCHAIN_SUPPORTS_GINV
+toolchain-mt := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mt)
+cflags-$(toolchain-mt) += -DTOOLCHAIN_SUPPORTS_MT

#
# Firmware support
diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
index 6eadd59f53e9..b60fa51e5fbb 100644
--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -318,9 +318,77 @@
.endm
#endif /* !CONFIG_CPU_MIPSR2 && !CONFIG_CPU_MIPSR5 && !CONFIG_CPU_MIPSR6 */

-/*
- * Temporary until all gas have MT ASE support
- */
+#ifdef TOOLCHAIN_SUPPORTS_MT
+ .macro _dmt reg = $0
+ .set push
+ .set mt
+ dmt \reg
+ .set pop
+ .endm
+
+ .macro _emt reg = $0
+ .set push
+ .set mt
+ emt \reg
+ .set pop
+ .endm
+
+ .macro _dvpe reg = $0
+ .set push
+ .set mt
+ dvpe \reg
+ .set pop
+ .endm
+
+ .macro _evpe reg = $0
+ .set push
+ .set mt
+ evpe \reg
+ .set pop
+ .endm
+
+ .macro _mftr rs, rt, u, sel, h = 0
+ .set push
+ .set mt
+ mftr \rs, \rt, \u, \sel, \h
+ .set pop
+ .endm
+
+ .macro _mttr rt, rs, u, sel, h = 0
+ .set push
+ .set mt
+ mttr \rt, \rs, \u, \sel, \h
+ .set pop
+ .endm
+
+ .macro _mftc0 rs, rt, sel = 0
+ .set push
+ .set mt
+ mftc0 \rs, \rt, \sel
+ .set pop
+ .endm
+
+ .macro _mttc0 rt, rs, sel = 0
+ .set push
+ .set mt
+ mttc0 \rt, \rs, \sel
+ .set pop
+ .endm
+
+ .macro _mftgpr rs, rt
+ .set push
+ .set mt
+ mftgpr \rs, \rt
+ .set pop
+ .endm
+
+ .macro _mttgpr rs, rt
+ .set push
+ .set mt
+ mttgpr \rs, \rt
+ .set pop
+ .endm
+#else
.macro _dmt reg = $0
parse_r __reg, \reg
insn_if_mips 0x41600bc1 | (__reg << 16)
@@ -374,6 +442,7 @@
.macro _mttgpr rs, rt
_mttr \rt, \rs, 1, 0, 0
.endm
+#endif

#ifdef TOOLCHAIN_SUPPORTS_MSA
.macro _cfcmsa rd, cs
diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h
index b1ee3c48e84b..93b8aa807b82 100644
--- a/arch/mips/include/asm/mipsmtregs.h
+++ b/arch/mips/include/asm/mipsmtregs.h
@@ -189,11 +189,16 @@ static inline unsigned core_nvpes(void)
return ((conf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
}

+#ifndef TOOLCHAIN_SUPPORTS_MT
#define _ASM_SET_DVPE \
_ASM_MACRO_1R(dvpe, rt, \
_ASM_INSN_IF_MIPS(0x41600001 | __rt << 16) \
_ASM_INSN32_IF_MM(0x0000157C | __rt << 21))
#define _ASM_UNSET_DVPE ".purgem dvpe\n\t"
+#else
+#define _ASM_SET_DVPE ".set\tmt\n\t"
+#define _ASM_UNSET_DVPE
+#endif

static inline unsigned int dvpe(void)
{
@@ -214,11 +219,16 @@ static inline unsigned int dvpe(void)
return res;
}

+#ifndef TOOLCHAIN_SUPPORTS_MT
#define _ASM_SET_EVPE \
_ASM_MACRO_1R(evpe, rt, \
_ASM_INSN_IF_MIPS(0x41600021 | __rt << 16) \
_ASM_INSN32_IF_MM(0x0000357C | __rt << 21))
#define _ASM_UNSET_EVPE ".purgem evpe\n\t"
+#else
+#define _ASM_SET_EVPE ".set\tmt\n\t"
+#define _ASM_UNSET_EVPE
+#endif

static inline void __raw_evpe(void)
{
@@ -243,11 +253,16 @@ static inline void evpe(int previous)
__raw_evpe();
}

+#ifndef TOOLCHAIN_SUPPORTS_MT
#define _ASM_SET_DMT \
_ASM_MACRO_1R(dmt, rt, \
_ASM_INSN_IF_MIPS(0x41600bc1 | __rt << 16) \
_ASM_INSN32_IF_MM(0x0000057C | __rt << 21))
#define _ASM_UNSET_DMT ".purgem dmt\n\t"
+#else
+#define _ASM_SET_DMT ".set\tmt\n\t"
+#define _ASM_UNSET_DMT
+#endif

static inline unsigned int dmt(void)
{
@@ -268,11 +283,16 @@ static inline unsigned int dmt(void)
return res;
}

+#ifndef TOOLCHAIN_SUPPORTS_MT
#define _ASM_SET_EMT \
_ASM_MACRO_1R(emt, rt, \
_ASM_INSN_IF_MIPS(0x41600be1 | __rt << 16) \
_ASM_INSN32_IF_MM(0x0000257C | __rt << 21))
#define _ASM_UNSET_EMT ".purgem emt\n\t"
+#else
+#define _ASM_SET_EMT ".set\tmt\n\t"
+#define _ASM_UNSET_EMT
+#endif

static inline void __raw_emt(void)
{
@@ -306,6 +326,7 @@ static inline void ehb(void)
" .set pop \n");
}

+#ifndef TOOLCHAIN_SUPPORTS_MT
#define _ASM_SET_MFTC0 \
_ASM_MACRO_2R_1S(mftc0, rs, rt, sel, \
_ASM_INSN_IF_MIPS(0x41000000 | __rt << 16 | \
@@ -313,6 +334,10 @@ static inline void ehb(void)
_ASM_INSN32_IF_MM(0x0000000E | __rt << 21 | \
__rs << 16 | \\sel << 4))
#define _ASM_UNSET_MFTC0 ".purgem mftc0\n\t"
+#else
+#define _ASM_SET_MFTC0 ".set\tmt\n\t"
+#define _ASM_UNSET_MFTC0
+#endif

#define mftc0(rt, sel) \
({ \
@@ -330,6 +355,7 @@ static inline void ehb(void)
__res; \
})

+#ifndef TOOLCHAIN_SUPPORTS_MT
#define _ASM_SET_MFTGPR \
_ASM_MACRO_2R(mftgpr, rs, rt, \
_ASM_INSN_IF_MIPS(0x41000020 | __rt << 16 | \
@@ -337,6 +363,10 @@ static inline void ehb(void)
_ASM_INSN32_IF_MM(0x0000040E | __rt << 21 | \
__rs << 16))
#define _ASM_UNSET_MFTGPR ".purgem mftgpr\n\t"
+#else
+#define _ASM_SET_MFTGPR ".set\tmt\n\t"
+#define _ASM_UNSET_MFTGPR
+#endif

#define mftgpr(rt) \
({ \
@@ -365,6 +395,7 @@ static inline void ehb(void)
__res; \
})

+#ifndef TOOLCHAIN_SUPPORTS_MT
#define _ASM_SET_MTTGPR \
_ASM_MACRO_2R(mttgpr, rt, rs, \
_ASM_INSN_IF_MIPS(0x41800020 | __rt << 16 | \
@@ -372,6 +403,10 @@ static inline void ehb(void)
_ASM_INSN32_IF_MM(0x00000406 | __rt << 21 | \
__rs << 16))
#define _ASM_UNSET_MTTGPR ".purgem mttgpr\n\t"
+#else
+#define _ASM_SET_MTTGPR ".set\tmt\n\t"
+#define _ASM_UNSET_MTTGPR
+#endif

#define mttgpr(rs, v) \
do { \
@@ -385,6 +420,7 @@ do { \
: : "r" (v)); \
} while (0)

+#ifndef TOOLCHAIN_SUPPORTS_MT
#define _ASM_SET_MTTC0 \
_ASM_MACRO_2R_1S(mttc0, rt, rs, sel, \
_ASM_INSN_IF_MIPS(0x41800000 | __rt << 16 | \
@@ -392,6 +428,10 @@ do { \
_ASM_INSN32_IF_MM(0x0000040E | __rt << 21 | \
__rs << 16 | \\sel << 4))
#define _ASM_UNSET_MTTC0 ".purgem mttc0\n\t"
+#else
+#define _ASM_SET_MTTC0 ".set\tmt\n\t"
+#define _ASM_UNSET_MTTC0
+#endif

#define mttc0(rs, sel, v) \
({ \

--
2.43.0