Commit ea8b75d2 authored by Heiko Carstens's avatar Heiko Carstens
Browse files

s390/sysinfo: convert bogomips calculation to C



Provide several one instruction fpu inline assemebles and use them to
implement the bogomips calculation in C like style. This is more for
illustration purposes on how kernel fpu code can be written in C.

This has the advantage that the author only has to take care of the
floating point instructions, but doesn't need to take care of general
purpose register allocation (if needed), and the semantics of all other
instructions not related to fpu.

Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent c8dde11d
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -36,6 +36,33 @@ asm(".include \"asm/fpu-insn-asm.h\"\n");
 * barrier.
 */

static __always_inline void fpu_cefbr(u8 f1, s32 val)
{
	asm volatile("cefbr	%[f1],%[val]\n"
		     :
		     : [f1] "I" (f1), [val] "d" (val)
		     : "memory");
}

static __always_inline unsigned long fpu_cgebr(u8 f2, u8 mode)
{
	unsigned long val;

	asm volatile("cgebr	%[val],%[mode],%[f2]\n"
		     : [val] "=d" (val)
		     : [f2] "I" (f2), [mode] "I" (mode)
		     : "memory");
	return val;
}

static __always_inline void fpu_debr(u8 f1, u8 f2)
{
	asm volatile("debr	%[f1],%[f2]\n"
		     :
		     : [f1] "I" (f1), [f2] "I" (f2)
		     : "memory");
}

static __always_inline void fpu_ld(unsigned short fpr, freg_t *reg)
{
	instrument_read(reg, sizeof(*reg));
@@ -45,6 +72,14 @@ static __always_inline void fpu_ld(unsigned short fpr, freg_t *reg)
		     : "memory");
}

static __always_inline void fpu_ldgr(u8 f1, u32 val)
{
	asm volatile("ldgr	%[f1],%[val]\n"
		     :
		     : [f1] "I" (f1), [val] "d" (val)
		     : "memory");
}

static __always_inline void fpu_lfpc(unsigned int *fpc)
{
	instrument_read(fpc, sizeof(*fpc));
+8 −15
Original line number Diff line number Diff line
@@ -447,21 +447,14 @@ void s390_adjust_jiffies(void)
		 * point division ..
		 */
		kernel_fpu_begin(&fpu, KERNEL_FPR);
		asm volatile(
			"	sfpc	%3\n"
			"	l	%0,%1\n"
			"	tmlh	%0,0xff80\n"
			"	jnz	0f\n"
			"	cefbr	%%f2,%0\n"
			"	j	1f\n"
			"0:	le	%%f2,%1\n"
			"1:	cefbr	%%f0,%2\n"
			"	debr	%%f0,%%f2\n"
			"	cgebr	%0,5,%%f0\n"
			: "=&d" (capability)
			: "Q" (info->capability), "d" (10000000), "d" (0)
			: "cc"
			);
		fpu_sfpc(0);
		if (info->capability & 0xff800000)
			fpu_ldgr(2, info->capability);
		else
			fpu_cefbr(2, info->capability);
		fpu_cefbr(0, 10000000);
		fpu_debr(0, 2);
		capability = fpu_cgebr(0, 5);
		kernel_fpu_end(&fpu, KERNEL_FPR);
	} else
		/*