📄 decoder.cc
字号:
syscmd ^= bitmask(2, 0); reg = set_bits(reg, bits(mem, 63, syscmd * 8), 63 - syscmd * 8, 0); gpr[rt(instr)] = sign_extend<UInt64>(reg, 64); return nothing_special; } case LB: { // Load Byte ///////////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tlb\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; PA pa = translate_vaddr(va, data_load); UInt8 x = load<byte>(va, pa); gpr[rt(instr)] = sign_extend<UInt64>(x, 8); return nothing_special; } case LH: { // Load Halfword ///////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tlh\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (bit(va, 0)) process_address_error(data_load, va); PA pa = translate_vaddr(va, data_load); UInt16 x = load<halfword>(va, pa); gpr[rt(instr)] = sign_extend<UInt64>(x, 16); return nothing_special; } case LWL: { // Load Word Left //////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tlwl\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; // WARNING: see the comment in unaligned.cc. PA pa = translate_vaddr(va, data_load); UInt32 mem = load<word>(round_down(va, 4), round_down(pa, 4)); UInt32 reg = gpr[rt(instr)]; int syscmd = bits(va, 1, 0); if (!big_endian_cpu()) syscmd ^= bitmask(1, 0); reg = set_bits(reg, mem, 31, syscmd * 8); gpr[rt(instr)] = sign_extend<UInt64>(reg, 32); return nothing_special; } case LW: { // Load Word ///////////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tlw\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (bits(va, 1, 0)) process_address_error(data_load, va); PA pa = translate_vaddr(va, data_load); UInt32 x = load<word>(va, pa); gpr[rt(instr)] = sign_extend<UInt64>(x, 32); return nothing_special; } case LBU: { // Load Byte Unsigned //////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tlbu\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; PA pa = translate_vaddr(va, data_load); UInt8 x = load<byte>(va, pa); gpr[rt(instr)] = zero_extend<UInt64>(x, 8); return nothing_special; } case LHU: { // Load Halfword Unsigned //////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tlhu\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (bit(va, 0)) process_address_error(data_load, va); PA pa = translate_vaddr(va, data_load); UInt16 x = load<halfword>(va, pa); gpr[rt(instr)] = zero_extend<UInt64>(x, 16); return nothing_special; } case LWR: { // Load Word Right /////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tlwr\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; // WARNING: see the comment in unaligned.cc. PA pa = translate_vaddr(va, data_load); UInt32 mem = load<word>(round_down(va, 4), round_down(pa, 4)); UInt32 reg = gpr[rt(instr)]; int syscmd = bits(va, 1, 0); if (big_endian_cpu()) syscmd ^= bitmask(1, 0); reg = set_bits(reg, bits(mem, 31, syscmd * 8), 31 - syscmd * 8, 0); gpr[rt(instr)] = sign_extend<UInt64>(reg, 32); return nothing_special; } case LWU: { // Load Word Unsigned //////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tlwu\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (bits(va, 1, 0)) process_address_error(data_load, va); PA pa = translate_vaddr(va, data_load); UInt32 x = load<word>(va, pa); gpr[rt(instr)] = zero_extend<UInt64>(x, 32); return nothing_special; } case SB: { // Store Byte //////////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tsb\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; PA pa = translate_vaddr(va, data_store); store<byte>(gpr[rt(instr)], va, pa); return nothing_special; } case SH: { // Store Halfword //////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tsh\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (bit(va, 0)) process_address_error(data_store, va); PA pa = translate_vaddr(va, data_store); store<halfword>(gpr[rt(instr)], va, pa); return nothing_special; } case SWL: { // Store Word Left /////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tswl\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; // WARNING: see the comment in unaligned.cc. PA pa = translate_vaddr(va, data_store); UInt32 mem = load<word>(round_down(va, 4), round_down(pa, 4)); UInt32 reg = gpr[rt(instr)]; int syscmd = bits(va, 1, 0); if (!big_endian_cpu()) syscmd ^= bitmask(1, 0); mem = set_bits(mem, bits(reg, 31, syscmd*8), 31 - syscmd * 8, 0); store<word>(mem, round_down(va, 4), round_down(pa, 4)); return nothing_special; } case SW: { // Store Word //////////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tsw\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (bits(va, 1, 0)) process_address_error(data_store, va); PA pa = translate_vaddr(va, data_store); store<word>(gpr[rt(instr)], va, pa); return nothing_special; } case SDL: { // Store Doubleword Left ///////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tsdl\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (!allow_xinstr()) process_reserved_instruction(); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; // WARNING: see the comment in unaligned.cc. PA pa = translate_vaddr(va, data_store); UInt64 mem = load<doubleword>(round_down(va, 8), round_down(pa, 8)); UInt64 reg = gpr[rt(instr)]; int syscmd = bits(va, 2, 0); if (!big_endian_cpu()) syscmd ^= bitmask(2, 0); mem = set_bits(mem, bits(reg, 63, syscmd*8), 63 - syscmd * 8, 0); store<doubleword>(mem, round_down(va, 8), round_down(pa, 8)); return nothing_special; } case SDR: { // Store Doubleword Right //////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tsdr\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (!allow_xinstr()) process_reserved_instruction(); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; // WARNING: see the comment in unaligned.cc. PA pa = translate_vaddr(va, data_store); UInt64 mem = load<doubleword>(round_down(va, 8), round_down(pa, 8)); UInt64 reg = gpr[rt(instr)]; int syscmd = bits(va, 2, 0); if (big_endian_cpu()) syscmd ^= bitmask(2, 0); mem = set_bits(mem, reg, 63, syscmd * 8); store<doubleword>(mem, round_down(va, 8), round_down(pa, 8)); return nothing_special; } case SWR: { // Store Word Right ////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tswr\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; // WARNING: see the comment in unaligned.cc. PA pa = translate_vaddr(va, data_store); UInt32 mem = load<word>(round_down(va, 4), round_down(pa, 4)); UInt32 reg = gpr[rt(instr)]; int syscmd = bits(va, 1, 0); if (big_endian_cpu()) syscmd ^= bitmask(1, 0); mem = set_bits(mem, reg, 31, syscmd * 8); store<word>(mem, round_down(va, 4), round_down(pa, 4)); return nothing_special; } case CACHE: { // Cache ///////////////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tcache\t%d, %d(%s)", pc, bits(instr, 20, 16), sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); return decode_cache(instr); } case LL: { // Load Linked /////////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tll\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (bits(va, 1, 0)) process_address_error(data_load, va); PA pa = translate_vaddr(va, data_load); UInt32 x = load<word>(va, pa); gpr[rt(instr)] = sign_extend<UInt64>(x, 32); cp0[LLAddr] = bits(pa, 35, 4); sync_bit = true; ll_bit = true; return nothing_special; } case LWC1: { // Load Word to Coprocessor 1 //////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\t.long\t0x%08x // lwc1", pc, instr); return decode_lwc1(instr); } case LWC2: { // Load Word to Coprocessor 2 //////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\t.long\t0x%08x // lwc2", pc, instr); process_reserved_instruction(); return nothing_special; } case LLD: { // Load Linked Doubleword //////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tlld\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (!allow_xinstr()) process_reserved_instruction(); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (bits(va, 2, 0)) process_address_error(data_load, va); PA pa = translate_vaddr(va, data_load); UInt64 x = load<doubleword>(va, pa); gpr[rt(instr)] = sign_extend<UInt64>(x, 64); cp0[LLAddr] = bits(pa, 35, 4); sync_bit = true; ll_bit = true; return nothing_special; } case LDC1: { // Load Doubleword To Coprocessor 1 ////////////////////////////////// return decode_ldc1(instr); } case LDC2: { // Load Doubleword To Coprocessor 2 ////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\t.long\t0x%08x // ldc2", pc, instr); process_reserved_instruction(); return nothing_special; } case LD: { // Load Doubleword /////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tld\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (!allow_xinstr()) process_reserved_instruction(); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (bits(va, 2, 0)) process_address_error(data_load, va); PA pa = translate_vaddr(va, data_load); UInt64 x = load<doubleword>(va, pa); gpr[rt(instr)] = sign_extend<UInt64>(x, 64); return nothing_special; } case SC: { // Store Conditional ///////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tsc\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (sync_bit) sync(); if (bits(va, 1, 0)) process_address_error(data_store, va); PA pa = translate_vaddr(va, data_store); if (ll_bit) store<word>(gpr[rt(instr)], va, pa); gpr[rt(instr)] = ll_bit; sync_bit = true; ll_bit = false; return nothing_special; } case SWC1: { // Store Word From Coprocessor 1 ///////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\t.long\t0x%08x // swc1", pc, instr); return decode_swc1(instr); } case SWC2: { // Store Word From Coprocessor 2 ///////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\t.long\t0x%08x // swc2", pc, instr); process_reserved_instruction(); return nothing_special; } case SCD: { // Store Conditional ///////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tscd\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (!allow_xinstr()) process_reserved_instruction(); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (bits(va, 2, 0)) process_address_error(data_store, va); PA pa = translate_vaddr(va, data_store); if (ll_bit) store<doubleword>(gpr[rt(instr)], va, pa); gpr[rt(instr)] = ll_bit; sync_bit = true; ll_bit = false; return nothing_special; } case SDC1: { // Store Doubleword From Coprocessor 1 /////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\t.long\t0x%08x // sdc1", pc, instr); if (!allow_xinstr()) process_reserved_instruction(); return decode_sdc1(instr); } case SDC2: { // Store Doubleword From Coprocessor 2 /////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\t.long\t0x%08x // sdc2", pc, instr); process_reserved_instruction(); return nothing_special; } case SD: { // Store Doubleword ////////////////////////////////////////////////// if (trace_level >= print_instructions) log("[%lx]\tsd\t%s, %d(%s)", pc, regname[rt(instr)], sign_extend<Int32>(offset(instr), 16), regname[base(instr)]); if (!allow_xinstr()) process_reserved_instruction(); if (sync_bit) sync(); VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)]; if (bits(va, 2, 0)) process_address_error(data_store, va); PA pa = translate_vaddr(va, data_store); store<doubleword>(gpr[rt(instr)], va, pa); return nothing_special; } default: // Reserved instruction. if (trace_level >= print_instructions) log("[%lx]\t.long\t0x%08x", pc, instr); process_reserved_instruction(); return nothing_special; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -