Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 333d1f67 authored by Ralf Baechle's avatar Ralf Baechle
Browse files

Gross macro abuse. Get rid of gpreg_t, vaddr_t, REG_TO_VA and


VA_TO_REG.  Who ever wrote this apparently did enjoy the C Puzzle Book.
ISBN 0201604612, a little old but still fun reading for the next
blackout ;)

Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 0bd5d2e9
Loading
Loading
Loading
Loading
+24 −24
Original line number Diff line number Diff line
@@ -196,7 +196,7 @@ static int isBranchInstr(mips_instruction * i)
static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
{
	mips_instruction ir;
	vaddr_t emulpc, contpc;
	void * emulpc, *contpc;
	unsigned int cond;

	if (get_user(ir, (mips_instruction *) xcp->cp0_epc)) {
@@ -221,12 +221,12 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
		 * Linux MIPS branch emulator operates on context, updating the
		 * cp0_epc.
		 */
		emulpc = REG_TO_VA(xcp->cp0_epc + 4);	/* Snapshot emulation target */
		emulpc = (void *) (xcp->cp0_epc + 4);	/* Snapshot emulation target */

		if (__compute_return_epc(xcp)) {
#ifdef CP1DBG
			printk("failed to emulate branch at %p\n",
				REG_TO_VA(xcp->cp0_epc));
				(void *) (xcp->cp0_epc));
#endif
			return SIGILL;
		}
@@ -235,13 +235,12 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
			return SIGBUS;
		}
		/* __compute_return_epc() will have updated cp0_epc */
		contpc = REG_TO_VA xcp->cp0_epc;
		contpc = (void *)  xcp->cp0_epc;
		/* In order not to confuse ptrace() et al, tweak context */
		xcp->cp0_epc = VA_TO_REG emulpc - 4;
	}
	else {
		emulpc = REG_TO_VA xcp->cp0_epc;
		contpc = REG_TO_VA(xcp->cp0_epc + 4);
		xcp->cp0_epc = (unsigned long) emulpc - 4;
	} else {
		emulpc = (void *)  xcp->cp0_epc;
		contpc = (void *) (xcp->cp0_epc + 4);
	}

      emul:
@@ -249,7 +248,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
	switch (MIPSInst_OPCODE(ir)) {
#ifndef SINGLE_ONLY_FPU
	case ldc1_op:{
		u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
		u64 *va = (void *) (xcp->regs[MIPSInst_RS(ir)] +
			MIPSInst_SIMM(ir));
		u64 val;

@@ -263,7 +262,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
	}

	case sdc1_op:{
		u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
		u64 *va = (void *) (xcp->regs[MIPSInst_RS(ir)] +
			MIPSInst_SIMM(ir));
		u64 val;

@@ -278,7 +277,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
#endif

	case lwc1_op:{
		u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
		u32 *va = (void *) (xcp->regs[MIPSInst_RS(ir)] +
			MIPSInst_SIMM(ir));
		u32 val;

@@ -298,7 +297,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
	}

	case swc1_op:{
		u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] +
		u32 *va = (void *) (xcp->regs[MIPSInst_RS(ir)] +
			MIPSInst_SIMM(ir));
		u32 val;

@@ -371,7 +370,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
				value = ctx->fcr31;
#ifdef CSRTRACE
				printk("%p gpr[%d]<-csr=%08x\n",
					REG_TO_VA(xcp->cp0_epc),
					(void *) (xcp->cp0_epc),
					MIPSInst_RT(ir), value);
#endif
			}
@@ -398,7 +397,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
			if (MIPSInst_RD(ir) == FPCREG_CSR) {
#ifdef CSRTRACE
				printk("%p gpr[%d]->csr=%08x\n",
					REG_TO_VA(xcp->cp0_epc),
					(void *) (xcp->cp0_epc),
					MIPSInst_RT(ir), value);
#endif
				ctx->fcr31 = value;
@@ -445,12 +444,12 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
				 * instruction
				 */
				xcp->cp0_epc += 4;
				contpc = REG_TO_VA
				contpc = (void *)
					(xcp->cp0_epc +
					(MIPSInst_SIMM(ir) << 2));

				if (get_user(ir, (mips_instruction *)
						REG_TO_VA xcp->cp0_epc)) {
						(void *)  xcp->cp0_epc)) {
					fpuemuprivate.stats.errors++;
					return SIGBUS;
				}
@@ -480,7 +479,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
				 * Single step the non-cp1
				 * instruction in the dslot
				 */
				return mips_dsemul(xcp, ir, VA_TO_REG contpc);
				return mips_dsemul(xcp, ir, (unsigned long) contpc);
			}
			else {
				/* branch not taken */
@@ -539,8 +538,9 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx)
	}

	/* we did it !! */
	xcp->cp0_epc = VA_TO_REG(contpc);
	xcp->cp0_epc = (unsigned long) contpc;
	xcp->cp0_cause &= ~CAUSEF_BD;

	return 0;
}

@@ -628,7 +628,7 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,

		switch (MIPSInst_FUNC(ir)) {
		case lwxc1_op:
			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
			va = (void *) (xcp->regs[MIPSInst_FR(ir)] +
				xcp->regs[MIPSInst_FT(ir)]);

			fpuemuprivate.stats.loads++;
@@ -648,7 +648,7 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
			break;

		case swxc1_op:
			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
			va = (void *) (xcp->regs[MIPSInst_FR(ir)] +
				xcp->regs[MIPSInst_FT(ir)]);

			fpuemuprivate.stats.stores++;
@@ -724,7 +724,7 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,

		switch (MIPSInst_FUNC(ir)) {
		case ldxc1_op:
			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
			va = (void *) (xcp->regs[MIPSInst_FR(ir)] +
				xcp->regs[MIPSInst_FT(ir)]);

			fpuemuprivate.stats.loads++;
@@ -736,7 +736,7 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
			break;

		case sdxc1_op:
			va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] +
			va = (void *) (xcp->regs[MIPSInst_FR(ir)] +
				xcp->regs[MIPSInst_FT(ir)]);

			fpuemuprivate.stats.stores++;
@@ -1282,7 +1282,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,
int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp,
	struct mips_fpu_soft_struct *ctx)
{
	gpreg_t oldepc, prevepc;
	unsigned long oldepc, prevepc;
	mips_instruction insn;
	int sig = 0;

+5 −5
Original line number Diff line number Diff line
@@ -49,10 +49,10 @@ struct emuframe {
	mips_instruction	emul;
	mips_instruction	badinst;
	mips_instruction	cookie;
	gpreg_t			epc;
	unsigned long		epc;
};

int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
{
	extern asmlinkage void handle_dsemulret(void);
	mips_instruction *dsemul_insns;
@@ -88,7 +88,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
	 */

	/* Ensure that the two instructions are in the same cache line */
	dsemul_insns = (mips_instruction *) REG_TO_VA ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
	dsemul_insns = (mips_instruction *) ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7);
	fr = (struct emuframe *) dsemul_insns;

	/* Verify that the stack pointer is not competely insane */
@@ -105,7 +105,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
		return SIGBUS;
	}

	regs->cp0_epc = VA_TO_REG & fr->emul;
	regs->cp0_epc = (unsigned long) &fr->emul;

	flush_cache_sigtramp((unsigned long)&fr->badinst);

@@ -115,7 +115,7 @@ int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc)
int do_dsemulret(struct pt_regs *xcp)
{
	struct emuframe *fr;
	gpreg_t epc;
	unsigned long epc;
	u32 insn, cookie;
	int err = 0;

+2 −8
Original line number Diff line number Diff line
typedef long gpreg_t;
typedef void *vaddr_t;

#define REG_TO_VA (vaddr_t)
#define VA_TO_REG (gpreg_t)

int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc);
int do_dsemulret(struct pt_regs *xcp);
extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc);
extern int do_dsemulret(struct pt_regs *xcp);

/* Instruction which will always cause an address error */
#define AdELOAD 0x8c000001	/* lw $0,1($0) */