GPR_K0
uasm_i_mfc0(&p, GPR_K0, C0_STATUS);
uasm_i_and(&p, GPR_K0, GPR_K0, GPR_T9);
uasm_il_bnez(&p, &r, GPR_K0, label_not_nmi);
UASM_i_LA(&p, GPR_K0, (long)&nmi_handler);
uasm_i_lui(&p, GPR_K0, val >> 16);
uasm_i_ori(&p, GPR_K0, GPR_K0, val & 0xffff);
uasm_i_mtc0(&p, GPR_K0, C0_CAUSE);
uasm_i_lui(&p, GPR_K0, val >> 16);
uasm_i_ori(&p, GPR_K0, GPR_K0, val & 0xffff);
uasm_i_mtc0(&p, GPR_K0, C0_STATUS);
UASM_i_LA(&buf, GPR_K0, handler);
uasm_i_jr(&buf, GPR_K0);
UASM_i_LA(&p, GPR_K0, ST0_EXL | KSU_USER | ST0_BEV | ST0_KX_IF_64);
uasm_i_mtc0(&p, GPR_K0, C0_STATUS);
UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, guest_ebase), GPR_K1);
build_set_exc_base(&p, GPR_K0);
uasm_i_addiu(&p, GPR_K0, GPR_ZERO, ST0_EXL | KSU_USER | ST0_IE | ST0_KX_IF_64);
uasm_i_or(&p, GPR_K0, GPR_K0, GPR_V0);
uasm_i_mtc0(&p, GPR_K0, C0_STATUS);
UASM_i_MFC0(&p, GPR_K0, C0_PWBASE);
UASM_i_MFC0(&p, GPR_K0, c0_kscratch(), pgd_reg);
UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, host_pgd), GPR_K1);
uasm_i_mfc0(&p, GPR_K0, C0_GUESTCTL0);
uasm_i_ins(&p, GPR_K0, GPR_V1, MIPS_GCTL0_GM_SHIFT, 1);
uasm_i_mtc0(&p, GPR_K0, C0_GUESTCTL0);
UASM_i_MFC0(&p, GPR_K0, C0_ENTRYHI);
UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, host_entryhi),
UASM_i_LW(&p, GPR_K0, 0, GPR_T3);
uasm_i_and(&p, GPR_K0, GPR_K0, GPR_T2);
uasm_i_andi(&p, GPR_K0, GPR_K0, MIPS_ENTRYHI_ASID);
uasm_i_mtc0(&p, GPR_K0, C0_ENTRYHI);
if (i == GPR_K0 || i == GPR_K1)
UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, hi), GPR_K1);
uasm_i_mthi(&p, GPR_K0);
UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, lo), GPR_K1);
uasm_i_mtlo(&p, GPR_K0);
UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, gprs[GPR_K0]), GPR_K1);
UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu, arch.gprs[GPR_K0]), GPR_K1);
uasm_i_lddir(&p, GPR_K0, GPR_K1, 3); /* global page dir */
uasm_i_lddir(&p, GPR_K1, GPR_K0, 1); /* middle page dir */
build_get_pmde64(&p, &l, &r, GPR_K0, GPR_K1); /* get pmd in GPR_K1 */
build_get_pgde32(&p, GPR_K0, GPR_K1); /* get pgd in GPR_K1 */
build_get_ptep(&p, GPR_K0, GPR_K1);
build_update_entries(&p, GPR_K0, GPR_K1);
UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu, arch.gprs[GPR_K0]), GPR_K1);
UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, gprs[GPR_K0]), GPR_K1);
if (i == GPR_K0 || i == GPR_K1)
UASM_i_MFC0(&p, GPR_K0, C0_EPC);
UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, pc), GPR_K1);
UASM_i_MFC0(&p, GPR_K0, C0_BADVADDR);
UASM_i_SW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, host_cp0_badvaddr),
uasm_i_mfc0(&p, GPR_K0, C0_CAUSE);
uasm_i_sw(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, host_cp0_cause), GPR_K1);
uasm_i_mfc0(&p, GPR_K0, C0_BADINSTR);
uasm_i_sw(&p, GPR_K0, offsetof(struct kvm_vcpu_arch,
uasm_i_mfc0(&p, GPR_K0, C0_BADINSTRP);
uasm_i_sw(&p, GPR_K0, offsetof(struct kvm_vcpu_arch,
uasm_i_or(&p, GPR_K0, GPR_V0, GPR_AT);
uasm_i_mtc0(&p, GPR_K0, C0_STATUS);
UASM_i_LA_mostly(&p, GPR_K0, (long)&ebase);
UASM_i_LW(&p, GPR_K0, uasm_rel_lo((long)&ebase), GPR_K0);
build_set_exc_base(&p, GPR_K0);
UASM_i_LW(&p, GPR_K0, offsetof(struct kvm_vcpu_arch, host_entryhi),
UASM_i_MTC0(&p, GPR_K0, C0_ENTRYHI);
uasm_i_mfc0(&p, GPR_K0, C0_GUESTCTL0);
uasm_i_ins(&p, GPR_K0, GPR_ZERO, MIPS_GCTL0_GM_SHIFT, 1);
uasm_i_mtc0(&p, GPR_K0, C0_GUESTCTL0);
uasm_i_sw(&p, GPR_K0,
kvm_mips_build_restore_scratch(&p, GPR_K0, GPR_SP);
UASM_i_LA_mostly(&p, GPR_K0, (long)&hwrena);
uasm_i_lw(&p, GPR_K0, uasm_rel_lo((long)&hwrena), GPR_K0);
uasm_i_mtc0(&p, GPR_K0, C0_HWRENA);
uasm_i_or(&p, GPR_K0, GPR_V1, GPR_AT);
uasm_i_mtc0(&p, GPR_K0, C0_STATUS);
uasm_i_sra(&p, GPR_K0, GPR_V0, 2);
uasm_i_move(&p, GPR_V0, GPR_K0);
UASM_i_LA_mostly(&p, GPR_K0, (long)&hwrena);
uasm_i_lw(&p, GPR_K0, uasm_rel_lo((long)&hwrena), GPR_K0);
uasm_i_mtc0(&p, GPR_K0, C0_HWRENA);
htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, GPR_K0, GPR_K1,
htlb_info.huge_pte = GPR_K0;
uasm_i_dmfc0(&p, GPR_K0, C0_BADVADDR);
uasm_i_xor(&p, GPR_K0, GPR_K0, GPR_K1);
uasm_i_dsrl_safe(&p, GPR_K1, GPR_K0, 62);
uasm_i_dsrl_safe(&p, GPR_K0, GPR_K0, 12 + 1);
uasm_i_dsll_safe(&p, GPR_K0, GPR_K0, 64 + 12 + 1 - segbits);
uasm_i_or(&p, GPR_K0, GPR_K0, GPR_K1);
uasm_il_bnez(&p, &r, GPR_K0, label_leave);
build_get_pmde64(&p, &l, &r, GPR_K0, GPR_K1); /* get pmd in GPR_K1 */
build_get_pgde32(&p, GPR_K0, GPR_K1); /* get pgd in GPR_K1 */
build_is_huge_pte(&p, &r, GPR_K0, GPR_K1, label_tlb_huge_update);
build_get_ptep(&p, GPR_K0, GPR_K1);
build_update_entries(&p, GPR_K0, GPR_K1);
build_huge_tlb_write_entry(&p, &l, &r, GPR_K0, tlb_random,
build_get_pgd_vmalloc64(&p, &l, &r, GPR_K0, GPR_K1, vmalloc_mode);
uasm_i_dmfc0(&p, GPR_K0, C0_BADVADDR);
uasm_i_dsrl_safe(&p, GPR_K1, GPR_K0,
uasm_il_bgez(&p, &r, GPR_K0, label_large_segbits_fault);
uasm_i_lddir(&p, GPR_K0, GPR_K1, 3); /* global page dir */
uasm_i_lddir(&p, GPR_K1, GPR_K0, 1); /* middle page dir */
uasm_i_lui(&p, GPR_K0, PM_DEFAULT_MASK >> 16);
uasm_i_ori(&p, GPR_K0, GPR_K0, PM_DEFAULT_MASK & 0xffff);
uasm_i_mtc0(&p, GPR_K0, C0_PAGEMASK);
uasm_i_ori(&p, GPR_K0, 0, PM_DEFAULT_MASK);
uasm_i_mtc0(&p, GPR_K0, C0_PAGEMASK);
build_r3000_tlbchange_handler_head(&p, GPR_K0, GPR_K1);
build_pte_present(&p, &r, GPR_K0, GPR_K1, -1, label_nopage_tlbl);
build_make_valid(&p, &r, GPR_K0, GPR_K1, -1);
build_r3000_tlb_reload_write(&p, &l, &r, GPR_K0, GPR_K1);
build_r3000_tlbchange_handler_head(&p, GPR_K0, GPR_K1);
build_pte_writable(&p, &r, GPR_K0, GPR_K1, -1, label_nopage_tlbs);
build_make_write(&p, &r, GPR_K0, GPR_K1, -1);
build_r3000_tlb_reload_write(&p, &l, &r, GPR_K0, GPR_K1);
build_r3000_tlbchange_handler_head(&p, GPR_K0, GPR_K1);
build_pte_modifiable(&p, &r, GPR_K0, GPR_K1, -1, label_nopage_tlbm);
build_make_write(&p, &r, GPR_K0, GPR_K1, -1);
build_r3000_pte_reload_tlbwi(&p, GPR_K0, GPR_K1);
uasm_i_dmfc0(&p, GPR_K0, C0_BADVADDR);
uasm_i_xor(&p, GPR_K0, GPR_K0, GPR_K1);
uasm_i_dsrl_safe(&p, GPR_K1, GPR_K0, 62);
uasm_i_dsrl_safe(&p, GPR_K0, GPR_K0, 12 + 1);
uasm_i_dsll_safe(&p, GPR_K0, GPR_K0, 64 + 12 + 1 - segbits);
uasm_i_or(&p, GPR_K0, GPR_K0, GPR_K1);
uasm_il_bnez(&p, &r, GPR_K0, label_leave);
uasm_i_lui(&p, GPR_K0, uasm_rel_hi((long)tlb_do_page_fault_0));
uasm_i_addiu(&p, GPR_K0, GPR_K0, uasm_rel_lo((long)tlb_do_page_fault_0));
uasm_i_jr(&p, GPR_K0);
uasm_i_lui(&p, GPR_K0, uasm_rel_hi((long)tlb_do_page_fault_1));
uasm_i_addiu(&p, GPR_K0, GPR_K0, uasm_rel_lo((long)tlb_do_page_fault_1));
uasm_i_jr(&p, GPR_K0);
uasm_i_lui(&p, GPR_K0, uasm_rel_hi((long)tlb_do_page_fault_1));
uasm_i_addiu(&p, GPR_K0, GPR_K0, uasm_rel_lo((long)tlb_do_page_fault_1));
uasm_i_jr(&p, GPR_K0);
r.r1 = GPR_K0;
UASM_i_CPUID_MFC0(p, GPR_K0, SMP_CPUID_REG);
UASM_i_SRL_SAFE(p, GPR_K0, GPR_K0, SMP_CPUID_REGSHIFT);
UASM_i_SLL(p, GPR_K0, GPR_K0, ilog2(sizeof(struct tlb_reg_save)));
UASM_i_ADDU(p, GPR_K0, GPR_K0, GPR_K1);
UASM_i_LA(p, GPR_K0, (long)&handler_reg_save);
UASM_i_SW(p, 1, offsetof(struct tlb_reg_save, a), GPR_K0);
UASM_i_SW(p, 2, offsetof(struct tlb_reg_save, b), GPR_K0);
UASM_i_LW(p, 1, offsetof(struct tlb_reg_save, a), GPR_K0);
UASM_i_LW(p, 2, offsetof(struct tlb_reg_save, b), GPR_K0);
uasm_i_mfc0(&p, GPR_K0, C0_BADVADDR);
uasm_i_srl(&p, GPR_K0, GPR_K0, 22); /* load delay */
uasm_i_sll(&p, GPR_K0, GPR_K0, 2);
uasm_i_addu(&p, GPR_K1, GPR_K1, GPR_K0);
uasm_i_mfc0(&p, GPR_K0, C0_CONTEXT);
uasm_i_andi(&p, GPR_K0, GPR_K0, 0xffc); /* load delay */
uasm_i_addu(&p, GPR_K1, GPR_K1, GPR_K0);
uasm_i_lw(&p, GPR_K0, 0, GPR_K1);
uasm_i_mtc0(&p, GPR_K0, C0_ENTRYLO0);