Commit 01ce6d4d authored by Huacai Chen's avatar Huacai Chen Committed by Thomas Bogendoerfer
Browse files

MIPS: Loongson-3: Fix fp register access if MSA enabled



If MSA is enabled, FPU_REG_WIDTH is 128 rather than 64, then get_fpr64()
/set_fpr64() in the original unaligned instruction emulation code access
the wrong fp registers. This is because the current code doesn't specify
the correct index field, so fix it.

Fixes: f83e4f98 ("MIPS: Loongson-3: Add some unaligned instructions emulation")
Signed-off-by: default avatarHuacai Chen <chenhc@lemote.com>
Signed-off-by: default avatarPei Huang <huangpei@loongson.cn>
Signed-off-by: default avatarThomas Bogendoerfer <tsbogend@alpha.franken.de>
parent b959b978
Loading
Loading
Loading
Loading
+8 −16
Original line number Diff line number Diff line
@@ -95,10 +95,8 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
			if (res)
				goto fault;

			set_fpr64(current->thread.fpu.fpr,
				insn.loongson3_lswc2_format.rt, value);
			set_fpr64(current->thread.fpu.fpr,
				insn.loongson3_lswc2_format.rq, value_next);
			set_fpr64(&current->thread.fpu.fpr[insn.loongson3_lswc2_format.rt], 0, value);
			set_fpr64(&current->thread.fpu.fpr[insn.loongson3_lswc2_format.rq], 0, value_next);
			compute_return_epc(regs);
			own_fpu(1);
		}
@@ -130,15 +128,13 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
				goto sigbus;

			lose_fpu(1);
			value_next = get_fpr64(current->thread.fpu.fpr,
					insn.loongson3_lswc2_format.rq);
			value_next = get_fpr64(&current->thread.fpu.fpr[insn.loongson3_lswc2_format.rq], 0);

			StoreDW(addr + 8, value_next, res);
			if (res)
				goto fault;

			value = get_fpr64(current->thread.fpu.fpr,
					insn.loongson3_lswc2_format.rt);
			value = get_fpr64(&current->thread.fpu.fpr[insn.loongson3_lswc2_format.rt], 0);

			StoreDW(addr, value, res);
			if (res)
@@ -204,8 +200,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
			if (res)
				goto fault;

			set_fpr64(current->thread.fpu.fpr,
					insn.loongson3_lsdc2_format.rt, value);
			set_fpr64(&current->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0, value);
			compute_return_epc(regs);
			own_fpu(1);

@@ -221,8 +216,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
			if (res)
				goto fault;

			set_fpr64(current->thread.fpu.fpr,
					insn.loongson3_lsdc2_format.rt, value);
			set_fpr64(&current->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0, value);
			compute_return_epc(regs);
			own_fpu(1);
			break;
@@ -286,8 +280,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
				goto sigbus;

			lose_fpu(1);
			value = get_fpr64(current->thread.fpu.fpr,
					insn.loongson3_lsdc2_format.rt);
			value = get_fpr64(&current->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0);

			StoreW(addr, value, res);
			if (res)
@@ -305,8 +298,7 @@ static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action,
				goto sigbus;

			lose_fpu(1);
			value = get_fpr64(current->thread.fpu.fpr,
					insn.loongson3_lsdc2_format.rt);
			value = get_fpr64(&current->thread.fpu.fpr[insn.loongson3_lsdc2_format.rt], 0);

			StoreDW(addr, value, res);
			if (res)