mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-23 03:32:32 +00:00
Resolves assumption that shifts greater than the bit count of the relevant int are well-defined in C.
This commit is contained in:
parent
3ec9a1d869
commit
c447655047
@ -1644,6 +1644,98 @@ class CPU::MC68000::ProcessorStorageTests {
|
||||
XCTAssertEqual(16, _machine->get_cycle_count());
|
||||
}
|
||||
|
||||
// MARK: LSL
|
||||
|
||||
- (void)testLSLb_Dn_2 {
|
||||
_machine->set_program({
|
||||
0xe529 // LSL.b D2, D1
|
||||
});
|
||||
auto state = _machine->get_processor_state();
|
||||
state.data[1] = 0xce3dd567;
|
||||
state.data[2] = 2;
|
||||
|
||||
_machine->set_processor_state(state);
|
||||
_machine->run_for_instructions(1);
|
||||
|
||||
state = _machine->get_processor_state();
|
||||
XCTAssertEqual(state.data[1], 0xce3dd59c);
|
||||
XCTAssertEqual(state.data[2], 2);
|
||||
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Negative | Flag::Carry);
|
||||
XCTAssertEqual(10, _machine->get_cycle_count());
|
||||
}
|
||||
|
||||
- (void)testLSLb_Dn_69 {
|
||||
_machine->set_program({
|
||||
0xe529 // LSL.b D2, D1
|
||||
});
|
||||
auto state = _machine->get_processor_state();
|
||||
state.data[1] = 0xce3dd567;
|
||||
state.data[2] = 0x69;
|
||||
|
||||
_machine->set_processor_state(state);
|
||||
_machine->run_for_instructions(1);
|
||||
|
||||
state = _machine->get_processor_state();
|
||||
XCTAssertEqual(state.data[1], 0xce3dd500);
|
||||
XCTAssertEqual(state.data[2], 0x69);
|
||||
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Zero);
|
||||
XCTAssertEqual(88, _machine->get_cycle_count());
|
||||
}
|
||||
|
||||
- (void)testLSLw_Dn_0 {
|
||||
_machine->set_program({
|
||||
0xe569 // LSL.w D2, D1
|
||||
});
|
||||
auto state = _machine->get_processor_state();
|
||||
state.data[1] = 0xce3dd567;
|
||||
state.data[2] = 0;
|
||||
|
||||
_machine->set_processor_state(state);
|
||||
_machine->run_for_instructions(1);
|
||||
|
||||
state = _machine->get_processor_state();
|
||||
XCTAssertEqual(state.data[1], 0xce3dd567);
|
||||
XCTAssertEqual(state.data[2], 0);
|
||||
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative);
|
||||
XCTAssertEqual(6, _machine->get_cycle_count());
|
||||
}
|
||||
|
||||
- (void)testLSLw_Dn_b {
|
||||
_machine->set_program({
|
||||
0xe569 // LSL.w D2, D1
|
||||
});
|
||||
auto state = _machine->get_processor_state();
|
||||
state.data[1] = 0xce3dd567;
|
||||
state.data[2] = 0xb;
|
||||
|
||||
_machine->set_processor_state(state);
|
||||
_machine->run_for_instructions(1);
|
||||
|
||||
state = _machine->get_processor_state();
|
||||
XCTAssertEqual(state.data[1], 0xce3d3800);
|
||||
XCTAssertEqual(state.data[2], 0xb);
|
||||
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry);
|
||||
XCTAssertEqual(28, _machine->get_cycle_count());
|
||||
}
|
||||
|
||||
- (void)testLSLl_Dn {
|
||||
_machine->set_program({
|
||||
0xe5a9 // LSL.l D2, D1
|
||||
});
|
||||
auto state = _machine->get_processor_state();
|
||||
state.data[1] = 0xce3dd567;
|
||||
state.data[2] = 0x20;
|
||||
|
||||
_machine->set_processor_state(state);
|
||||
_machine->run_for_instructions(1);
|
||||
|
||||
state = _machine->get_processor_state();
|
||||
XCTAssertEqual(state.data[1], 0);
|
||||
XCTAssertEqual(state.data[2], 0x20);
|
||||
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Zero);
|
||||
XCTAssertEqual(72, _machine->get_cycle_count());
|
||||
}
|
||||
|
||||
// MARK: MOVEM
|
||||
|
||||
- (void)testMOVEM {
|
||||
|
@ -1557,7 +1557,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
||||
if(!shift_count) { \
|
||||
carry_flag_ = 0; \
|
||||
} else { \
|
||||
destination = decltype(destination)(value << shift_count); \
|
||||
destination = (shift_count < size) ? decltype(destination)(value << shift_count) : 0; \
|
||||
extend_flag_ = carry_flag_ = decltype(carry_flag_)(value) & decltype(carry_flag_)( (1 << (size - 1)) >> (shift_count - 1) ); \
|
||||
} \
|
||||
\
|
||||
@ -1583,10 +1583,14 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
||||
if(!shift_count) { \
|
||||
carry_flag_ = 0; \
|
||||
} else { \
|
||||
destination = decltype(destination)(\
|
||||
(value >> shift_count) | \
|
||||
((value & decltype(value)(1 << (size - 1)) ? 0xffffffff : 0x000000000) << (size - shift_count)) \
|
||||
); \
|
||||
destination = (shift_count < size) ? \
|
||||
decltype(destination)(\
|
||||
(value >> shift_count) | \
|
||||
((value & decltype(value)(1 << (size - 1)) ? 0xffffffff : 0x000000000) << (size - shift_count)) \
|
||||
) : \
|
||||
decltype(destination)( \
|
||||
(value & decltype(value)(1 << (size - 1))) ? 0xffffffff : 0x000000000 \
|
||||
); \
|
||||
extend_flag_ = carry_flag_ = decltype(carry_flag_)(value) & decltype(carry_flag_)(1 << (shift_count - 1)); \
|
||||
} \
|
||||
\
|
||||
@ -1634,7 +1638,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
||||
if(!shift_count) { \
|
||||
carry_flag_ = 0; \
|
||||
} else { \
|
||||
destination = value >> shift_count; \
|
||||
destination = (shift_count < size) ? (value >> shift_count) : 0; \
|
||||
extend_flag_ = carry_flag_ = value & decltype(carry_flag_)(1 << (shift_count - 1)); \
|
||||
} \
|
||||
\
|
||||
|
Loading…
Reference in New Issue
Block a user