arch/sparc/kernel/visemul.c

Source file repositories/reference/linux-study-clean/arch/sparc/kernel/visemul.c

File Facts

System
Linux kernel
Corpus path
arch/sparc/kernel/visemul.c
Extension
.c
Size
20124 bytes
Lines
900
Domain
Architecture Layer
Bucket
arch/sparc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct edge_tab {
	u16 left, right;
};
static struct edge_tab edge8_tab[8] = {
	{ 0xff, 0x80 },
	{ 0x7f, 0xc0 },
	{ 0x3f, 0xe0 },
	{ 0x1f, 0xf0 },
	{ 0x0f, 0xf8 },
	{ 0x07, 0xfc },
	{ 0x03, 0xfe },
	{ 0x01, 0xff },
};
static struct edge_tab edge8_tab_l[8] = {
	{ 0xff, 0x01 },
	{ 0xfe, 0x03 },
	{ 0xfc, 0x07 },
	{ 0xf8, 0x0f },
	{ 0xf0, 0x1f },
	{ 0xe0, 0x3f },
	{ 0xc0, 0x7f },
	{ 0x80, 0xff },
};
static struct edge_tab edge16_tab[4] = {
	{ 0xf, 0x8 },
	{ 0x7, 0xc },
	{ 0x3, 0xe },
	{ 0x1, 0xf },
};
static struct edge_tab edge16_tab_l[4] = {
	{ 0xf, 0x1 },
	{ 0xe, 0x3 },
	{ 0xc, 0x7 },
	{ 0x8, 0xf },
};
static struct edge_tab edge32_tab[2] = {
	{ 0x3, 0x2 },
	{ 0x1, 0x3 },
};
static struct edge_tab edge32_tab_l[2] = {
	{ 0x3, 0x1 },
	{ 0x2, 0x3 },
};

static void edge(struct pt_regs *regs, unsigned int insn, unsigned int opf)
{
	unsigned long orig_rs1, rs1, orig_rs2, rs2, rd_val;
	u16 left, right;

	maybe_flush_windows(RS1(insn), RS2(insn), RD(insn), 0);
	orig_rs1 = rs1 = fetch_reg(RS1(insn), regs);
	orig_rs2 = rs2 = fetch_reg(RS2(insn), regs);

	if (test_thread_flag(TIF_32BIT)) {
		rs1 = rs1 & 0xffffffff;
		rs2 = rs2 & 0xffffffff;
	}
	switch (opf) {
	default:
	case EDGE8_OPF:
	case EDGE8N_OPF:
		left = edge8_tab[rs1 & 0x7].left;
		right = edge8_tab[rs2 & 0x7].right;
		break;
	case EDGE8L_OPF:
	case EDGE8LN_OPF:
		left = edge8_tab_l[rs1 & 0x7].left;
		right = edge8_tab_l[rs2 & 0x7].right;
		break;

	case EDGE16_OPF:
	case EDGE16N_OPF:
		left = edge16_tab[(rs1 >> 1) & 0x3].left;
		right = edge16_tab[(rs2 >> 1) & 0x3].right;
		break;

	case EDGE16L_OPF:
	case EDGE16LN_OPF:
		left = edge16_tab_l[(rs1 >> 1) & 0x3].left;
		right = edge16_tab_l[(rs2 >> 1) & 0x3].right;
		break;

	case EDGE32_OPF:
	case EDGE32N_OPF:
		left = edge32_tab[(rs1 >> 2) & 0x1].left;
		right = edge32_tab[(rs2 >> 2) & 0x1].right;
		break;

	case EDGE32L_OPF:
	case EDGE32LN_OPF:

Annotation

Implementation Notes