aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/include/asm/mipsregs.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 7a59ad6e7f7d..ac70613fd3b8 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1181,6 +1181,89 @@ static inline int mm_insn_16bit(u16 insn)
1181#endif 1181#endif
1182 1182
1183/* 1183/*
1184 * parse_r var, r - Helper assembler macro for parsing register names.
1185 *
1186 * This converts the register name in $n form provided in \r to the
1187 * corresponding register number, which is assigned to the variable \var. It is
1188 * needed to allow explicit encoding of instructions in inline assembly where
1189 * registers are chosen by the compiler in $n form, allowing us to avoid using
1190 * fixed register numbers.
1191 *
1192 * It also allows newer instructions (not implemented by the assembler) to be
1193 * transparently implemented using assembler macros, instead of needing separate
1194 * cases depending on toolchain support.
1195 *
1196 * Simple usage example:
1197 * __asm__ __volatile__("parse_r __rt, %0\n\t"
1198 * ".insn\n\t"
1199 * "# di %0\n\t"
1200 * ".word (0x41606000 | (__rt << 16))"
1201 * : "=r" (status);
1202 */
1203
1204/* Match an individual register number and assign to \var */
1205#define _IFC_REG(n) \
1206 ".ifc \\r, $" #n "\n\t" \
1207 "\\var = " #n "\n\t" \
1208 ".endif\n\t"
1209
1210__asm__(".macro parse_r var r\n\t"
1211 "\\var = -1\n\t"
1212 _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3)
1213 _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7)
1214 _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11)
1215 _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15)
1216 _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19)
1217 _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23)
1218 _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27)
1219 _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31)
1220 ".iflt \\var\n\t"
1221 ".error \"Unable to parse register name \\r\"\n\t"
1222 ".endif\n\t"
1223 ".endm");
1224
1225#undef _IFC_REG
1226
1227/*
1228 * C macros for generating assembler macros for common instruction formats.
1229 *
1230 * The names of the operands can be chosen by the caller, and the encoding of
1231 * register operand \<Rn> is assigned to __<Rn> where it can be accessed from
1232 * the ENC encodings.
1233 */
1234
1235/* Instructions with no operands */
1236#define _ASM_MACRO_0(OP, ENC) \
1237 __asm__(".macro " #OP "\n\t" \
1238 ENC \
1239 ".endm")
1240
1241/* Instructions with 2 register operands */
1242#define _ASM_MACRO_2R(OP, R1, R2, ENC) \
1243 __asm__(".macro " #OP " " #R1 ", " #R2 "\n\t" \
1244 "parse_r __" #R1 ", \\" #R1 "\n\t" \
1245 "parse_r __" #R2 ", \\" #R2 "\n\t" \
1246 ENC \
1247 ".endm")
1248
1249/* Instructions with 3 register operands */
1250#define _ASM_MACRO_3R(OP, R1, R2, R3, ENC) \
1251 __asm__(".macro " #OP " " #R1 ", " #R2 ", " #R3 "\n\t" \
1252 "parse_r __" #R1 ", \\" #R1 "\n\t" \
1253 "parse_r __" #R2 ", \\" #R2 "\n\t" \
1254 "parse_r __" #R3 ", \\" #R3 "\n\t" \
1255 ENC \
1256 ".endm")
1257
1258/* Instructions with 2 register operands and 1 optional select operand */
1259#define _ASM_MACRO_2R_1S(OP, R1, R2, SEL3, ENC) \
1260 __asm__(".macro " #OP " " #R1 ", " #R2 ", " #SEL3 " = 0\n\t" \
1261 "parse_r __" #R1 ", \\" #R1 "\n\t" \
1262 "parse_r __" #R2 ", \\" #R2 "\n\t" \
1263 ENC \
1264 ".endm")
1265
1266/*
1184 * TLB Invalidate Flush 1267 * TLB Invalidate Flush
1185 */ 1268 */
1186static inline void tlbinvf(void) 1269static inline void tlbinvf(void)