mirror of
https://github.com/pound-emu/pound.git
synced 2025-12-11 07:36:57 +00:00
Compare commits
4 commits
a0ed4382a5
...
18fa5dd65a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18fa5dd65a | ||
|
|
ac950250a8 | ||
|
|
1c3b730899 | ||
|
|
a543f78b77 |
6 changed files with 1654 additions and 129 deletions
173
.clang-format
Executable file → Normal file
173
.clang-format
Executable file → Normal file
|
|
@ -1,83 +1,140 @@
|
|||
# Google C/C++ Code Style settings
|
||||
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
# Author: Kehan Xue, kehan.xue (at) gmail.com
|
||||
|
||||
Language: Cpp
|
||||
BasedOnStyle: Google
|
||||
AccessModifierOffset: -1
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignOperands: Align
|
||||
AlignConsecutiveMacros: true
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveDeclarations: true
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: Never # To avoid conflict, set this "Never" and each "if statement" should include brace when coding
|
||||
AllowShortLambdasOnASingleLine: Inline
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakAfterDefinitionReturnType: TopLevel
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: true
|
||||
BreakBeforeBraces: Allman
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterStruct: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
AfterCaseLabel: false
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeComma
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakInheritanceList: BeforeColon
|
||||
ColumnLimit: 120
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakAfterJavaFieldAnnotations: true
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false # Make sure the * or & align on the left
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
FixNamespaceComments: true
|
||||
IncludeBlocks: Preserve
|
||||
Cpp11BracedListStyle: false
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: false
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentCaseLabels: true
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertBraces: true
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PointerAlignment: Left
|
||||
ReflowComments: false
|
||||
# SeparateDefinitionBlocks: Always # Only support since clang-format 14
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: false
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParens: Custom
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterFunctionDefinitionName: true
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 2
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: c++11
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
SpaceBeforeSquareBrackets: false
|
||||
Standard: Latest
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
...
|
||||
|
||||
|
|
|
|||
1428
BARC-style-guide.pdf
Executable file
1428
BARC-style-guide.pdf
Executable file
File diff suppressed because one or more lines are too long
|
|
@ -2,6 +2,7 @@ add_library(jit STATIC)
|
|||
|
||||
target_sources(jit PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/decoder/arm32.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ir/type.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(jit PRIVATE common host)
|
||||
|
|
|
|||
|
|
@ -1,65 +1,73 @@
|
|||
#include "arm32.h"
|
||||
#include <string.h>
|
||||
#include "common/passert.h"
|
||||
#include <string.h>
|
||||
|
||||
#define LOG_MODULE "jit"
|
||||
#include "common/logging.h"
|
||||
|
||||
namespace pound::jit::decoder
|
||||
{
|
||||
namespace pound::jit::decoder {
|
||||
#define INSTRUCTION_ARRAY_CAPACITY 261
|
||||
|
||||
#define HASH_TABLE_INVALID_INDEX 0xFFFF
|
||||
#define INSTRUCTION_BITSTRING_LENGTH 32
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* Foward Declarations
|
||||
* ============================================================================
|
||||
*/
|
||||
void arm32_add_instruction(arm32_decoder_t* decoder, const char* name, const char* bitstring);
|
||||
|
||||
void arm32_parse_bitstring(const char* bitstring, uint32_t* mask, uint32_t* expected);
|
||||
void arm32_grow_instructions_array(arm32_decoder_t* decoder, size_t new_capacity);
|
||||
static void arm32_add_instruction(arm32_decoder_t *p_decoder,
|
||||
const char *p_name,
|
||||
const char *p_bitstring);
|
||||
static void arm32_parse_bitstring(const char *p_bitstring,
|
||||
uint32_t *p_mask,
|
||||
uint32_t *p_expected);
|
||||
|
||||
/*
|
||||
* ============================================================================
|
||||
* Public Functions
|
||||
* ============================================================================
|
||||
*/
|
||||
void arm32_init(pound::host::memory::arena_t allocator, arm32_decoder_t* decoder)
|
||||
void
|
||||
arm32_init (pound::host::memory::arena_t allocator, arm32_decoder_t *p_decoder)
|
||||
{
|
||||
PVM_ASSERT(nullptr != decoder);
|
||||
PVM_ASSERT(nullptr != p_decoder);
|
||||
PVM_ASSERT(nullptr != allocator.data);
|
||||
|
||||
(void)memset(decoder, 0, sizeof(arm32_decoder_t));
|
||||
decoder->allocator = allocator;
|
||||
(void)memset(p_decoder, 0, sizeof(arm32_decoder_t));
|
||||
p_decoder->allocator = allocator;
|
||||
|
||||
/* Setup Instructions array.*/
|
||||
size_t instructions_array_size = INSTRUCTION_ARRAY_CAPACITY * sizeof(arm32_instruction_info_t);
|
||||
PVM_ASSERT(instructions_array_size <= decoder->allocator.capacity);
|
||||
LOG_TRACE("Allocated %d bytes to instructions array", instructions_array_size);
|
||||
size_t instructions_array_size
|
||||
= INSTRUCTION_ARRAY_CAPACITY * sizeof(arm32_instruction_info_t);
|
||||
PVM_ASSERT(instructions_array_size <= p_decoder->allocator.capacity);
|
||||
LOG_TRACE("Allocated %d bytes to instructions array",
|
||||
instructions_array_size);
|
||||
|
||||
void* new_ptr = pound::host::memory::arena_allocate(&decoder->allocator, instructions_array_size);
|
||||
PVM_ASSERT(nullptr != new_ptr);
|
||||
void *p_memory = pound::host::memory::arena_allocate(
|
||||
&p_decoder->allocator, instructions_array_size);
|
||||
PVM_ASSERT(nullptr != p_memory);
|
||||
|
||||
decoder->instructions = (arm32_instruction_info_t*)new_ptr;
|
||||
decoder->instruction_capacity = INSTRUCTION_ARRAY_CAPACITY;
|
||||
p_decoder->p_instructions = (arm32_instruction_info_t *)p_memory;
|
||||
p_decoder->instruction_capacity = INSTRUCTION_ARRAY_CAPACITY;
|
||||
|
||||
/* Add all Arm32 instructions */
|
||||
#define INST(fn, name, bitstring) arm32_add_instruction(decoder, name, bitstring);
|
||||
#define INST(fn, name, bitstring) \
|
||||
arm32_add_instruction(p_decoder, name, bitstring);
|
||||
#include "./arm32.inc"
|
||||
#undef INST
|
||||
}
|
||||
|
||||
arm32_instruction_info_t* arm32_decode(arm32_decoder_t* decoder, uint32_t instruction)
|
||||
arm32_instruction_info_t *
|
||||
arm32_decode (arm32_decoder_t *p_decoder, uint32_t instruction)
|
||||
{
|
||||
for (size_t i = 0; i < decoder->instruction_count; ++i)
|
||||
for (size_t i = 0; i < p_decoder->instruction_count; ++i)
|
||||
{
|
||||
arm32_instruction_info_t* info = &decoder->instructions[i];
|
||||
if ((instruction & info->mask) == info->expected)
|
||||
arm32_instruction_info_t *p_info = &p_decoder->p_instructions[i];
|
||||
if ((instruction & p_info->mask) == p_info->expected)
|
||||
{
|
||||
LOG_TRACE("Instruction found for 0x%08X: %s", instruction, info->name);
|
||||
return info;
|
||||
LOG_TRACE("Instruction found for 0x%08X: %s",
|
||||
instruction,
|
||||
p_info->p_name);
|
||||
return p_info;
|
||||
}
|
||||
}
|
||||
PVM_ASSERT_MSG(false, "No instruction found for 0x%08X", instruction);
|
||||
|
|
@ -71,55 +79,64 @@ arm32_instruction_info_t* arm32_decode(arm32_decoder_t* decoder, uint32_t instru
|
|||
* ============================================================================
|
||||
*/
|
||||
|
||||
void arm32_add_instruction(arm32_decoder_t* decoder, const char* name, const char* bitstring)
|
||||
static void
|
||||
arm32_add_instruction (arm32_decoder_t *p_decoder,
|
||||
const char *p_name,
|
||||
const char *p_bitstring)
|
||||
{
|
||||
PVM_ASSERT(nullptr != decoder);
|
||||
PVM_ASSERT(nullptr != decoder->allocator.data);
|
||||
PVM_ASSERT(nullptr != name);
|
||||
PVM_ASSERT(nullptr != bitstring);
|
||||
PVM_ASSERT(decoder->instruction_count < decoder->instruction_capacity);
|
||||
PVM_ASSERT(nullptr != p_decoder);
|
||||
PVM_ASSERT(nullptr != p_decoder->allocator.data);
|
||||
PVM_ASSERT(nullptr != p_name);
|
||||
PVM_ASSERT(nullptr != p_bitstring);
|
||||
PVM_ASSERT(p_decoder->instruction_count < p_decoder->instruction_capacity);
|
||||
|
||||
uint32_t mask = 0;
|
||||
uint32_t mask = 0;
|
||||
uint32_t expected = 0;
|
||||
arm32_parse_bitstring(bitstring, &mask, &expected);
|
||||
arm32_parse_bitstring(p_bitstring, &mask, &expected);
|
||||
|
||||
arm32_instruction_info_t* info = &decoder->instructions[decoder->instruction_count];
|
||||
PVM_ASSERT(nullptr != info);
|
||||
info->name = name;
|
||||
info->mask = mask;
|
||||
info->expected = expected;
|
||||
arm32_instruction_info_t *p_info
|
||||
= &p_decoder->p_instructions[p_decoder->instruction_count];
|
||||
PVM_ASSERT(nullptr != p_info);
|
||||
p_info->p_name = p_name;
|
||||
p_info->mask = mask;
|
||||
p_info->expected = expected;
|
||||
|
||||
++decoder->instruction_count;
|
||||
++p_decoder->instruction_count;
|
||||
|
||||
LOG_TRACE("Instruction Registered: %s", info->name);
|
||||
LOG_TRACE("Mask: 0x%08X", info->mask);
|
||||
LOG_TRACE("Expected: 0x%08X", info->expected);
|
||||
LOG_TRACE("Instruction Registered: %s", p_info->p_name);
|
||||
LOG_TRACE("Mask: 0x%08X", p_info->mask);
|
||||
LOG_TRACE("Expected: 0x%08X", p_info->expected);
|
||||
}
|
||||
|
||||
void arm32_parse_bitstring(const char* bitstring, uint32_t* mask, uint32_t* expected)
|
||||
static void
|
||||
arm32_parse_bitstring (const char *p_bitstring,
|
||||
uint32_t *p_mask,
|
||||
uint32_t *p_expected)
|
||||
{
|
||||
PVM_ASSERT(nullptr != bitstring);
|
||||
PVM_ASSERT(nullptr != mask);
|
||||
PVM_ASSERT(nullptr != expected);
|
||||
PVM_ASSERT(32 == strlen(bitstring));
|
||||
PVM_ASSERT(nullptr != p_bitstring);
|
||||
PVM_ASSERT(nullptr != p_mask);
|
||||
PVM_ASSERT(nullptr != p_expected);
|
||||
PVM_ASSERT(INSTRUCTION_BITSTRING_LENGTH == strlen(p_bitstring));
|
||||
|
||||
*mask = 0;
|
||||
*expected = 0;
|
||||
*p_mask = 0;
|
||||
*p_expected = 0;
|
||||
uint8_t instruction_size_bits = 32;
|
||||
for (unsigned int i = 0; (i < instruction_size_bits) && (bitstring[i] != '\0'); ++i)
|
||||
for (unsigned int i = 0;
|
||||
(i < instruction_size_bits) && (p_bitstring[i] != '\0');
|
||||
++i)
|
||||
{
|
||||
uint32_t bit_position = 31 - i;
|
||||
switch (bitstring[i])
|
||||
switch (p_bitstring[i])
|
||||
{
|
||||
case '0':
|
||||
*mask |= (1U << bit_position);
|
||||
*p_mask |= (1U << bit_position);
|
||||
break;
|
||||
case '1':
|
||||
*mask |= (1U << bit_position);
|
||||
*expected |= (1U << bit_position);
|
||||
*p_mask |= (1U << bit_position);
|
||||
*p_expected |= (1U << bit_position);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace pound::jit::decoder
|
||||
} // namespace pound::jit::p_decoder
|
||||
|
|
|
|||
|
|
@ -5,29 +5,27 @@
|
|||
#include <stdint.h>
|
||||
#include "host/memory/arena.h"
|
||||
|
||||
namespace pound::jit::decoder
|
||||
{
|
||||
namespace pound::jit::decoder {
|
||||
typedef struct arm32_decoder arm32_decoder_t;
|
||||
typedef void (*arm32_handler_fn)(arm32_decoder_t* decoder, uint32_t instruction);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char* name;
|
||||
uint32_t mask;
|
||||
uint32_t expected;
|
||||
const char *p_name;
|
||||
uint32_t mask;
|
||||
uint32_t expected;
|
||||
} arm32_instruction_info_t;
|
||||
|
||||
struct arm32_decoder
|
||||
{
|
||||
pound::host::memory::arena_t allocator;
|
||||
arm32_instruction_info_t* instructions;
|
||||
size_t instruction_count;
|
||||
size_t instruction_capacity;
|
||||
arm32_instruction_info_t *p_instructions;
|
||||
size_t instruction_count;
|
||||
size_t instruction_capacity;
|
||||
};
|
||||
|
||||
extern arm32_decoder_t g_arm32_decoder;
|
||||
|
||||
void arm32_init(pound::host::memory::arena_t allocator, arm32_decoder_t* decoder);
|
||||
arm32_instruction_info_t* arm32_decode(arm32_decoder_t* decoder, uint32_t instruction);
|
||||
void arm32_init(pound::host::memory::arena_t allocator,
|
||||
arm32_decoder_t *p_decoder);
|
||||
arm32_instruction_info_t *arm32_decode(arm32_decoder_t *p_decoder,
|
||||
uint32_t instruction);
|
||||
}
|
||||
#endif // POUND_JIT_DECODER_ARM32_H
|
||||
#endif // POUND_JIT_DECODER_ARM32_H
|
||||
|
|
|
|||
24
src/jit/ir/type.cpp
Normal file
24
src/jit/ir/type.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
namespace pound::jit::decoder
|
||||
{
|
||||
typedef enum {
|
||||
IR_TYPE_VOID = 0,
|
||||
IR_TYPE_U1 = 1 << 0,
|
||||
IR_TYPE_U8 = 1 << 1,
|
||||
IR_TYPE_U16 = 1 << 2,
|
||||
IR_TYPE_U32 = 1 << 3,
|
||||
IR_TYPE_U64 = 1 << 4,
|
||||
IR_TYPE_U128 = 1 << 5,
|
||||
IR_TYPE_A32_REG = 1 << 6, // ARM32 GPR R0-R14
|
||||
IR_TYPE_A32_EXT_REG = 1 << 7, // ARM32 Extended Registers (e.g., for VFP/NEON, or just R15 if treated specially)
|
||||
IR_TYPE_A32_CPSR = 1 << 8, // ARM32 CPSR/SPSR
|
||||
IR_TYPE_COND = 1 << 9, // Condition codes
|
||||
IR_TYPE_ACC_TYPE = 1 << 10, // Memory access type
|
||||
IR_TYPE_OPAQUE = 1 << 11, // Represents a value defined by another IR instruction
|
||||
} ir_type_t;
|
||||
|
||||
bool ir_are_types_compatible(ir_type_t t1, ir_type_t t2)
|
||||
{
|
||||
const bool is_compatible = (t1 == t2) || (IR_TYPE_OPAQUE == t1) || (IR_TYPE_OPAQUE == t2);
|
||||
return is_compatible;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue