1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-04 18:29:40 +00:00

Start fleshing out x86 performance.

This commit is contained in:
Thomas Harte 2023-10-05 14:37:58 -04:00
parent 524e4ae65c
commit 059f300500
5 changed files with 186 additions and 3 deletions

View 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 &registers,
MemoryT &memory,
IOT &io
) {
switch((operation != Operation::Invalid) ? operation : instruction.operation) {
default:
assert(false);
return;
}
}*/
}
#endif /* PerformImplementation_h */

View File

@ -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 */

View File

@ -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;
};
}

View File

@ -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>";

View File

@ -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