Commit dd6d29a6 authored by Jiaxun Yang's avatar Jiaxun Yang Committed by Thomas Bogendoerfer
Browse files

MIPS: Implement microMIPS MT ASE helpers



Implement various microMIPS MT ASE helpers accroading to:

MIPS® Architecture for Programmers
Volume IV-f: The MIPS® MT Module for the microMIPS32™ Architecture

Fixes build error:
{standard input}:2616: Error: branch to a symbol in another ISA mode

This make MT ASE available on microMIPS as well.

Boot tested on M5150 with microMIPS enabled on M5150.

Signed-off-by: default avatarJiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: default avatarThomas Bogendoerfer <tsbogend@alpha.franken.de>
parent 74efddad
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -216,27 +216,33 @@
 * Temporary until all gas have MT ASE support
 */
	.macro	DMT	reg=0
	.word	0x41600bc1 | (\reg << 16)
	insn_if_mips	0x41600bc1 | (\reg << 16)
	insn32_if_mm    0x0000057C | (\reg << 21)
	.endm

	.macro	EMT	reg=0
	.word	0x41600be1 | (\reg << 16)
	insn_if_mips	0x41600be1 | (\reg << 16)
	insn32_if_mm    0x0000257C | (\reg << 21)
	.endm

	.macro	DVPE	reg=0
	.word	0x41600001 | (\reg << 16)
	insn_if_mips	0x41600001 | (\reg << 16)
	insn32_if_mm    0x0000157C | (\reg << 21)
	.endm

	.macro	EVPE	reg=0
	.word	0x41600021 | (\reg << 16)
	insn_if_mips	0x41600021 | (\reg << 16)
	insn32_if_mm    0x0000357C | (\reg << 21)
	.endm

	.macro	MFTR	rt=0, rd=0, u=0, sel=0
	 .word	0x41000000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
	.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)
	.endm

	.macro	MTTR	rt=0, rd=0, u=0, sel=0
	 .word	0x41800000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)
	.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)
	.endm

#ifdef TOOLCHAIN_SUPPORTS_MSA
+154 −102
Original line number Diff line number Diff line
@@ -189,18 +189,23 @@ static inline unsigned core_nvpes(void)
	return ((conf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
}

#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"

static inline unsigned int dvpe(void)
{
	int res = 0;

	__asm__ __volatile__(
	"	.set	push					\n"
	"	.set	noreorder					\n"
	"	.set	noat						\n"
	"	.set	mips32r2					\n"
	"	.word	0x41610001		# dvpe $1		\n"
	"	move	%0, $1						\n"
	"	.set	"MIPS_ISA_LEVEL"			\n"
	_ASM_SET_DVPE
	"	dvpe	%0					\n"
	"	ehb						\n"
	_ASM_UNSET_DVPE
	"	.set	pop					\n"
	: "=r" (res));

@@ -209,15 +214,21 @@ static inline unsigned int dvpe(void)
	return res;
}

#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"

static inline void __raw_evpe(void)
{
	__asm__ __volatile__(
	"	.set	push					\n"
	"	.set	noreorder					\n"
	"	.set	noat						\n"
	"	.set	mips32r2					\n"
	"	.word	0x41600021		# evpe			\n"
	"	.set	"MIPS_ISA_LEVEL"			\n"
	_ASM_SET_EVPE
	"	evpe    $0					\n"
	"	ehb						\n"
	_ASM_UNSET_EVPE
	"	.set	pop					\n");
}

@@ -232,17 +243,23 @@ static inline void evpe(int previous)
		__raw_evpe();
}

#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"

static inline unsigned int dmt(void)
{
	int res;

	__asm__ __volatile__(
	"	.set	push					\n"
	"	.set	mips32r2					\n"
	"	.set	noat						\n"
	"	.word	0x41610BC1			# dmt $1	\n"
	"	.set	"MIPS_ISA_LEVEL"			\n"
	_ASM_SET_DMT
	"	dmt	%0					\n"
	"	ehb						\n"
	"	move	%0, $1						\n"
	_ASM_UNSET_DMT
	"	.set	pop					\n"
	: "=r" (res));

@@ -251,13 +268,20 @@ static inline unsigned int dmt(void)
	return res;
}

#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"

static inline void __raw_emt(void)
{
	__asm__ __volatile__(
	"	.set	push					\n"
	"	.set	noreorder					\n"
	"	.set	mips32r2					\n"
	"	.word	0x41600be1			# emt		\n"
	"	.set	"MIPS_ISA_LEVEL"			\n"
	_ASM_SET_EMT
	"	emt	$0					\n"
	_ASM_UNSET_EMT
	"	ehb						\n"
	"	.set	pop");
}
@@ -277,39 +301,53 @@ static inline void ehb(void)
{
	__asm__ __volatile__(
	"	.set	push				\n"
	"	.set	mips32r2				\n"
	"	.set	"MIPS_ISA_LEVEL"		\n"
	"	ehb					\n"
	"	.set	pop				\n");
}

#define _ASM_SET_MFTC0							\
	_ASM_MACRO_2R_1S(mftc0, rs, rt, sel,				\
			_ASM_INSN_IF_MIPS(0x41000000 | __rt << 16 |	\
				__rs << 11 | \\sel)			\
			_ASM_INSN32_IF_MM(0x0000000E | __rt << 21 |	\
				__rs << 16 | \\sel << 4))
#define _ASM_UNSET_MFTC0 ".purgem mftc0\n\t"

#define mftc0(rt, sel)							\
({									\
	unsigned long	__res;						\
									\
	__asm__ __volatile__(						\
	"	.set	push				\n"	\
	"	.set	mips32r2				\n"	\
	"	.set	noat					\n"	\
	"	# mftc0 $1, $" #rt ", " #sel "			\n"	\
	"	.word	0x41000800 | (" #rt " << 16) | " #sel " \n"	\
	"	move	%0, $1					\n"	\
	"	.set	"MIPS_ISA_LEVEL"		\n"	\
	_ASM_SET_MFTC0							\
	"	mftc0	$1, " #rt ", " #sel "		\n"	\
	_ASM_UNSET_MFTC0						\
	"	.set	pop				\n"	\
	: "=r" (__res));						\
									\
	__res;								\
})

#define _ASM_SET_MFTGPR							\
	_ASM_MACRO_2R(mftgpr, rs, rt,					\
			_ASM_INSN_IF_MIPS(0x41000020 | __rt << 16 |	\
				__rs << 11)				\
			_ASM_INSN32_IF_MM(0x0000040E | __rt << 21 |	\
				__rs << 16))
#define _ASM_UNSET_MFTGPR ".purgem mftgpr\n\t"

#define mftgpr(rt)							\
({									\
	unsigned long __res;						\
									\
	__asm__ __volatile__(						\
	"	.set	push				\n"	\
	"	.set	noat					\n"	\
	"	.set	mips32r2				\n"	\
	"	# mftgpr $1," #rt "				\n"	\
	"	.word	0x41000820 | (" #rt " << 16)		\n"	\
	"	move	%0, $1					\n"	\
	"	.set	"MIPS_ISA_LEVEL"		\n"	\
	_ASM_SET_MFTGPR							\
	"	mftgpr	%0," #rt "			\n"	\
	_ASM_UNSET_MFTGPR						\
	"	.set	pop				\n"	\
	: "=r" (__res));						\
									\
@@ -327,28 +365,42 @@ static inline void ehb(void)
	__res;								\
})

#define mttgpr(rd,v)							\
#define _ASM_SET_MTTGPR							\
	_ASM_MACRO_2R(mttgpr, rt, rs,					\
			_ASM_INSN_IF_MIPS(0x41800020 | __rt << 16 |	\
				__rs << 11)				\
			_ASM_INSN32_IF_MM(0x00000406 | __rt << 21 |	\
				__rs << 16))
#define _ASM_UNSET_MTTGPR ".purgem mttgpr\n\t"

#define mttgpr(rs, v)							\
do {									\
	__asm__ __volatile__(						\
	"	.set	push				\n"	\
	"	.set	mips32r2				\n"	\
	"	.set	noat					\n"	\
	"	move	$1, %0					\n"	\
	"	# mttgpr $1, " #rd "				\n"	\
	"	.word	0x41810020 | (" #rd " << 11)		\n"	\
	"	.set	"MIPS_ISA_LEVEL"		\n"	\
	_ASM_SET_MTTGPR							\
	"	mttgpr	%0, " #rs "			\n"	\
	_ASM_UNSET_MTTGPR						\
	"	.set	pop				\n"	\
	: : "r" (v));							\
} while (0)

#define mttc0(rd, sel, v)							\
#define _ASM_SET_MTTC0							\
	_ASM_MACRO_2R_1S(mttc0, rt, rs, sel,				\
			_ASM_INSN_IF_MIPS(0x41800000 | __rt << 16 |	\
				__rs << 11 | \\sel)			\
			_ASM_INSN32_IF_MM(0x0000040E | __rt << 21 |	\
				__rs << 16 | \\sel << 4))
#define _ASM_UNSET_MTTC0 ".purgem mttc0\n\t"

#define mttc0(rs, sel, v)							\
({									\
	__asm__ __volatile__(						\
	"	.set	push				\n"	\
	"	.set	mips32r2				\n"	\
	"	.set	noat					\n"	\
	"	move	$1, %0					\n"	\
	"	# mttc0 %0," #rd ", " #sel "			\n"	\
	"	.word	0x41810000 | (" #rd " << 11) | " #sel " \n"	\
	"	.set	"MIPS_ISA_LEVEL"		\n"	\
	_ASM_SET_MTTC0							\
	"	mttc0	%0," #rs ", " #sel "		\n"	\
	_ASM_UNSET_MTTC0						\
	"	.set	pop				\n"	\
	:								\
	: "r" (v));							\
@@ -371,49 +423,49 @@ do { \


/* you *must* set the target tc (settc) before trying to use these */
#define read_vpe_c0_vpecontrol()	mftc0(1, 1)
#define write_vpe_c0_vpecontrol(val)	mttc0(1, 1, val)
#define read_vpe_c0_vpeconf0()		mftc0(1, 2)
#define write_vpe_c0_vpeconf0(val)	mttc0(1, 2, val)
#define read_vpe_c0_vpeconf1()		mftc0(1, 3)
#define write_vpe_c0_vpeconf1(val)	mttc0(1, 3, val)
#define read_vpe_c0_count()		mftc0(9, 0)
#define write_vpe_c0_count(val)		mttc0(9, 0, val)
#define read_vpe_c0_status()		mftc0(12, 0)
#define write_vpe_c0_status(val)	mttc0(12, 0, val)
#define read_vpe_c0_cause()		mftc0(13, 0)
#define write_vpe_c0_cause(val)		mttc0(13, 0, val)
#define read_vpe_c0_config()		mftc0(16, 0)
#define write_vpe_c0_config(val)	mttc0(16, 0, val)
#define read_vpe_c0_config1()		mftc0(16, 1)
#define write_vpe_c0_config1(val)	mttc0(16, 1, val)
#define read_vpe_c0_config7()		mftc0(16, 7)
#define write_vpe_c0_config7(val)	mttc0(16, 7, val)
#define read_vpe_c0_ebase()		mftc0(15, 1)
#define write_vpe_c0_ebase(val)		mttc0(15, 1, val)
#define write_vpe_c0_compare(val)	mttc0(11, 0, val)
#define read_vpe_c0_badvaddr()		mftc0(8, 0)
#define read_vpe_c0_epc()		mftc0(14, 0)
#define write_vpe_c0_epc(val)		mttc0(14, 0, val)
#define read_vpe_c0_vpecontrol()	mftc0($1, 1)
#define write_vpe_c0_vpecontrol(val)	mttc0($1, 1, val)
#define read_vpe_c0_vpeconf0()		mftc0($1, 2)
#define write_vpe_c0_vpeconf0(val)	mttc0($1, 2, val)
#define read_vpe_c0_vpeconf1()		mftc0($1, 3)
#define write_vpe_c0_vpeconf1(val)	mttc0($1, 3, val)
#define read_vpe_c0_count()		mftc0($9, 0)
#define write_vpe_c0_count(val)		mttc0($9, 0, val)
#define read_vpe_c0_status()		mftc0($12, 0)
#define write_vpe_c0_status(val)	mttc0($12, 0, val)
#define read_vpe_c0_cause()		mftc0($13, 0)
#define write_vpe_c0_cause(val)		mttc0($13, 0, val)
#define read_vpe_c0_config()		mftc0($16, 0)
#define write_vpe_c0_config(val)	mttc0($16, 0, val)
#define read_vpe_c0_config1()		mftc0($16, 1)
#define write_vpe_c0_config1(val)	mttc0($16, 1, val)
#define read_vpe_c0_config7()		mftc0($16, 7)
#define write_vpe_c0_config7(val)	mttc0($16, 7, val)
#define read_vpe_c0_ebase()		mftc0($15, 1)
#define write_vpe_c0_ebase(val)		mttc0($15, 1, val)
#define write_vpe_c0_compare(val)	mttc0($11, 0, val)
#define read_vpe_c0_badvaddr()		mftc0($8, 0)
#define read_vpe_c0_epc()		mftc0($14, 0)
#define write_vpe_c0_epc(val)		mttc0($14, 0, val)


/* TC */
#define read_tc_c0_tcstatus()		mftc0(2, 1)
#define write_tc_c0_tcstatus(val)	mttc0(2, 1, val)
#define read_tc_c0_tcbind()		mftc0(2, 2)
#define write_tc_c0_tcbind(val)		mttc0(2, 2, val)
#define read_tc_c0_tcrestart()		mftc0(2, 3)
#define write_tc_c0_tcrestart(val)	mttc0(2, 3, val)
#define read_tc_c0_tchalt()		mftc0(2, 4)
#define write_tc_c0_tchalt(val)		mttc0(2, 4, val)
#define read_tc_c0_tccontext()		mftc0(2, 5)
#define write_tc_c0_tccontext(val)	mttc0(2, 5, val)
#define read_tc_c0_tcstatus()		mftc0($2, 1)
#define write_tc_c0_tcstatus(val)	mttc0($2, 1, val)
#define read_tc_c0_tcbind()		mftc0($2, 2)
#define write_tc_c0_tcbind(val)		mttc0($2, 2, val)
#define read_tc_c0_tcrestart()		mftc0($2, 3)
#define write_tc_c0_tcrestart(val)	mttc0($2, 3, val)
#define read_tc_c0_tchalt()		mftc0($2, 4)
#define write_tc_c0_tchalt(val)		mttc0($2, 4, val)
#define read_tc_c0_tccontext()		mftc0($2, 5)
#define write_tc_c0_tccontext(val)	mttc0($2, 5, val)

/* GPR */
#define read_tc_gpr_sp()		mftgpr(29)
#define write_tc_gpr_sp(val)		mttgpr(29, val)
#define read_tc_gpr_gp()		mftgpr(28)
#define write_tc_gpr_gp(val)		mttgpr(28, val)
#define read_tc_gpr_sp()		mftgpr($29)
#define write_tc_gpr_sp(val)		mttgpr($29, val)
#define read_tc_gpr_gp()		mftgpr($28)
#define write_tc_gpr_gp(val)		mttgpr($28, val)

__BUILD_SET_C0(mvpcontrol)

+9 −0
Original line number Diff line number Diff line
@@ -1452,6 +1452,15 @@ static inline int mm_insn_16bit(u16 insn)
 * the ENC encodings.
 */

/* Instructions with 1 register operand */
#define _ASM_MACRO_1R(OP, R1, ENC)				\
		".macro	" #OP " " #R1 "\n\t"			\
		_ASM_SET_PARSE_R					\
		"parse_r __" #R1 ", \\" #R1 "\n\t"			\
		ENC							\
		_ASM_UNSET_PARSE_R					\
		".endm\n\t"

/* Instructions with 1 register operand & 1 immediate operand */
#define _ASM_MACRO_1R1I(OP, R1, I2, ENC)				\
		".macro	" #OP " " #R1 ", " #I2 "\n\t"			\
+2 −2
Original line number Diff line number Diff line
@@ -95,8 +95,8 @@ int vpe_run(struct vpe *v)
	 * We don't pass the memsize here, so VPE programs need to be
	 * compiled with DFLT_STACK_SIZE and DFLT_HEAP_SIZE defined.
	 */
	mttgpr(7, 0);
	mttgpr(6, v->ntcs);
	mttgpr($7, 0);
	mttgpr($6, v->ntcs);

	/* set up VPE1 */
	/*