mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Start fleshing out x86 performance.
This commit is contained in:
parent
524e4ae65c
commit
059f300500
110
InstructionSets/x86/Implementation/PerformImplementation.hpp
Normal file
110
InstructionSets/x86/Implementation/PerformImplementation.hpp
Normal file
@ -0,0 +1,110 @@
|
||||
//
|
||||
// PerformImplementation.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 05/10/2023.
|
||||
// Copyright © 2023 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef PerformImplementation_h
|
||||
#define PerformImplementation_h
|
||||
|
||||
namespace InstructionSet::x86 {
|
||||
|
||||
namespace Primitive {
|
||||
|
||||
void aaa(CPU::RegisterPair16 &ax, Status &status) {
|
||||
/*
|
||||
IF ((AL AND 0FH) > 9) OR (AF = 1)
|
||||
THEN
|
||||
AL ← (AL + 6);
|
||||
AH ← AH + 1;
|
||||
AF ← 1;
|
||||
CF ← 1;
|
||||
ELSE
|
||||
AF ← 0;
|
||||
CF ← 0;
|
||||
FI;
|
||||
AL ← AL AND 0FH;
|
||||
*/
|
||||
/*
|
||||
The AF and CF flags are set to 1 if the adjustment results in a decimal carry;
|
||||
otherwise they are cleared to 0. The OF, SF, ZF, and PF flags are undefined.
|
||||
*/
|
||||
if((ax.halves.low & 0x0f) > 9 || status.auxiliary_carry) {
|
||||
ax.halves.low += 6;
|
||||
++ax.halves.high;
|
||||
status.auxiliary_carry = status.carry = 1;
|
||||
} else {
|
||||
status.auxiliary_carry = status.carry = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void aad(CPU::RegisterPair16 &ax, uint8_t imm, Status &status) {
|
||||
/*
|
||||
tempAL ← AL;
|
||||
tempAH ← AH;
|
||||
AL ← (tempAL + (tempAH * imm8)) AND FFH; (* imm8 is set to 0AH for the AAD mnemonic *)
|
||||
AH ← 0
|
||||
*/
|
||||
/*
|
||||
The SF, ZF, and PF flags are set according to the result;
|
||||
the OF, AF, and CF flags are undefined.
|
||||
*/
|
||||
ax.halves.low = ax.halves.low + (ax.halves.high * imm);
|
||||
ax.halves.high = 0;
|
||||
status.sign = ax.halves.low & 0x80;
|
||||
status.parity = status.zero = ax.halves.low;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <
|
||||
Model model,
|
||||
Operation operation,
|
||||
DataSize data_size,
|
||||
typename FlowControllerT
|
||||
> void perform(
|
||||
CPU::RegisterPair16 &destination,
|
||||
CPU::RegisterPair16 &source,
|
||||
Status &status,
|
||||
FlowControllerT &flow_controller
|
||||
) {
|
||||
switch(operation) {
|
||||
case Operation::AAA: Primitive::aaa(destination, status); break;
|
||||
case Operation::AAD: Primitive::aad(destination, source.halves.low, status); break;
|
||||
}
|
||||
|
||||
(void)flow_controller;
|
||||
}
|
||||
|
||||
|
||||
/*template <
|
||||
Model model,
|
||||
typename InstructionT,
|
||||
typename FlowControllerT,
|
||||
typename DataPointerResolverT,
|
||||
typename RegistersT,
|
||||
typename MemoryT,
|
||||
typename IOT,
|
||||
Operation operation
|
||||
> void perform(
|
||||
const InstructionT &instruction,
|
||||
Status &status,
|
||||
FlowControllerT &flow_controller,
|
||||
DataPointerResolverT &resolver,
|
||||
RegistersT ®isters,
|
||||
MemoryT &memory,
|
||||
IOT &io
|
||||
) {
|
||||
switch((operation != Operation::Invalid) ? operation : instruction.operation) {
|
||||
default:
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* PerformImplementation_h */
|
@ -10,6 +10,9 @@
|
||||
#define Perform_h
|
||||
|
||||
#include "Instruction.hpp"
|
||||
#include "Model.hpp"
|
||||
#include "Status.hpp"
|
||||
#include "../../Numeric/RegisterSizes.hpp"
|
||||
|
||||
namespace InstructionSet::x86 {
|
||||
|
||||
@ -22,14 +25,15 @@ namespace InstructionSet::x86 {
|
||||
/// whatever is specifed in @c instruction.
|
||||
template <
|
||||
Model model,
|
||||
typename InstructionT,
|
||||
typename FlowControllerT,
|
||||
typename DataPointerResolverT,
|
||||
typename RegistersT,
|
||||
typename MemoryT,
|
||||
typename IOT,
|
||||
Operation operation = Operation::Undefined
|
||||
Operation operation = Operation::Invalid
|
||||
> void perform(
|
||||
const Instruction &instruction,
|
||||
const InstructionT &instruction,
|
||||
Status &status,
|
||||
FlowControllerT &flow_controller,
|
||||
DataPointerResolverT &resolver,
|
||||
@ -38,6 +42,32 @@ template <
|
||||
IOT &io
|
||||
);
|
||||
|
||||
template <
|
||||
Model model,
|
||||
Operation operation,
|
||||
DataSize data_size,
|
||||
typename FlowControllerT
|
||||
> void perform(
|
||||
CPU::RegisterPair32 &destination,
|
||||
CPU::RegisterPair32 &source,
|
||||
Status &status,
|
||||
FlowControllerT &flow_controller
|
||||
);
|
||||
|
||||
template <
|
||||
Model model,
|
||||
Operation operation,
|
||||
DataSize data_size,
|
||||
typename FlowControllerT
|
||||
> void perform(
|
||||
CPU::RegisterPair16 &destination,
|
||||
CPU::RegisterPair16 &source,
|
||||
Status &status,
|
||||
FlowControllerT &flow_controller
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
#include "Implementation/PerformImplementation.hpp"
|
||||
|
||||
#endif /* Perform_h */
|
||||
|
@ -54,6 +54,16 @@ static constexpr uint32_t VirtualMode = 1 << 17;
|
||||
}
|
||||
|
||||
struct Status {
|
||||
// Non-zero => set; zero => unset.
|
||||
uint32_t carry;
|
||||
uint32_t auxiliary_carry;
|
||||
uint32_t sign;
|
||||
|
||||
// Zero => set; non-zero => unset.
|
||||
uint32_t zero;
|
||||
|
||||
// Odd number of bits => set; even => unset.
|
||||
uint32_t parity;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1128,6 +1128,7 @@
|
||||
423BDC492AB24699008E37B6 /* 8088Tests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 8088Tests.mm; sourceTree = "<group>"; };
|
||||
42437B342ACF02A9006DFED1 /* Status.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Status.hpp; sourceTree = "<group>"; };
|
||||
42437B352ACF0AA2006DFED1 /* Perform.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Perform.hpp; sourceTree = "<group>"; };
|
||||
42437B382ACF2798006DFED1 /* PerformImplementation.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = PerformImplementation.hpp; sourceTree = "<group>"; };
|
||||
4281572E2AA0334300E16AA1 /* Carry.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Carry.hpp; sourceTree = "<group>"; };
|
||||
428168372A16C25C008ECD27 /* LineLayout.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LineLayout.hpp; sourceTree = "<group>"; };
|
||||
428168392A37AFB4008ECD27 /* DispatcherTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DispatcherTests.mm; sourceTree = "<group>"; };
|
||||
@ -2325,6 +2326,14 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
42437B372ACF2798006DFED1 /* Implementation */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
42437B382ACF2798006DFED1 /* PerformImplementation.hpp */,
|
||||
);
|
||||
path = Implementation;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
42A5E8322ABBE16F00A0DD5D /* Neskell Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -4995,8 +5004,9 @@
|
||||
4BEDA3B825B25563000C2DBD /* Decoder.hpp */,
|
||||
4BEDA3DB25B2588F000C2DBD /* Instruction.hpp */,
|
||||
4BE3C69527CBC540000EAD28 /* Model.hpp */,
|
||||
42437B342ACF02A9006DFED1 /* Status.hpp */,
|
||||
42437B352ACF0AA2006DFED1 /* Perform.hpp */,
|
||||
42437B342ACF02A9006DFED1 /* Status.hpp */,
|
||||
42437B372ACF2798006DFED1 /* Implementation */,
|
||||
);
|
||||
path = x86;
|
||||
sourceTree = "<group>";
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "NSData+dataWithContentsOfGZippedFile.h"
|
||||
|
||||
#include "../../../InstructionSets/x86/Decoder.hpp"
|
||||
#include "../../../InstructionSets/x86/Perform.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -185,4 +186,26 @@ constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"
|
||||
NSLog(@"%ld failures out of %ld tests: %@", failures.count, testFiles.count, [[failures allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]);
|
||||
}
|
||||
|
||||
- (void)testExecution {
|
||||
CPU::RegisterPair16 source, dest;
|
||||
InstructionSet::x86::Status status;
|
||||
struct NoFlow {
|
||||
} flow_controller;
|
||||
|
||||
dest.full = 0xff;
|
||||
source.full = 10;
|
||||
|
||||
InstructionSet::x86::perform<
|
||||
InstructionSet::x86::Model::i8086,
|
||||
InstructionSet::x86::Operation::AAD,
|
||||
InstructionSet::x86::DataSize::Byte
|
||||
>(
|
||||
dest,
|
||||
source,
|
||||
status,
|
||||
flow_controller
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
Loading…
Reference in New Issue
Block a user