mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-09 00:37:27 +00:00
Gets started on 6+10 decoding, places stake as to other fields.
This commit is contained in:
parent
233a69a1d8
commit
db50b0fe23
@ -32,7 +32,8 @@ Instruction Decoder::decode(uint32_t opcode) {
|
||||
if(condition()) return Instruction(Operation::operation, opcode); \
|
||||
return Instruction(opcode);
|
||||
|
||||
#define Six(x) (unsigned(x) << 26)
|
||||
#define Six(x) (unsigned(x) << 26)
|
||||
#define SixTen(x, y) (Six(x) | (y << 1))
|
||||
|
||||
// First pass: weed out all those instructions identified entirely by the
|
||||
// top six bits.
|
||||
@ -73,6 +74,47 @@ Instruction Decoder::decode(uint32_t opcode) {
|
||||
Bind(Six(0b001010), cmpli); Bind(Six(0b001011), cmpi);
|
||||
}
|
||||
|
||||
// Second pass: all those with a top six bits and a bottom nine or ten.
|
||||
switch(opcode & SixTen(0b111111, 0b1111111111)) {
|
||||
default: break;
|
||||
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0000001001), mulhdux);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0000010101), ldx);
|
||||
BindConditional(is64bit, SixTen(0b011111, 0b0000011011), sldx);
|
||||
|
||||
Bind(SixTen(0b010011, 0b0000000000), mcrf);
|
||||
Bind(SixTen(0b010011, 0b0000010000), bclrx);
|
||||
Bind(SixTen(0b010011, 0b0000100001), crnor);
|
||||
Bind(SixTen(0b010011, 0b0000110010), rfi);
|
||||
Bind(SixTen(0b010011, 0b0010000001), crandc);
|
||||
Bind(SixTen(0b010011, 0b0010010110), isync);
|
||||
Bind(SixTen(0b010011, 0b0011000001), crxor);
|
||||
Bind(SixTen(0b010011, 0b0011100001), crnand);
|
||||
Bind(SixTen(0b010011, 0b0100000001), crand);
|
||||
Bind(SixTen(0b010011, 0b0100100001), creqv);
|
||||
Bind(SixTen(0b010011, 0b0110100001), crorc);
|
||||
Bind(SixTen(0b010011, 0b0111000001), cror);
|
||||
Bind(SixTen(0b010011, 0b1000010000), bcctrx);
|
||||
Bind(SixTen(0b011111, 0b0000000000), cmp);
|
||||
Bind(SixTen(0b011111, 0b0000000100), tw);
|
||||
Bind(SixTen(0b011111, 0b0000001000), subfcx); Bind(SixTen(0b011111, 0b1000001000), subfcx);
|
||||
Bind(SixTen(0b011111, 0b0000001010), addcx); Bind(SixTen(0b011111, 0b1000001010), addcx);
|
||||
Bind(SixTen(0b011111, 0b0000001011), mulhwux);
|
||||
Bind(SixTen(0b011111, 0b0000010011), mfcr);
|
||||
Bind(SixTen(0b011111, 0b0000010100), lwarx);
|
||||
Bind(SixTen(0b011111, 0b0000010111), lwzx);
|
||||
Bind(SixTen(0b011111, 0b0000011000), slwx);
|
||||
Bind(SixTen(0b011111, 0b0000011010), cntlzwx);
|
||||
Bind(SixTen(0b011111, 0b0000011100), andx);
|
||||
Bind(SixTen(0b011111, 0b0000100000), cmpl);
|
||||
Bind(SixTen(0b011111, 0b0000101000), subfx); Bind(SixTen(0b011111, 0b1000101000), subfx);
|
||||
}
|
||||
|
||||
// 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 Bind
|
||||
|
@ -55,9 +55,16 @@ enum class Operation: uint8_t {
|
||||
fresx, frsqrtex, fselx, fsqrtx, frsqrtsx, slbia, slbie,
|
||||
|
||||
// 64-bit only PowerPC instructions.
|
||||
cntlzdx, divdx, divdux, extswx, fcfidx, fctidx, fctidzx, tdi
|
||||
cntlzdx, divdx, divdux, extswx, fcfidx, fctidx, fctidzx, tdi, mulhdux, ldx,
|
||||
sldx
|
||||
};
|
||||
|
||||
/*!
|
||||
Holds a decoded PowerPC instruction.
|
||||
|
||||
Implementation note: because the PowerPC encoding is particularly straightforward,
|
||||
only the operation has been decoded ahead of time; all other fields are decoded on-demand.
|
||||
*/
|
||||
struct Instruction {
|
||||
const Operation operation = Operation::Undefined;
|
||||
const uint32_t opcode = 0;
|
||||
@ -65,7 +72,34 @@ struct Instruction {
|
||||
Instruction(uint32_t opcode) : opcode(opcode) {}
|
||||
Instruction(Operation operation, uint32_t opcode) : operation(operation), opcode(opcode) {}
|
||||
|
||||
// TODO: all field decoding here.
|
||||
// Instruction fields are decoded below; naming is as directly dictated by
|
||||
// Motorola's documentation, and the definitions below are sorted by synonym.
|
||||
uint16_t uimm() { return uint16_t(opcode & 0xffff); }
|
||||
int16_t simm() { return int16_t(opcode & 0xffff); }
|
||||
|
||||
int to() { return (opcode >> 21) & 0x1f; }
|
||||
int d() { return (opcode >> 21) & 0x1f; }
|
||||
int bo() { return (opcode >> 21) & 0x1f; }
|
||||
int crbD() { return (opcode >> 21) & 0x1f; }
|
||||
int s() { return (opcode >> 21) & 0x1f; }
|
||||
|
||||
int a() { return (opcode >> 16) & 0x1f; }
|
||||
int bi() { return (opcode >> 16) & 0x1f; }
|
||||
int crbA() { return (opcode >> 16) & 0x1f; }
|
||||
|
||||
int b() { return (opcode >> 11) & 0x1f; }
|
||||
int crbB() { return (opcode >> 11) & 0x1f; }
|
||||
|
||||
int crfd() { return (opcode >> 23) & 0x07; }
|
||||
|
||||
int bd() { return (opcode >> 2) & 0x3fff; }
|
||||
|
||||
int li() { return (opcode >> 2) & 0x0fff; }
|
||||
|
||||
// Various single bit fields.
|
||||
int l() { return (opcode >> 21) & 0x01; }
|
||||
int aa() { return (opcode >> 1) & 0x01; }
|
||||
int lk() { return opcode & 0x01; }
|
||||
};
|
||||
|
||||
struct Decoder {
|
||||
|
Loading…
x
Reference in New Issue
Block a user