mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-23 18:29:16 +00:00
Add documentation for bx, bcx, bcctrx.
Catch bcx tests.
This commit is contained in:
parent
f05d3e6af3
commit
e5af5b57ad
@ -25,7 +25,52 @@ enum class Operation: uint8_t {
|
|||||||
|
|
||||||
// 32- and 64-bit PowerPC instructions.
|
// 32- and 64-bit PowerPC instructions.
|
||||||
addx, addcx, addex, addi, addic, addic_, addis, addmex, addzex, andx,
|
addx, addcx, addex, addi, addic, addic_, addis, addmex, addzex, andx,
|
||||||
andcx, andi_, andis_, bx, bcx, bcctrx, bclrx, cmp, cmpi, cmpl, cmpli,
|
andcx, andi_, andis_,
|
||||||
|
|
||||||
|
/// Branch unconditional.
|
||||||
|
///
|
||||||
|
/// Use li() to get the included immediate value.
|
||||||
|
///
|
||||||
|
/// Use aa() to determine whether it's a relative (aa() = 0) or absolute (aa() != 0) address.
|
||||||
|
/// Also check lk() to determine whether to update the link register.
|
||||||
|
///
|
||||||
|
/// Synonyms include:
|
||||||
|
/// * b (relative, no link) [though assemblers might encode as a bcx];
|
||||||
|
/// * bl (relative, link);
|
||||||
|
/// * ba (absolute, no link);
|
||||||
|
/// * bla (absolute, link).
|
||||||
|
bx,
|
||||||
|
|
||||||
|
/// Branch conditional.
|
||||||
|
///
|
||||||
|
/// lk() determines whether to update the link register.
|
||||||
|
/// bd() supplies a relative displacment.
|
||||||
|
/// bi() specifies which CR bit to use as a condition.
|
||||||
|
/// bo() provides other branch options:
|
||||||
|
/// 0000y => decrement count register, branch if new value != 0 && !condition.
|
||||||
|
/// 0001y => decrement count register, branch if new value == 0 && !condition.
|
||||||
|
/// 001zy => branch if !condition
|
||||||
|
/// 0100y => decrement count register, branch if new value != 0 && condition.
|
||||||
|
/// 0101y => decrement count register, branch if new value == 0 && condition.
|
||||||
|
/// 011zy => branch if condition.
|
||||||
|
/// 1z00y => decrement count register, branch if new value != 0.
|
||||||
|
/// 1z01y => decrement count register, branch if new value == 0.
|
||||||
|
/// 1z1zz => branch always.
|
||||||
|
/// (z should be 0 to create a valid field; y can be any value)
|
||||||
|
///
|
||||||
|
/// Synonyms incude:
|
||||||
|
/// * b (relative, no link) [though assemblers might encode as a bx].
|
||||||
|
bcx,
|
||||||
|
|
||||||
|
/// Branch conditional to count register.
|
||||||
|
///
|
||||||
|
/// bi(), bo() and lk() are as per bcx.
|
||||||
|
///
|
||||||
|
/// On the MPC601, anything that decrements the count register will use the non-decremented
|
||||||
|
/// version as the branch target. Other processors will use the decremented version.
|
||||||
|
bcctrx,
|
||||||
|
|
||||||
|
bclrx, cmp, cmpi, cmpl, cmpli,
|
||||||
cntlzwx, crand, crandc, creqv, crnand, crnor, cror, crorc, crxor, dcbf,
|
cntlzwx, crand, crandc, creqv, crnand, crnor, cror, crorc, crxor, dcbf,
|
||||||
dcbst, dcbt, dcbtst, dcbz, divwx, divwux, eciwx, ecowx, eieio, eqvx,
|
dcbst, dcbt, dcbtst, dcbz, divwx, divwux, eciwx, ecowx, eieio, eqvx,
|
||||||
extsbx, extshx, fabsx, faddx, faddsx, fcmpo, fcmpu, fctiwx, fctiwzx,
|
extsbx, extshx, fabsx, faddx, faddsx, fcmpo, fcmpu, fctiwx, fctiwzx,
|
||||||
|
@ -53,12 +53,23 @@ namespace {
|
|||||||
|
|
||||||
switch(instruction.operation) {
|
switch(instruction.operation) {
|
||||||
default:
|
default:
|
||||||
// NSAssert(FALSE, @"Didn't handle %@", line);
|
NSAssert(FALSE, @"Didn't handle %@", line);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operation::bx: {
|
case Operation::bcx: {
|
||||||
const uint32_t destination = uint32_t(std::strtol([columns[3] UTF8String], 0, 16));
|
switch(instruction.bo()) {
|
||||||
|
case 0x14: case 0x15: XCTAssertEqualObjects(operation, @"b"); break;
|
||||||
|
default:
|
||||||
|
NSLog(@"No opcode tested for bcx with bo %02x", instruction.bo());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t destination = uint32_t(std::strtol([columns[3] UTF8String], 0, 16));
|
||||||
|
const uint32_t decoded_destination = instruction.bd() + address;
|
||||||
|
XCTAssertEqual(decoded_destination, destination);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case Operation::bx: {
|
||||||
switch((instruction.aa() ? 2 : 0) | (instruction.lk() ? 1 : 0)) {
|
switch((instruction.aa() ? 2 : 0) | (instruction.lk() ? 1 : 0)) {
|
||||||
case 0: XCTAssertEqualObjects(operation, @"b"); break;
|
case 0: XCTAssertEqualObjects(operation, @"b"); break;
|
||||||
case 1: XCTAssertEqualObjects(operation, @"bl"); break;
|
case 1: XCTAssertEqualObjects(operation, @"bl"); break;
|
||||||
@ -66,6 +77,7 @@ namespace {
|
|||||||
case 3: XCTAssertEqualObjects(operation, @"bla"); break;
|
case 3: XCTAssertEqualObjects(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, destination);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user