mirror of
https://github.com/TomHarte/CLK.git
synced 2024-09-29 16:55:59 +00:00
Complete 'misc instructions' tests.
This commit is contained in:
parent
c581aef11d
commit
31276de5c3
@ -56,6 +56,14 @@ enum class BranchOption: uint32_t {
|
|||||||
Always = 0b1010,
|
Always = 0b1010,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// @returns @c 0 if reg == 0; @c ~0 otherwise.
|
||||||
|
/// @discussion Provides a branchless way to substitute the value 0 for the value of r0
|
||||||
|
/// in affected instructions.
|
||||||
|
template <typename IntT> constexpr IntT is_zero_mask(uint32_t reg) {
|
||||||
|
return ~IntT((reg - 1) >> 5);
|
||||||
|
}
|
||||||
|
|
||||||
enum class Operation: uint8_t {
|
enum class Operation: uint8_t {
|
||||||
Undefined,
|
Undefined,
|
||||||
|
|
||||||
@ -632,7 +640,30 @@ enum class Operation: uint8_t {
|
|||||||
/// rD()
|
/// rD()
|
||||||
mfcr,
|
mfcr,
|
||||||
|
|
||||||
mffsx, mfmsr, mfspr, mfsr, mfsrin,
|
/// Move from FPSCR.
|
||||||
|
/// mffs mffs.
|
||||||
|
/// frD() [rc()]
|
||||||
|
mffsx,
|
||||||
|
|
||||||
|
/// Move from machine state register.
|
||||||
|
/// mfmsr
|
||||||
|
/// rD()
|
||||||
|
mfmsr,
|
||||||
|
|
||||||
|
/// Move from special purpose record.
|
||||||
|
/// mfmsr
|
||||||
|
/// rD(), spr()
|
||||||
|
mfspr,
|
||||||
|
|
||||||
|
/// Move from segment register.
|
||||||
|
/// mfsr
|
||||||
|
/// rD(), sr()
|
||||||
|
mfsr,
|
||||||
|
|
||||||
|
/// Move from segment register indirect.
|
||||||
|
/// mfsrin
|
||||||
|
/// rD(), rB()
|
||||||
|
mfsrin,
|
||||||
|
|
||||||
/// Move to condition register fields.
|
/// Move to condition register fields.
|
||||||
/// mtcrf
|
/// mtcrf
|
||||||
@ -659,7 +690,25 @@ enum class Operation: uint8_t {
|
|||||||
/// crfD(), imm()
|
/// crfD(), imm()
|
||||||
mtfsfix,
|
mtfsfix,
|
||||||
|
|
||||||
mtmsr, mtspr, mtsr, mtsrin,
|
/// Move to FPSCR.
|
||||||
|
/// mtfs
|
||||||
|
/// frS()
|
||||||
|
mtmsr,
|
||||||
|
|
||||||
|
/// Move to special purpose record.
|
||||||
|
/// mtmsr
|
||||||
|
/// rD(), spr()
|
||||||
|
mtspr,
|
||||||
|
|
||||||
|
/// Move to segment register.
|
||||||
|
/// mfsr
|
||||||
|
/// sr(), rS()
|
||||||
|
mtsr,
|
||||||
|
|
||||||
|
/// Move to segment register indirect.
|
||||||
|
/// mtsrin
|
||||||
|
/// rD(), rB()
|
||||||
|
mtsrin,
|
||||||
|
|
||||||
/// Multiply high word.
|
/// Multiply high word.
|
||||||
/// mulhw mulgw.
|
/// mulhw mulgw.
|
||||||
@ -895,7 +944,19 @@ enum class Operation: uint8_t {
|
|||||||
//
|
//
|
||||||
// MARK: - Supervisor, optional.
|
// MARK: - Supervisor, optional.
|
||||||
//
|
//
|
||||||
tlbia, tlbie, tlbsync,
|
|
||||||
|
/// Translation lookaside buffer invalidate all.
|
||||||
|
/// tlbia
|
||||||
|
tlbia,
|
||||||
|
|
||||||
|
/// Translation lookaside buffer invalidate entry.
|
||||||
|
/// tlbie
|
||||||
|
/// rB()
|
||||||
|
tlbie,
|
||||||
|
|
||||||
|
/// Translation lookaside buffer synchronise.
|
||||||
|
/// tlbsync
|
||||||
|
tlbsync,
|
||||||
|
|
||||||
//
|
//
|
||||||
// MARK: - Optional.
|
// MARK: - Optional.
|
||||||
@ -1155,6 +1216,12 @@ struct Instruction {
|
|||||||
uint32_t l() const { return opcode & 0x200000; }
|
uint32_t l() const { return opcode & 0x200000; }
|
||||||
/// Enables setting of OV and SO in the XER; @c 0 or @c non-0.
|
/// Enables setting of OV and SO in the XER; @c 0 or @c non-0.
|
||||||
uint32_t oe() const { return opcode & 0x400; }
|
uint32_t oe() const { return opcode & 0x400; }
|
||||||
|
|
||||||
|
|
||||||
|
/// Identifies a special purpose register.
|
||||||
|
uint32_t spr() const { return (opcode >> 11) & 0x3ff; }
|
||||||
|
/// Identifies a time base register.
|
||||||
|
uint32_t tbr() const { return (opcode >> 11) & 0x3ff; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sanity check on Instruction size.
|
// Sanity check on Instruction size.
|
||||||
|
@ -315,6 +315,33 @@ NSString *offset(Instruction instruction) {
|
|||||||
XCTAssertEqualObjects(columns[3], conditionreg(instruction.crfD()));
|
XCTAssertEqualObjects(columns[3], conditionreg(instruction.crfD()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Operation::mffsx:
|
||||||
|
AssertEqualOperationNameE(operation, @"mffsx", instruction);
|
||||||
|
AssertEqualFR(columns[3], instruction.frD());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Operation::mtmsr:
|
||||||
|
AssertEqualOperationName(operation, @"mtmsr");
|
||||||
|
AssertEqualR(columns[3], instruction.rS());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Operation::mtsrin:
|
||||||
|
AssertEqualOperationName(operation, @"mtsrin");
|
||||||
|
AssertEqualR(columns[3], instruction.rD());
|
||||||
|
AssertEqualR(columns[4], instruction.rB());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Operation::mtsr:
|
||||||
|
AssertEqualOperationName(operation, @"mtsr");
|
||||||
|
XCTAssertEqual([columns[3] intValue], instruction.sr());
|
||||||
|
AssertEqualR(columns[4], instruction.rS());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Operation::tlbie:
|
||||||
|
AssertEqualOperationName(operation, @"tlbie");
|
||||||
|
AssertEqualR(columns[3], instruction.rB());
|
||||||
|
break;
|
||||||
|
|
||||||
case Operation::icbi:
|
case Operation::icbi:
|
||||||
AssertEqualOperationName(operation, @"icbi");
|
AssertEqualOperationName(operation, @"icbi");
|
||||||
AssertEqualR(columns[3], instruction.rA(), false);
|
AssertEqualR(columns[3], instruction.rA(), false);
|
||||||
@ -398,12 +425,24 @@ NSString *offset(Instruction instruction) {
|
|||||||
AssertEqualOperationName(operation, @#x); \
|
AssertEqualOperationName(operation, @#x); \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
NoArg(isync);
|
NoArg(isync);
|
||||||
NoArg(sync);
|
NoArg(sync);
|
||||||
NoArg(eieio);
|
NoArg(eieio);
|
||||||
|
NoArg(tlbia);
|
||||||
|
|
||||||
#undef NoArg
|
#undef NoArg
|
||||||
|
|
||||||
|
#define D(x) \
|
||||||
|
case Operation::x: \
|
||||||
|
AssertEqualOperationName(operation, @#x); \
|
||||||
|
AssertEqualR(columns[3], instruction.rD()); \
|
||||||
|
break;
|
||||||
|
|
||||||
|
D(mfcr);
|
||||||
|
D(mfmsr);
|
||||||
|
|
||||||
|
#undef D
|
||||||
|
|
||||||
#define Shift(x) \
|
#define Shift(x) \
|
||||||
case Operation::x: \
|
case Operation::x: \
|
||||||
AssertEqualOperationNameE(operation, @#x, instruction); \
|
AssertEqualOperationNameE(operation, @#x, instruction); \
|
||||||
@ -412,9 +451,9 @@ NSString *offset(Instruction instruction) {
|
|||||||
AssertEqualR(columns[5], instruction.rB()); \
|
AssertEqualR(columns[5], instruction.rB()); \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Shift(slwx);
|
Shift(slwx);
|
||||||
Shift(srwx);
|
Shift(srwx);
|
||||||
Shift(srawx);
|
Shift(srawx);
|
||||||
|
|
||||||
#undef Shift
|
#undef Shift
|
||||||
|
|
||||||
@ -500,21 +539,13 @@ NSString *offset(Instruction instruction) {
|
|||||||
ABCz(lwzux);
|
ABCz(lwzux);
|
||||||
ABCz(lbzx);
|
ABCz(lbzx);
|
||||||
ABCz(lbzux);
|
ABCz(lbzux);
|
||||||
ABCz(stwx);
|
|
||||||
ABCz(stwux);
|
|
||||||
ABCz(stbx);
|
|
||||||
ABCz(stbux);
|
|
||||||
ABCz(lhzx);
|
ABCz(lhzx);
|
||||||
ABCz(lhzux);
|
ABCz(lhzux);
|
||||||
ABCz(lhax);
|
ABCz(lhax);
|
||||||
ABCz(lhaux);
|
ABCz(lhaux);
|
||||||
ABCz(sthx);
|
|
||||||
ABCz(sthux);
|
|
||||||
ABCz(lhbrx);
|
ABCz(lhbrx);
|
||||||
ABCz(lwbrx);
|
ABCz(lwbrx);
|
||||||
ABCz(lwarx);
|
ABCz(lwarx);
|
||||||
ABCz(stwbrx);
|
|
||||||
ABCz(sthbrx);
|
|
||||||
ABCz(eciwx);
|
ABCz(eciwx);
|
||||||
ABCz(lswx);
|
ABCz(lswx);
|
||||||
ABCz(lwa);
|
ABCz(lwa);
|
||||||
@ -582,7 +613,20 @@ NSString *offset(Instruction instruction) {
|
|||||||
AssertEqualR(columns[5], instruction.rB()); \
|
AssertEqualR(columns[5], instruction.rB()); \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
SAB(ecowx);
|
||||||
|
SAB(stbux);
|
||||||
|
SAB(stbx);
|
||||||
|
SAB(sthbrx);
|
||||||
|
SAB(sthux);
|
||||||
|
SAB(sthx);
|
||||||
|
SAB(stswx);
|
||||||
|
SAB(stwbrx);
|
||||||
SAB(stwcx_);
|
SAB(stwcx_);
|
||||||
|
SAB(stwux);
|
||||||
|
SAB(stwx);
|
||||||
|
SAB(stdcx_);
|
||||||
|
SAB(stdux);
|
||||||
|
SAB(stdx);
|
||||||
|
|
||||||
#undef SAB
|
#undef SAB
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user