1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-04 18:29:40 +00:00

Completes test cases.

This commit is contained in:
Thomas Harte 2022-04-06 21:09:58 -04:00
parent 4ab1857a11
commit 1f44ad1723
3 changed files with 252 additions and 12 deletions

View File

@ -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:

View File

@ -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.

View File

@ -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);