mirror of
https://github.com/n64dev/cen64.git
synced 2024-06-23 14:33:13 -04:00
Commit preliminary (untested) TLB support.
This commit is contained in:
parent
925e1e2dcd
commit
5f5d4da9a6
|
@ -151,6 +151,7 @@ file(GLOB VI_SOURCES ${PROJECT_SOURCE_DIR}/vi/*.c)
|
|||
file(GLOB VR4300_SOURCES ${PROJECT_SOURCE_DIR}/vr4300/*.c)
|
||||
file(GLOB ARCH_FPU_SOURCES arch/${CEN64_ARCH_DIR}/fpu/*.c)
|
||||
file(GLOB ARCH_RSP_SOURCES arch/${CEN64_ARCH_DIR}/rsp/*.c)
|
||||
file(GLOB ARCH_TLB_SOURCES arch/${CEN64_ARCH_DIR}/tlb/*.c)
|
||||
|
||||
#
|
||||
# Glob all the files together.
|
||||
|
@ -178,7 +179,7 @@ endif (DEFINED WIN32)
|
|||
add_executable(cen64 ${EXTRA_OS_EXE} ${ASM_SOURCES} ${OS_SOURCES}
|
||||
${COMMON_SOURCES} ${CEN64_SOURCES} ${AI_SOURCES} ${BUS_SOURCES} ${PI_SOURCES}
|
||||
${RDP_SOURCES} ${RSP_SOURCES} ${RI_SOURCES} ${SI_SOURCES} ${VI_SOURCES}
|
||||
${VR4300_SOURCES} ${ARCH_FPU_SOURCES} ${ARCH_RSP_SOURCES})
|
||||
${VR4300_SOURCES} ${ARCH_FPU_SOURCES} ${ARCH_RSP_SOURCES} ${ARCH_TLB_SOURCES})
|
||||
|
||||
target_link_libraries(cen64 ${EXTRA_OS_LIBS} ${OPENGL_gl_LIBRARY})
|
||||
|
||||
|
|
82
arch/x86_64/tlb/tlb.c
Normal file
82
arch/x86_64/tlb/tlb.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// arch/x86_64/tlb/tlb.c: Translation lookaside buffer.
|
||||
//
|
||||
// CEN64: Cycle-Accurate Nintendo 64 Simulator.
|
||||
// Copyright (C) 2014, Tyler J. Stachecki.
|
||||
//
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// 'LICENSE', which is part of this source code package.
|
||||
//
|
||||
|
||||
#include "common.h"
|
||||
#include "arch/x86_64/tlb/tlb.h"
|
||||
#include <emmintrin.h>
|
||||
|
||||
// Initializes the TLB with invalid entries.
|
||||
void tlb_init(struct cen64_tlb *tlb) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
tlb->vpn2[i] = ~0;
|
||||
}
|
||||
|
||||
// Probes the TLB for matching entry. Returns the index or -1.
|
||||
int tlb_probe(struct cen64_tlb *tlb, uint64_t vaddr, uint8_t vasid) {
|
||||
int one_hot_idx;
|
||||
uint32_t vpn2;
|
||||
unsigned i;
|
||||
|
||||
vpn2 =
|
||||
(vaddr >> 35 & 0x18000000U) |
|
||||
(vaddr >> 13 & 0x7FFFFFF);
|
||||
|
||||
__m128i vpn = _mm_set1_epi32(vpn2);
|
||||
__m128i asid = _mm_set1_epi8(vasid);
|
||||
|
||||
// Scan 8 entries in parallel.
|
||||
for (i = 0; i < 32 / 8; i += 8) {
|
||||
__m128i check_l, check_h, vpn_check;
|
||||
__m128i check_a, check_g, asid_check;
|
||||
__m128i check;
|
||||
|
||||
__m128i page_mask_l = _mm_load_si128((__m128i*) (tlb->page_mask + i + 0));
|
||||
__m128i page_mask_h = _mm_load_si128((__m128i*) (tlb->page_mask + i + 4));
|
||||
__m128i vpn_l = _mm_load_si128((__m128i*) (tlb->vpn2 + i + 0));
|
||||
__m128i vpn_h = _mm_load_si128((__m128i*) (tlb->vpn2 + i + 4));
|
||||
|
||||
// Check for matching VPNs.
|
||||
check_l = _mm_and_si128(vpn_l, page_mask_l);
|
||||
check_l = _mm_cmpeq_epi32(check_l, vpn);
|
||||
check_h = _mm_and_si128(vpn_h, page_mask_h);
|
||||
check_h = _mm_cmpeq_epi32(check_h, vpn);
|
||||
vpn_check = _mm_packs_epi32(check_l, check_h);
|
||||
vpn_check = _mm_packs_epi16(vpn_check, vpn_check);
|
||||
|
||||
// Check for matching ASID/global, too.
|
||||
check_g = _mm_loadl_epi64((__m128i*) (tlb->global + i));
|
||||
check_a = _mm_loadl_epi64((__m128i*) (tlb->asid + i));
|
||||
asid_check = _mm_cmpeq_epi8(check_a, asid);
|
||||
asid_check = _mm_or_si128(check_g, asid_check);
|
||||
|
||||
// Match only on VPN match && (asid match || global)
|
||||
check = _mm_and_si128(vpn_check, asid_check);
|
||||
if ((one_hot_idx = _mm_movemask_epi8(check)) != 0)
|
||||
return i + cen64_one_hot_lut[one_hot_idx & 0xFF];
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Writes an entry to the TLB.
|
||||
int tlb_write(struct cen64_tlb *tlb, unsigned index, uint64_t entry_hi,
|
||||
uint64_t entry_lo_0, uint64_t entry_lo_1, uint32_t page_mask) {
|
||||
tlb->page_mask[index] = page_mask;
|
||||
tlb->vpn2[index] =
|
||||
(entry_hi >> 35 & 0x18000000U) |
|
||||
(entry_hi >> 13 & 0x7FFFFFF);
|
||||
|
||||
tlb->global[index] = (entry_lo_0 & 0x1) && (entry_lo_1 & 0x1) ? 0xFF : 0x00;
|
||||
tlb->asid[index] = entry_hi & 0xFF;
|
||||
return 0;
|
||||
}
|
||||
|
28
arch/x86_64/tlb/tlb.h
Normal file
28
arch/x86_64/tlb/tlb.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// arch/x86_64/tlb/tlb.h: Translation lookaside buffer.
|
||||
//
|
||||
// CEN64: Cycle-Accurate Nintendo 64 Simulator.
|
||||
// Copyright (C) 2014, Tyler J. Stachecki.
|
||||
//
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// 'LICENSE', which is part of this source code package.
|
||||
//
|
||||
|
||||
#ifndef __arch_tlb_h__
|
||||
#define __arch_tlb_h__
|
||||
|
||||
struct cen64_tlb {
|
||||
uint32_t page_mask[32];
|
||||
uint32_t vpn2[32];
|
||||
uint8_t global[32];
|
||||
uint8_t asid[32];
|
||||
};
|
||||
|
||||
void tlb_init(struct cen64_tlb *tlb);
|
||||
|
||||
int tlb_probe(struct cen64_tlb *tlb, uint64_t vpn2, uint8_t vasid);
|
||||
int tlb_write(struct cen64_tlb *tlb, unsigned index, uint64_t entry_hi,
|
||||
uint64_t entry_lo_0, uint64_t entry_lo_1, uint32_t page_mask);
|
||||
|
||||
#endif
|
||||
|
|
@ -149,5 +149,10 @@ void cen64_return(struct bus_controller *bus)
|
|||
#cmakedefine VR4300_BUSY_WAIT_DETECTION
|
||||
|
||||
#include "common/debug.h"
|
||||
|
||||
// Common/shared LUT with one-hot semantics.
|
||||
// Returns index (0-based) of hot bit, or -1.
|
||||
extern const int8_t cen64_one_hot_lut[256];
|
||||
|
||||
#endif
|
||||
|
||||
|
|
51
common/one_hot.c
Normal file
51
common/one_hot.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// vr4300/one_hot.c: 8-bit one-hot LUT.
|
||||
//
|
||||
// CEN64: Cycle-Accurate Nintendo 64 Simulator.
|
||||
// Copyright (C) 2014, Tyler J. Stachecki.
|
||||
//
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// 'LICENSE', which is part of this source code package.
|
||||
//
|
||||
|
||||
#include "common.h"
|
||||
|
||||
cen64_align(const int8_t cen64_one_hot_lut[256], CACHE_LINE_SIZE) = {
|
||||
-1,
|
||||
|
||||
// 1
|
||||
0,
|
||||
|
||||
// 2
|
||||
1, -1,
|
||||
|
||||
// 4
|
||||
2, -1, -1, -1,
|
||||
|
||||
// 8
|
||||
3, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
// 16
|
||||
4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
// 32
|
||||
5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
// 64
|
||||
6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
// 128
|
||||
7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
17
os/unix/x86_64/tlb/tlb.h
Normal file
17
os/unix/x86_64/tlb/tlb.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// os/unix/x86_64/tlb/tlb.h
|
||||
//
|
||||
// Extern declarations for host TLB functions.
|
||||
//
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// 'LICENSE', which is part of this source code package.
|
||||
//
|
||||
|
||||
#ifndef __os_tlb_h__
|
||||
#define __os_tlb_h__
|
||||
#include "common.h"
|
||||
|
||||
#include "arch/x86_64/tlb/tlb.h"
|
||||
|
||||
#endif
|
||||
|
17
os/windows/x86_64/tlb/tlb.h
Normal file
17
os/windows/x86_64/tlb/tlb.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// os/windows/x86_64/tlb/tlb.h
|
||||
//
|
||||
// Extern declarations for host TLB functions.
|
||||
//
|
||||
// This file is subject to the terms and conditions defined in
|
||||
// 'LICENSE', which is part of this source code package.
|
||||
//
|
||||
|
||||
#ifndef __os_tlb_h__
|
||||
#define __os_tlb_h__
|
||||
#include "common.h"
|
||||
|
||||
#include "arch/x86_64/tlb/tlb.h"
|
||||
|
||||
#endif
|
||||
|
82
vr4300/cp0.c
82
vr4300/cp0.c
|
@ -9,9 +9,49 @@
|
|||
//
|
||||
|
||||
#include "common.h"
|
||||
#include "tlb/tlb.h"
|
||||
#include "vr4300/cp0.h"
|
||||
#include "vr4300/cpu.h"
|
||||
|
||||
static const uint64_t vr4300_cp0_reg_masks[32] = {
|
||||
0x000000008000003FULL, // 0: VR4300_CP0_REGISTER_INDEX
|
||||
0x000000000000003FULL, // 1: VR4300_CP0_REGISTER_RANDOM
|
||||
0x000000007FFFFFFFULL, // 2: VR4300_CP0_REGISTER_ENTRYLO0
|
||||
0x000000007FFFFFFFULL, // 3: VR4300_CP0_REGISTER_ENTRYLO1
|
||||
0xFFFFFFFFFFFFFFF0ULL, // 4: VR4300_CP0_REGISTER_CONTEXT
|
||||
0x0000000001FFE000ULL, // 5: VR4300_CP0_REGISTER_PAGEMASK
|
||||
0xFFFFFFFFFFFFFFFFULL, // 6: VR4300_CP0_REGISTER_WIRED
|
||||
0x000000000000003FULL, // 7:
|
||||
0xFFFFFFFFFFFFFFFFULL, // 8: VR4300_CP0_REGISTER_BADVADDR
|
||||
0x00000000FFFFFFFFULL, // 9: VR4300_CP0_REGISTER_COUNT
|
||||
0xC00000FFFFFFE0FFULL, // 10: VR4300_CP0_REGISTER_ENTRYHI
|
||||
0x00000000FFFFFFFFULL, // 11: VR4300_CP0_REGISTER_COMPARE
|
||||
0x00000000FFFFFFFFULL, // 12: VR4300_CP0_REGISTER_STATUS
|
||||
0x00000000B000FFFFULL, // 13: VR4300_CP0_REGISTER_CAUSE
|
||||
0xFFFFFFFFFFFFFFFFULL, // 14: VR4300_CP0_REGISTER_EPC
|
||||
0x000000000000FFFFULL, // 15; VR4300_CP0_REGISTER_PRID
|
||||
0x000000007FFFFFFFULL, // 16: VR4300_CP0_REGISTER_CONFIG
|
||||
0x00000000FFFFFFFFULL, // 17: VR4300_CP0_REGISTER_LLADDR
|
||||
0x00000000FFFFFFFBULL, // 18: VR4300_CP0_REGISTER_WATCHLO
|
||||
0x000000000000000FULL, // 19: VR4300_CP0_REGISTER_WATCHHI
|
||||
0xFFFFFFFFFFFFFFFFULL, // 20: VR4300_CP0_REGISTER_XCONTEXT
|
||||
0xFFFFFFFFFFFFFFFFULL, // 21:
|
||||
0xFFFFFFFFFFFFFFFFULL, // 22:
|
||||
0xFFFFFFFFFFFFFFFFULL, // 23:
|
||||
0xFFFFFFFFFFFFFFFFULL, // 24:
|
||||
0xFFFFFFFFFFFFFFFFULL, // 25:
|
||||
0x0000000000000000ULL, // 26: VR4300_CP0_REGISTER_PARITYERROR
|
||||
0x0000000000000000ULL, // 27: VR4300_CP0_REGISTER_CACHEERR
|
||||
0x000000000FFFFFC0ULL, // 28: VR4300_CP0_REGISTER_TAGLO
|
||||
0x0000000000000000ULL, // 29: VR4300_CP0_REGISTER_TAGHI
|
||||
0xFFFFFFFFFFFFFFFFULL, // 30: VR4300_CP0_REGISTER_ERROREPC
|
||||
0xFFFFFFFFFFFFFFFFULL, // 31
|
||||
};
|
||||
|
||||
static inline uint64_t mask_reg(unsigned reg, uint64_t data) {
|
||||
return vr4300_cp0_reg_masks[reg] & data;
|
||||
};
|
||||
|
||||
//
|
||||
// ERET
|
||||
//
|
||||
|
@ -49,15 +89,14 @@ int VR4300_ERET(struct vr4300 *vr4300,
|
|||
|
||||
//
|
||||
// MFC0
|
||||
// TODO/FIXME: Combine with MFC{1,2}?
|
||||
//
|
||||
int VR4300_MFC0(struct vr4300 *vr4300,
|
||||
uint32_t iw, uint64_t rs, uint64_t rt) {
|
||||
struct vr4300_exdc_latch *exdc_latch = &vr4300->pipeline.exdc_latch;
|
||||
unsigned src = GET_RD(iw) + 32;
|
||||
unsigned dest = GET_RT(iw);
|
||||
unsigned src = GET_RD(iw);
|
||||
|
||||
exdc_latch->result = (int32_t) vr4300->regs[src];
|
||||
exdc_latch->result = mask_reg(src, vr4300->regs[32 + src]);
|
||||
exdc_latch->dest = dest;
|
||||
return 0;
|
||||
}
|
||||
|
@ -67,20 +106,45 @@ int VR4300_MFC0(struct vr4300 *vr4300,
|
|||
//
|
||||
int VR4300_MTC0(struct vr4300 *vr4300,
|
||||
uint32_t iw, uint64_t rs, uint64_t rt) {
|
||||
unsigned dest = GET_RD(iw) + 32;
|
||||
unsigned dest = 32 + GET_RD(iw);
|
||||
|
||||
if (dest == VR4300_CP0_REGISTER_COMPARE)
|
||||
vr4300->regs[VR4300_CP0_REGISTER_CAUSE] &= ~0x8000;
|
||||
|
||||
// TODO/FIXME: Sign extend, or...?
|
||||
// Would make sense for EPC, etc.
|
||||
//exdc_latch->result = (int32_t) rt;
|
||||
//exdc_latch->dest = dest;
|
||||
vr4300->regs[dest] = (int32_t) rt;
|
||||
vr4300->regs[dest] = rt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// TLBP
|
||||
//
|
||||
int VR4300_TLBP(struct vr4300 *vr4300,
|
||||
uint32_t iw, uint64_t rs, uint64_t rt) {
|
||||
uint64_t entry_hi = mask_reg(10, vr4300->regs[VR4300_CP0_REGISTER_ENTRYHI]);
|
||||
|
||||
if (tlb_probe(&vr4300->tlb, entry_hi, entry_hi & 0xFF) != -1)
|
||||
vr4300->regs[VR4300_CP0_REGISTER_INDEX] |= 0x80000000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// TLBWI
|
||||
//
|
||||
int VR4300_TLBWI(struct vr4300 *vr4300,
|
||||
uint32_t iw, uint64_t rs, uint64_t rt) {
|
||||
uint64_t entry_hi = mask_reg(10, vr4300->regs[VR4300_CP0_REGISTER_ENTRYHI]);
|
||||
uint64_t entry_lo_0 = mask_reg(2, vr4300->regs[VR4300_CP0_REGISTER_ENTRYLO0]);
|
||||
uint64_t entry_lo_1 = mask_reg(3, vr4300->regs[VR4300_CP0_REGISTER_ENTRYLO1]);
|
||||
uint32_t page_mask = mask_reg(5, vr4300->regs[VR4300_CP0_REGISTER_PAGEMASK]);
|
||||
unsigned index = vr4300->regs[VR4300_CP0_REGISTER_INDEX] & 0x3F;
|
||||
|
||||
tlb_write(&vr4300->tlb, index, entry_hi, entry_lo_0, entry_lo_1, page_mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initializes the coprocessor.
|
||||
void vr4300_cp0_init(struct vr4300 *vr4300) {
|
||||
tlb_init(&vr4300->tlb);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ enum vr4300_cp0_register {
|
|||
int VR4300_ERET(struct vr4300 *vr4300, uint32_t iw, uint64_t rs, uint64_t rt);
|
||||
int VR4300_MFC0(struct vr4300 *vr4300, uint32_t iw, uint64_t rs, uint64_t rt);
|
||||
int VR4300_MTC0(struct vr4300 *vr4300, uint32_t iw, uint64_t rs, uint64_t rt);
|
||||
int VR4300_TLBP(struct vr4300 *vr4300, uint32_t iw, uint64_t rs, uint64_t rt);
|
||||
int VR4300_TLBWI(struct vr4300 *vr4300, uint32_t iw, uint64_t rs, uint64_t rt);
|
||||
|
||||
void vr4300_cp0_init(struct vr4300 *vr4300);
|
||||
|
||||
|
|
|
@ -35,10 +35,11 @@ int vr4300_init(struct vr4300 *vr4300, struct bus_controller *bus) {
|
|||
|
||||
vr4300_cp0_init(vr4300);
|
||||
vr4300_cp1_init(vr4300);
|
||||
|
||||
vr4300_dcache_init(&vr4300->dcache);
|
||||
vr4300_icache_init(&vr4300->icache);
|
||||
vr4300_pipeline_init(&vr4300->pipeline);
|
||||
|
||||
vr4300_pipeline_init(&vr4300->pipeline);
|
||||
vr4300->signals = VR4300_SIGNAL_COLDRESET;
|
||||
|
||||
// MESS uses this version, so we will too?
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#ifndef __vr4300_cpu_h__
|
||||
#define __vr4300_cpu_h__
|
||||
#include "common.h"
|
||||
#include "tlb/tlb.h"
|
||||
#include "vr4300/cp0.h"
|
||||
#include "vr4300/cp1.h"
|
||||
#include "vr4300/dcache.h"
|
||||
|
@ -90,6 +91,11 @@ extern const char *mi_register_mnemonics[NUM_MI_REGISTERS];
|
|||
|
||||
struct vr4300 {
|
||||
struct vr4300_pipeline pipeline;
|
||||
|
||||
// Align the TLB to a 16-byte boundary for vectorization.
|
||||
uint8_t padding_for_tlb[(16 - (sizeof(struct vr4300_pipeline) % 16)) % 16];
|
||||
struct cen64_tlb tlb;
|
||||
|
||||
struct vr4300_cp1 cp1;
|
||||
|
||||
struct bus_controller *bus;
|
||||
|
|
|
@ -771,10 +771,7 @@ int VR4300_INV(struct vr4300 *vr4300,
|
|||
rfex_latch->common.pc);
|
||||
|
||||
// TODO/FIXME: Implement this instruction later.
|
||||
if (opcode == VR4300_OPCODE_TLBP)
|
||||
vr4300->regs[VR4300_CP0_REGISTER_INDEX] = (int32_t) 0x80000000;
|
||||
|
||||
else if (opcode != VR4300_OPCODE_TLBWI && opcode != VR4300_OPCODE_TLBR)
|
||||
if (opcode != VR4300_OPCODE_TLBR)
|
||||
assert(0 && "Unimplemented instruction encountered.");
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -172,9 +172,9 @@ extern const char *vr4300_opcode_mnemonics[NUM_VR4300_OPCODES];
|
|||
|
||||
#define CACHE VR4300_BUILD_OP(CACHE, CACHE, INFO1(NEEDRS))
|
||||
#define ERET VR4300_BUILD_OP(ERET, ERET, INFO1(NONE))
|
||||
#define TLBP VR4300_BUILD_OP(TLBP, INV, INFO1(NONE))
|
||||
#define TLBP VR4300_BUILD_OP(TLBP, TLBP, INFO1(NONE))
|
||||
#define TLBR VR4300_BUILD_OP(TLBR, INV, INFO1(NONE))
|
||||
#define TLBWI VR4300_BUILD_OP(TLBWI, INV, INFO1(NONE))
|
||||
#define TLBWI VR4300_BUILD_OP(TLBWI, TLBWI, INFO1(NONE))
|
||||
#define TLBWR VR4300_BUILD_OP(TLBWR, INV, INFO1(NONE))
|
||||
|
||||
#define BC1 VR4300_BUILD_OP(BC1, BC1, INFO1(BRANCH))
|
||||
|
|
Loading…
Reference in a new issue