// SPDX-License-Identifier: GPL-2.0 /* * (C) Copyright 1998 Linus Torvalds */ #include #include #define STT(reg, val) \ asm volatile ("fimovd $f"#reg", %0" : "=r"(val)); #define STS(reg, val) \ asm volatile ("fimovs $f"#reg", %0" : "=r"(val)); #define LDT(reg, val) \ asm volatile ("ifmovd %0, $f"#reg : : "r"(val)); #define LDS(reg, val) \ asm volatile ("ifmovs %0, $f"#reg : : "r"(val)); #define VLDD(reg, val) \ asm volatile ("vldd $f"#reg", %0" : : "m"(val) : "memory"); #define VSTD(reg, val) \ asm volatile ("vstd $f"#reg", %0" : "=m"(val) : : "memory"); #define VLDS(reg, val) \ asm volatile ("vlds $f"#reg", %0" : : "m"(val) : "memory"); #define LDWE(reg, val) \ asm volatile ("ldwe $f"#reg", %0" : : "m"(val) : "memory"); #define VSTS(reg, val) \ asm volatile ("vsts $f"#reg", %0" : "=m"(val) : : "memory"); #define STDH(reg, val) \ asm volatile ("vstd $f"#reg", %0" : "=m"(val) : : "memory"); void sw64_write_simd_fp_reg_s(unsigned long reg, unsigned long f0, unsigned long f1) { unsigned long tmpa[4] __attribute__((aligned(16))); tmpa[0] = f0; tmpa[1] = f1; switch (reg) { case 0: VLDS(0, *tmpa); break; case 1: VLDS(1, *tmpa); break; case 2: VLDS(2, *tmpa); break; case 3: VLDS(3, *tmpa); break; case 4: VLDS(4, *tmpa); break; case 5: VLDS(5, *tmpa); break; case 6: VLDS(6, *tmpa); break; case 7: VLDS(7, *tmpa); break; case 8: VLDS(8, *tmpa); break; case 9: VLDS(9, *tmpa); break; case 10: VLDS(10, *tmpa); break; case 11: VLDS(11, *tmpa); break; case 12: VLDS(12, *tmpa); break; case 13: VLDS(13, *tmpa); break; case 14: VLDS(14, *tmpa); break; case 15: VLDS(15, *tmpa); break; case 16: VLDS(16, *tmpa); break; case 17: VLDS(17, *tmpa); break; case 18: VLDS(18, *tmpa); break; case 19: VLDS(19, *tmpa); break; case 20: VLDS(20, *tmpa); break; case 21: VLDS(21, *tmpa); break; case 22: VLDS(22, *tmpa); break; case 23: VLDS(23, *tmpa); break; case 24: VLDS(24, *tmpa); break; case 25: VLDS(25, *tmpa); break; case 26: VLDS(26, *tmpa); break; case 27: VLDS(27, *tmpa); break; case 28: VLDS(28, *tmpa); break; case 29: VLDS(29, *tmpa); break; case 30: VLDS(30, *tmpa); break; case 31: break; } } void sw64_write_simd_fp_reg_d(unsigned long reg, unsigned long f0, unsigned long f1, unsigned long f2, unsigned long f3) { unsigned long tmpa[4] __attribute__((aligned(32))); tmpa[0] = f0; tmpa[1] = f1; tmpa[2] = f2; tmpa[3] = f3; switch (reg) { case 0: VLDD(0, *tmpa); break; case 1: VLDD(1, *tmpa); break; case 2: VLDD(2, *tmpa); break; case 3: VLDD(3, *tmpa); break; case 4: VLDD(4, *tmpa); break; case 5: VLDD(5, *tmpa); break; case 6: VLDD(6, *tmpa); break; case 7: VLDD(7, *tmpa); break; case 8: VLDD(8, *tmpa); break; case 9: VLDD(9, *tmpa); break; case 10: VLDD(10, *tmpa); break; case 11: VLDD(11, *tmpa); break; case 12: VLDD(12, *tmpa); break; case 13: VLDD(13, *tmpa); break; case 14: VLDD(14, *tmpa); break; case 15: VLDD(15, *tmpa); break; case 16: VLDD(16, *tmpa); break; case 17: VLDD(17, *tmpa); break; case 18: VLDD(18, *tmpa); break; case 19: VLDD(19, *tmpa); break; case 20: VLDD(20, *tmpa); break; case 21: VLDD(21, *tmpa); break; case 22: VLDD(22, *tmpa); break; case 23: VLDD(23, *tmpa); break; case 24: VLDD(24, *tmpa); break; case 25: VLDD(25, *tmpa); break; case 26: VLDD(26, *tmpa); break; case 27: VLDD(27, *tmpa); break; case 28: VLDD(28, *tmpa); break; case 29: VLDD(29, *tmpa); break; case 30: VLDD(30, *tmpa); break; case 31: break; } } void sw64_write_simd_fp_reg_ldwe(unsigned long reg, int a) { switch (reg) { case 0: LDWE(0, a); break; case 1: LDWE(1, a); break; case 2: LDWE(2, a); break; case 3: LDWE(3, a); break; case 4: LDWE(4, a); break; case 5: LDWE(5, a); break; case 6: LDWE(6, a); break; case 7: LDWE(7, a); break; case 8: LDWE(8, a); break; case 9: LDWE(9, a); break; case 10: LDWE(10, a); break; case 11: LDWE(11, a); break; case 12: LDWE(12, a); break; case 13: LDWE(13, a); break; case 14: LDWE(14, a); break; case 15: LDWE(15, a); break; case 16: LDWE(16, a); break; case 17: LDWE(17, a); break; case 18: LDWE(18, a); break; case 19: LDWE(19, a); break; case 20: LDWE(20, a); break; case 21: LDWE(21, a); break; case 22: LDWE(22, a); break; case 23: LDWE(23, a); break; case 24: LDWE(24, a); break; case 25: LDWE(25, a); break; case 26: LDWE(26, a); break; case 27: LDWE(27, a); break; case 28: LDWE(28, a); break; case 29: LDWE(29, a); break; case 30: LDWE(30, a); break; case 31: break; } } void sw64_read_simd_fp_m_s(unsigned long reg, unsigned long *fp_value) { volatile unsigned long tmpa[2] __attribute__((aligned(16))); switch (reg) { case 0: VSTS(0, *tmpa); break; case 1: VSTS(1, *tmpa); break; case 2: VSTS(2, *tmpa); break; case 3: VSTS(3, *tmpa); break; case 4: VSTS(4, *tmpa); break; case 5: VSTS(5, *tmpa); break; case 6: VSTS(6, *tmpa); break; case 7: VSTS(7, *tmpa); break; case 8: VSTS(8, *tmpa); break; case 9: VSTS(9, *tmpa); break; case 10: VSTS(10, *tmpa); break; case 11: VSTS(11, *tmpa); break; case 12: VSTS(12, *tmpa); break; case 13: VSTS(13, *tmpa); break; case 14: VSTS(14, *tmpa); break; case 15: VSTS(15, *tmpa); break; case 16: VSTS(16, *tmpa); break; case 17: VSTS(17, *tmpa); break; case 18: VSTS(18, *tmpa); break; case 19: VSTS(19, *tmpa); break; case 20: VSTS(20, *tmpa); break; case 21: VSTS(21, *tmpa); break; case 22: VSTS(22, *tmpa); break; case 23: VSTS(23, *tmpa); break; case 24: VSTS(24, *tmpa); break; case 25: VSTS(25, *tmpa); break; case 26: VSTS(26, *tmpa); break; case 27: VSTS(27, *tmpa); break; case 28: VSTS(28, *tmpa); break; case 29: VSTS(29, *tmpa); break; case 30: VSTS(30, *tmpa); break; case 31: VSTS(31, *tmpa); break; } *fp_value = tmpa[0]; *(fp_value+1) = tmpa[1]; } void sw64_read_simd_fp_m_d(unsigned long reg, unsigned long *fp_value) { volatile unsigned long tmpa[4] __attribute__((aligned(32))); switch (reg) { case 0: VSTD(0, *tmpa); break; case 1: VSTD(1, *tmpa); break; case 2: VSTD(2, *tmpa); break; case 3: VSTD(3, *tmpa); break; case 4: VSTD(4, *tmpa); break; case 5: VSTD(5, *tmpa); break; case 6: VSTD(6, *tmpa); break; case 7: VSTD(7, *tmpa); break; case 8: VSTD(8, *tmpa); break; case 9: VSTD(9, *tmpa); break; case 10: VSTD(10, *tmpa); break; case 11: VSTD(11, *tmpa); break; case 12: VSTD(12, *tmpa); break; case 13: VSTD(13, *tmpa); break; case 14: VSTD(14, *tmpa); break; case 15: VSTD(15, *tmpa); break; case 16: VSTD(16, *tmpa); break; case 17: VSTD(17, *tmpa); break; case 18: VSTD(18, *tmpa); break; case 19: VSTD(19, *tmpa); break; case 20: VSTD(20, *tmpa); break; case 21: VSTD(21, *tmpa); break; case 22: VSTD(22, *tmpa); break; case 23: VSTD(23, *tmpa); break; case 24: VSTD(24, *tmpa); break; case 25: VSTD(25, *tmpa); break; case 26: VSTD(26, *tmpa); break; case 27: VSTD(27, *tmpa); break; case 28: VSTD(28, *tmpa); break; case 29: VSTD(29, *tmpa); break; case 30: VSTD(30, *tmpa); break; case 31: VSTD(31, *tmpa); break; } *fp_value = tmpa[0]; *(fp_value+1) = tmpa[1]; *(fp_value+2) = tmpa[2]; *(fp_value+3) = tmpa[3]; return; } unsigned long sw64_read_fp_reg(unsigned long reg) { unsigned long val; switch (reg) { case 0: STT(0, val); break; case 1: STT(1, val); break; case 2: STT(2, val); break; case 3: STT(3, val); break; case 4: STT(4, val); break; case 5: STT(5, val); break; case 6: STT(6, val); break; case 7: STT(7, val); break; case 8: STT(8, val); break; case 9: STT(9, val); break; case 10: STT(10, val); break; case 11: STT(11, val); break; case 12: STT(12, val); break; case 13: STT(13, val); break; case 14: STT(14, val); break; case 15: STT(15, val); break; case 16: STT(16, val); break; case 17: STT(17, val); break; case 18: STT(18, val); break; case 19: STT(19, val); break; case 20: STT(20, val); break; case 21: STT(21, val); break; case 22: STT(22, val); break; case 23: STT(23, val); break; case 24: STT(24, val); break; case 25: STT(25, val); break; case 26: STT(26, val); break; case 27: STT(27, val); break; case 28: STT(28, val); break; case 29: STT(29, val); break; case 30: STT(30, val); break; case 31: STT(31, val); break; default: return 0; } return val; } EXPORT_SYMBOL(sw64_read_fp_reg); void sw64_write_fp_reg(unsigned long reg, unsigned long val) { switch (reg) { case 0: LDT(0, val); break; case 1: LDT(1, val); break; case 2: LDT(2, val); break; case 3: LDT(3, val); break; case 4: LDT(4, val); break; case 5: LDT(5, val); break; case 6: LDT(6, val); break; case 7: LDT(7, val); break; case 8: LDT(8, val); break; case 9: LDT(9, val); break; case 10: LDT(10, val); break; case 11: LDT(11, val); break; case 12: LDT(12, val); break; case 13: LDT(13, val); break; case 14: LDT(14, val); break; case 15: LDT(15, val); break; case 16: LDT(16, val); break; case 17: LDT(17, val); break; case 18: LDT(18, val); break; case 19: LDT(19, val); break; case 20: LDT(20, val); break; case 21: LDT(21, val); break; case 22: LDT(22, val); break; case 23: LDT(23, val); break; case 24: LDT(24, val); break; case 25: LDT(25, val); break; case 26: LDT(26, val); break; case 27: LDT(27, val); break; case 28: LDT(28, val); break; case 29: LDT(29, val); break; case 30: LDT(30, val); break; case 31: LDT(31, val); break; } } EXPORT_SYMBOL(sw64_write_fp_reg); unsigned long sw64_read_fp_reg_s(unsigned long reg) { unsigned long val; switch (reg) { case 0: STS(0, val); break; case 1: STS(1, val); break; case 2: STS(2, val); break; case 3: STS(3, val); break; case 4: STS(4, val); break; case 5: STS(5, val); break; case 6: STS(6, val); break; case 7: STS(7, val); break; case 8: STS(8, val); break; case 9: STS(9, val); break; case 10: STS(10, val); break; case 11: STS(11, val); break; case 12: STS(12, val); break; case 13: STS(13, val); break; case 14: STS(14, val); break; case 15: STS(15, val); break; case 16: STS(16, val); break; case 17: STS(17, val); break; case 18: STS(18, val); break; case 19: STS(19, val); break; case 20: STS(20, val); break; case 21: STS(21, val); break; case 22: STS(22, val); break; case 23: STS(23, val); break; case 24: STS(24, val); break; case 25: STS(25, val); break; case 26: STS(26, val); break; case 27: STS(27, val); break; case 28: STS(28, val); break; case 29: STS(29, val); break; case 30: STS(30, val); break; case 31: STS(31, val); break; default: return 0; } return val; } EXPORT_SYMBOL(sw64_read_fp_reg_s); void sw64_write_fp_reg_s(unsigned long reg, unsigned long val) { switch (reg) { case 0: LDS(0, val); break; case 1: LDS(1, val); break; case 2: LDS(2, val); break; case 3: LDS(3, val); break; case 4: LDS(4, val); break; case 5: LDS(5, val); break; case 6: LDS(6, val); break; case 7: LDS(7, val); break; case 8: LDS(8, val); break; case 9: LDS(9, val); break; case 10: LDS(10, val); break; case 11: LDS(11, val); break; case 12: LDS(12, val); break; case 13: LDS(13, val); break; case 14: LDS(14, val); break; case 15: LDS(15, val); break; case 16: LDS(16, val); break; case 17: LDS(17, val); break; case 18: LDS(18, val); break; case 19: LDS(19, val); break; case 20: LDS(20, val); break; case 21: LDS(21, val); break; case 22: LDS(22, val); break; case 23: LDS(23, val); break; case 24: LDS(24, val); break; case 25: LDS(25, val); break; case 26: LDS(26, val); break; case 27: LDS(27, val); break; case 28: LDS(28, val); break; case 29: LDS(29, val); break; case 30: LDS(30, val); break; case 31: LDS(31, val); break; } } EXPORT_SYMBOL(sw64_write_fp_reg_s);