#define KERN_REG_SIZE (NUMSAVEREGS * REGSZ)
#define KERN_EXC_FRAME_SIZE (CF_SZ + KERN_REG_SIZE + 16)
#define SAVE_REG(reg, offs, base, bo) \
REG_S reg, bo + (REGSZ * offs) (base)
#define RESTORE_REG(reg, offs, base, bo) \
REG_L reg, bo + (REGSZ * offs) (base)
#define SAVE_CPU(frame, bo) \
SAVE_REG(AT, AST, frame, bo) ;\
SAVE_REG(v0, V0, frame, bo) ;\
SAVE_REG(v1, V1, frame, bo) ;\
SAVE_REG(a0, A0, frame, bo) ;\
SAVE_REG(a1, A1, frame, bo) ;\
SAVE_REG(a2, A2, frame, bo) ;\
SAVE_REG(a3, A3, frame, bo) ;\
MFC0 a0, COP_0_CAUSE_REG ;\
MFC0_HAZARD ;\
SAVE_REG(a4, A4, frame, bo) ;\
SAVE_REG(a5, A5, frame, bo) ;\
MFC0 a1, COP_0_STATUS_REG ;\
MFC0_HAZARD ;\
SAVE_REG(a6, A6, frame, bo) ;\
SAVE_REG(a7, A7, frame, bo) ;\
PRE_MFC0_ADDR_HAZARD ;\
DMFC0 a2, COP_0_BAD_VADDR ;\
MFC0_HAZARD ;\
SAVE_REG(t0, T0, frame, bo) ;\
SAVE_REG(t1, T1, frame, bo) ;\
DMFC0 a3, COP_0_EXC_PC ;\
MFC0_HAZARD ;\
SAVE_REG(t2, T2, frame, bo) ;\
SAVE_REG(t3, T3, frame, bo) ;\
SAVE_REG(t8, T8, frame, bo) ;\
SAVE_REG(t9, T9, frame, bo) ;\
SAVE_REG(gp, GP, frame, bo) ;\
SAVE_REG(ra, RA, frame, bo) ;\
mflo v0 ;\
mfhi v1 ;\
SAVE_REG(v0, MULLO, frame, bo) ;\
SAVE_REG(v1, MULHI, frame, bo) ;\
SAVE_REG(a0, CAUSE, frame, bo) ;\
SAVE_REG(a1, SR, frame, bo) ;\
SAVE_REG(a2, BADVADDR, frame, bo) ;\
SAVE_REG(a3, PC, frame, bo) ;\
SAVE_REG(sp, SP, frame, bo) ;\
PTR_ADDU a0, frame, bo ;\
GET_CPU_INFO(v0, v1) ;\
lw a2, CI_IPL(v0) ;\
SAVE_REG(a2, CPL, frame, bo)
#define SAVE_CPU_SREG(frame, bo) \
SAVE_REG(s0, S0, frame, bo) ;\
SAVE_REG(s1, S1, frame, bo) ;\
SAVE_REG(s2, S2, frame, bo) ;\
SAVE_REG(s3, S3, frame, bo) ;\
SAVE_REG(s4, S4, frame, bo) ;\
SAVE_REG(s5, S5, frame, bo) ;\
SAVE_REG(s6, S6, frame, bo) ;\
SAVE_REG(s7, S7, frame, bo) ;\
SAVE_REG(s8, S8, frame, bo)
#define RESTORE_CPU(frame, bo) \
RESTORE_REG(t1, SR, frame, bo) ;\
RESTORE_REG(t2, MULLO, frame, bo) ;\
RESTORE_REG(t3, MULHI, frame, bo) ;\
MTC0 t1, COP_0_STATUS_REG ;\
MTC0_SR_IE_HAZARD ;\
mtlo t2 ;\
mthi t3 ;\
DMTC0 a0, COP_0_EXC_PC ;\
MTC0_HAZARD ;\
RESTORE_REG(AT, AST, frame, bo) ;\
RESTORE_REG(v0, V0, frame, bo) ;\
RESTORE_REG(v1, V1, frame, bo) ;\
RESTORE_REG(a0, A0, frame, bo) ;\
RESTORE_REG(a1, A1, frame, bo) ;\
RESTORE_REG(a2, A2, frame, bo) ;\
RESTORE_REG(a3, A3, frame, bo) ;\
RESTORE_REG(a4, A4, frame, bo) ;\
RESTORE_REG(a5, A5, frame, bo) ;\
RESTORE_REG(a6, A6, frame, bo) ;\
RESTORE_REG(a7, A7, frame, bo) ;\
RESTORE_REG(t0, T0, frame, bo) ;\
RESTORE_REG(t1, T1, frame, bo) ;\
RESTORE_REG(t2, T2, frame, bo) ;\
RESTORE_REG(t3, T3, frame, bo) ;\
RESTORE_REG(t8, T8, frame, bo) ;\
RESTORE_REG(t9, T9, frame, bo) ;\
RESTORE_REG(gp, GP, frame, bo) ;\
RESTORE_REG(ra, RA, frame, bo)
#define RESTORE_CPU_SREG(frame, bo) \
RESTORE_REG(s0, S0, frame, bo) ;\
RESTORE_REG(s1, S1, frame, bo) ;\
RESTORE_REG(s2, S2, frame, bo) ;\
RESTORE_REG(s3, S3, frame, bo) ;\
RESTORE_REG(s4, S4, frame, bo) ;\
RESTORE_REG(s5, S5, frame, bo) ;\
RESTORE_REG(s6, S6, frame, bo) ;\
RESTORE_REG(s7, S7, frame, bo) ;\
RESTORE_REG(s8, S8, frame, bo)