mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-25 16:31:42 +00:00
Completes test cases.
This commit is contained in:
parent
4ab1857a11
commit
1f44ad1723
@ -20,6 +20,203 @@ template <Model model, bool validate_reserved_bits, Operation operation> Instruc
|
||||
|
||||
// Otherwise, validation depends on operation
|
||||
// (and, in principle, processor model).
|
||||
switch(operation) {
|
||||
case Operation::addmex: case Operation::addzex:
|
||||
case Operation::bcctrx: case Operation::bclrx:
|
||||
case Operation::cntlzdx: case Operation::cntlzwx:
|
||||
case Operation::extsbx: case Operation::extshx: case Operation::extswx:
|
||||
case Operation::fmulx: case Operation::fmulsx:
|
||||
case Operation::negx:
|
||||
case Operation::subfmex: case Operation::subfzex:
|
||||
if(opcode & 0b000000'00000'00000'11111'0000000000'0) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::cmp: case Operation::cmpl:
|
||||
if(opcode & 0b000000'00010'00000'00000'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::cmpi: case Operation::cmpli:
|
||||
if(opcode & 0b000000'00010'00000'00000'0000000000'0) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::dcbf: case Operation::dcbi: case Operation::dcbst:
|
||||
case Operation::dcbt: case Operation::dcbtst: case Operation::dcbz:
|
||||
if(opcode & 0b000000'11111'00000'00000'0000000000'0) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::crand: case Operation::crandc: case Operation::creqv:
|
||||
case Operation::crnand: case Operation::crnor: case Operation::cror:
|
||||
case Operation::crorc: case Operation::crxor:
|
||||
case Operation::eciwx: case Operation::ecowx:
|
||||
case Operation::lbzux: case Operation::lbzx:
|
||||
case Operation::ldarx:
|
||||
case Operation::ldux: case Operation::ldx:
|
||||
case Operation::lfdux: case Operation::lfdx:
|
||||
case Operation::lfsux: case Operation::lfsx:
|
||||
case Operation::lhaux: case Operation::lhax: case Operation::lhbrx:
|
||||
case Operation::lhzux: case Operation::lhzx:
|
||||
case Operation::lswi: case Operation::lswx:
|
||||
case Operation::lwarx: case Operation::lwaux: case Operation::lwax: case Operation::lwbrx:
|
||||
case Operation::lwzux: case Operation::lwzx:
|
||||
case Operation::mfspr: case Operation::mftb:
|
||||
case Operation::mtspr:
|
||||
case Operation::stbux: case Operation::stbx:
|
||||
case Operation::stdux: case Operation::stdx:
|
||||
case Operation::stfdux: case Operation::stfdx:
|
||||
case Operation::stfiwx:
|
||||
case Operation::stfsux: case Operation::stfsx:
|
||||
case Operation::sthbrx:
|
||||
case Operation::sthux: case Operation::sthx:
|
||||
case Operation::stswi: case Operation::stswx:
|
||||
case Operation::stwbrx:
|
||||
case Operation::stwux: case Operation::stwx:
|
||||
case Operation::td: case Operation::tw:
|
||||
if(opcode & 0b000000'00000'00000'00000'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::fabsx: case Operation::fcfidx:
|
||||
case Operation::fctidx: case Operation::fctidzx:
|
||||
case Operation::fctiwx: case Operation::fctiwzx:
|
||||
case Operation::fmrx: case Operation::fnabsx:
|
||||
case Operation::fnegx: case Operation::frspx:
|
||||
if(opcode & 0b000000'00000'11111'00000'0000000000'0) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::faddx: case Operation::faddsx:
|
||||
case Operation::fdivx: case Operation::fdivsx:
|
||||
case Operation::fsubx: case Operation::fsubsx:
|
||||
if(opcode & 0b000000'00000'00000'00000'1111100000'0) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::fcmpo: case Operation::fcmpu:
|
||||
if(opcode & 0b000000'00011'00000'00000'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::fresx: case Operation::frsqrtex:
|
||||
case Operation::fsqrtx: case Operation::fsqrtsx:
|
||||
if(opcode & 0b000000'00000'11111'00000'1111100000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::icbi:
|
||||
if(opcode & 0b000000'11111'00000'00000'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::eieio:
|
||||
case Operation::isync:
|
||||
case Operation::rfi:
|
||||
case Operation::slbia:
|
||||
case Operation::sync:
|
||||
case Operation::tlbia:
|
||||
case Operation::tlbsync:
|
||||
if(opcode & 0b000000'11111'11111'11111'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::mcrf: case Operation::mcrfs:
|
||||
if(opcode & 0b000000'00011'00011'11111'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::mcrxr:
|
||||
if(opcode & 0b000000'00011'11111'11111'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::mfcr:
|
||||
case Operation::mfmsr:
|
||||
case Operation::mtmsr:
|
||||
if(opcode & 0b000000'00000'11111'11111'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::mffsx:
|
||||
case Operation::mtfsb0x:
|
||||
case Operation::mtfsb1x:
|
||||
if(opcode & 0b000000'00000'11111'11111'0000000000'0) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::mtfsfx:
|
||||
if(opcode & 0b000000'10000'00001'00000'0000000000'0) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::mtfsfix:
|
||||
if(opcode & 0b000000'00011'11111'00001'0000000000'0) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::mtsr:
|
||||
if(opcode & 0b000000'00000'10000'11111'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::mtsrin:
|
||||
if(opcode & 0b000000'00000'11111'00000'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::mulhdx: case Operation::mulhdux:
|
||||
case Operation::mulhwx: case Operation::mulhwux:
|
||||
if(opcode & 0b000000'00000'00000'00000'1000000000'0) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::sc:
|
||||
if(opcode & 0b000000'11111'11111'11111'1111111110'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::slbie:
|
||||
case Operation::tlbie:
|
||||
if(opcode & 0b000000'11111'11111'00000'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::stwcx_:
|
||||
if(!(opcode & 0b000000'00000'00000'00000'0000000000'1)) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::clcs:
|
||||
if(opcode & 0b000000'00000'00000'11111'0000000000'1) return Instruction(opcode);
|
||||
break;
|
||||
|
||||
case Operation::addx: case Operation::addcx: case Operation::addex:
|
||||
case Operation::addi: case Operation::addic: case Operation::addic_:
|
||||
case Operation::addis:
|
||||
case Operation::andx: case Operation::andcx:
|
||||
case Operation::andi_: case Operation::andis_:
|
||||
case Operation::bx: case Operation::bcx:
|
||||
case Operation::divdx: case Operation::divdux:
|
||||
case Operation::divwx: case Operation::divwux:
|
||||
case Operation::eqvx:
|
||||
case Operation::fmaddx: case Operation::fmaddsx:
|
||||
case Operation::fmsubx: case Operation::fmsubsx:
|
||||
case Operation::fnmaddx: case Operation::fnmaddsx:
|
||||
case Operation::fnmsubx: case Operation::fnmsubsx:
|
||||
case Operation::fselx:
|
||||
case Operation::lbz: case Operation::lbzu:
|
||||
case Operation::lfd: case Operation::lfdu:
|
||||
case Operation::lfs: case Operation::lfsu:
|
||||
case Operation::lha: case Operation::lhau:
|
||||
case Operation::lhz: case Operation::lhzu:
|
||||
case Operation::lmw: case Operation::lwa:
|
||||
case Operation::lwz: case Operation::lwzu:
|
||||
case Operation::mulld: case Operation::mulli: case Operation::mullwx:
|
||||
case Operation::nandx: case Operation::norx:
|
||||
case Operation::orx: case Operation::orcx:
|
||||
case Operation::ori: case Operation::oris:
|
||||
case Operation::rlwimix: case Operation::rlwinmx: case Operation::rlwnmx:
|
||||
case Operation::sldx: case Operation::slwx:
|
||||
case Operation::sradx: case Operation::sradix:
|
||||
case Operation::srawx: case Operation::srawix:
|
||||
case Operation::srdx: case Operation::srwx:
|
||||
case Operation::stb: case Operation::stbu:
|
||||
case Operation::std: case Operation::stdcx_: case Operation::stdu:
|
||||
case Operation::stfd: case Operation::stfdu:
|
||||
case Operation::stfs: case Operation::stfsu:
|
||||
case Operation::sth: case Operation::sthu:
|
||||
case Operation::stmw:
|
||||
case Operation::stw: case Operation::stwu:
|
||||
case Operation::subfx: case Operation::subfcx: case Operation::subfex:
|
||||
case Operation::subfic:
|
||||
case Operation::tdi: case Operation::twi:
|
||||
case Operation::xorx: case Operation::xori: case Operation::xoris:
|
||||
|
||||
// TODO: ld ldu
|
||||
// TODO: rldclx rldcrx rldicx rldicrx rldimix
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return Instruction(operation, opcode, is_supervisor);
|
||||
}
|
||||
|
||||
@ -338,7 +535,7 @@ Instruction Decoder<model, validate_reserved_bits>::decode(uint32_t opcode) {
|
||||
return Instruction(opcode);
|
||||
}
|
||||
|
||||
// std and stdu
|
||||
// std and stdu [TODO: or ld and ldu?]
|
||||
switch(opcode & 0b111111'00'00000000'00000000'000000'11) {
|
||||
case 0b111110'00'00000000'00000000'000000'00: return instruction<model, validate_reserved_bits, Operation::std>(opcode);
|
||||
case 0b111110'00'00000000'00000000'000000'01:
|
||||
|
@ -192,7 +192,7 @@ enum class Operation: uint8_t {
|
||||
|
||||
/// Shift right extended with MQ.
|
||||
/// sreq sreq.
|
||||
/// rA(), rB(), rB() [rc()]
|
||||
/// rA(), rS(), rB() [rc()]
|
||||
sreqx,
|
||||
|
||||
/// Shift right immediate with MQ.
|
||||
|
@ -138,7 +138,7 @@ NSString *offset(Instruction instruction) {
|
||||
NSString *const wholeFile = [[NSString alloc] initWithData:testData encoding:NSUTF8StringEncoding];
|
||||
NSArray<NSString *> *const lines = [wholeFile componentsSeparatedByString:@"\n"];
|
||||
|
||||
InstructionSet::PowerPC::Decoder<InstructionSet::PowerPC::Model::MPC601> decoder;
|
||||
InstructionSet::PowerPC::Decoder<InstructionSet::PowerPC::Model::MPC601, true> decoder;
|
||||
for(NSString *const line in lines) {
|
||||
// Ignore empty lines and comments.
|
||||
if([line length] == 0) {
|
||||
@ -156,8 +156,6 @@ NSString *offset(Instruction instruction) {
|
||||
NSString *const operation = columns[2];
|
||||
const auto instruction = decoder.decode(opcode);
|
||||
|
||||
NSLog(@"%@", line);
|
||||
|
||||
// Deal with some of the simplified mnemonics as special cases;
|
||||
// underlying observation: distinguishing special cases isn't that
|
||||
// important to a mere decoder.
|
||||
@ -193,6 +191,10 @@ NSString *offset(Instruction instruction) {
|
||||
NSAssert(FALSE, @"Didn't handle %@", line);
|
||||
break;
|
||||
|
||||
case Operation::Undefined:
|
||||
XCTAssertEqualObjects(operation, @"dc.l");
|
||||
break;
|
||||
|
||||
case Operation::rlwimix: {
|
||||
// This maps the opposite way from most of the other tests
|
||||
// owing to the simplified names being a shade harder to
|
||||
@ -362,6 +364,12 @@ NSString *offset(Instruction instruction) {
|
||||
AssertEqualR(columns[4], instruction.rB());
|
||||
break;
|
||||
|
||||
case Operation::clcs:
|
||||
AssertEqualOperationName(operation, @"clcs");
|
||||
AssertEqualR(columns[3], instruction.rD());
|
||||
AssertEqualR(columns[4], instruction.rA());
|
||||
break;
|
||||
|
||||
case Operation::mtsr:
|
||||
AssertEqualOperationName(operation, @"mtsr");
|
||||
XCTAssertEqual([columns[3] intValue], instruction.sr());
|
||||
@ -393,6 +401,15 @@ NSString *offset(Instruction instruction) {
|
||||
XCTAssertEqual([columns[5] hexInt], instruction.nb());
|
||||
break;
|
||||
|
||||
case Operation::rlmix:
|
||||
AssertEqualOperationNameE(operation, @"rlmix", instruction);
|
||||
AssertEqualR(columns[3], instruction.rA());
|
||||
AssertEqualR(columns[4], instruction.rS());
|
||||
AssertEqualR(columns[5], instruction.rB());
|
||||
XCTAssertEqual([columns[6] intValue], instruction.mb());
|
||||
XCTAssertEqual([columns[7] intValue], instruction.me());
|
||||
break;
|
||||
|
||||
case Operation::cmp:
|
||||
if([operation isEqualToString:@"cmpw"]) {
|
||||
XCTAssertFalse(instruction.l());
|
||||
@ -488,13 +505,24 @@ NSString *offset(Instruction instruction) {
|
||||
|
||||
#undef Shift
|
||||
|
||||
case Operation::srawix:
|
||||
AssertEqualOperationNameE(operation, @"srawix", instruction);
|
||||
AssertEqualR(columns[3], instruction.rA());
|
||||
AssertEqualR(columns[4], instruction.rS());
|
||||
XCTAssertEqual([columns[5] hexInt], instruction.sh());
|
||||
|
||||
#define ASsh(x) \
|
||||
case Operation::x: \
|
||||
AssertEqualOperationNameE(operation, @#x, instruction); \
|
||||
AssertEqualR(columns[3], instruction.rA()); \
|
||||
AssertEqualR(columns[4], instruction.rS()); \
|
||||
XCTAssertEqual([columns[5] hexInt], instruction.sh()); \
|
||||
break;
|
||||
|
||||
ASsh(sliqx);
|
||||
ASsh(slliqx);
|
||||
ASsh(sraiqx);
|
||||
ASsh(sriqx);
|
||||
ASsh(srliqx);
|
||||
ASsh(srawix);
|
||||
|
||||
#undef ASsh
|
||||
|
||||
#define CRMod(x) \
|
||||
case Operation::x: \
|
||||
AssertEqualOperationName(operation, @#x); \
|
||||
@ -534,12 +562,13 @@ NSString *offset(Instruction instruction) {
|
||||
XCTAssertEqual([columns[5] hexInt], instruction.simm()); \
|
||||
} break;
|
||||
|
||||
ArithImm(mulli);
|
||||
ArithImm(subfic);
|
||||
ArithImm(dozi);
|
||||
ArithImm(addi);
|
||||
ArithImm(addic);
|
||||
ArithImm(addic_);
|
||||
ArithImm(addis);
|
||||
ArithImm(mulli);
|
||||
ArithImm(subfic);
|
||||
|
||||
#undef ArithImm
|
||||
|
||||
@ -625,6 +654,20 @@ NSString *offset(Instruction instruction) {
|
||||
AssertEqualR(columns[5], instruction.rB()); \
|
||||
break;
|
||||
|
||||
ASB(maskgx);
|
||||
ASB(maskirx);
|
||||
ASB(rribx);
|
||||
ASB(slex);
|
||||
ASB(sleqx);
|
||||
ASB(sllqx);
|
||||
ASB(slqx);
|
||||
ASB(sraqx);
|
||||
ASB(srex);
|
||||
ASB(sreax);
|
||||
ASB(sreqx);
|
||||
ASB(srlqx);
|
||||
ASB(srqx);
|
||||
|
||||
ASB(andx);
|
||||
ASB(andcx);
|
||||
ASB(norx);
|
||||
|
Loading…
Reference in New Issue
Block a user