mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-21 05:29:13 +00:00
Complete shift tests.
This commit is contained in:
parent
8efd506471
commit
7c8f044380
@ -530,7 +530,22 @@ enum class Operation: uint8_t {
|
|||||||
/// rA(), rS(), rB() [rc()]
|
/// rA(), rS(), rB() [rc()]
|
||||||
slwx,
|
slwx,
|
||||||
|
|
||||||
srawx, srawix, srwx, stb, stbu,
|
/// Shift right algebraic word.
|
||||||
|
/// sraw sraw.
|
||||||
|
/// rA(), rS(), rB() [rc()]
|
||||||
|
srawx,
|
||||||
|
|
||||||
|
/// Shift right algebraic word immediate.
|
||||||
|
/// srawi srawi.
|
||||||
|
/// rA(), rS(), sh() [rc()]
|
||||||
|
srawix,
|
||||||
|
|
||||||
|
/// Shift right word.
|
||||||
|
/// srw srw.
|
||||||
|
/// rA(), rS(), rB() [rc()]
|
||||||
|
srwx,
|
||||||
|
|
||||||
|
stb, stbu,
|
||||||
|
|
||||||
/// Store byte with update indexed.
|
/// Store byte with update indexed.
|
||||||
///
|
///
|
||||||
|
@ -14,31 +14,63 @@
|
|||||||
|
|
||||||
using namespace InstructionSet::PowerPC;
|
using namespace InstructionSet::PowerPC;
|
||||||
|
|
||||||
|
@interface NSString (HexConversion)
|
||||||
|
|
||||||
|
- (long int)hexInt;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NSString (HexConversion)
|
||||||
|
|
||||||
|
- (long int)hexInt {
|
||||||
|
return strtol([self UTF8String], NULL, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@interface DingusdevPowerPCTests : XCTestCase
|
@interface DingusdevPowerPCTests : XCTestCase
|
||||||
@end
|
@end
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
/// Acts as XCTAssertEqualObjects but maps underscores to dots, as per this code's enum naming convention.
|
enum class NamingConvention {
|
||||||
void AssertEqualOperationName(NSString *lhs, NSString *rhs) {
|
None = 0,
|
||||||
NSString *const lhsMapped = [lhs stringByReplacingOccurrencesOfString:@"_" withString:@"."];
|
ApplyO = 1,
|
||||||
NSString *const rhsMapped = [rhs stringByReplacingOccurrencesOfString:@"_" withString:@"."];
|
ApplyE = 2,
|
||||||
XCTAssertEqualObjects(lhsMapped, rhsMapped);
|
ApplyOE = 3
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/// Converts any underscores in @c rhs to dots.
|
||||||
|
///
|
||||||
|
/// If convention != NamingConvention::None, trims the trailing 'x' from the @c rhs and
|
||||||
|
/// appends one or more of @c o and @c . depending on the @c oe() and @c rc() flags of @c instruction.
|
||||||
|
///
|
||||||
|
/// Then compares with the @c lhs.
|
||||||
|
void AssertEqualOperationName(NSString *lhs, NSString *rhs, Instruction instruction = Instruction(), NamingConvention convention = NamingConvention::None) {
|
||||||
|
rhs = [rhs stringByReplacingOccurrencesOfString:@"_" withString:@"."];
|
||||||
|
|
||||||
|
if(convention != NamingConvention::None) {
|
||||||
|
XCTAssert([rhs characterAtIndex:rhs.length - 1] == 'x');
|
||||||
|
rhs = [rhs substringToIndex:rhs.length - 1];
|
||||||
|
}
|
||||||
|
if(int(convention) & int(NamingConvention::ApplyO) && instruction.oe()) rhs = [rhs stringByAppendingString:@"o"];
|
||||||
|
if(int(convention) & int(NamingConvention::ApplyE) && instruction.rc()) rhs = [rhs stringByAppendingString:@"."];
|
||||||
|
|
||||||
/// Trims the trailing 'x' from the @c lhs and appends one or more of @c o and @c . depending on the @c oe() and @c rc() flags of @c instruction.
|
|
||||||
/// Then compares with the @c rhs.
|
|
||||||
void AssertEqualOperationNameOE(NSString *lhs, Instruction instruction, NSString *rhs) {
|
|
||||||
XCTAssert([lhs characterAtIndex:lhs.length - 1] == 'x');
|
|
||||||
lhs = [lhs substringToIndex:lhs.length - 1];
|
|
||||||
if(instruction.oe()) lhs = [lhs stringByAppendingString:@"o"];
|
|
||||||
if(instruction.rc()) lhs = [lhs stringByAppendingString:@"."];
|
|
||||||
XCTAssertEqualObjects(lhs, rhs);
|
XCTAssertEqualObjects(lhs, rhs);
|
||||||
}
|
}
|
||||||
|
void AssertEqualOperationNameO(NSString *lhs, NSString *rhs, Instruction instruction) {
|
||||||
|
AssertEqualOperationName(lhs, rhs, instruction, NamingConvention::ApplyO);
|
||||||
|
}
|
||||||
|
void AssertEqualOperationNameE(NSString *lhs, NSString *rhs, Instruction instruction) {
|
||||||
|
AssertEqualOperationName(lhs, rhs, instruction, NamingConvention::ApplyE);
|
||||||
|
}
|
||||||
|
void AssertEqualOperationNameOE(NSString *lhs, NSString *rhs, Instruction instruction) {
|
||||||
|
AssertEqualOperationName(lhs, rhs, instruction, NamingConvention::ApplyOE);
|
||||||
|
}
|
||||||
|
|
||||||
/// Forms the string @c r[reg] and compares it to @c name
|
/// Forms the string @c r[reg] and compares it to @c name
|
||||||
void AssertEqualR(NSString *name, uint32_t reg) {
|
void AssertEqualR(NSString *name, uint32_t reg, bool permitR0 = true) {
|
||||||
NSString *const regName = [NSString stringWithFormat:@"r%d", reg];
|
NSString *const regName = (reg || permitR0) ? [NSString stringWithFormat:@"r%d", reg] : @"0";
|
||||||
XCTAssertEqualObjects(name, regName);
|
XCTAssertEqualObjects(name, regName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,8 +130,8 @@ NSString *condition(uint32_t code) {
|
|||||||
NSArray<NSString *> *const columns = [line componentsSeparatedByString:@","];
|
NSArray<NSString *> *const columns = [line componentsSeparatedByString:@","];
|
||||||
|
|
||||||
// Columns are 1: address; 2: opcode; 3–: specific to the instruction.
|
// Columns are 1: address; 2: opcode; 3–: specific to the instruction.
|
||||||
const uint32_t address = uint32_t(std::strtol([columns[0] UTF8String], 0, 16));
|
const auto address = uint32_t([columns[0] hexInt]);
|
||||||
const uint32_t opcode = uint32_t(std::strtol([columns[1] UTF8String], 0, 16));
|
const auto opcode = uint32_t([columns[1] hexInt]);
|
||||||
NSString *const operation = columns[2];
|
NSString *const operation = columns[2];
|
||||||
const auto instruction = decoder.decode(opcode);
|
const auto instruction = decoder.decode(opcode);
|
||||||
|
|
||||||
@ -231,6 +263,27 @@ NSString *condition(uint32_t code) {
|
|||||||
NSAssert(FALSE, @"Didn't handle rlwinmx %@", line);
|
NSAssert(FALSE, @"Didn't handle rlwinmx %@", line);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
#define Shift(x) \
|
||||||
|
case Operation::x: \
|
||||||
|
AssertEqualOperationNameE(operation, @#x, instruction); \
|
||||||
|
AssertEqualR(columns[3], instruction.rA()); \
|
||||||
|
AssertEqualR(columns[4], instruction.rS()); \
|
||||||
|
AssertEqualR(columns[5], instruction.rB()); \
|
||||||
|
break;
|
||||||
|
|
||||||
|
Shift(slwx);
|
||||||
|
Shift(srwx);
|
||||||
|
Shift(srawx);
|
||||||
|
|
||||||
|
#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());
|
||||||
|
break;
|
||||||
|
|
||||||
#define CRMod(x) \
|
#define CRMod(x) \
|
||||||
case Operation::x: \
|
case Operation::x: \
|
||||||
AssertEqualOperationName(operation, @#x); \
|
AssertEqualOperationName(operation, @#x); \
|
||||||
@ -257,19 +310,17 @@ NSString *condition(uint32_t code) {
|
|||||||
AssertEqualR([columns lastObject], instruction.rS());
|
AssertEqualR([columns lastObject], instruction.rS());
|
||||||
|
|
||||||
if(columns.count > 4) {
|
if(columns.count > 4) {
|
||||||
const auto crm = strtol([columns[3] UTF8String], NULL, 16);
|
XCTAssertEqual([columns[3] hexInt], instruction.crm());
|
||||||
XCTAssertEqual(crm, instruction.crm());
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
||||||
#define ArithImm(x) \
|
#define ArithImm(x) \
|
||||||
case Operation::x: { \
|
case Operation::x: { \
|
||||||
const auto simm = strtol([columns[5] UTF8String], NULL, 16); \
|
|
||||||
AssertEqualOperationName(operation, @#x); \
|
AssertEqualOperationName(operation, @#x); \
|
||||||
AssertEqualR(columns[3], instruction.rD()); \
|
AssertEqualR(columns[3], instruction.rD()); \
|
||||||
AssertEqualR(columns[4], instruction.rA()); \
|
AssertEqualR(columns[4], instruction.rA()); \
|
||||||
XCTAssertEqual(simm, instruction.simm()); \
|
XCTAssertEqual([columns[5] hexInt], instruction.simm()); \
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
ArithImm(mulli);
|
ArithImm(mulli);
|
||||||
@ -306,7 +357,7 @@ NSString *condition(uint32_t code) {
|
|||||||
|
|
||||||
#define ABD(x) \
|
#define ABD(x) \
|
||||||
case Operation::x: \
|
case Operation::x: \
|
||||||
AssertEqualOperationNameOE(@#x, instruction, operation); \
|
AssertEqualOperationNameOE(operation, @#x, instruction); \
|
||||||
[self testABDInstruction:instruction columns:columns testZero:NO]; \
|
[self testABDInstruction:instruction columns:columns testZero:NO]; \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -405,8 +456,7 @@ NSString *condition(uint32_t code) {
|
|||||||
decoded_destination = instruction.bd() + address;
|
decoded_destination = instruction.bd() + address;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t destination = uint32_t(std::strtol([[columns lastObject] UTF8String], 0, 16));
|
XCTAssertEqual(decoded_destination, [[columns lastObject] hexInt]);
|
||||||
XCTAssertEqual(decoded_destination, destination);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
@ -431,16 +481,17 @@ NSString *condition(uint32_t code) {
|
|||||||
NSString *expectedCR;
|
NSString *expectedCR;
|
||||||
|
|
||||||
if(addConditionToOperand) {
|
if(addConditionToOperand) {
|
||||||
NSString *suffix;
|
expectedCR = condition(instruction.bi());
|
||||||
switch(Condition(instruction.bi() & 3)) {
|
// NSString *suffix;
|
||||||
default: break;
|
// switch(Condition(instruction.bi() & 3)) {
|
||||||
case Condition::Negative: suffix = @"lt"; break;
|
// default: break;
|
||||||
case Condition::Positive: suffix = @"gt"; break;
|
// case Condition::Negative: suffix = @"lt"; break;
|
||||||
case Condition::Zero: suffix = @"eq"; break;
|
// case Condition::Positive: suffix = @"gt"; break;
|
||||||
case Condition::SummaryOverflow: suffix = @"so"; break;
|
// case Condition::Zero: suffix = @"eq"; break;
|
||||||
}
|
// case Condition::SummaryOverflow: suffix = @"so"; break;
|
||||||
|
// }
|
||||||
expectedCR = [NSString stringWithFormat:@"4*cr%d+%@", instruction.bi() >> 2, suffix];
|
//
|
||||||
|
// expectedCR = [NSString stringWithFormat:@"4*cr%d+%@", instruction.bi() >> 2, suffix];
|
||||||
} else {
|
} else {
|
||||||
expectedCR = [NSString stringWithFormat:@"cr%d", instruction.bi() >> 2];
|
expectedCR = [NSString stringWithFormat:@"cr%d", instruction.bi() >> 2];
|
||||||
}
|
}
|
||||||
@ -456,10 +507,9 @@ NSString *condition(uint32_t code) {
|
|||||||
case 3: AssertEqualOperationName(operation, @"bla"); break;
|
case 3: AssertEqualOperationName(operation, @"bla"); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t destination = uint32_t(std::strtol([columns[3] UTF8String], 0, 16));
|
|
||||||
const uint32_t decoded_destination =
|
const uint32_t decoded_destination =
|
||||||
instruction.li() + (instruction.aa() ? 0 : address);
|
instruction.li() + (instruction.aa() ? 0 : address);
|
||||||
XCTAssertEqual(decoded_destination, destination);
|
XCTAssertEqual(decoded_destination, [columns[3] hexInt]);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user