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: Jiaxun Yang <jiaxun.yang@flygoat.com> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
This commit is contained in:
parent
74efddad96
commit
dd6d29a614
@ -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
|
||||
|
@ -189,19 +189,24 @@ 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"
|
||||
" ehb \n"
|
||||
" .set pop \n"
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_LEVEL" \n"
|
||||
_ASM_SET_DVPE
|
||||
" dvpe %0 \n"
|
||||
" ehb \n"
|
||||
_ASM_UNSET_DVPE
|
||||
" .set pop \n"
|
||||
: "=r" (res));
|
||||
|
||||
instruction_hazard();
|
||||
@ -209,16 +214,22 @@ 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"
|
||||
" ehb \n"
|
||||
" .set pop \n");
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_LEVEL" \n"
|
||||
_ASM_SET_EVPE
|
||||
" evpe $0 \n"
|
||||
" ehb \n"
|
||||
_ASM_UNSET_EVPE
|
||||
" .set pop \n");
|
||||
}
|
||||
|
||||
/* Enable virtual processor execution if previous suggested it should be.
|
||||
@ -232,18 +243,24 @@ 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"
|
||||
" ehb \n"
|
||||
" move %0, $1 \n"
|
||||
" .set pop \n"
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_LEVEL" \n"
|
||||
_ASM_SET_DMT
|
||||
" dmt %0 \n"
|
||||
" ehb \n"
|
||||
_ASM_UNSET_DMT
|
||||
" .set pop \n"
|
||||
: "=r" (res));
|
||||
|
||||
instruction_hazard();
|
||||
@ -251,14 +268,21 @@ 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"
|
||||
" ehb \n"
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_LEVEL" \n"
|
||||
_ASM_SET_EMT
|
||||
" emt $0 \n"
|
||||
_ASM_UNSET_EMT
|
||||
" ehb \n"
|
||||
" .set pop");
|
||||
}
|
||||
|
||||
@ -276,41 +300,55 @@ static inline void emt(int previous)
|
||||
static inline void ehb(void)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set mips32r2 \n"
|
||||
" ehb \n"
|
||||
" .set pop \n");
|
||||
" .set push \n"
|
||||
" .set "MIPS_ISA_LEVEL" \n"
|
||||
" ehb \n"
|
||||
" .set pop \n");
|
||||
}
|
||||
|
||||
#define mftc0(rt,sel) \
|
||||
#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; \
|
||||
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 pop \n" \
|
||||
" .set push \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 pop \n" \
|
||||
" .set push \n" \
|
||||
" .set "MIPS_ISA_LEVEL" \n" \
|
||||
_ASM_SET_MFTGPR \
|
||||
" mftgpr %0," #rt " \n" \
|
||||
_ASM_UNSET_MFTGPR \
|
||||
" .set pop \n" \
|
||||
: "=r" (__res)); \
|
||||
\
|
||||
__res; \
|
||||
@ -321,35 +359,49 @@ static inline void ehb(void)
|
||||
unsigned long __res; \
|
||||
\
|
||||
__asm__ __volatile__( \
|
||||
" mftr %0, " #rt ", " #u ", " #sel " \n" \
|
||||
" mftr %0, " #rt ", " #u ", " #sel " \n" \
|
||||
: "=r" (__res)); \
|
||||
\
|
||||
__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 pop \n" \
|
||||
" .set push \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 pop \n" \
|
||||
" .set push \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)
|
||||
|
||||
|
@ -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" \
|
||||
|
@ -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 */
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user