mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-15 14:27:29 +00:00
Make an attempt at DIVS timing.
This commit is contained in:
@@ -2522,13 +2522,13 @@ void ProcessorBase::did_bit_op(int bit_position) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <bool did_overflow> void ProcessorBase::did_divu(uint32_t dividend, uint32_t divisor) {
|
template <bool did_overflow> void ProcessorBase::did_divu(uint32_t dividend, uint32_t divisor) {
|
||||||
if(did_overflow) {
|
if(!divisor) {
|
||||||
dynamic_instruction_length_ = 3; // Just a quick nn n, and then on to prefetch.
|
dynamic_instruction_length_ = 4; // nn nn precedes the usual exception activity.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!divisor) {
|
if(did_overflow) {
|
||||||
dynamic_instruction_length_ = 4; // nn nn precedes the usual exception activity.
|
dynamic_instruction_length_ = 3; // Just a quick nn n, and then on to prefetch.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2561,16 +2561,55 @@ template <bool did_overflow> void ProcessorBase::did_divu(uint32_t dividend, uin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool did_overflow> void ProcessorBase::did_divs(int32_t, int32_t) {
|
|
||||||
// TODO: calculate cost.
|
|
||||||
}
|
|
||||||
|
|
||||||
#define convert_to_bit_count_16(x) \
|
#define convert_to_bit_count_16(x) \
|
||||||
x = ((x & 0xaaaa) >> 1) + (x & 0x5555); \
|
x = ((x & 0xaaaa) >> 1) + (x & 0x5555); \
|
||||||
x = ((x & 0xcccc) >> 2) + (x & 0x3333); \
|
x = ((x & 0xcccc) >> 2) + (x & 0x3333); \
|
||||||
x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f); \
|
x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f); \
|
||||||
x = ((x & 0xff00) >> 8) + (x & 0x00ff);
|
x = ((x & 0xff00) >> 8) + (x & 0x00ff);
|
||||||
|
|
||||||
|
template <bool did_overflow> void ProcessorBase::did_divs(int32_t dividend, int32_t divisor) {
|
||||||
|
// The route to spotting divide by 0 is just nn nn.
|
||||||
|
if(!divisor) {
|
||||||
|
dynamic_instruction_length_ = 4; // nn nn precedes the usual exception activity.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It's either five or six microcycles to get into the main loop, depending
|
||||||
|
// on dividend sign.
|
||||||
|
dynamic_instruction_length_ = 5 + (dividend < 0);
|
||||||
|
|
||||||
|
if(did_overflow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There's always a cost of four microcycles per bit, plus an additional
|
||||||
|
// one for each that is non-zero.
|
||||||
|
//
|
||||||
|
// The sign bit does not count here; it's the low fifteen bits that matter
|
||||||
|
// only, in the unsigned version of the result.
|
||||||
|
dynamic_instruction_length_ += 60;
|
||||||
|
|
||||||
|
int result_bits = abs(dividend / divisor) & 0x7fff;
|
||||||
|
convert_to_bit_count_16(result_bits);
|
||||||
|
dynamic_instruction_length_ += result_bits;
|
||||||
|
|
||||||
|
// Determine the tail cost; a divisor of less than 0 leads to one exit,
|
||||||
|
// a divisor of greater than zero makes the result a function of the
|
||||||
|
// sign of the dividend.
|
||||||
|
//
|
||||||
|
// In all cases, this is counting from 'No more bits' in the Yacht diagram.
|
||||||
|
if(divisor < 0) {
|
||||||
|
dynamic_instruction_length_ += 4;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dividend < 0) {
|
||||||
|
dynamic_instruction_length_ += 5;
|
||||||
|
} else {
|
||||||
|
dynamic_instruction_length_ += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename IntT> void ProcessorBase::did_mulu(IntT multiplier) {
|
template <typename IntT> void ProcessorBase::did_mulu(IntT multiplier) {
|
||||||
// Count number of bits set.
|
// Count number of bits set.
|
||||||
convert_to_bit_count_16(multiplier);
|
convert_to_bit_count_16(multiplier);
|
||||||
|
Reference in New Issue
Block a user