#include <trap.h>
#include <smp.h>
#include <umem.h>
#include <arch/softfloat.h>

static uint32_t ls(uint64_t* addr)
{
	uint32_t r;
	asm ("fld f0, %1; mftx.s %0, f0" : "=r"(r) : "m"(*addr));
	return r;
}

static void ss(uint64_t* addr, uint32_t val)
{
	asm ("mxtf.s f0, %0; fsd f0, %1" : : "r"(val), "m"(*addr));
}

static int emulate_fpu_silly(struct hw_trapframe *state,
                             ancillary_state_t *silly)
{
	int insn;
	if (memcpy_from_user(current, &insn, (void*)state->epc, 4))
	{
		state->cause = CAUSE_FAULT_FETCH;
		handle_trap(state);
	}

	#define DECLARE_INSN(name, match, mask) bool is_##name = (insn & mask) == match;
	#include <arch/opcodes.h>
	#undef DECLARE_INSN

	int rd  = (insn >> 27) & 0x1f;
	int rs1 = (insn >> 22) & 0x1f;
	int rs2 = (insn >> 17) & 0x1f;
	int rs3 = (insn >> 12) & 0x1f;

	int imm = (insn << 10) >> 20;
	int bimm = ((insn >> 10) & 0x7f) | ((insn & 0xf8000000) >> 20);

	void* load_address = (void*)(state->gpr[rs1] + imm);
	void* store_address = (void*)(state->gpr[rs1] + bimm);

	softfloat_t sf;
	sf.float_rounding_mode = silly->fsr >> 5;
	sf.float_exception_flags = silly->fsr & 0x1f;

	if (is_fsqrt_s)
		ss(&silly->fpr[rd], float32_sqrt(&sf, ls(&silly->fpr[rs1])));
	else if (is_fsqrt_d)
		silly->fpr[rd] = float64_sqrt(&sf, silly->fpr[rs1]);
	else if (is_fdiv_s)
		ss(&silly->fpr[rd], float32_div(&sf, ls(&silly->fpr[rs1]), ls(&silly->fpr[rs2])));
	else if (is_fdiv_d)
		silly->fpr[rd] = float64_div(&sf, silly->fpr[rs1], silly->fpr[rs2]);
	/* Eventually, we will emulate the full FPU, including the below insns
	else if (is_mffsr)
	{
		// use sf instead of silly->fsr
		state->gpr[rd] = silly->fsr;
	}
	else if (is_mtfsr)
	{
		// use sf instead of silly->fsr
		int temp = silly->fsr;
		silly->fsr = state->gpr[rs1] & 0xFF;
		state->gpr[rd] = silly->fsr;
	}
	else if (is_fld)
	{
		uint64_t dest;
		if (!memcpy_from_user(current, &dest, load_address, sizeof(dest)))
		{
			state->cause = CAUSE_FAULT_LOAD;
			state->badvaddr = (long)load_address;
			handle_trap(state);
		}
		silly->fpr[rd] = dest;
	}
	else if (is_flw)
	{
		uint32_t dest;
		if (!memcpy_from_user(current, &dest, load_address, sizeof(dest)))
		{
			state->cause = CAUSE_FAULT_LOAD;
			state->badvaddr = (long)load_address;
			handle_trap(state);
		}
		silly->fpr[rd] = dest;
	}
	else if (is_fsd)
	{
		if (!memcpy_to_user(current, store_address, &silly->fpr[rs2], sizeof(uint64_t)))
		{
			state->cause = CAUSE_FAULT_STORE;
			state->badvaddr = (long)store_address;
			handle_trap(state);
		}
	}
	else if (is_flw)
	{
		if (!memcpy_to_user(current, store_address, &silly->fpr[rs2], sizeof(uint32_t)))
		{
			state->cause = CAUSE_FAULT_STORE;
			state->badvaddr = (long)store_address;
			handle_trap(state);
		}
	}
	*/
	else
	  return 1;
	
	silly->fsr = sf.float_rounding_mode << 5 | sf.float_exception_flags;
	return 0;
}

/* For now we can only emulate missing compute insns, not the whole FPU */
int emulate_fpu(struct hw_trapframe *state)
{
	if (!(state->sr & SR_EF))
	{
		state->cause = CAUSE_FP_DISABLED;
		handle_trap(state);
	}

	ancillary_state_t fp_state;
	save_fp_state(&fp_state);
	int code = emulate_fpu_silly(state, &fp_state);
	restore_fp_state(&fp_state);
	return code;
}
