mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-17 10:06:21 +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,
|
||||
};
|
||||
|
||||
|
||||
/// @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 {
|
||||
Undefined,
|
||||
|
||||
@ -632,7 +640,30 @@ enum class Operation: uint8_t {
|
||||
/// rD()
|
||||
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.
|
||||
/// mtcrf
|
||||
@ -659,7 +690,25 @@ enum class Operation: uint8_t {
|
||||
/// crfD(), imm()
|
||||
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.
|
||||
/// mulhw mulgw.
|
||||
@ -895,7 +944,19 @@ enum class Operation: uint8_t {
|
||||
//
|
||||
// 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.
|
||||
@ -1155,6 +1216,12 @@ struct Instruction {
|
||||
uint32_t l() const { return opcode & 0x200000; }
|
||||
/// Enables setting of OV and SO in the XER; @c 0 or @c non-0.
|
||||
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.
|
||||
|
@ -315,6 +315,33 @@ NSString *offset(Instruction instruction) {
|
||||
XCTAssertEqualObjects(columns[3], conditionreg(instruction.crfD()));
|
||||
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:
|
||||
AssertEqualOperationName(operation, @"icbi");
|
||||
AssertEqualR(columns[3], instruction.rA(), false);
|
||||
@ -398,12 +425,24 @@ NSString *offset(Instruction instruction) {
|
||||
AssertEqualOperationName(operation, @#x); \
|
||||
break;
|
||||
|
||||
NoArg(isync);
|
||||
NoArg(sync);
|
||||
NoArg(eieio);
|
||||
NoArg(isync);
|
||||
NoArg(sync);
|
||||
NoArg(eieio);
|
||||
NoArg(tlbia);
|
||||
|
||||
#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) \
|
||||
case Operation::x: \
|
||||
AssertEqualOperationNameE(operation, @#x, instruction); \
|
||||
@ -412,9 +451,9 @@ NSString *offset(Instruction instruction) {
|
||||
AssertEqualR(columns[5], instruction.rB()); \
|
||||
break;
|
||||
|
||||
Shift(slwx);
|
||||
Shift(srwx);
|
||||
Shift(srawx);
|
||||
Shift(slwx);
|
||||
Shift(srwx);
|
||||
Shift(srawx);
|
||||
|
||||
#undef Shift
|
||||
|
||||
@ -500,21 +539,13 @@ NSString *offset(Instruction instruction) {
|
||||
ABCz(lwzux);
|
||||
ABCz(lbzx);
|
||||
ABCz(lbzux);
|
||||
ABCz(stwx);
|
||||
ABCz(stwux);
|
||||
ABCz(stbx);
|
||||
ABCz(stbux);
|
||||
ABCz(lhzx);
|
||||
ABCz(lhzux);
|
||||
ABCz(lhax);
|
||||
ABCz(lhaux);
|
||||
ABCz(sthx);
|
||||
ABCz(sthux);
|
||||
ABCz(lhbrx);
|
||||
ABCz(lwbrx);
|
||||
ABCz(lwarx);
|
||||
ABCz(stwbrx);
|
||||
ABCz(sthbrx);
|
||||
ABCz(eciwx);
|
||||
ABCz(lswx);
|
||||
ABCz(lwa);
|
||||
@ -582,7 +613,20 @@ NSString *offset(Instruction instruction) {
|
||||
AssertEqualR(columns[5], instruction.rB()); \
|
||||
break;
|
||||
|
||||
SAB(ecowx);
|
||||
SAB(stbux);
|
||||
SAB(stbx);
|
||||
SAB(sthbrx);
|
||||
SAB(sthux);
|
||||
SAB(sthx);
|
||||
SAB(stswx);
|
||||
SAB(stwbrx);
|
||||
SAB(stwcx_);
|
||||
SAB(stwux);
|
||||
SAB(stwx);
|
||||
SAB(stdcx_);
|
||||
SAB(stdux);
|
||||
SAB(stdx);
|
||||
|
||||
#undef SAB
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user