mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-18 01:07:58 +00:00
Match majority of branch tests.
This commit is contained in:
parent
7d4fe55d63
commit
1a5d3bb69c
@ -37,7 +37,7 @@ enum class Condition: uint32_t {
|
|||||||
// CRs2–7 fill out the condition register.
|
// CRs2–7 fill out the condition register.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BranchOptions: uint32_t {
|
enum class BranchOption: uint32_t {
|
||||||
// Naming convention:
|
// Naming convention:
|
||||||
//
|
//
|
||||||
// Dec_ prefix => decrement the CTR;
|
// Dec_ prefix => decrement the CTR;
|
||||||
@ -239,8 +239,8 @@ struct Instruction {
|
|||||||
/// Branch conditional options as per PowerPC spec, i.e. options + branch-prediction flag.
|
/// Branch conditional options as per PowerPC spec, i.e. options + branch-prediction flag.
|
||||||
uint32_t bo() const { return (opcode >> 21) & 0x1f; }
|
uint32_t bo() const { return (opcode >> 21) & 0x1f; }
|
||||||
/// Just the branch options, with the branch prediction flag severed.
|
/// Just the branch options, with the branch prediction flag severed.
|
||||||
BranchOptions branch_options() const {
|
BranchOption branch_options() const {
|
||||||
return BranchOptions((opcode >> 22) & 0xf);
|
return BranchOption((opcode >> 22) & 0xf);
|
||||||
}
|
}
|
||||||
/// Just the branch-prediction hint; @c 0 => expect untaken; @c non-0 => expect take.
|
/// Just the branch-prediction hint; @c 0 => expect untaken; @c non-0 => expect take.
|
||||||
uint32_t branch_prediction_hint() const {
|
uint32_t branch_prediction_hint() const {
|
||||||
|
@ -53,13 +53,18 @@ using namespace InstructionSet::PowerPC;
|
|||||||
NSAssert(FALSE, @"Didn't handle %@", line);
|
NSAssert(FALSE, @"Didn't handle %@", line);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Operation::bcx:
|
||||||
case Operation::bclrx:
|
case Operation::bclrx:
|
||||||
case Operation::bcctrx: {
|
case Operation::bcctrx: {
|
||||||
NSString *baseOperation = nil;
|
NSString *baseOperation = nil;
|
||||||
|
BOOL addConditionToOperand = NO;
|
||||||
|
|
||||||
switch(instruction.branch_options()) {
|
switch(instruction.branch_options()) {
|
||||||
case BranchOptions::Always: baseOperation = @"b"; break;
|
case BranchOption::Always: baseOperation = @"b"; break;
|
||||||
case BranchOptions::Clear:
|
case BranchOption::Dec_Zero: baseOperation = @"bdz"; break;
|
||||||
|
case BranchOption::Dec_NotZero: baseOperation = @"bdnz"; break;
|
||||||
|
|
||||||
|
case BranchOption::Clear:
|
||||||
switch(Condition(instruction.bi() & 3)) {
|
switch(Condition(instruction.bi() & 3)) {
|
||||||
default: break;
|
default: break;
|
||||||
case Condition::Negative: baseOperation = @"bge"; break;
|
case Condition::Negative: baseOperation = @"bge"; break;
|
||||||
@ -70,7 +75,16 @@ using namespace InstructionSet::PowerPC;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BranchOptions::Set:
|
case BranchOption::Dec_ZeroAndClear:
|
||||||
|
baseOperation = @"bdzf";
|
||||||
|
addConditionToOperand = YES;
|
||||||
|
break;
|
||||||
|
case BranchOption::Dec_NotZeroAndClear:
|
||||||
|
baseOperation = @"bdnzf";
|
||||||
|
addConditionToOperand = YES;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BranchOption::Set:
|
||||||
switch(Condition(instruction.bi() & 3)) {
|
switch(Condition(instruction.bi() & 3)) {
|
||||||
default: break;
|
default: break;
|
||||||
case Condition::Negative: baseOperation = @"blt"; break;
|
case Condition::Negative: baseOperation = @"blt"; break;
|
||||||
@ -81,13 +95,39 @@ using namespace InstructionSet::PowerPC;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case BranchOption::Dec_ZeroAndSet:
|
||||||
|
baseOperation = @"bdzt";
|
||||||
|
addConditionToOperand = YES;
|
||||||
|
break;
|
||||||
|
case BranchOption::Dec_NotZeroAndSet:
|
||||||
|
baseOperation = @"bdnzt";
|
||||||
|
addConditionToOperand = YES;
|
||||||
|
break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(instruction.operation == Operation::bcctrx) {
|
switch(instruction.operation) {
|
||||||
baseOperation = [baseOperation stringByAppendingString:@"ctr"];
|
case Operation::bcctrx:
|
||||||
} else {
|
baseOperation = [baseOperation stringByAppendingString:@"ctr"];
|
||||||
baseOperation = [baseOperation stringByAppendingString:@"lr"];
|
break;
|
||||||
|
case Operation::bclrx:
|
||||||
|
baseOperation = [baseOperation stringByAppendingString:@"lr"];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Operation::bcx: {
|
||||||
|
// if(instruction.aa()) {
|
||||||
|
// baseOperation = [baseOperation stringByAppendingString:@"a"];
|
||||||
|
// } else {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
const uint32_t destination = uint32_t(std::strtol([[columns lastObject] UTF8String], 0, 16));
|
||||||
|
const uint32_t decoded_destination = instruction.bd() + address;
|
||||||
|
XCTAssertEqual(decoded_destination, destination);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!baseOperation) {
|
if(!baseOperation) {
|
||||||
@ -103,25 +143,65 @@ using namespace InstructionSet::PowerPC;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(instruction.bi() & ~3) {
|
if(instruction.bi() & ~3) {
|
||||||
NSString *const expectedCR = [NSString stringWithFormat:@"cr%d", instruction.bi() >> 2];
|
NSString *expectedCR;
|
||||||
|
|
||||||
|
if(addConditionToOperand) {
|
||||||
|
NSString *suffix;
|
||||||
|
switch(Condition(instruction.bi() & 3)) {
|
||||||
|
default: break;
|
||||||
|
case Condition::Negative: suffix = @"lt"; break;
|
||||||
|
case Condition::Positive: suffix = @"gt"; break;
|
||||||
|
case Condition::Zero: suffix = @"eq"; break;
|
||||||
|
case Condition::SummaryOverflow: suffix = @"so"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedCR = [NSString stringWithFormat:@"4*cr%d+%@", instruction.bi() >> 2, suffix];
|
||||||
|
} else {
|
||||||
|
expectedCR = [NSString stringWithFormat:@"cr%d", instruction.bi() >> 2];
|
||||||
|
}
|
||||||
XCTAssertEqualObjects(columns[3], expectedCR);
|
XCTAssertEqualObjects(columns[3], expectedCR);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Operation::bcx: {
|
/* case Operation::bcx: {
|
||||||
|
NSString *expectedOperation;
|
||||||
switch(instruction.branch_options()) {
|
switch(instruction.branch_options()) {
|
||||||
case BranchOptions::Always:
|
case BranchOption::Always: expectedOperation = @"b"; break;
|
||||||
XCTAssertEqualObjects(operation, @"b");
|
case BranchOption::Set:
|
||||||
|
switch(Condition(instruction.bi() & 3)) {
|
||||||
|
default: break;
|
||||||
|
case Condition::Negative: expectedOperation = @"blt"; break;
|
||||||
|
case Condition::Positive: expectedOperation = @"bgt"; break;
|
||||||
|
case Condition::Zero: expectedOperation = @"beq"; break;
|
||||||
|
case Condition::SummaryOverflow: expectedOperation = @"bso"; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BranchOption::Clear:
|
||||||
|
switch(Condition(instruction.bi() & 3)) {
|
||||||
|
default: break;
|
||||||
|
case Condition::Negative: expectedOperation = @"bge"; break;
|
||||||
|
case Condition::Positive: expectedOperation = @"ble"; break;
|
||||||
|
case Condition::Zero: expectedOperation = @"bne"; break;
|
||||||
|
case Condition::SummaryOverflow: expectedOperation = @"bns"; break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
NSLog(@"No opcode tested for bcx with bo %02x", instruction.bo());
|
NSLog(@"No opcode tested for bcx with bo %02x [%@]", instruction.bo(), line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(instruction.lk()) {
|
||||||
|
expectedOperation = [expectedOperation stringByAppendingString:@"l"];
|
||||||
|
}
|
||||||
|
if(instruction.branch_prediction_hint()) {
|
||||||
|
expectedOperation = [expectedOperation stringByAppendingString:@"+"];
|
||||||
|
}
|
||||||
|
XCTAssertEqualObjects(operation, expectedOperation);
|
||||||
|
|
||||||
const uint32_t destination = uint32_t(std::strtol([columns[3] UTF8String], 0, 16));
|
const uint32_t destination = uint32_t(std::strtol([columns[3] UTF8String], 0, 16));
|
||||||
const uint32_t decoded_destination = instruction.bd() + address;
|
const uint32_t decoded_destination = instruction.bd() + address;
|
||||||
XCTAssertEqual(decoded_destination, destination);
|
XCTAssertEqual(decoded_destination, destination);
|
||||||
} break;
|
} break;*/
|
||||||
|
|
||||||
case Operation::bx: {
|
case Operation::bx: {
|
||||||
switch((instruction.aa() ? 2 : 0) | (instruction.lk() ? 1 : 0)) {
|
switch((instruction.aa() ? 2 : 0) | (instruction.lk() ? 1 : 0)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user