msa.h 5.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * Copyright (C) 2013 Imagination Technologies
 * Author: Paul Burton <paul.burton@imgtec.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */
#ifndef _ASM_MSA_H
#define _ASM_MSA_H

#include <asm/mipsregs.h>

15 16 17
extern void _save_msa(struct task_struct *);
extern void _restore_msa(struct task_struct *);

18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
static inline void enable_msa(void)
{
	if (cpu_has_msa) {
		set_c0_config5(MIPS_CONF5_MSAEN);
		enable_fpu_hazard();
	}
}

static inline void disable_msa(void)
{
	if (cpu_has_msa) {
		clear_c0_config5(MIPS_CONF5_MSAEN);
		disable_fpu_hazard();
	}
}

static inline int is_msa_enabled(void)
{
	if (!cpu_has_msa)
		return 0;

	return read_c0_config5() & MIPS_CONF5_MSAEN;
}

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
static inline int thread_msa_context_live(void)
{
	/*
	 * Check cpu_has_msa only if it's a constant. This will allow the
	 * compiler to optimise out code for CPUs without MSA without adding
	 * an extra redundant check for CPUs with MSA.
	 */
	if (__builtin_constant_p(cpu_has_msa) && !cpu_has_msa)
		return 0;

	return test_thread_flag(TIF_MSA_CTX_LIVE);
}

static inline void save_msa(struct task_struct *t)
{
	if (cpu_has_msa)
		_save_msa(t);
}

static inline void restore_msa(struct task_struct *t)
{
	if (cpu_has_msa)
		_restore_msa(t);
}

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
#ifdef TOOLCHAIN_SUPPORTS_MSA

#define __BUILD_MSA_CTL_REG(name, cs)				\
static inline unsigned int read_msa_##name(void)		\
{								\
	unsigned int reg;					\
	__asm__ __volatile__(					\
	"	.set	push\n"					\
	"	.set	msa\n"					\
	"	cfcmsa	%0, $" #cs "\n"				\
	"	.set	pop\n"					\
	: "=r"(reg));						\
	return reg;						\
}								\
								\
static inline void write_msa_##name(unsigned int val)		\
{								\
	__asm__ __volatile__(					\
	"	.set	push\n"					\
	"	.set	msa\n"					\
87
	"	ctcmsa	$" #cs ", %0\n"				\
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
	"	.set	pop\n"					\
	: : "r"(val));						\
}

#else /* !TOOLCHAIN_SUPPORTS_MSA */

/*
 * Define functions using .word for the c[ft]cmsa instructions in order to
 * allow compilation with toolchains that do not support MSA. Once all
 * toolchains in use support MSA these can be removed.
 */

#define __BUILD_MSA_CTL_REG(name, cs)				\
static inline unsigned int read_msa_##name(void)		\
{								\
	unsigned int reg;					\
	__asm__ __volatile__(					\
	"	.set	push\n"					\
	"	.set	noat\n"					\
	"	.word	0x787e0059 | (" #cs " << 11)\n"		\
	"	move	%0, $1\n"				\
	"	.set	pop\n"					\
	: "=r"(reg));						\
	return reg;						\
}								\
								\
static inline void write_msa_##name(unsigned int val)		\
{								\
	__asm__ __volatile__(					\
	"	.set	push\n"					\
	"	.set	noat\n"					\
	"	move	$1, %0\n"				\
	"	.word	0x783e0819 | (" #cs " << 6)\n"		\
	"	.set	pop\n"					\
	: : "r"(val));						\
}

#endif /* !TOOLCHAIN_SUPPORTS_MSA */

#define MSA_IR		0
#define MSA_CSR		1
#define MSA_ACCESS	2
#define MSA_SAVE	3
#define MSA_MODIFY	4
#define MSA_REQUEST	5
#define MSA_MAP		6
#define MSA_UNMAP	7

__BUILD_MSA_CTL_REG(ir, 0)
__BUILD_MSA_CTL_REG(csr, 1)
__BUILD_MSA_CTL_REG(access, 2)
__BUILD_MSA_CTL_REG(save, 3)
__BUILD_MSA_CTL_REG(modify, 4)
__BUILD_MSA_CTL_REG(request, 5)
__BUILD_MSA_CTL_REG(map, 6)
__BUILD_MSA_CTL_REG(unmap, 7)

/* MSA Implementation Register (MSAIR) */
#define MSA_IR_REVB		0
#define MSA_IR_REVF		(_ULCAST_(0xff) << MSA_IR_REVB)
#define MSA_IR_PROCB		8
#define MSA_IR_PROCF		(_ULCAST_(0xff) << MSA_IR_PROCB)
#define MSA_IR_WRPB		16
#define MSA_IR_WRPF		(_ULCAST_(0x1) << MSA_IR_WRPB)

/* MSA Control & Status Register (MSACSR) */
#define MSA_CSR_RMB		0
#define MSA_CSR_RMF		(_ULCAST_(0x3) << MSA_CSR_RMB)
#define MSA_CSR_RM_NEAREST	0
#define MSA_CSR_RM_TO_ZERO	1
#define MSA_CSR_RM_TO_POS	2
#define MSA_CSR_RM_TO_NEG	3
#define MSA_CSR_FLAGSB		2
#define MSA_CSR_FLAGSF		(_ULCAST_(0x1f) << MSA_CSR_FLAGSB)
#define MSA_CSR_FLAGS_IB	2
#define MSA_CSR_FLAGS_IF	(_ULCAST_(0x1) << MSA_CSR_FLAGS_IB)
#define MSA_CSR_FLAGS_UB	3
#define MSA_CSR_FLAGS_UF	(_ULCAST_(0x1) << MSA_CSR_FLAGS_UB)
#define MSA_CSR_FLAGS_OB	4
#define MSA_CSR_FLAGS_OF	(_ULCAST_(0x1) << MSA_CSR_FLAGS_OB)
#define MSA_CSR_FLAGS_ZB	5
#define MSA_CSR_FLAGS_ZF	(_ULCAST_(0x1) << MSA_CSR_FLAGS_ZB)
#define MSA_CSR_FLAGS_VB	6
#define MSA_CSR_FLAGS_VF	(_ULCAST_(0x1) << MSA_CSR_FLAGS_VB)
#define MSA_CSR_ENABLESB	7
#define MSA_CSR_ENABLESF	(_ULCAST_(0x1f) << MSA_CSR_ENABLESB)
#define MSA_CSR_ENABLES_IB	7
#define MSA_CSR_ENABLES_IF	(_ULCAST_(0x1) << MSA_CSR_ENABLES_IB)
#define MSA_CSR_ENABLES_UB	8
#define MSA_CSR_ENABLES_UF	(_ULCAST_(0x1) << MSA_CSR_ENABLES_UB)
#define MSA_CSR_ENABLES_OB	9
#define MSA_CSR_ENABLES_OF	(_ULCAST_(0x1) << MSA_CSR_ENABLES_OB)
#define MSA_CSR_ENABLES_ZB	10
#define MSA_CSR_ENABLES_ZF	(_ULCAST_(0x1) << MSA_CSR_ENABLES_ZB)
#define MSA_CSR_ENABLES_VB	11
#define MSA_CSR_ENABLES_VF	(_ULCAST_(0x1) << MSA_CSR_ENABLES_VB)
#define MSA_CSR_CAUSEB		12
#define MSA_CSR_CAUSEF		(_ULCAST_(0x3f) << MSA_CSR_CAUSEB)
#define MSA_CSR_CAUSE_IB	12
#define MSA_CSR_CAUSE_IF	(_ULCAST_(0x1) << MSA_CSR_CAUSE_IB)
#define MSA_CSR_CAUSE_UB	13
#define MSA_CSR_CAUSE_UF	(_ULCAST_(0x1) << MSA_CSR_CAUSE_UB)
#define MSA_CSR_CAUSE_OB	14
#define MSA_CSR_CAUSE_OF	(_ULCAST_(0x1) << MSA_CSR_CAUSE_OB)
#define MSA_CSR_CAUSE_ZB	15
#define MSA_CSR_CAUSE_ZF	(_ULCAST_(0x1) << MSA_CSR_CAUSE_ZB)
#define MSA_CSR_CAUSE_VB	16
#define MSA_CSR_CAUSE_VF	(_ULCAST_(0x1) << MSA_CSR_CAUSE_VB)
#define MSA_CSR_CAUSE_EB	17
#define MSA_CSR_CAUSE_EF	(_ULCAST_(0x1) << MSA_CSR_CAUSE_EB)
#define MSA_CSR_NXB		18
#define MSA_CSR_NXF		(_ULCAST_(0x1) << MSA_CSR_NXB)
#define MSA_CSR_FSB		24
#define MSA_CSR_FSF		(_ULCAST_(0x1) << MSA_CSR_FSB)

#endif /* _ASM_MSA_H */