mirror of
https://github.com/TomHarte/CLK.git
synced 2025-12-22 04:18:01 +00:00
Take a swing at three-operand IMUL.
This commit is contained in:
@@ -132,6 +132,7 @@ void imul(
|
|||||||
modify_t<IntT> destination_high,
|
modify_t<IntT> destination_high,
|
||||||
modify_t<IntT> destination_low,
|
modify_t<IntT> destination_low,
|
||||||
read_t<IntT> source,
|
read_t<IntT> source,
|
||||||
|
read_t<IntT> multiplicand,
|
||||||
ContextT &context
|
ContextT &context
|
||||||
) {
|
) {
|
||||||
/*
|
/*
|
||||||
@@ -160,8 +161,8 @@ void imul(
|
|||||||
FI;
|
FI;
|
||||||
*/
|
*/
|
||||||
using sIntT = typename std::make_signed<IntT>::type;
|
using sIntT = typename std::make_signed<IntT>::type;
|
||||||
destination_high = IntT((sIntT(destination_low) * sIntT(source)) >> (8 * sizeof(IntT)));
|
destination_high = IntT((sIntT(multiplicand) * sIntT(source)) >> (8 * sizeof(IntT)));
|
||||||
destination_low = IntT(sIntT(destination_low) * sIntT(source));
|
destination_low = IntT(sIntT(multiplicand) * sIntT(source));
|
||||||
|
|
||||||
const auto sign_extension = (destination_low & Numeric::top_bit<IntT>()) ? IntT(~0) : 0;
|
const auto sign_extension = (destination_low & Numeric::top_bit<IntT>()) ? IntT(~0) : 0;
|
||||||
context.flags.template set_from<Flag::Overflow, Flag::Carry>(destination_high != sign_extension);
|
context.flags.template set_from<Flag::Overflow, Flag::Carry>(destination_high != sign_extension);
|
||||||
|
|||||||
@@ -241,7 +241,12 @@ template <
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case Operation::MUL: Primitive::mul<IntT>(pair_high(), pair_low(), source_r(), context); return;
|
case Operation::MUL: Primitive::mul<IntT>(pair_high(), pair_low(), source_r(), context); return;
|
||||||
case Operation::IMUL_1: Primitive::imul<IntT>(pair_high(), pair_low(), source_r(), context); return;
|
case Operation::IMUL_1:
|
||||||
|
Primitive::imul<IntT>(pair_high(), pair_low(), source_r(), pair_low(), context);
|
||||||
|
return;
|
||||||
|
case Operation::IMUL_3:
|
||||||
|
Primitive::imul<IntT>(pair_high(), pair_low(), source_r(), IntT(instruction.operand()), context);
|
||||||
|
return;
|
||||||
case Operation::DIV: Primitive::div<IntT>(pair_high(), pair_low(), source_r(), context); return;
|
case Operation::DIV: Primitive::div<IntT>(pair_high(), pair_low(), source_r(), context); return;
|
||||||
case Operation::IDIV: Primitive::idiv<false, IntT>(pair_high(), pair_low(), source_r(), context); return;
|
case Operation::IDIV: Primitive::idiv<false, IntT>(pair_high(), pair_low(), source_r(), context); return;
|
||||||
case Operation::IDIV_REP:
|
case Operation::IDIV_REP:
|
||||||
@@ -570,7 +575,6 @@ template <
|
|||||||
// LSL
|
// LSL
|
||||||
// LTR
|
// LTR
|
||||||
// STR
|
// STR
|
||||||
// IMUL_3
|
|
||||||
// LOADALL
|
// LOADALL
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,7 +651,8 @@ void perform(
|
|||||||
|
|
||||||
// This is reachable only if the data and address size combination in use isn't available
|
// This is reachable only if the data and address size combination in use isn't available
|
||||||
// on the processor model nominated.
|
// on the processor model nominated.
|
||||||
assert(false);}
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Public function; just indirects into a trampoline into a version of perform templated on data and address size.
|
// Public function; just indirects into a trampoline into a version of perform templated on data and address size.
|
||||||
|
|||||||
@@ -258,6 +258,7 @@ NSArray<NSString *> *test_files(const char *const home) {
|
|||||||
// @"D4.json.gz", // AAM
|
// @"D4.json.gz", // AAM
|
||||||
// @"F6.7.json.gz", // IDIV byte
|
// @"F6.7.json.gz", // IDIV byte
|
||||||
// @"F7.7.json.gz", // IDIV word
|
// @"F7.7.json.gz", // IDIV word
|
||||||
|
@"C8.json.gz", // ENTER
|
||||||
]];
|
]];
|
||||||
|
|
||||||
NSSet *ignoreList = nil;
|
NSSet *ignoreList = nil;
|
||||||
|
|||||||
Reference in New Issue
Block a user