mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-30 04:50:08 +00:00
Conquers another page of instructions; adds supervisor flag.
This commit is contained in:
parent
db50b0fe23
commit
ebfa35c2c7
@ -27,10 +27,15 @@ Instruction Decoder::decode(uint32_t opcode) {
|
||||
// I've decided to hew directly to the mnemonics.
|
||||
|
||||
#define Bind(mask, operation) case mask: return Instruction(Operation::operation, opcode);
|
||||
#define BindSupervisor(mask, operation) case mask: return Instruction(Operation::operation, opcode, true);
|
||||
#define BindConditional(condition, mask, operation) \
|
||||
case mask: \
|
||||
if(condition()) return Instruction(Operation::operation, opcode); \
|
||||
return Instruction(opcode);
|
||||
#define BindSupervisorConditional(condition, mask, operation) \
|
||||
case mask: \
|
||||
if(condition()) return Instruction(Operation::operation, opcode, true); \
|
||||
return Instruction(opcode);
|
||||
|
||||
#define Six(x) (unsigned(x) << 26)
|
||||
#define SixTen(x, y) (Six(x) | (y << 1))
|
||||
@ -81,6 +86,19 @@ Instruction Decoder::decode(uint32_t opcode) {
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0000001001), mulhdux);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0000010101), ldx);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0000011011), sldx);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0000110101), ldux);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0000111010), cntlzdx);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0001000100), td);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0001001001), mulhdx);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0001010100), ldarx);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0010010101), stdx);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0010110101), stdux);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0011101001), mulld); BindConditional(is64bit, SixTen(0b011111, 0b1011101001), mulld);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0101010101), lwax);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0101110101), lwaux);
|
||||
// BindConditional(is64bit, SixTen(0b011111, 0b1100111011), sradix); // TODO: encoding is unclear re: the sh flag.
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0110110010), slbie);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0111001001), divdux); BindConditional(is64bit, SixTen(0b011111, 0b1111001001), divdux);
|
||||
|
||||
Bind(SixTen(0b010011, 0b0000000000), mcrf);
|
||||
Bind(SixTen(0b010011, 0b0000010000), bclrx);
|
||||
@ -108,14 +126,67 @@ Instruction Decoder::decode(uint32_t opcode) {
|
||||
Bind(SixTen(0b011111, 0b0000011100), andx);
|
||||
Bind(SixTen(0b011111, 0b0000100000), cmpl);
|
||||
Bind(SixTen(0b011111, 0b0000101000), subfx); Bind(SixTen(0b011111, 0b1000101000), subfx);
|
||||
Bind(SixTen(0b011111, 0b0000110110), dcbst);
|
||||
Bind(SixTen(0b011111, 0b0000110111), lwzux);
|
||||
Bind(SixTen(0b011111, 0b0000111100), andcx);
|
||||
Bind(SixTen(0b011111, 0b0001001011), mulhwx);
|
||||
Bind(SixTen(0b011111, 0b0001010011), mfmsr);
|
||||
Bind(SixTen(0b011111, 0b0001010110), dcbf);
|
||||
Bind(SixTen(0b011111, 0b0001010111), lbzx);
|
||||
Bind(SixTen(0b011111, 0b0001101000), negx); Bind(SixTen(0b011111, 0b1001101000), negx);
|
||||
Bind(SixTen(0b011111, 0b0001110111), lbzux);
|
||||
Bind(SixTen(0b011111, 0b0001111100), norx);
|
||||
Bind(SixTen(0b011111, 0b0010001000), subfex); Bind(SixTen(0b011111, 0b1010001000), subfex);
|
||||
Bind(SixTen(0b011111, 0b0010001010), addex); Bind(SixTen(0b011111, 0b1010001010), addex);
|
||||
Bind(SixTen(0b011111, 0b0010010000), mtcrf);
|
||||
Bind(SixTen(0b011111, 0b0010010010), mtmsr);
|
||||
Bind(SixTen(0b011111, 0b0010010111), stwx);
|
||||
Bind(SixTen(0b011111, 0b0010110111), stwux);
|
||||
Bind(SixTen(0b011111, 0b0011001000), subfzex); Bind(SixTen(0b011111, 0b1011001000), subfzex);
|
||||
Bind(SixTen(0b011111, 0b0011001010), addzex); Bind(SixTen(0b011111, 0b1011001010), addzex);
|
||||
Bind(SixTen(0b011111, 0b0011010111), stbx);
|
||||
Bind(SixTen(0b011111, 0b0011101000), subfmex); Bind(SixTen(0b011111, 0b1011101000), subfmex);
|
||||
Bind(SixTen(0b011111, 0b0011101010), addmex); Bind(SixTen(0b011111, 0b1011101010), addmex);
|
||||
Bind(SixTen(0b011111, 0b0011101011), mullwx); Bind(SixTen(0b011111, 0b1011101011), mullwx);
|
||||
Bind(SixTen(0b011111, 0b0011110110), dcbtst);
|
||||
Bind(SixTen(0b011111, 0b0011110111), stbux);
|
||||
Bind(SixTen(0b011111, 0b0100001010), addx); Bind(SixTen(0b011111, 0b1100001010), addx);
|
||||
Bind(SixTen(0b011111, 0b0100010110), dcbt);
|
||||
Bind(SixTen(0b011111, 0b0100010111), lhzx);
|
||||
Bind(SixTen(0b011111, 0b0100011100), eqvx);
|
||||
Bind(SixTen(0b011111, 0b0100110110), eciwx);
|
||||
Bind(SixTen(0b011111, 0b0100110111), lhzux);
|
||||
Bind(SixTen(0b011111, 0b0100111100), xorx);
|
||||
Bind(SixTen(0b011111, 0b0101010111), lhax);
|
||||
Bind(SixTen(0b011111, 0b0101110011), mftb);
|
||||
Bind(SixTen(0b011111, 0b0101110111), lhaux);
|
||||
Bind(SixTen(0b011111, 0b0110010111), sthx);
|
||||
Bind(SixTen(0b011111, 0b0110011100), orcx);
|
||||
Bind(SixTen(0b011111, 0b0110110110), ecowx);
|
||||
Bind(SixTen(0b011111, 0b0110110111), sthux);
|
||||
Bind(SixTen(0b011111, 0b0110111100), orx);
|
||||
Bind(SixTen(0b011111, 0b0111001011), divwux); Bind(SixTen(0b011111, 0b1111001011), divwux);
|
||||
Bind(SixTen(0b011111, 0b0111010110), dcbi);
|
||||
|
||||
Bind(SixTen(0b011111, 0b0101010011), mfspr); // Flagged as "supervisor and user"?
|
||||
Bind(SixTen(0b011111, 0b0111010011), mtspr); // Flagged as "supervisor and user"?
|
||||
|
||||
BindSupervisorConditional(is32bit, SixTen(0b011111, 0b0011010010), mtsr);
|
||||
BindSupervisorConditional(is32bit, SixTen(0b011111, 0b0011110010), mtsrin);
|
||||
|
||||
BindSupervisor(SixTen(0b011111, 0b0100110010), tlbie); // TODO: mark formally as optional?
|
||||
BindSupervisor(SixTen(0b011111, 0b0101110010), tlbia); // TODO: mark formally as optional?
|
||||
}
|
||||
|
||||
// TODO: stwcx., stdcx.
|
||||
|
||||
// Check for sc.
|
||||
if((opcode & 0b010001'00000'00000'00000000000000'1'0) == 0b010001'00000'00000'00000000000000'1'0) {
|
||||
return Instruction(Operation::sc, opcode);
|
||||
}
|
||||
|
||||
#undef Six
|
||||
#undef SixTen
|
||||
|
||||
#undef Bind
|
||||
#undef BindConditional
|
||||
|
@ -46,17 +46,20 @@ enum class Operation: uint8_t {
|
||||
sc, slwx, srawx, srawix, srwx, stb, stbu, stbux, stbx, stfd, stfdu,
|
||||
stfdux, stfdx, stfs, stfsu, stfsux, stfsx, sth, sthbrx, sthu, sthux, sthx,
|
||||
stmw, stswi, stswx, stw, stwbrx, stwcx_, stwu, stwux, stwx, subfx, subfcx,
|
||||
subfex, subfic, subfmex, subfzex, sync, tlbie, tw, twi, xorx, xori, xoris,
|
||||
subfex, subfic, subfmex, subfzex, sync, tw, twi, xorx, xori, xoris, mftb,
|
||||
|
||||
// 32-bit, supervisor level.
|
||||
dcbi,
|
||||
|
||||
// Supervisor, optional.
|
||||
tlbia, tlbie,
|
||||
|
||||
// Optional.
|
||||
fresx, frsqrtex, fselx, fsqrtx, frsqrtsx, slbia, slbie,
|
||||
|
||||
// 64-bit only PowerPC instructions.
|
||||
cntlzdx, divdx, divdux, extswx, fcfidx, fctidx, fctidzx, tdi, mulhdux, ldx,
|
||||
sldx
|
||||
sldx, ldux, td, mulhdx, ldarx, stdx, stdux, mulld, lwax, lwaux, sradix,
|
||||
};
|
||||
|
||||
/*!
|
||||
@ -67,10 +70,11 @@ enum class Operation: uint8_t {
|
||||
*/
|
||||
struct Instruction {
|
||||
const Operation operation = Operation::Undefined;
|
||||
const bool is_supervisor = false;
|
||||
const uint32_t opcode = 0;
|
||||
|
||||
Instruction(uint32_t opcode) : opcode(opcode) {}
|
||||
Instruction(Operation operation, uint32_t opcode) : operation(operation), opcode(opcode) {}
|
||||
Instruction(Operation operation, uint32_t opcode, bool is_supervisor = false) : operation(operation), is_supervisor(is_supervisor), opcode(opcode) {}
|
||||
|
||||
// Instruction fields are decoded below; naming is as directly dictated by
|
||||
// Motorola's documentation, and the definitions below are sorted by synonym.
|
||||
@ -100,6 +104,7 @@ struct Instruction {
|
||||
int l() { return (opcode >> 21) & 0x01; }
|
||||
int aa() { return (opcode >> 1) & 0x01; }
|
||||
int lk() { return opcode & 0x01; }
|
||||
int rc() { return opcode & 0x01; }
|
||||
};
|
||||
|
||||
struct Decoder {
|
||||
@ -115,6 +120,10 @@ struct Decoder {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is32bit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is601() {
|
||||
return model_ == Model::MPC601;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user