mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-01 13:58:20 +00:00
Decodes operations for the simplest 45.
This commit is contained in:
parent
ed63e7ea75
commit
233a69a1d8
@ -13,162 +13,70 @@ using namespace CPU::Decoder::PowerPC;
|
|||||||
Decoder::Decoder(Model model) : model_(model) {}
|
Decoder::Decoder(Model model) : model_(model) {}
|
||||||
|
|
||||||
Instruction Decoder::decode(uint32_t opcode) {
|
Instruction Decoder::decode(uint32_t opcode) {
|
||||||
switch(opcode >> 26) {
|
// Quick bluffer's guide to PowerPC instruction encoding:
|
||||||
case 31:
|
//
|
||||||
const uint8_t dest = (opcode >> 21) & 0x1f;
|
// There is a six-bit field at the very top of the instruction.
|
||||||
const uint8_t a = (opcode >> 16) & 0x1f;
|
// Sometimes that fully identifies an instruction, but usually
|
||||||
const uint8_t b = (opcode >> 11) & 0x1f;
|
// it doesn't.
|
||||||
|
//
|
||||||
#define OECase(x) case x: case 0x200 + x
|
// There is an addition 9- or 10-bit field starting one bit above
|
||||||
switch((opcode >> 1) & 0x3ff) {
|
// least significant that disambiguates the rest. Strictly speaking
|
||||||
case 0:
|
// it's a 10-bit field, but the mnemonics for many instructions treat
|
||||||
// cmp; 601 10-26
|
// it as a 9-bit field with a flag at the top.
|
||||||
break;
|
//
|
||||||
case 4:
|
// I've decided to hew directly to the mnemonics.
|
||||||
// tw; 601 10-214
|
|
||||||
break;
|
|
||||||
OECase(8):
|
|
||||||
// subfcx; 601 10-207
|
|
||||||
break;
|
|
||||||
// case 9:
|
|
||||||
// // mulhdux
|
|
||||||
// break;
|
|
||||||
OECase(10):
|
|
||||||
// addcx; 601 10-9
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
// mulhwux; 601 10-142
|
|
||||||
break;
|
|
||||||
case 19:
|
|
||||||
// mfcr; 601 10-122
|
|
||||||
break;
|
|
||||||
case 20:
|
|
||||||
// lwarx
|
|
||||||
break;
|
|
||||||
case 21:
|
|
||||||
// ldx
|
|
||||||
break;
|
|
||||||
// lwzx
|
|
||||||
// slwx
|
|
||||||
// cntlzwx
|
|
||||||
// sldx
|
|
||||||
// andx
|
|
||||||
// ampl
|
|
||||||
// subfx
|
|
||||||
// ldux
|
|
||||||
// dcbst
|
|
||||||
// lwzux
|
|
||||||
// cntlzdx
|
|
||||||
// andcx
|
|
||||||
// td
|
|
||||||
// mulhx
|
|
||||||
// mulhwx
|
|
||||||
// mfmsr
|
|
||||||
// ldarx
|
|
||||||
// dcbf
|
|
||||||
// lbzx
|
|
||||||
// negx
|
|
||||||
// norx
|
|
||||||
// subfex
|
|
||||||
// adex
|
|
||||||
// mtcrf
|
|
||||||
// mtmsr
|
|
||||||
// stfx
|
|
||||||
// stwcx.
|
|
||||||
// stwx
|
|
||||||
// stdux
|
|
||||||
// stwux
|
|
||||||
// subfzex
|
|
||||||
// addzex
|
|
||||||
// mtsr
|
|
||||||
// stdcx.
|
|
||||||
// stbx
|
|
||||||
// subfmex
|
|
||||||
// mulld
|
|
||||||
// addmex
|
|
||||||
// mullwx
|
|
||||||
// mtsrin
|
|
||||||
// scbtst
|
|
||||||
// stbux
|
|
||||||
// addx
|
|
||||||
// dcbt
|
|
||||||
// lhzx
|
|
||||||
// eqvx
|
|
||||||
// tlbie
|
|
||||||
// eciwx
|
|
||||||
// lhzux
|
|
||||||
// xorx
|
|
||||||
// mfspr
|
|
||||||
// lwax
|
|
||||||
// lhax
|
|
||||||
// lbia
|
|
||||||
// mftb
|
|
||||||
// lwaux
|
|
||||||
// lhaux
|
|
||||||
// sthx
|
|
||||||
// orcx
|
|
||||||
// sradix
|
|
||||||
// slbie
|
|
||||||
// ecowx
|
|
||||||
// sthux
|
|
||||||
// orx
|
|
||||||
// divdux
|
|
||||||
// divwux
|
|
||||||
// mtspr
|
|
||||||
// dcbi
|
|
||||||
// nandx
|
|
||||||
// divdx
|
|
||||||
// divwx
|
|
||||||
// slbia
|
|
||||||
// mcrxr
|
|
||||||
// lswx
|
|
||||||
// lwbrx
|
|
||||||
// lfsx
|
|
||||||
// srwx
|
|
||||||
// srdx
|
|
||||||
// tlbsync
|
|
||||||
// lfsux
|
|
||||||
// mfsr
|
|
||||||
// lswi
|
|
||||||
// sync
|
|
||||||
// lfdx
|
|
||||||
// lfdux
|
|
||||||
// mfsrin
|
|
||||||
// stswx
|
|
||||||
// stwbrx
|
|
||||||
// stfsx
|
|
||||||
// stfsux
|
|
||||||
// stswi
|
|
||||||
// stfdx
|
|
||||||
// stfdux
|
|
||||||
// lhbrx
|
|
||||||
// srawx
|
|
||||||
// sradx
|
|
||||||
// srawix
|
|
||||||
// eieio
|
|
||||||
// ethbrx
|
|
||||||
// extshx
|
|
||||||
// extsbx
|
|
||||||
// lcbi
|
|
||||||
// stfiwx
|
|
||||||
// extsw
|
|
||||||
// dcbz
|
|
||||||
OECase(138):
|
|
||||||
// addex
|
|
||||||
break;
|
|
||||||
OECase(266):
|
|
||||||
// addx
|
|
||||||
break;
|
|
||||||
case 28:
|
|
||||||
// andx
|
|
||||||
break;
|
|
||||||
case 60:
|
|
||||||
// andcx
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#undef OECase
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Instruction();
|
#define Bind(mask, operation) case mask: return Instruction(Operation::operation, opcode);
|
||||||
|
#define BindConditional(condition, mask, operation) \
|
||||||
|
case mask: \
|
||||||
|
if(condition()) return Instruction(Operation::operation, opcode); \
|
||||||
|
return Instruction(opcode);
|
||||||
|
|
||||||
|
#define Six(x) (unsigned(x) << 26)
|
||||||
|
|
||||||
|
// First pass: weed out all those instructions identified entirely by the
|
||||||
|
// top six bits.
|
||||||
|
switch(opcode & Six(0b111111)) {
|
||||||
|
default: break;
|
||||||
|
|
||||||
|
BindConditional(is64bit, Six(0b000010), tdi);
|
||||||
|
|
||||||
|
Bind(Six(0b000011), twi);
|
||||||
|
Bind(Six(0b000111), mulli);
|
||||||
|
Bind(Six(0b001000), subfic);
|
||||||
|
Bind(Six(0b001100), addic); Bind(Six(0b001101), addic_);
|
||||||
|
Bind(Six(0b001110), addi); Bind(Six(0b001111), addis);
|
||||||
|
Bind(Six(0b010000), bcx);
|
||||||
|
Bind(Six(0b010010), bx);
|
||||||
|
Bind(Six(0b010100), rlwimix);
|
||||||
|
Bind(Six(0b010101), rlwinmx);
|
||||||
|
Bind(Six(0b010111), rlwnmx);
|
||||||
|
|
||||||
|
Bind(Six(0b011000), ori); Bind(Six(0b011001), oris);
|
||||||
|
Bind(Six(0b011010), xori); Bind(Six(0b011011), xoris);
|
||||||
|
Bind(Six(0b011100), andi_); Bind(Six(0b011101), andis_);
|
||||||
|
Bind(Six(0b100000), lwz); Bind(Six(0b100001), lwzu);
|
||||||
|
Bind(Six(0b100010), lbz); Bind(Six(0b100011), lbzu);
|
||||||
|
Bind(Six(0b100100), stw); Bind(Six(0b100101), stwu);
|
||||||
|
Bind(Six(0b100110), stb); Bind(Six(0b100111), stbu);
|
||||||
|
Bind(Six(0b101000), lhz); Bind(Six(0b101001), lhzu);
|
||||||
|
Bind(Six(0b101010), lha); Bind(Six(0b101011), lhau);
|
||||||
|
Bind(Six(0b101100), sth); Bind(Six(0b101101), sthu);
|
||||||
|
Bind(Six(0b101110), lmw); Bind(Six(0b101111), stmw);
|
||||||
|
Bind(Six(0b110000), lfs); Bind(Six(0b110001), lfsu);
|
||||||
|
Bind(Six(0b110010), lfd); Bind(Six(0b110011), lfdu);
|
||||||
|
Bind(Six(0b110100), stfs); Bind(Six(0b110101), stfsu);
|
||||||
|
Bind(Six(0b110110), stfd); Bind(Six(0b110111), stfdu);
|
||||||
|
|
||||||
|
// Assumed below here: reserved bits can be ignored.
|
||||||
|
// This might need to be a function of CPU model.
|
||||||
|
Bind(Six(0b001010), cmpli); Bind(Six(0b001011), cmpi);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef Six
|
||||||
|
|
||||||
|
#undef Bind
|
||||||
|
#undef BindConditional
|
||||||
|
|
||||||
|
return Instruction(opcode);
|
||||||
}
|
}
|
||||||
|
@ -55,16 +55,17 @@ enum class Operation: uint8_t {
|
|||||||
fresx, frsqrtex, fselx, fsqrtx, frsqrtsx, slbia, slbie,
|
fresx, frsqrtex, fselx, fsqrtx, frsqrtsx, slbia, slbie,
|
||||||
|
|
||||||
// 64-bit only PowerPC instructions.
|
// 64-bit only PowerPC instructions.
|
||||||
cntlzdx, divdx, divdux, extswx, fcfidx, fctidx, fctidzx
|
cntlzdx, divdx, divdux, extswx, fcfidx, fctidx, fctidzx, tdi
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Instruction {
|
struct Instruction {
|
||||||
Operation operation = Operation::Undefined;
|
const Operation operation = Operation::Undefined;
|
||||||
|
const uint32_t opcode = 0;
|
||||||
|
|
||||||
//
|
Instruction(uint32_t opcode) : opcode(opcode) {}
|
||||||
|
Instruction(Operation operation, uint32_t opcode) : operation(operation), opcode(opcode) {}
|
||||||
|
|
||||||
Instruction() {}
|
// TODO: all field decoding here.
|
||||||
Instruction(Operation operation) : operation(operation) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Decoder {
|
struct Decoder {
|
||||||
@ -75,6 +76,14 @@ struct Decoder {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Model model_;
|
Model model_;
|
||||||
|
|
||||||
|
bool is64bit() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is601() {
|
||||||
|
return model_ == Model::MPC601;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user