2013-01-14 06:25:28 +01:00
|
|
|
/**
|
|
|
|
|
******************************************************************************
|
|
|
|
|
* Xenia : Xbox 360 Emulator Research Project *
|
|
|
|
|
******************************************************************************
|
|
|
|
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
|
|
|
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
|
|
|
******************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <xenia/cpu/ppc/instr.h>
|
|
|
|
|
|
2013-01-20 10:13:59 +01:00
|
|
|
#include "cpu/ppc/instr_tables.h"
|
2013-01-14 06:25:28 +01:00
|
|
|
|
|
|
|
|
|
2013-01-20 10:13:59 +01:00
|
|
|
using namespace xe::cpu::ppc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
InstrType* xe::cpu::ppc::GetInstrType(uint32_t code) {
|
|
|
|
|
InstrType* slot = NULL;
|
2013-01-14 06:25:28 +01:00
|
|
|
switch (code >> 26) {
|
|
|
|
|
case 4:
|
|
|
|
|
// Opcode = 4, index = bits 5-0 (6)
|
2013-01-20 10:13:59 +01:00
|
|
|
slot = &xe::cpu::ppc::tables::instr_table_4[XESELECTBITS(code, 0, 5)];
|
2013-01-14 06:25:28 +01:00
|
|
|
break;
|
|
|
|
|
case 19:
|
|
|
|
|
// Opcode = 19, index = bits 10-1 (10)
|
2013-01-20 10:13:59 +01:00
|
|
|
slot = &xe::cpu::ppc::tables::instr_table_19[XESELECTBITS(code, 1, 10)];
|
2013-01-14 06:25:28 +01:00
|
|
|
break;
|
|
|
|
|
case 30:
|
|
|
|
|
// Opcode = 30, index = bits 5-1 (5)
|
2013-01-20 10:13:59 +01:00
|
|
|
slot = &xe::cpu::ppc::tables::instr_table_30[XESELECTBITS(code, 1, 5)];
|
2013-01-14 06:25:28 +01:00
|
|
|
break;
|
|
|
|
|
case 31:
|
|
|
|
|
// Opcode = 31, index = bits 10-1 (10)
|
2013-01-20 10:13:59 +01:00
|
|
|
slot = &xe::cpu::ppc::tables::instr_table_31[XESELECTBITS(code, 1, 10)];
|
2013-01-14 06:25:28 +01:00
|
|
|
break;
|
|
|
|
|
case 58:
|
|
|
|
|
// Opcode = 58, index = bits 1-0 (2)
|
2013-01-20 10:13:59 +01:00
|
|
|
slot = &xe::cpu::ppc::tables::instr_table_58[XESELECTBITS(code, 0, 1)];
|
2013-01-14 06:25:28 +01:00
|
|
|
break;
|
|
|
|
|
case 59:
|
|
|
|
|
// Opcode = 59, index = bits 5-1 (5)
|
2013-01-20 10:13:59 +01:00
|
|
|
slot = &xe::cpu::ppc::tables::instr_table_59[XESELECTBITS(code, 1, 5)];
|
2013-01-14 06:25:28 +01:00
|
|
|
break;
|
|
|
|
|
case 62:
|
|
|
|
|
// Opcode = 62, index = bits 1-0 (2)
|
2013-01-20 10:13:59 +01:00
|
|
|
slot = &xe::cpu::ppc::tables::instr_table_62[XESELECTBITS(code, 0, 1)];
|
2013-01-14 06:25:28 +01:00
|
|
|
break;
|
|
|
|
|
case 63:
|
|
|
|
|
// Opcode = 63, index = bits 10-1 (10)
|
2013-01-20 10:13:59 +01:00
|
|
|
slot = &xe::cpu::ppc::tables::instr_table_63[XESELECTBITS(code, 1, 10)];
|
2013-01-14 06:25:28 +01:00
|
|
|
break;
|
|
|
|
|
default:
|
2013-01-20 10:13:59 +01:00
|
|
|
slot = &xe::cpu::ppc::tables::instr_table[XESELECTBITS(code, 26, 31)];
|
2013-01-14 06:25:28 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (!slot || !slot->opcode) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return slot;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-20 10:13:59 +01:00
|
|
|
int xe::cpu::ppc::RegisterInstrEmit(uint32_t code, InstrEmitFn emit) {
|
|
|
|
|
InstrType* instr_type = GetInstrType(code);
|
2013-01-14 06:25:28 +01:00
|
|
|
if (!instr_type) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
XEASSERTNULL(instr_type->emit);
|
|
|
|
|
instr_type->emit = emit;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|