Compare commits
279 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6ed4adb0ed | ||
|
f16c24363c | ||
|
fd7e68573c | ||
|
f1873f0794 | ||
|
a01d98e584 | ||
|
c7a53a5be6 | ||
|
4633631d7e | ||
|
100608e0ac | ||
|
35a0b36a0d | ||
|
5470db3a5f | ||
|
d6802f3cb9 | ||
|
5b4e0c2b55 | ||
|
8175fae67a | ||
|
13c90eb542 | ||
|
f98665c577 | ||
|
8843f3feba | ||
|
514cf59398 | ||
|
03c133cd48 | ||
|
880abea32e | ||
|
fc9a8f2a89 | ||
|
40c467d958 | ||
|
4bde6385b8 | ||
|
688ef958e3 | ||
|
6da7223472 | ||
|
a1d4bc8375 | ||
|
197e2a91be | ||
|
4d9d628b67 | ||
|
f720feebbf | ||
|
6076808f5e | ||
|
0af17f0f40 | ||
|
81e5321bfc | ||
|
27d3666285 | ||
|
c6b794db3a | ||
|
1fa4c39a20 | ||
|
0ba148b6bb | ||
|
65540da3f7 | ||
|
e660757824 | ||
|
05a6d16dde | ||
|
79ec9af3f2 | ||
|
8f37df448f | ||
|
d710a71ba0 | ||
|
8dd211b662 | ||
|
398ed22b09 | ||
|
6f1da4335b | ||
|
c86dc364b1 | ||
|
70eb7a5eab | ||
|
c1cd2ba57e | ||
|
00da0ef87d | ||
|
be9abbf510 | ||
|
0b72e6b2f2 | ||
|
6ea39d7bfa | ||
|
c0abe031ee | ||
|
fe667863b2 | ||
|
e514e05dc8 | ||
|
d978d0a483 | ||
|
37cacdafa7 | ||
|
78e3696663 | ||
|
a0215a4f21 | ||
|
2310416c46 | ||
|
52db653ec1 | ||
|
6fe76e478f | ||
|
ba05ec743d | ||
|
05ef25a61e | ||
|
b26cc4ede7 | ||
|
8dc5f703e8 | ||
|
c05d7e47f4 | ||
|
9dc8489693 | ||
|
f443c97f70 | ||
|
4837ceb73f | ||
|
42299c9406 | ||
|
850bbfc31a | ||
|
1e95f51469 | ||
|
e525e5d62e | ||
|
18deb8846d | ||
|
34ce9afeae | ||
|
d0411b7d52 | ||
|
34fda8c9b5 | ||
|
b4a357e44f | ||
|
2b224f262b | ||
|
3c306e0899 | ||
|
e82ab0c7ca | ||
|
983064c694 | ||
|
9230d95bad | ||
|
8b0790588b | ||
|
0a9c43757a | ||
|
fccfe35c4f | ||
|
064fed63f5 | ||
|
f43f471124 | ||
|
f99abb32e2 | ||
|
18f044e90c | ||
|
5b961c031c | ||
|
500cce511f | ||
|
885d6ff706 | ||
|
efc182ce27 | ||
|
06ef87fe63 | ||
|
f3d8251072 | ||
|
0d5efc90ed | ||
|
30b8e4e970 | ||
|
3da1ddf5da | ||
|
bfdd1b85fb | ||
|
686d468d32 | ||
|
23b15678cd | ||
|
d1054abd90 | ||
|
d358c8359b | ||
|
9e9494ebf9 | ||
|
015ada7a33 | ||
|
12e832ebd3 | ||
|
e327d2a148 | ||
|
366f9686dd | ||
|
a2927401bc | ||
|
bbb339d641 | ||
|
8e76334c20 | ||
|
739f1e2161 | ||
|
4ee6ca5b94 | ||
|
347898ea53 | ||
|
6caed58be4 | ||
|
c4185832ba | ||
|
2b0994b086 | ||
|
f9acbc152d | ||
|
3eed21567e | ||
|
f3370cb149 | ||
|
494fb97e49 | ||
|
bd8786af0b | ||
|
f0a7499814 | ||
|
da4a90b724 | ||
|
96a9109915 | ||
|
f5a33edcf4 | ||
|
1bd98bdeb2 | ||
|
e4696a6539 | ||
|
74350d6133 | ||
|
cbf86b2e8f | ||
|
cb757dfaf9 | ||
|
5ad94d01d4 | ||
|
cdba71b353 | ||
|
01d187cf83 | ||
|
ab06ce74c5 | ||
|
1e2b227113 | ||
|
9d5dbe67fe | ||
|
9a409ca347 | ||
|
449acece05 | ||
|
ee3f6fc4a5 | ||
|
e95b51609c | ||
|
323589a484 | ||
|
33f4b25f28 | ||
|
538d965636 | ||
|
4b99110533 | ||
|
94f2489083 | ||
|
6de1b1fd96 | ||
|
80abcdfe95 | ||
|
0dc6588a66 | ||
|
65ad05c608 | ||
|
2db8890453 | ||
|
3f4268328e | ||
|
33cabb487b | ||
|
ab2ca897ce | ||
|
2c37e150a9 | ||
|
ee68f2575a | ||
|
4f100266c3 | ||
|
c22a67f95f | ||
|
e6bc6371c9 | ||
|
2acca6d7b1 | ||
|
fc2095301d | ||
|
32f0b8c6f3 | ||
|
10c9b735e9 | ||
|
fefb511404 | ||
|
bedafe7b6f | ||
|
242d7f1700 | ||
|
90e892dfa5 | ||
|
c98e0751b0 | ||
|
f3b4a4e5fc | ||
|
1c7d71cadb | ||
|
840050738f | ||
|
2ee5cc7bf4 | ||
|
490180f9dc | ||
|
2582f3076d | ||
|
0032d42b2c | ||
|
5c70c20c6e | ||
|
71236aa405 | ||
|
31a38e2a62 | ||
|
ee0e4d5428 | ||
|
f6296e83e5 | ||
|
39840b5fb1 | ||
|
fe0bfccfaa | ||
|
25ee4e9b2b | ||
|
9f7d4c0ab0 | ||
|
038928232c | ||
|
100affa083 | ||
|
e27075955d | ||
|
0959a15b10 | ||
|
4a87e4d97b | ||
|
9de7caa68d | ||
|
e23d78eb86 | ||
|
d0b45fce78 | ||
|
0126dd53a3 | ||
|
901c8459ec | ||
|
746fed6704 | ||
|
54c0f2a670 | ||
|
28ea8ef24f | ||
|
115129e1dd | ||
|
f41d594015 | ||
|
c8abb42c3c | ||
|
95732265f6 | ||
|
9f834c4232 | ||
|
d10d8bf7ae | ||
|
f6a2db7866 | ||
|
d2fdbd29f5 | ||
|
f5dff9620b | ||
|
28e75a8fa2 | ||
|
6170c81af3 | ||
|
3d578170db | ||
|
d99499b6e3 | ||
|
950c434157 | ||
|
d6362a305f | ||
|
38bb033328 | ||
|
87f1ddd27f | ||
|
9e994560a7 | ||
|
e37de95079 | ||
|
8e46ae95ec | ||
|
e7cece0f0f | ||
|
890a4b996e | ||
|
5b2ae228cc | ||
|
9fc8315f92 | ||
|
32935cd7a1 | ||
|
fd02382d38 | ||
|
4fce263228 | ||
|
50c7e10814 | ||
|
7c8ab991be | ||
|
067e169803 | ||
|
ccdbbe799a | ||
|
fac53cfd54 | ||
|
cfe2c7bed5 | ||
|
f0b9b5cce4 | ||
|
803b868356 | ||
|
907452d918 | ||
|
c12bca7b4e | ||
|
e1736c8214 | ||
|
d3e7a991a4 | ||
|
e7b0d17a83 | ||
|
df18dc273e | ||
|
b6341e402d | ||
|
3f2f703936 | ||
|
4acee4531c | ||
|
2a476d3372 | ||
|
0a41cb044c | ||
|
5a0f736d41 | ||
|
020534dbc8 | ||
|
cee2801847 | ||
|
51c38a4723 | ||
|
bb01d1024a | ||
|
903a5d9b8b | ||
|
e360dea558 | ||
|
582443ef5c | ||
|
80a42216c7 | ||
|
6576f4d090 | ||
|
55e983e5a1 | ||
|
a6f9c733a1 | ||
|
3c129ff4e5 | ||
|
db386a5958 | ||
|
179cc694e3 | ||
|
887a51b176 | ||
|
5b81379dac | ||
|
4fff9f7060 | ||
|
40c407782d | ||
|
5946f17632 | ||
|
7e0ff7449c | ||
|
d597219aea | ||
|
a311396cf8 | ||
|
94607cab7f | ||
|
4d193a30b0 | ||
|
c1ad265f47 | ||
|
4e2a2c99ba | ||
|
ea33f253d4 | ||
|
ebc41560d9 | ||
|
2d2c696aa4 | ||
|
b622c25a56 | ||
|
439cf499ed | ||
|
cd5f1daaba | ||
|
ec95f6dc98 | ||
|
66dfe5df46 |
|
@ -0,0 +1,67 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
# Project name and version
|
||||
project(oscar64 VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Define the executable
|
||||
add_executable(oscar64)
|
||||
|
||||
|
||||
# Glob all source files in the oscar64/ directory
|
||||
file(GLOB OSCAR64_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/oscar64/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/oscar64/*.h")
|
||||
|
||||
# Add the sources to the target
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${OSCAR64_SOURCES})
|
||||
|
||||
|
||||
# Add header files
|
||||
target_include_directories(oscar64 PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
# Compiler settings based on configuration
|
||||
set_target_properties(oscar64 PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED YES
|
||||
CXX_EXTENSIONS NO
|
||||
)
|
||||
|
||||
# Set debug and release configurations
|
||||
target_compile_definitions(oscar64 PRIVATE $<$<CONFIG:Debug>:_DEBUG;_CONSOLE> $<$<CONFIG:Release>:NDEBUG;_CONSOLE>)
|
||||
target_compile_options(oscar64 PRIVATE $<$<CONFIG:Debug>:/W3 /WX> $<$<CONFIG:Release>:/O2 /W3>)
|
||||
|
||||
# Post-build steps (only for Release builds)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
add_custom_command(TARGET oscar64 POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:oscar64> ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(oscar64 PRIVATE kernel32 user32 gdi32 winspool comdlg32 advapi32 shell32 ole32 oleaut32 uuid odbc32 odbccp32 version)
|
||||
elseif (APPLE)
|
||||
# Add macOS-specific frameworks to replace Windows libraries
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
"-framework Cocoa" # For GUI and application support
|
||||
"-framework CoreFoundation" # For Core Foundation utilities (similar to advapi32 or shell32)
|
||||
"-framework CoreGraphics" # For graphics and rendering (similar to gdi32)
|
||||
"-framework IOKit" # For hardware interaction
|
||||
"-framework AppKit" # For GUI (equivalent to user32)
|
||||
)
|
||||
elseif (UNIX)
|
||||
# Add Linux-specific libraries for equivalent functionality
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
pthread # For threading (similar to kernel32)
|
||||
dl # For dynamic library loading (similar to LoadLibrary)
|
||||
m # For math library (optional but common on Linux)
|
||||
X11 # For X Window System (similar to user32 for GUI support)
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
# Output directories
|
||||
set_target_properties(oscar64 PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Debug
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Release
|
||||
)
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
rem @echo off
|
||||
|
||||
@call :test rolrortest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test bitfields.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -15,6 +18,9 @@ rem @echo off
|
|||
@call :testh opp_vector.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_static_vector.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_vector_string.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -33,7 +39,7 @@ rem @echo off
|
|||
@call :testh opp_list.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_functional.cpp
|
||||
@call :testn opp_functional.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh operatoroverload.cpp
|
||||
|
@ -51,7 +57,7 @@ rem @echo off
|
|||
@call :testh constructortest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh copyconstructor.cpp
|
||||
@call :testn copyconstructor.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh copyassign.cpp
|
||||
|
@ -274,6 +280,15 @@ exit /b %errorlevel%
|
|||
..\bin\oscar64 -e -O2 -n -dHEAPCHECK %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O0 -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -331,6 +346,12 @@ exit /b %errorlevel%
|
|||
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@exit /b 0
|
||||
|
||||
:testb
|
||||
|
@ -370,4 +391,10 @@ exit /b %errorlevel%
|
|||
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@exit /b 0
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int t, n;
|
||||
|
||||
|
@ -161,7 +162,7 @@ void test_return_value(void)
|
|||
C2 c(test_ret_v());
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
assert(n == 6 && t == 0);
|
||||
}
|
||||
|
||||
void test_return_reference(void)
|
||||
|
@ -184,7 +185,7 @@ void test_retparam_value(void)
|
|||
test_param_fv(test_ret_v());
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
assert(n == 6 && t == 0);
|
||||
}
|
||||
|
||||
void test_retparam_reference(void)
|
||||
|
@ -200,7 +201,6 @@ void test_retparam_reference(void)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
#if 0
|
||||
test_dcopy_init();
|
||||
test_copy_init();
|
||||
test_minit();
|
||||
|
@ -208,9 +208,8 @@ int main(void)
|
|||
test_param_value();
|
||||
test_param_ref();
|
||||
test_return_value();
|
||||
#endif
|
||||
test_retparam_value();
|
||||
// test_retparam_reference();
|
||||
test_retparam_reference();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -50,5 +50,11 @@ autorefreturn: autorefreturn.cpp
|
|||
$(OSCAR64_CC) -e -Os -n $<
|
||||
$(OSCAR64_CC) -e -O3 -n $<
|
||||
|
||||
copyconstructor: copyconstructor.cpp
|
||||
$(OSCAR64_CC) -e -O2 -n $<
|
||||
$(OSCAR64_CC) -e -O0 -n $<
|
||||
$(OSCAR64_CC) -e -Os -n $<
|
||||
$(OSCAR64_CC) -e -O3 -n $<
|
||||
|
||||
clean:
|
||||
@$(RM) *.asm *.bcs *.int *.lbl *.map *.prg
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
#include <opp/static_vector.h>
|
||||
#include <opp/algorithm.h>
|
||||
#include <assert.h>
|
||||
#include <opp/iostream.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
opp::static_vector<int, 20> a;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
a.push_back(i);
|
||||
|
||||
int s = 0;
|
||||
for(int i=0; i<a.size(); i++)
|
||||
s += a[i];
|
||||
|
||||
assert(s == 45);
|
||||
|
||||
for(int i=0; i<5; i++)
|
||||
a.erase(i);
|
||||
|
||||
s = 0;
|
||||
for(int i=0; i<a.size(); i++)
|
||||
s += a[i];
|
||||
|
||||
assert(s == 1 + 3 + 5 + 7 + 9);
|
||||
|
||||
opp::static_vector<int, 100> v;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
v.push_back(i);
|
||||
|
||||
assert(v.size() == 10);
|
||||
v.insert(0, 20);
|
||||
assert(v.size() == 11);
|
||||
v.insert(6, 21);
|
||||
assert(v.size() == 12);
|
||||
v.insert(12, 22);
|
||||
|
||||
int * fi = opp::find(v.begin(), v.end(), 21);
|
||||
|
||||
fi = v.insert(fi, 30);
|
||||
fi = v.insert(fi, 31);
|
||||
fi = v.insert(fi, 32);
|
||||
|
||||
assert(v.size() == 16);
|
||||
assert(v[0] == 20);
|
||||
assert(v[15] == 22);
|
||||
assert(v[8] == 32);
|
||||
|
||||
fi = opp::find(v.begin(), v.end(), 32);
|
||||
|
||||
for(int i=0; i<30; i++)
|
||||
{
|
||||
fi = v.insert(fi, i + 40);
|
||||
}
|
||||
|
||||
assert(v.size() == 46);
|
||||
assert(v[28] == 60);
|
||||
|
||||
v.erase(10, 10);
|
||||
|
||||
for(int i : v)
|
||||
opp::cout << i << ", ";
|
||||
opp::cout << "\n";
|
||||
|
||||
assert(v.size() == 36);
|
||||
assert(v[18] == 60);
|
||||
|
||||
v.assign(42, 11);
|
||||
|
||||
assert(v.size() == 42);
|
||||
assert(v[0] == 11);
|
||||
assert(v[15] == 11);
|
||||
assert(v[41] == 11);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -64,5 +64,15 @@ int main(void)
|
|||
opp::cout << i << ", ";
|
||||
opp::cout << "\n";
|
||||
|
||||
assert(v.size() == 36);
|
||||
assert(v[18] == 60);
|
||||
|
||||
v.assign(42, 11);
|
||||
|
||||
assert(v.size() == 42);
|
||||
assert(v[0] == 11);
|
||||
assert(v[15] == 11);
|
||||
assert(v[41] == 11);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
#include <assert.h>
|
||||
|
||||
__noinline unsigned long rollright32(unsigned long a) {
|
||||
unsigned long tmp = a & 1;
|
||||
return ( a >> 1) + (tmp << 31);
|
||||
}
|
||||
|
||||
__noinline unsigned rollright16(unsigned a) {
|
||||
unsigned tmp = a & 1;
|
||||
return ( a >> 1) + (tmp << 15);
|
||||
}
|
||||
|
||||
__noinline char rollright8(char a) {
|
||||
char tmp = a & 1;
|
||||
return ( a >> 1) + (tmp << 7);
|
||||
}
|
||||
|
||||
__noinline unsigned long rollleft32(unsigned long a) {
|
||||
unsigned long tmp = (a >> 31) & 1;
|
||||
return ( a << 1) + tmp;
|
||||
}
|
||||
|
||||
__noinline unsigned rollleft16(unsigned a) {
|
||||
unsigned tmp = (a >> 15) & 1;
|
||||
return ( a << 1) + tmp;
|
||||
}
|
||||
|
||||
__noinline char rollleft8(char a) {
|
||||
char tmp = (a >> 7) & 1;
|
||||
return ( a << 1) + tmp;
|
||||
}
|
||||
|
||||
int main() {
|
||||
unsigned long lv = 0x12345678ul;
|
||||
unsigned val = 0x1234;
|
||||
char c=0x12;
|
||||
|
||||
unsigned long lvt[33];
|
||||
unsigned valt[17];
|
||||
char ct[9];
|
||||
|
||||
lvt[0] = lv;
|
||||
valt[0] = val;
|
||||
ct[0] = c;
|
||||
|
||||
assert(rollleft8(rollright8(c)) == c);
|
||||
assert(rollleft16(rollright16(val)) == val);
|
||||
assert(rollleft32(rollright32(lv)) == lv);
|
||||
|
||||
for(int i=0; i<32; i++)
|
||||
lvt[i + 1] = rollright32(lvt[i]);
|
||||
for(int i=0; i<16; i++)
|
||||
valt[i + 1] = rollright16(valt[i]);
|
||||
for(int i=0; i<8; i++)
|
||||
ct[i + 1] = rollright8(ct[i]);
|
||||
|
||||
for(int i=0; i<=32; i++)
|
||||
{
|
||||
assert(lvt[32 - i] == lv);
|
||||
lv = rollleft32(lv);
|
||||
}
|
||||
|
||||
for(int i=0; i<=16; i++)
|
||||
{
|
||||
assert(valt[16 - i] == val);
|
||||
val = rollleft16(val);
|
||||
}
|
||||
|
||||
for(int i=0; i<=8; i++)
|
||||
{
|
||||
assert(ct[8 - i] == c);
|
||||
c = rollleft8(c);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -63,6 +63,33 @@ bool nge(long a, long b)
|
|||
|
||||
|
||||
|
||||
|
||||
inline bool ieq(long a, long b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
inline bool ilt(long a, long b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
inline bool igt(long a, long b)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
|
||||
inline bool ile(long a, long b)
|
||||
{
|
||||
return a <= b;
|
||||
}
|
||||
|
||||
inline bool ige(long a, long b)
|
||||
{
|
||||
return a >= b;
|
||||
}
|
||||
|
||||
|
||||
bool beqz(long a)
|
||||
{
|
||||
return a == 0;
|
||||
|
@ -188,7 +215,71 @@ bool nge1(long a)
|
|||
|
||||
|
||||
|
||||
void cmp(long a, long b)
|
||||
bool beqm(long a)
|
||||
{
|
||||
return a == -1;
|
||||
}
|
||||
|
||||
bool bltm(long a)
|
||||
{
|
||||
return a < -1;
|
||||
}
|
||||
|
||||
bool bgtm(long a)
|
||||
{
|
||||
return a > -1;
|
||||
}
|
||||
|
||||
bool blem(long a)
|
||||
{
|
||||
return a <= -1;
|
||||
}
|
||||
|
||||
bool bgem(long a)
|
||||
{
|
||||
return a >= -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool neqm(long a)
|
||||
{
|
||||
return a == -1;
|
||||
}
|
||||
|
||||
#pragma native(neqm)
|
||||
|
||||
bool nltm(long a)
|
||||
{
|
||||
return a < -1;
|
||||
}
|
||||
|
||||
#pragma native(nltm)
|
||||
|
||||
bool ngtm(long a)
|
||||
{
|
||||
return a > -1;
|
||||
}
|
||||
|
||||
#pragma native(ngtm)
|
||||
|
||||
bool nlem(long a)
|
||||
{
|
||||
return a <= -1;
|
||||
}
|
||||
|
||||
#pragma native(nlem)
|
||||
|
||||
bool ngem(long a)
|
||||
{
|
||||
return a >= -1;
|
||||
}
|
||||
|
||||
#pragma native(ngem)
|
||||
|
||||
|
||||
|
||||
void cmpc(long a, long b)
|
||||
{
|
||||
bool beqf = beq(a, b), bltf = blt(a, b), bgtf = bgt(a, b), blef = ble(a, b), bgef = bge(a, b);
|
||||
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
|
||||
|
@ -203,6 +294,27 @@ void cmp(long a, long b)
|
|||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
void cmpi(long a, long b)
|
||||
{
|
||||
bool ieqf = ieq(a, b), iltf = ilt(a, b), igtf = igt(a, b), ilef = ile(a, b), igef = ige(a, b);
|
||||
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
|
||||
|
||||
printf("INLINE %ld, %ld : EQ %d LT %d GT %d\r", a, b, ieqf, iltf, igtf);
|
||||
printf("NATIVE %ld, %ld : EQ %d LT %d GT %d\r", a, b, neqf, nltf, ngtf);
|
||||
|
||||
assert(ieqf == neqf);
|
||||
assert(iltf == nltf);
|
||||
assert(igtf == ngtf);
|
||||
assert(ilef == nlef);
|
||||
assert(igef == ngef);
|
||||
}
|
||||
|
||||
void cmp(long a, long b)
|
||||
{
|
||||
cmpc(a, b);
|
||||
cmpi(a, b);
|
||||
}
|
||||
|
||||
void cmpz(long a)
|
||||
{
|
||||
bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(a);
|
||||
|
@ -233,6 +345,21 @@ void cmp1(long a)
|
|||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
void cmpm(long a)
|
||||
{
|
||||
bool beqf = beqm(a), bltf = bltm(a), bgtf = bgtm(a), blef = blem(a), bgef = bgem(a);
|
||||
bool neqf = neqm(a), nltf = nltm(a), ngtf = ngtm(a), nlef = nlem(a), ngef = ngem(a);
|
||||
|
||||
printf("BYTE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, beqf, bltf, bgtf, blef, bgef);
|
||||
printf("NATIVE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, neqf, nltf, ngtf, nlef, ngef);
|
||||
|
||||
assert(beqf == neqf);
|
||||
assert(bltf == nltf);
|
||||
assert(bgtf == ngtf);
|
||||
assert(blef == nlef);
|
||||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
cmp( 0, 1);
|
||||
|
@ -327,6 +454,10 @@ int main(void)
|
|||
cmp1(256);
|
||||
cmp1(10000);
|
||||
cmp1(20000);
|
||||
cmp1(1000000l);
|
||||
cmp1(2000000l);
|
||||
cmp1(100000000l);
|
||||
cmp1(200000000l);
|
||||
cmp1(-1);
|
||||
cmp1(-2);
|
||||
cmp1(-3);
|
||||
|
@ -334,6 +465,34 @@ int main(void)
|
|||
cmp1(-256);
|
||||
cmp1(-10000);
|
||||
cmp1(-20000);
|
||||
cmp1(-1000000l);
|
||||
cmp1(-2000000l);
|
||||
cmp1(-100000000l);
|
||||
cmp1(-200000000l);
|
||||
|
||||
cmpm(0);
|
||||
cmpm(1);
|
||||
cmpm(2);
|
||||
cmpm(3);
|
||||
cmpm(255);
|
||||
cmpm(256);
|
||||
cmpm(10000);
|
||||
cmpm(20000);
|
||||
cmpm(1000000l);
|
||||
cmpm(2000000l);
|
||||
cmpm(100000000l);
|
||||
cmpm(200000000l);
|
||||
cmpm(-1);
|
||||
cmpm(-2);
|
||||
cmpm(-3);
|
||||
cmpm(-255);
|
||||
cmpm(-256);
|
||||
cmpm(-10000);
|
||||
cmpm(-20000);
|
||||
cmpm(-1000000l);
|
||||
cmpm(-2000000l);
|
||||
cmpm(-100000000l);
|
||||
cmpm(-200000000l);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ enum SIDFXState
|
|||
SIDFX_WAIT
|
||||
};
|
||||
|
||||
static struct SIDFXChannel
|
||||
__striped static struct SIDFXChannel
|
||||
{
|
||||
const SIDFX * volatile com;
|
||||
byte delay, priority;
|
||||
|
@ -27,6 +27,7 @@ void sidfx_init(void)
|
|||
channels[i].com = nullptr;
|
||||
channels[i].state = SIDFX_IDLE;
|
||||
channels[i].priority = 0;
|
||||
channels[i].delay = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +36,11 @@ bool sidfx_idle(byte chn)
|
|||
return channels[chn].state == SIDFX_IDLE;
|
||||
}
|
||||
|
||||
char sidfx_cnt(byte chn)
|
||||
{
|
||||
return channels[chn].cnt;
|
||||
}
|
||||
|
||||
void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
|
||||
{
|
||||
SIDFXState ns = channels[chn].state;
|
||||
|
@ -47,6 +53,7 @@ void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
|
|||
return;
|
||||
|
||||
channels[chn].state = SIDFX_IDLE;
|
||||
channels[chn].delay = 1;
|
||||
|
||||
channels[chn].com = fx;
|
||||
channels[chn].cnt = cnt - 1;
|
||||
|
@ -59,71 +66,95 @@ void sidfx_stop(byte chn)
|
|||
{
|
||||
channels[chn].com = nullptr;
|
||||
if (channels[chn].state != SIDFX_IDLE)
|
||||
{
|
||||
channels[chn].state = SIDFX_RESET_0;
|
||||
channels[chn].delay = 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void sidfx_loop_ch(byte ch)
|
||||
{
|
||||
switch (channels[ch].state)
|
||||
if (channels[ch].state)
|
||||
{
|
||||
case SIDFX_IDLE:
|
||||
break;
|
||||
case SIDFX_RESET_0:
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_RESET_1:
|
||||
// sid.voices[ch].ctrl = SID_CTRL_TEST;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_READY:
|
||||
const SIDFX * com = channels[ch].com;
|
||||
|
||||
channels[ch].delay--;
|
||||
if (channels[ch].delay)
|
||||
{
|
||||
if (com->dfreq)
|
||||
{
|
||||
const SIDFX * com = channels[ch].com;
|
||||
channels[ch].freq += com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
}
|
||||
if (com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
}
|
||||
|
||||
while (!channels[ch].delay)
|
||||
{
|
||||
switch (channels[ch].state)
|
||||
{
|
||||
case SIDFX_IDLE:
|
||||
channels[ch].delay = 1;
|
||||
break;
|
||||
case SIDFX_RESET_0:
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
if (com)
|
||||
channels[ch].state = SIDFX_READY;
|
||||
else
|
||||
channels[ch].state = SIDFX_IDLE;
|
||||
channels[ch].delay = 1;
|
||||
break;
|
||||
case SIDFX_RESET_1:
|
||||
sid.voices[ch].ctrl = SID_CTRL_TEST;
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_READY:
|
||||
channels[ch].freq = com->freq;
|
||||
channels[ch].pwm = com->pwm;
|
||||
|
||||
sid.voices[ch].freq = com->freq;
|
||||
sid.voices[ch].pwm = com->pwm;
|
||||
sid.voices[ch].attdec = com->attdec;
|
||||
sid.voices[ch].susrel = com->susrel;
|
||||
sid.voices[ch].ctrl = com->ctrl;
|
||||
|
||||
if (com->ctrl & SID_CTRL_GATE)
|
||||
{
|
||||
channels[ch].freq = com->freq;
|
||||
channels[ch].pwm = com->pwm;
|
||||
|
||||
sid.voices[ch].freq = com->freq;
|
||||
sid.voices[ch].pwm = com->pwm;
|
||||
sid.voices[ch].attdec = com->attdec;
|
||||
sid.voices[ch].susrel = com->susrel;
|
||||
sid.voices[ch].ctrl = com->ctrl;
|
||||
|
||||
channels[ch].delay = com->time1;
|
||||
channels[ch].state = SIDFX_PLAY;
|
||||
}
|
||||
else
|
||||
channels[ch].state = SIDFX_IDLE;
|
||||
}
|
||||
break;
|
||||
case SIDFX_PLAY:
|
||||
{
|
||||
const SIDFX * com = channels[ch].com;
|
||||
if (com->dfreq)
|
||||
{
|
||||
channels[ch].freq += com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
channels[ch].delay = com->time0;
|
||||
channels[ch].state = SIDFX_PLAY;
|
||||
}
|
||||
if (com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
|
||||
if (channels[ch].delay)
|
||||
channels[ch].delay--;
|
||||
else if (com->time0)
|
||||
break;
|
||||
case SIDFX_PLAY:
|
||||
if (com->time0)
|
||||
{
|
||||
sid.voices[ch].ctrl = com->ctrl & ~SID_CTRL_GATE;
|
||||
channels[ch].delay = com->time0;
|
||||
channels[ch].delay = com->time0 - 1;
|
||||
channels[ch].state = SIDFX_WAIT;
|
||||
}
|
||||
else if (channels[ch].cnt)
|
||||
{
|
||||
char sr = com->susrel & 0xf0;
|
||||
com++;
|
||||
char ctrl = com->ctrl;
|
||||
if ((com->attdec & 0xef) == 0 && (ctrl & SID_CTRL_GATE) && (com->susrel & 0xf0) > sr)
|
||||
{
|
||||
sid.voices[ch].ctrl = ctrl & ~SID_CTRL_GATE;
|
||||
sid.voices[ch].ctrl = ctrl | SID_CTRL_GATE;
|
||||
}
|
||||
channels[ch].cnt--;
|
||||
channels[ch].com = com;
|
||||
channels[ch].priority = com->priority;
|
||||
|
@ -131,42 +162,30 @@ inline void sidfx_loop_ch(byte ch)
|
|||
}
|
||||
else
|
||||
{
|
||||
channels[ch].com = nullptr;
|
||||
com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SIDFX_WAIT:
|
||||
{
|
||||
const SIDFX * com = channels[ch].com;
|
||||
if (com->dfreq)
|
||||
{
|
||||
channels[ch].freq += com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
}
|
||||
if (com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
|
||||
if (channels[ch].delay)
|
||||
channels[ch].delay--;
|
||||
else if (channels[ch].cnt)
|
||||
break;
|
||||
case SIDFX_WAIT:
|
||||
if (channels[ch].cnt)
|
||||
{
|
||||
com++;
|
||||
channels[ch].cnt--;
|
||||
channels[ch].com = com;
|
||||
channels[ch].priority = com->priority;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
if (com->ctrl & SID_CTRL_GATE)
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
else
|
||||
channels[ch].state = SIDFX_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
channels[ch].com = nullptr;
|
||||
com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ inline void sidfx_play(byte chn, const SIDFX * fx, byte cnt);
|
|||
|
||||
void sidfx_stop(byte chn);
|
||||
|
||||
char sidfx_cnt(byte chn);
|
||||
|
||||
void sidfx_loop(void);
|
||||
|
||||
void sidfx_loop_2(void);
|
||||
|
|
|
@ -16,7 +16,7 @@ void cia_init(void)
|
|||
cia2.ddrb = 0x00;
|
||||
cia1.ddra = 0xff;
|
||||
|
||||
cia2.prb = 0x07;
|
||||
cia2.pra = 0x07;
|
||||
cia2.ddra = 0x3f;
|
||||
|
||||
char i0 = cia1.icr;
|
||||
|
|
|
@ -69,7 +69,7 @@ BANKINLINE bool krnio_open(char fnum, char device, char channel)
|
|||
{
|
||||
krnio_pstatus[fnum] = KRNIO_OK;
|
||||
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
lda #0
|
||||
sta accu
|
||||
|
@ -94,8 +94,7 @@ BANKINLINE bool krnio_open(char fnum, char device, char channel)
|
|||
|
||||
BANKOUT
|
||||
E2:
|
||||
};
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_open)
|
||||
|
@ -131,7 +130,7 @@ BANKINLINE krnioerr krnio_status(void)
|
|||
|
||||
BANKINLINE bool krnio_load(char fnum, char device, char channel)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
lda fnum
|
||||
|
@ -149,14 +148,14 @@ BANKINLINE bool krnio_load(char fnum, char device, char channel)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_load)
|
||||
|
||||
BANKINLINE bool krnio_save(char device, const char* start, const char* end)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
lda #0
|
||||
|
@ -175,14 +174,14 @@ BANKINLINE bool krnio_save(char device, const char* start, const char* end)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_save)
|
||||
|
||||
BANKINLINE bool krnio_chkout(char fnum)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
ldx fnum
|
||||
|
@ -193,14 +192,14 @@ BANKINLINE bool krnio_chkout(char fnum)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chkout)
|
||||
|
||||
BANKINLINE bool krnio_chkin(char fnum)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
ldx fnum
|
||||
|
@ -211,7 +210,7 @@ BANKINLINE bool krnio_chkin(char fnum)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chkin)
|
||||
|
@ -230,14 +229,14 @@ BANKINLINE void krnio_clrchn(void)
|
|||
|
||||
BANKINLINE bool krnio_chrout(char ch)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
lda ch
|
||||
jsr $ffd2 // chrout
|
||||
sta accu
|
||||
BANKOUT
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chrout)
|
||||
|
@ -422,7 +421,7 @@ int krnio_gets(char fnum, char * data, int num)
|
|||
|
||||
if (krnio_chkin(fnum))
|
||||
{
|
||||
krnioerr err;
|
||||
krnioerr err = KRNIO_OK;
|
||||
int i = 0;
|
||||
int ch;
|
||||
while (i + 1 < num)
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
#include <c64/asm6502.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
volatile char npos = 1, tpos = 0;
|
||||
volatile byte rirq_count;
|
||||
static byte rirq_pcount;
|
||||
|
||||
byte rasterIRQRows[NUM_IRQS + 1];
|
||||
byte rasterIRQIndex[NUM_IRQS + 1];
|
||||
byte rasterIRQIndex[NUM_IRQS + 1]; // Sort order of interrupt index, offset by one
|
||||
#ifdef ZPAGE_IRQS
|
||||
__zeropage
|
||||
#endif
|
||||
byte rasterIRQNext[NUM_IRQS + 1];
|
||||
byte rasterIRQLow[NUM_IRQS];
|
||||
byte rasterIRQNext[NUM_IRQS + 1]; // Rasterline of interrupt, terminated by 0xff
|
||||
byte rasterIRQLow[NUM_IRQS]; // Address of interrupt code
|
||||
byte rasterIRQHigh[NUM_IRQS];
|
||||
|
||||
#ifdef ZPAGE_IRQS
|
||||
|
@ -22,28 +22,25 @@ __zeropage
|
|||
#endif
|
||||
byte nextIRQ;
|
||||
|
||||
__asm irq0
|
||||
// nextIRQ is the index of the next expected IRQ, or $ff if no IRQ is scheduled
|
||||
|
||||
__asm rirq_isr_ram_io
|
||||
{
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
kentry:
|
||||
asl $d019
|
||||
stx plrx + 1
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
|
||||
sta plra + 1
|
||||
sty plry + 1
|
||||
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -51,21 +48,82 @@ ji:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e2
|
||||
// carry is cleared at this point
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
tay
|
||||
sbc #2
|
||||
cmp $d012
|
||||
bcc l1
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
plry:
|
||||
ldy #0
|
||||
plra:
|
||||
lda #0
|
||||
plrx:
|
||||
ldx #0
|
||||
rti
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp plrx
|
||||
|
||||
// No more interrupts to service
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq plry
|
||||
}
|
||||
|
||||
__asm rirq_isr_io
|
||||
{
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
kentry:
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
ldy rasterIRQIndex + 1, x
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
||||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
exd:
|
||||
dey
|
||||
ex:
|
||||
sty $d012
|
||||
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
|
@ -73,25 +131,22 @@ ex:
|
|||
pla
|
||||
rti
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
e2:
|
||||
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
tay
|
||||
|
||||
bit $d011
|
||||
bpl ex
|
||||
|
||||
e1:
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
ldy rasterIRQNext
|
||||
jmp exd
|
||||
|
||||
beq exd
|
||||
}
|
||||
|
||||
__asm irq2
|
||||
__asm rirq_isr_noio
|
||||
{
|
||||
pha
|
||||
txa
|
||||
|
@ -105,20 +160,15 @@ kentry:
|
|||
lda #$35
|
||||
sta $01
|
||||
|
||||
asl $d019
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -126,21 +176,20 @@ ji:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
// carry is cleared at this point
|
||||
|
||||
tay
|
||||
dey
|
||||
sbc #2
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
ex:
|
||||
|
||||
exd:
|
||||
pla
|
||||
sta $01
|
||||
|
||||
|
@ -151,45 +200,35 @@ ex:
|
|||
pla
|
||||
rti
|
||||
|
||||
e2:
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
ldx npos
|
||||
stx tpos
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
jmp ex
|
||||
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq exd
|
||||
}
|
||||
|
||||
__asm irq1
|
||||
__asm rirq_isr_kernal_io
|
||||
{
|
||||
lda $d019
|
||||
bpl ex2
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -198,45 +237,36 @@ jx:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e2
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
tay
|
||||
|
||||
sec
|
||||
sbc #4
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
w1:
|
||||
jmp ex
|
||||
|
||||
e2:
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
lda rasterIRQNext, x
|
||||
sec
|
||||
sbc #1
|
||||
sta $d012
|
||||
|
||||
ex:
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
exd:
|
||||
jmp $ea81
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp $ea81
|
||||
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
jmp $ea81
|
||||
|
||||
ex2:
|
||||
|
@ -245,7 +275,7 @@ ex2:
|
|||
jmp $ea31
|
||||
}
|
||||
|
||||
__asm irq3
|
||||
__asm rirq_isr_kernal_noio
|
||||
{
|
||||
lda $01
|
||||
pha
|
||||
|
@ -256,17 +286,14 @@ __asm irq3
|
|||
bpl ex2
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -275,49 +302,40 @@ jx:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
tay
|
||||
|
||||
sec
|
||||
sbc #4
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
w1:
|
||||
jmp ex
|
||||
|
||||
e2:
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
lda rasterIRQNext, x
|
||||
sec
|
||||
sbc #1
|
||||
sta $d012
|
||||
|
||||
ex:
|
||||
asl $d019
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
exd:
|
||||
pla
|
||||
sta $01
|
||||
|
||||
jmp $ea81
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq exd
|
||||
|
||||
ex2:
|
||||
LDA $DC0D
|
||||
cli
|
||||
|
@ -347,8 +365,8 @@ void rirq_build(RIRQCode * ic, byte size)
|
|||
ic->size = size;
|
||||
|
||||
asm_im(ic->code + 0, ASM_LDY, 0);
|
||||
asm_im(ic->code + 2, ASM_LDA, 0);
|
||||
asm_ab(ic->code + 4, ASM_CPX, 0xd012);
|
||||
asm_im(ic->code + 2, ASM_LDX, 0);
|
||||
asm_ab(ic->code + 4, ASM_CMP, 0xd012);
|
||||
asm_rl(ic->code + 7, ASM_BCS, -5);
|
||||
asm_ab(ic->code + 9, ASM_STY, 0x0000);
|
||||
|
||||
|
@ -362,7 +380,7 @@ void rirq_build(RIRQCode * ic, byte size)
|
|||
}
|
||||
else
|
||||
{
|
||||
asm_ab(ic->code + 12, ASM_STA, 0x0000);
|
||||
asm_ab(ic->code + 12, ASM_STX, 0x0000);
|
||||
|
||||
byte p = 15;
|
||||
for(byte i=2; i<size; i++)
|
||||
|
@ -421,7 +439,8 @@ void rirq_addrhi(RIRQCode * ic, byte n, byte hi)
|
|||
void rirq_data(RIRQCode * ic, byte n, byte data)
|
||||
{
|
||||
byte p = irqdi[n];
|
||||
ic->code[p] = data;
|
||||
// ic->code[p] = data;
|
||||
(volatile char *)(ic->code)[p] = data;
|
||||
}
|
||||
|
||||
void rirq_write(RIRQCode * ic, byte n, void * addr, byte data)
|
||||
|
@ -481,7 +500,7 @@ void rirq_init_kernal(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = irq1;
|
||||
*(void **)0x0314 = rirq_isr_kernal_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -489,7 +508,7 @@ void rirq_init_kernal(void)
|
|||
|
||||
}
|
||||
|
||||
void rirq_init_kernal_io(void)
|
||||
void rirq_init_kernal_noio(void)
|
||||
{
|
||||
rirq_init_tables();
|
||||
|
||||
|
@ -498,7 +517,7 @@ void rirq_init_kernal_io(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = irq3;
|
||||
*(void **)0x0314 = rirq_isr_kernal_noio;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -515,8 +534,8 @@ void rirq_init_crt(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = irq0.kentry;
|
||||
*(void **)0xfffe = irq0;
|
||||
*(void **)0x0314 = rirq_isr_io.kentry;
|
||||
*(void **)0xfffe = rirq_isr_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -524,7 +543,7 @@ void rirq_init_crt(void)
|
|||
|
||||
}
|
||||
|
||||
void rirq_init_crt_io(void)
|
||||
void rirq_init_crt_noio(void)
|
||||
{
|
||||
rirq_init_tables();
|
||||
|
||||
|
@ -533,8 +552,8 @@ void rirq_init_crt_io(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = irq2.kentry;
|
||||
*(void **)0xfffe = irq2;
|
||||
*(void **)0x0314 = rirq_isr_noio.kentry;
|
||||
*(void **)0xfffe = rirq_isr_noio;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -551,7 +570,7 @@ void rirq_init_io(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0xfffe = irq0;
|
||||
*(void **)0xfffe = rirq_isr_ram_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -568,7 +587,7 @@ void rirq_init_memmap(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0xfffe = irq2;
|
||||
*(void **)0xfffe = rirq_isr_noio;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -586,12 +605,18 @@ void rirq_init(bool kernalIRQ)
|
|||
|
||||
void rirq_wait(void)
|
||||
{
|
||||
while (tpos != npos) ;
|
||||
npos++;
|
||||
char i0 = rirq_pcount;
|
||||
char i1;
|
||||
do {
|
||||
i1 = rirq_count;
|
||||
} while (i0 == i1);
|
||||
rirq_pcount = i1;
|
||||
}
|
||||
|
||||
void rirq_sort(void)
|
||||
void rirq_sort(bool inirq)
|
||||
{
|
||||
// disable raster interrupts while sorting
|
||||
nextIRQ = 0xff;
|
||||
#if 1
|
||||
byte maxr = rasterIRQRows[rasterIRQIndex[1]];
|
||||
for(byte i = 2; i<NUM_IRQS + 1; i++)
|
||||
|
@ -639,10 +664,18 @@ void rirq_sort(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
npos++;
|
||||
byte yp = rasterIRQNext[nextIRQ];
|
||||
if (yp != 0xff)
|
||||
vic.raster = yp - 1;
|
||||
rirq_pcount = rirq_count;
|
||||
if (inirq)
|
||||
nextIRQ = NUM_IRQS - 1;
|
||||
else
|
||||
{
|
||||
byte yp = rasterIRQNext[0];
|
||||
if (yp != 0xff)
|
||||
{
|
||||
vic.raster = yp - 1;
|
||||
nextIRQ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rirq_start(void)
|
||||
|
@ -656,6 +689,7 @@ void rirq_start(void)
|
|||
lda #100
|
||||
sta $d012
|
||||
|
||||
asl $d019
|
||||
cli
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ void rirq_init_kernal(void);
|
|||
|
||||
// Raster IRQ through kernal, with IO range not always enabled
|
||||
// calls kernal continuation
|
||||
void rirq_init_kernal_io(void);
|
||||
void rirq_init_kernal_noio(void);
|
||||
|
||||
// Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range always enabled
|
||||
// does not call kernal continuation
|
||||
|
@ -162,7 +162,7 @@ void rirq_init_crt(void);
|
|||
|
||||
// Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range not always enabled
|
||||
// does not call kernal continuation
|
||||
void rirq_init_crt_io(void);
|
||||
void rirq_init_crt_noio(void);
|
||||
|
||||
// Raster IRQ through RAM vector, with ROM disabled and IO range always enabled
|
||||
// does not call kernal continuation
|
||||
|
@ -179,8 +179,9 @@ void rirq_start(void);
|
|||
void rirq_stop(void);
|
||||
|
||||
// Sort the raster IRQ, must be performed at the end of the frame after changing
|
||||
// the vertical position of one of the interrupt operatins.
|
||||
void rirq_sort(void);
|
||||
// the vertical position of one of the interrupt operations.
|
||||
// Set the inirq flag to true when calling this from an interrupt
|
||||
void rirq_sort(bool inirq = false);
|
||||
|
||||
// Wait for the last raster IRQ op to have completed. Must be called before a
|
||||
// sort if the raster IRQ system is active
|
||||
|
|
|
@ -171,6 +171,12 @@ void vspr_init(char * screen)
|
|||
}
|
||||
}
|
||||
|
||||
void vspr_shutdown(void)
|
||||
{
|
||||
for(int i=0; i<VSPRITES_MAX - 7; i++)
|
||||
rirq_clear(i);
|
||||
}
|
||||
|
||||
void vspr_screen(char * screen)
|
||||
{
|
||||
vspriteScreen = screen + 0x3f8;
|
||||
|
@ -309,6 +315,8 @@ void vspr_update(void)
|
|||
if (!done && spriteYPos[ti + 9] < 250)
|
||||
{
|
||||
byte ri = spriteOrder[ti + 8];
|
||||
rirq_move(ti, spriteYPos[ti + 1] + 23);
|
||||
|
||||
#ifdef VSPRITE_REVERSE
|
||||
char m = 0x80 >> (ti & 7);
|
||||
#else
|
||||
|
@ -325,7 +333,6 @@ void vspr_update(void)
|
|||
rirq_data(spirq + ti, 3, vspriteImage[ri]);
|
||||
|
||||
rirq_data(spirq + ti, 4, xymask);
|
||||
rirq_move(ti, spriteYPos[ti + 1] + 23);
|
||||
// spriteYPos[ti + 9] = vspriteYLow[ri];
|
||||
}
|
||||
else
|
||||
|
|
|
@ -68,6 +68,8 @@ inline void spr_expand(char sp, bool xexpand, bool yexpand);
|
|||
|
||||
void vspr_init(char * screen);
|
||||
|
||||
void vspr_shutdown(void);
|
||||
|
||||
void vspr_screen(char * screen);
|
||||
|
||||
// set one sprite with the given attribute
|
||||
|
|
|
@ -114,4 +114,21 @@ void vic_waitBelow(int line)
|
|||
}
|
||||
}
|
||||
|
||||
void vic_waitRange(char below, char above)
|
||||
{
|
||||
while (vic.ctrl1 & VIC_CTRL1_RST8)
|
||||
;
|
||||
|
||||
if (vic.raster >= above)
|
||||
{
|
||||
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
|
||||
;
|
||||
while (vic.ctrl1 & VIC_CTRL1_RST8)
|
||||
;
|
||||
}
|
||||
|
||||
while (vic.raster < below)
|
||||
;
|
||||
}
|
||||
|
||||
#pragma native(vic_waitLine)
|
||||
|
|
|
@ -118,6 +118,9 @@ void vic_waitLine(int line);
|
|||
// wait for beam to be below a line
|
||||
void vic_waitBelow(int line);
|
||||
|
||||
// wait for beam to be in a given range on screen
|
||||
void vic_waitRange(char below, char above);
|
||||
|
||||
// reference to the VIC chip
|
||||
#define vic (*((struct VIC *)0xd000))
|
||||
|
||||
|
|
|
@ -131,6 +131,18 @@ __asm bsinit
|
|||
lda #147
|
||||
jmp $ffd2
|
||||
}
|
||||
#elif defined(__CBMPET__)
|
||||
#define bsout 0xffd2
|
||||
#define bsin 0xffe4
|
||||
__asm bsplot
|
||||
{
|
||||
/* no equivalent on PET */
|
||||
}
|
||||
__asm bsinit
|
||||
{
|
||||
/* no equivalent on PET */
|
||||
}
|
||||
#define bsget 0xffcf
|
||||
#else
|
||||
#define bsout 0xffd2
|
||||
#define bsin 0xffe4
|
||||
|
@ -212,11 +224,10 @@ void putpch(char c)
|
|||
c ^= 0xa0;
|
||||
c ^= 0x20;
|
||||
#else
|
||||
if (c >= 97)
|
||||
c ^= 0x20;
|
||||
c ^= 0x20;
|
||||
#endif
|
||||
|
||||
if (giocharmap == IOCHM_PETSCII_2)
|
||||
if (giocharmap == IOCHM_PETSCII_1)
|
||||
c &= 0xdf;
|
||||
}
|
||||
}
|
||||
|
@ -268,11 +279,19 @@ char getpch(void)
|
|||
|
||||
char kbhit(void)
|
||||
{
|
||||
#if defined(__CBMPET__)
|
||||
return __asm
|
||||
{
|
||||
lda $9e
|
||||
sta accu
|
||||
};
|
||||
#else
|
||||
return __asm
|
||||
{
|
||||
lda $c6
|
||||
sta accu
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
char getche(void)
|
||||
|
@ -323,10 +342,7 @@ void putch(char c)
|
|||
|
||||
void clrscr(void)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
jsr bsinit
|
||||
}
|
||||
putrch(147);
|
||||
}
|
||||
|
||||
void textcursor(bool show)
|
||||
|
@ -336,6 +352,24 @@ void textcursor(bool show)
|
|||
|
||||
void gotoxy(char cx, char cy)
|
||||
{
|
||||
#if defined(__CBMPET__)
|
||||
#define CURS_X 0xc6
|
||||
#define CURS_Y 0xd8
|
||||
#define SCREEN_PTR 0xc4
|
||||
#define SCR_LINELEN 0xd5
|
||||
|
||||
__assume(cy < 25);
|
||||
|
||||
*(volatile char *)CURS_X = cx;
|
||||
*(volatile char *)CURS_Y = cy;
|
||||
|
||||
if (*(volatile char *)SCR_LINELEN > 40)
|
||||
cy <<= 1;
|
||||
|
||||
const unsigned off = cy * 40;
|
||||
|
||||
* (volatile unsigned *)SCREEN_PTR = off + 0x8000;
|
||||
#else
|
||||
__asm
|
||||
{
|
||||
ldx cy
|
||||
|
@ -343,6 +377,7 @@ void gotoxy(char cx, char cy)
|
|||
clc
|
||||
jsr bsplot
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void textcolor(char c)
|
||||
|
@ -350,6 +385,24 @@ void textcolor(char c)
|
|||
*(volatile char *)0x0286 = c;
|
||||
}
|
||||
|
||||
void bgcolor(char c)
|
||||
{
|
||||
*(volatile char *)0xd021 = c;
|
||||
}
|
||||
|
||||
void bordercolor(char c)
|
||||
{
|
||||
*(volatile char *)0xd020 = c;
|
||||
}
|
||||
|
||||
void revers(char r)
|
||||
{
|
||||
if (r)
|
||||
putrch(18);
|
||||
else
|
||||
putrch(18 + 128);
|
||||
}
|
||||
|
||||
char wherex(void)
|
||||
{
|
||||
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__)
|
||||
|
|
|
@ -43,6 +43,26 @@ void dispmode80col(void);
|
|||
#define PETSCII_F7 0x88
|
||||
#define PETSCII_F8 0x8c
|
||||
|
||||
enum ConioColors
|
||||
{
|
||||
COLOR_BLACK,
|
||||
COLOR_WHITE,
|
||||
COLOR_RED,
|
||||
COLOR_CYAN,
|
||||
COLOR_PURPLE,
|
||||
COLOR_GREEN,
|
||||
COLOR_BLUE,
|
||||
COLOR_YELLOW,
|
||||
|
||||
COLOR_ORANGE,
|
||||
COLOR_BROWN,
|
||||
COLOR_LT_RED,
|
||||
COLOR_DARK_GREY,
|
||||
COLOR_MED_GREY,
|
||||
COLOR_LT_GREEN,
|
||||
COLOR_LT_BLUE,
|
||||
COLOR_LT_GREY
|
||||
};
|
||||
// Lowlevel console in/out
|
||||
|
||||
// using petscii translation
|
||||
|
@ -74,6 +94,12 @@ void gotoxy(char x, char y);
|
|||
|
||||
inline void textcolor(char c);
|
||||
|
||||
inline void bgcolor(char c);
|
||||
|
||||
inline void bordercolor(char c);
|
||||
|
||||
inline void revers(char r);
|
||||
|
||||
inline char wherex(void);
|
||||
|
||||
inline char wherey(void);
|
||||
|
|
118
include/crt.c
118
include/crt.c
|
@ -236,46 +236,40 @@ w0:
|
|||
// Clear BSS Segment
|
||||
|
||||
#ifndef NOBSSCLEAR
|
||||
lda #<BSSStart
|
||||
sta ip
|
||||
lda #>BSSStart
|
||||
sta ip + 1
|
||||
ldx #>BSSStart
|
||||
ldy #<BSSStart
|
||||
|
||||
sec
|
||||
lda #>BSSEnd
|
||||
sbc #>BSSStart
|
||||
beq w1
|
||||
tax
|
||||
lda #0
|
||||
ldy #0
|
||||
l1: sta (ip), y
|
||||
sta ip
|
||||
l3:
|
||||
stx ip + 1
|
||||
cpx #>BSSEnd
|
||||
beq w2
|
||||
l1:
|
||||
sta (ip), y
|
||||
iny
|
||||
bne l1
|
||||
inc ip + 1
|
||||
dex
|
||||
bne l1
|
||||
w1:
|
||||
sec
|
||||
lda #<BSSEnd
|
||||
sbc #<BSSStart
|
||||
beq w2
|
||||
tay
|
||||
lda #0
|
||||
l2: dey
|
||||
sta (ip), y
|
||||
bne l2
|
||||
w2:
|
||||
#endif
|
||||
#ifndef NOZPCLEAR
|
||||
ldx #<ZeroStart
|
||||
cpx #<ZeroEnd
|
||||
beq w3
|
||||
l3: sta $00, x
|
||||
inx
|
||||
cpx #<ZeroEnd
|
||||
bne l3
|
||||
w3:
|
||||
bne l3
|
||||
l2:
|
||||
sta (ip), y
|
||||
iny
|
||||
w2:
|
||||
cpy #<BSSEnd
|
||||
bne l2
|
||||
#endif
|
||||
|
||||
#ifndef NOZPCLEAR
|
||||
lda #0
|
||||
ldx #<ZeroStart
|
||||
bne w3
|
||||
l4: sta $00, x
|
||||
inx
|
||||
w3:
|
||||
cpx #<ZeroEnd
|
||||
bne l4
|
||||
#endif
|
||||
|
||||
lda #<StackEnd - 2
|
||||
sta sp
|
||||
lda #>StackEnd - 2
|
||||
|
@ -673,21 +667,19 @@ L1: rol accu
|
|||
sbc tmp + 1
|
||||
lda tmp + 6
|
||||
sbc tmp + 2
|
||||
tax
|
||||
lda tmp + 7
|
||||
sbc tmp + 3
|
||||
bcc W1
|
||||
stx tmp + 6
|
||||
sta tmp + 7
|
||||
lda tmp + 4
|
||||
sbc tmp + 0
|
||||
sta tmp + 4
|
||||
lda tmp + 5
|
||||
sbc tmp + 1
|
||||
sta tmp + 5
|
||||
lda tmp + 6
|
||||
sbc tmp + 2
|
||||
sta tmp + 6
|
||||
lda tmp + 7
|
||||
sbc tmp + 3
|
||||
sta tmp + 7
|
||||
sec
|
||||
W1: dey
|
||||
bne L1
|
||||
rol accu
|
||||
|
@ -764,6 +756,11 @@ __asm mul32
|
|||
sta tmp + 6
|
||||
sta tmp + 7
|
||||
|
||||
lda tmp + 3
|
||||
ora tmp + 2
|
||||
ora tmp + 1
|
||||
beq WB
|
||||
|
||||
lda tmp + 0
|
||||
jsr WM
|
||||
lda tmp + 1
|
||||
|
@ -781,6 +778,7 @@ WM:
|
|||
stx accu + 1
|
||||
sta accu
|
||||
rts
|
||||
WB: lda tmp + 0
|
||||
W0:
|
||||
sec
|
||||
ror
|
||||
|
@ -3078,7 +3076,7 @@ __asm inp_binop_sub_f32
|
|||
|
||||
#pragma bytecode(BC_BINOP_SUB_F32, inp_binop_sub_f32)
|
||||
|
||||
__asm fmul8
|
||||
__asm crt_fmul8
|
||||
{
|
||||
sec
|
||||
ror
|
||||
|
@ -3112,7 +3110,7 @@ W1:
|
|||
rts
|
||||
}
|
||||
|
||||
__asm fmul
|
||||
__asm crt_fmul
|
||||
{
|
||||
lda accu
|
||||
ora accu + 1
|
||||
|
@ -3153,13 +3151,13 @@ W2:
|
|||
beq W5
|
||||
bne W6
|
||||
W4:
|
||||
jsr fmul8
|
||||
jsr crt_fmul8
|
||||
lda tmp + 1
|
||||
W6:
|
||||
jsr fmul8
|
||||
jsr crt_fmul8
|
||||
W5:
|
||||
lda tmp + 2
|
||||
jsr fmul8
|
||||
jsr crt_fmul8
|
||||
|
||||
sec
|
||||
lda tmp + 8
|
||||
|
@ -3216,12 +3214,12 @@ __asm inp_binop_mul_f32
|
|||
{
|
||||
jsr freg.split_exp
|
||||
sty tmpy
|
||||
jsr fmul
|
||||
jsr crt_fmul
|
||||
ldy tmpy
|
||||
jmp startup.exec
|
||||
}
|
||||
|
||||
__asm fdiv
|
||||
__asm crt_fdiv
|
||||
{
|
||||
lda accu
|
||||
ora accu + 1
|
||||
|
@ -3343,13 +3341,13 @@ ZERO:
|
|||
__asm inp_binop_div_f32
|
||||
{
|
||||
jsr freg.split_exp
|
||||
jsr fdiv
|
||||
jsr crt_fdiv
|
||||
jmp startup.exec
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_BINOP_DIV_F32, inp_binop_div_f32)
|
||||
|
||||
__asm fcmp
|
||||
__asm crt_fcmp
|
||||
{
|
||||
lda accu + 3
|
||||
eor tmp + 3
|
||||
|
@ -4064,9 +4062,9 @@ __asm load32
|
|||
#pragma runtime(fmergea, freg.merge_aexp)
|
||||
#pragma runtime(fadd, faddsub.fadd)
|
||||
#pragma runtime(fsub, faddsub.fsub)
|
||||
#pragma runtime(fmul, fmul)
|
||||
#pragma runtime(fdiv, fdiv)
|
||||
#pragma runtime(fcmp, fcmp)
|
||||
#pragma runtime(fmul, crt_fmul)
|
||||
#pragma runtime(fdiv, crt_fdiv)
|
||||
#pragma runtime(fcmp, crt_fcmp)
|
||||
#pragma runtime(ffromi, sint16_to_float)
|
||||
#pragma runtime(ffromu, uint16_to_float)
|
||||
#pragma runtime(ftoi, f32_to_i16)
|
||||
|
@ -4564,7 +4562,7 @@ struct Heap {
|
|||
|
||||
#pragma section(heap, 0x0000, HeapStart, HeapEnd)
|
||||
|
||||
__asm malloc
|
||||
__asm crt_malloc
|
||||
{
|
||||
// make room for two additional bytes
|
||||
// to store pointer to end of used memory
|
||||
|
@ -4791,14 +4789,14 @@ hc2:
|
|||
__asm inp_malloc
|
||||
{
|
||||
sty tmpy
|
||||
jsr malloc
|
||||
jsr crt_malloc
|
||||
ldy tmpy
|
||||
jmp startup.exec
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_MALLOC, inp_malloc)
|
||||
|
||||
__asm free
|
||||
__asm crt_free
|
||||
{
|
||||
|
||||
// check nullptr free
|
||||
|
@ -5015,21 +5013,21 @@ nostart:
|
|||
__asm inp_free
|
||||
{
|
||||
sty tmpy
|
||||
jsr free
|
||||
jsr crt_free
|
||||
ldy tmpy
|
||||
jmp startup.exec
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_FREE, inp_free)
|
||||
|
||||
__asm breakpoint
|
||||
__asm crt_breakpoint
|
||||
{
|
||||
rts
|
||||
}
|
||||
|
||||
#pragma runtime(malloc, malloc)
|
||||
#pragma runtime(free, free)
|
||||
#pragma runtime(breakpoint, breakpoint)
|
||||
#pragma runtime(malloc, crt_malloc)
|
||||
#pragma runtime(free, crt_free)
|
||||
#pragma runtime(breakpoint, crt_breakpoint)
|
||||
|
||||
#if 0
|
||||
|
||||
|
|
|
@ -123,8 +123,9 @@ int lmul4f12s(int x, int y)
|
|||
|
||||
lda #0
|
||||
sta accu + 1
|
||||
L2:
|
||||
|
||||
bcc W4
|
||||
L2:
|
||||
tay
|
||||
clc
|
||||
lda accu + 1
|
||||
|
@ -165,7 +166,7 @@ W1:
|
|||
bcc W2
|
||||
|
||||
tay
|
||||
sec
|
||||
// sec ; we know it is set here
|
||||
lda accu + 1
|
||||
sbc y
|
||||
sta accu + 1
|
||||
|
|
|
@ -525,7 +525,7 @@ void bm_polygon_nc_fill(const Bitmap * bm, const ClipRect * clip, int * px, int
|
|||
static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up, char pattern, LineOp op)
|
||||
{
|
||||
char ip = 0;
|
||||
bool delta16 = ((dx | dy) & 0xff80) != 0;
|
||||
bool delta16 =((dx | dy) & 0xff80) != 0;
|
||||
|
||||
// ylow
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_LDY, ly);
|
||||
|
@ -579,82 +579,105 @@ static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool
|
|||
break;
|
||||
}
|
||||
|
||||
if (dx && dy)
|
||||
{
|
||||
// m >= 0
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + delta16);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BMI, delta16 ? 5 + 15 + 13 + 2 : 5 + 15 + 7 + 2);
|
||||
}
|
||||
|
||||
if (dy)
|
||||
{
|
||||
ip += asm_np(BLIT_CODE + ip, up ? ASM_DEY : ASM_INY);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_CPY, up ? 0xff : 0x08);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, 15);
|
||||
bool delta8 = false;
|
||||
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_LDY, up ? 0x07 : 0x00);
|
||||
}
|
||||
|
||||
if (dx && dy)
|
||||
{
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_SEC);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
|
||||
if (delta16)
|
||||
if (dx)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
|
||||
// m >= 0
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + delta16);
|
||||
char n = delta16 ? 18 + 13 + 2 : 18 + 7 + 2;
|
||||
if (!up) n++;
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BMI, n);
|
||||
delta8 = !delta16;
|
||||
}
|
||||
|
||||
if (up)
|
||||
{
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_DEY);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta8 ? 17 : 15);
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x07);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_INY);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_CPY, 0x08);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, delta8 ? 16 : 14);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x00);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
|
||||
}
|
||||
|
||||
if (dx)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_SEC);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
|
||||
if (delta16)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 13 + 4 + 12);
|
||||
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We know regdp to be in the accu at this point
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 5 + 4 + 12);
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
}
|
||||
}
|
||||
|
||||
// m < 0
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta16 ? 4 + 13 + 13 : 4 + 13 + 7);
|
||||
}
|
||||
|
||||
if (dx)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ASL : ASM_LSR, REG_D0);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 13);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 12);
|
||||
|
||||
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ROL : ASM_ROR, REG_D0);
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, left ? 0xf8 : 0x08);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
|
||||
if (left)
|
||||
{
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, 0xf8);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCS, 2);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_DEC, REG_SP + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, 0x08);
|
||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 2);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_SP + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (dx && dy)
|
||||
{
|
||||
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
|
||||
if (delta16)
|
||||
{
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8);
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
|
||||
}
|
||||
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||
}
|
||||
|
||||
// l --
|
||||
|
|
|
@ -110,12 +110,12 @@ float atan2(float p, float q)
|
|||
return s;
|
||||
}
|
||||
|
||||
#define F_EXP_0 1.0000003
|
||||
#define F_EXP_1 0.693147059
|
||||
#define F_EXP_2 0.240173099
|
||||
#define F_EXP_3 0.055816392
|
||||
#define F_EXP_4 0.008965036
|
||||
#define F_EXP_5 0.001898429
|
||||
#define F_EXP_0 1.0
|
||||
#define F_EXP_1 0.69315668
|
||||
#define F_EXP_2 0.240132068
|
||||
#define F_EXP_3 0.055876024
|
||||
#define F_EXP_4 0.008940801
|
||||
#define F_EXP_5 0.001894414
|
||||
|
||||
float exp(float f)
|
||||
{
|
||||
|
@ -143,12 +143,12 @@ float exp(float f)
|
|||
return s * x.f;
|
||||
}
|
||||
|
||||
#define F_LOG_0 -3.78712618
|
||||
#define F_LOG_1 10.0957081
|
||||
#define F_LOG_2 -13.9747486
|
||||
#define F_LOG_3 12.7568806
|
||||
#define F_LOG_4 -6.48114552
|
||||
#define F_LOG_5 1.39045416
|
||||
#define F_LOG_0 -3.78717706
|
||||
#define F_LOG_1 10.0960498
|
||||
#define F_LOG_2 -13.975654
|
||||
#define F_LOG_3 12.7580616
|
||||
#define F_LOG_4 -6.48190725
|
||||
#define F_LOG_5 1.39064767
|
||||
|
||||
float log(float f)
|
||||
{
|
||||
|
|
|
@ -33,10 +33,15 @@ bool isfinite(float f);
|
|||
#pragma intrinsic(sin)
|
||||
#pragma intrinsic(cos)
|
||||
#pragma intrinsic(tan)
|
||||
#pragma intrinsic(atan)
|
||||
#pragma intrinsic(atan2)
|
||||
|
||||
#pragma intrinsic(log)
|
||||
#pragma intrinsic(exp)
|
||||
|
||||
#pragma intrinsic(pow)
|
||||
#pragma intrinsic(sqrt)
|
||||
|
||||
#pragma compile("math.c")
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef OPP_BOUNDINT_H
|
||||
#define OPP_BOUNDINT_H
|
||||
|
||||
namespace opp {
|
||||
|
||||
template<int tmin, int tmax>
|
||||
constexpr auto boundinttype(void)
|
||||
{
|
||||
if constexpr (tmin >= 0 && tmax <= 255)
|
||||
return (char)0;
|
||||
else if constexpr (tmin >= -128 && tmax <= 127)
|
||||
return (signed char)0;
|
||||
else
|
||||
return (int)0;
|
||||
}
|
||||
|
||||
template<int tmin, int tmax>
|
||||
class boundint
|
||||
{
|
||||
protected:
|
||||
decltype(boundinttype<tmin, tmax>()) v;
|
||||
public:
|
||||
boundint(int i)
|
||||
: v(i)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void operator=(int k)
|
||||
{
|
||||
__assume(k >= tmin && k <= tmax);
|
||||
v = k;
|
||||
}
|
||||
|
||||
void operator+=(int k)
|
||||
{
|
||||
k += v;
|
||||
__assume(k >= tmin && k <= tmax);
|
||||
v = k;
|
||||
}
|
||||
|
||||
void operator-=(int k)
|
||||
{
|
||||
k = v - k;
|
||||
__assume(k >= tmin && k <= tmax);
|
||||
v = k;
|
||||
}
|
||||
|
||||
operator int() const
|
||||
{
|
||||
int k = v;
|
||||
__assume(k >= tmin && k <= tmax);
|
||||
return k;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -37,7 +37,7 @@ public:
|
|||
showpos = 0x0800,
|
||||
skipws = 0x1000,
|
||||
unitbuf = 0x2000,
|
||||
uppercase = 0x3000,
|
||||
uppercase = 0x4000,
|
||||
|
||||
adjustfield = 0x00b0,
|
||||
basefield = 0x004a,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <opp/utility.h>
|
||||
#include <oscar.h>
|
||||
|
||||
namespace opp {
|
||||
|
||||
|
@ -11,8 +12,8 @@ template <class T, int N>
|
|||
class static_vector
|
||||
{
|
||||
protected:
|
||||
char _space[N * sizeof(T)];
|
||||
enum { m = N } _size;
|
||||
char _space[N * sizeof(T)];
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
|
@ -20,23 +21,28 @@ public:
|
|||
|
||||
static_vector(size_t n) : _size(n)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (n > N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i) T;
|
||||
new (data + i) T();
|
||||
}
|
||||
|
||||
static_vector(const static_vector & v)
|
||||
: _size(v._size)
|
||||
{
|
||||
size_t n = _size;
|
||||
T * data = (T*)_space, * vdata = (T*)(v._space);
|
||||
for(size_t i=0; i<_size; i++)
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i)T(vdata[i]);
|
||||
}
|
||||
|
||||
~static_vector(void)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
data[i].~T();
|
||||
}
|
||||
|
||||
|
@ -45,10 +51,12 @@ public:
|
|||
if (this != &v)
|
||||
{
|
||||
T * data = (T*)_space, * vdata = (T*)(v._space);
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
data[i].~T();
|
||||
_size = v._size;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i)T(vdata[i]);
|
||||
}
|
||||
return *this;
|
||||
|
@ -69,6 +77,11 @@ public:
|
|||
return _size == 0;
|
||||
}
|
||||
|
||||
bool full(void) const
|
||||
{
|
||||
return _size == N;
|
||||
}
|
||||
|
||||
size_t capacity(void) const
|
||||
{
|
||||
return N;
|
||||
|
@ -76,6 +89,8 @@ public:
|
|||
|
||||
void resize(size_t n);
|
||||
|
||||
void clear(void);
|
||||
|
||||
T & at(size_t at)
|
||||
{
|
||||
return ((T*)_space)[at];
|
||||
|
@ -166,6 +181,8 @@ public:
|
|||
((T*)_space)[_size].~T();
|
||||
}
|
||||
|
||||
void assign(size_t count, const T & t);
|
||||
|
||||
void insert(size_t at, const T & t);
|
||||
|
||||
void erase(size_t at, size_t n = 1);
|
||||
|
@ -177,34 +194,50 @@ public:
|
|||
};
|
||||
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::clear(void)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
data[i].~T();
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::resize(size_t n)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (n > N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
if (n < _size)
|
||||
{
|
||||
for(size_t i=n; i<_size; i++)
|
||||
data[i].~T();
|
||||
_size = n;
|
||||
}
|
||||
else
|
||||
else if (n > 0)
|
||||
{
|
||||
for(size_t i=_size; i<n; i++)
|
||||
new(data + i)T;
|
||||
_size = n;
|
||||
new(data + i)T();
|
||||
}
|
||||
_size = n;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::push_back(const T & t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(t);
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::push_back(T && t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(t);
|
||||
}
|
||||
|
||||
|
@ -212,14 +245,28 @@ template <class T, int N>
|
|||
template <typename ...P>
|
||||
void static_vector<T, N>::emplace_back(const P&... p)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(p...);
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::assign(size_t count, const T & t)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
data[i].~T();
|
||||
for(size_t i=0; i<count; i++)
|
||||
new (data + i)T(t);
|
||||
_size = count;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::insert(size_t at, const T & t)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
new (data + _size)T;
|
||||
new (data + _size)T();
|
||||
for(size_t i=_size; i>at; i--)
|
||||
data[i] = move(data[i - 1]);
|
||||
data[at] = t;
|
||||
|
@ -240,9 +287,12 @@ void static_vector<T, N>::erase(size_t at, size_t n)
|
|||
template <class T, int N>
|
||||
T * static_vector<T, N>::insert(T * at, const T & t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
T * dp = data + _size;
|
||||
new (dp)T;
|
||||
new (dp)T();
|
||||
while (dp != at)
|
||||
{
|
||||
dp--;
|
||||
|
|
|
@ -21,13 +21,14 @@ public:
|
|||
vector(size_t n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
|
||||
{
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (_data + i) T;
|
||||
new (_data + i) T();
|
||||
}
|
||||
|
||||
vector(const vector & v)
|
||||
: _data((T*)malloc(v._size * sizeof(T))), _size(v._size), _capacity(v._size)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (_data + i)T(v._data[i]);
|
||||
}
|
||||
|
||||
|
@ -50,14 +51,16 @@ public:
|
|||
{
|
||||
if (this != &v)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
_data[i].~T();
|
||||
free(_data);
|
||||
|
||||
_data = (T*)malloc(v._size * sizeof(T));
|
||||
_size = v._size;
|
||||
_capacity = v._size;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (_data + i)T(v._data[i]);
|
||||
}
|
||||
return *this;
|
||||
|
@ -94,6 +97,8 @@ public:
|
|||
return _capacity;
|
||||
}
|
||||
|
||||
void clear(void);
|
||||
|
||||
void resize(size_t n);
|
||||
|
||||
void reserve(size_t n);
|
||||
|
@ -190,6 +195,8 @@ public:
|
|||
_data[_size].~T();
|
||||
}
|
||||
|
||||
void assign(size_t count, const T & t);
|
||||
|
||||
void insert(size_t at, const T & t);
|
||||
|
||||
void erase(size_t at, size_t n = 1);
|
||||
|
@ -204,7 +211,7 @@ protected:
|
|||
|
||||
|
||||
template <class T>
|
||||
void vector<T>::reserve(size_t n)
|
||||
__noinline void vector<T>::reserve(size_t n)
|
||||
{
|
||||
if (n > _capacity)
|
||||
{
|
||||
|
@ -221,7 +228,15 @@ void vector<T>::reserve(size_t n)
|
|||
}
|
||||
|
||||
template <class T>
|
||||
void vector<T>::resize(size_t n)
|
||||
void vector<T>::clear(void)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
_data[i].~T();
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
__noinline void vector<T>::resize(size_t n)
|
||||
{
|
||||
if (n < _size)
|
||||
{
|
||||
|
@ -232,7 +247,7 @@ void vector<T>::resize(size_t n)
|
|||
else if (n < _capacity)
|
||||
{
|
||||
for(size_t i=_size; i<n; i++)
|
||||
new(_data + i)T;
|
||||
new(_data + i)T();
|
||||
_size = n;
|
||||
}
|
||||
else
|
||||
|
@ -286,12 +301,27 @@ void vector<T>::emplace_back(const P&... p)
|
|||
new (add_back())T(p...);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void vector<T>::assign(size_t count, const T & t)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
_data[i].~T();
|
||||
if (count > _capacity)
|
||||
{
|
||||
_size = 0;
|
||||
reserve(count);
|
||||
}
|
||||
for(size_t i=0; i<count; i++)
|
||||
new (_data + i)T(t);
|
||||
_size = count;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void vector<T>::insert(size_t at, const T & t)
|
||||
{
|
||||
if (_size == _capacity)
|
||||
reserve(_size + 1 + (_size >> 1));
|
||||
new (_data + _size)T;
|
||||
new (_data + _size)T();
|
||||
for(size_t i=_size; i>at; i--)
|
||||
_data[i] = move(_data[i - 1]);
|
||||
_data[at] = t;
|
||||
|
@ -318,7 +348,7 @@ T * vector<T>::insert(T * at, const T & t)
|
|||
at = (T *)(f + unsigned(_data));
|
||||
}
|
||||
T * dp = _data + _size;
|
||||
new (dp)T;
|
||||
new (dp)T();
|
||||
while (dp != at)
|
||||
{
|
||||
dp--;
|
||||
|
|
|
@ -129,3 +129,10 @@ __native const char * oscar_expand_lzo_buf(char * dp, const char * sp)
|
|||
|
||||
return sp + 1;
|
||||
}
|
||||
|
||||
void debugcrash(void)
|
||||
{
|
||||
__asm volatile {
|
||||
byt $02
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ void breakpoint(void);
|
|||
|
||||
#pragma intrinsic(breakpoint)
|
||||
|
||||
void debugcrash(void);
|
||||
|
||||
#pragma compile("oscar.c")
|
||||
|
||||
#endif
|
||||
|
|
|
@ -417,7 +417,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
|
|||
si.precision = i;
|
||||
}
|
||||
|
||||
if (c == 'd' || c == p'd')
|
||||
if (c == 'd' || c == p'd' || c == 'i' || c == p'i')
|
||||
{
|
||||
bi = nformi(&si, bp, *fps++, true);
|
||||
}
|
||||
|
@ -556,6 +556,17 @@ int sprintf(char * str, const char * fmt, ...)
|
|||
return d - str;
|
||||
}
|
||||
|
||||
void vprintf(const char * fmt, va_list vlist)
|
||||
{
|
||||
char buff[50];
|
||||
sformat(buff, fmt, (int *)vlist, true);
|
||||
}
|
||||
|
||||
int vsprintf(char * str, const char * fmt, va_list vlist)
|
||||
{
|
||||
char * d = sformat(str, fmt, (int *)vlist, false);
|
||||
return d - str;
|
||||
}
|
||||
|
||||
static inline bool isspace(char c)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void putchar(char c);
|
||||
|
||||
|
@ -18,6 +19,10 @@ void printf(const char * fmt, ...);
|
|||
|
||||
int sprintf(char * str, const char * fmt, ...);
|
||||
|
||||
void vprintf(const char * fmt, va_list vlist);
|
||||
|
||||
int vsprintf(char * str, const char * fmt, va_list vlist);
|
||||
|
||||
int scanf(const char * fmt, ...);
|
||||
|
||||
int sscanf(const char * str, const char * fmt, ...);
|
||||
|
|
|
@ -544,7 +544,7 @@ unsigned heapfree(void)
|
|||
}
|
||||
|
||||
#if 0
|
||||
struct Heap {
|
||||
struct Heap {q
|
||||
unsigned int size;
|
||||
Heap * next;
|
||||
} * freeHeap;
|
||||
|
@ -667,6 +667,97 @@ void * calloc(int num, int size)
|
|||
return p;
|
||||
}
|
||||
|
||||
void * realloc(void * ptr, unsigned size)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
#ifdef HEAPCHECK
|
||||
Heap * pheap = (Heap *)((char *)ptr - 6);
|
||||
Heap * eheap = pheap->next;
|
||||
|
||||
unsigned psize = (char *)eheap - (char *)pheap;
|
||||
|
||||
void * nptr = malloc(size);
|
||||
memcpy(nptr, ptr, psize - 6);
|
||||
free(ptr);
|
||||
return nptr;
|
||||
#else
|
||||
unsigned nsize = (size + 5) & ~3;
|
||||
|
||||
// Get heap info
|
||||
Heap * pheap = (Heap *)((char *)ptr - 2);
|
||||
Heap * eheap = pheap->next;
|
||||
|
||||
unsigned psize = (char *)eheap - (char *)pheap;
|
||||
|
||||
Heap * h = HeapNode.next;
|
||||
Heap * hp = &HeapNode;
|
||||
while (h && h < pheap)
|
||||
{
|
||||
hp = h;
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
if (nsize <= psize)
|
||||
{
|
||||
// check if we should free some memory
|
||||
if (nsize + sizeof(HeapNode) < psize)
|
||||
{
|
||||
Heap * nheap = (Heap *)((char *)pheap + nsize);
|
||||
pheap->next = nheap;
|
||||
|
||||
if (h == eheap)
|
||||
{
|
||||
nheap->end = h->end;
|
||||
nheap->next = h->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
nheap->end = eheap;
|
||||
nheap->next = h;
|
||||
}
|
||||
|
||||
hp->next = nheap;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
else if (h == eheap)
|
||||
{
|
||||
// Free space after this
|
||||
|
||||
// Check if enough space if extending
|
||||
unsigned xsize = (char *)h->end - (char *)pheap;
|
||||
if (xsize >= nsize)
|
||||
{
|
||||
if (xsize > nsize + sizeof(HeapNode))
|
||||
{
|
||||
Heap * nheap = (Heap *)((char *)pheap + nsize);
|
||||
pheap->next = nheap;
|
||||
nheap->end = h->end;
|
||||
nheap->next = h->next;
|
||||
hp->next = nheap;
|
||||
}
|
||||
else
|
||||
{
|
||||
pheap->next = h->end;
|
||||
hp->next = h->next;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void * nptr = malloc(size);
|
||||
memcpy(nptr, ptr, psize - 2);
|
||||
free(ptr);
|
||||
return nptr;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static unsigned seed = 31232;
|
||||
|
||||
unsigned int rand(void)
|
||||
|
|
|
@ -45,6 +45,8 @@ void free(void * ptr);
|
|||
|
||||
void * calloc(int num, int size);
|
||||
|
||||
void * realloc(void * ptr, unsigned size);
|
||||
|
||||
unsigned heapfree(void);
|
||||
|
||||
unsigned int rand(void);
|
||||
|
|
|
@ -138,6 +138,20 @@ char * cpycat(char * dst, const char * src)
|
|||
|
||||
#pragma native(cpycat)
|
||||
|
||||
char* strchr( const char* str, int ch )
|
||||
{
|
||||
char * p = (char *)str;
|
||||
|
||||
while (*p != (char)ch)
|
||||
{
|
||||
if (!*p)
|
||||
return nullptr;
|
||||
p++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
void * memset(void * dst, int value, int size)
|
||||
{
|
||||
__asm
|
||||
|
|
|
@ -21,6 +21,8 @@ int memcmp(const void * ptr1, const void * ptr2, int size);
|
|||
|
||||
void * memmove(void * dst, const void * src, int size);
|
||||
|
||||
char* strchr( const char* str, int ch );
|
||||
|
||||
#pragma intrinsic(strcpy)
|
||||
|
||||
#pragma intrinsic(memcpy)
|
||||
|
|
|
@ -12,8 +12,8 @@ export OSCAR64_CFLAGS =
|
|||
export OSCAR64_CXX = $(project_dir)/bin/oscar64
|
||||
MKDIR_PARENT = /bin/mkdir -p -m 755
|
||||
INSTALL = /usr/bin/install
|
||||
INSTALL_PROGRAM = $(INSTALL) --mode=755
|
||||
INSTALL_DATA = $(INSTALL) --mode=644
|
||||
INSTALL_PROGRAM = $(INSTALL) -m 755
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
DESTDIR =
|
||||
prefix = /usr/local
|
||||
exec_prefix = $(prefix)
|
||||
|
@ -38,7 +38,7 @@ else
|
|||
endif
|
||||
|
||||
|
||||
all: --prep-build-dir compiler samples tests
|
||||
all: compiler samples check
|
||||
|
||||
|
||||
$(srcdir)/%.o: $(project_dir)/oscar64/%.cpp
|
||||
|
@ -56,7 +56,7 @@ $(srcdir)/%.d: $(project_dir)/oscar64/%.cpp
|
|||
$(RM) $@.$$$$
|
||||
|
||||
|
||||
compiler: $(objects)
|
||||
compiler: --prep-build-dir $(objects)
|
||||
@$(MKDIR_PARENT) $(srcdir)
|
||||
@echo "Linking compiler..."
|
||||
$(CXX) $(CPPFLAGS) $(objects) $(linklibs) -o $(project_dir)/bin/oscar64
|
||||
|
@ -85,7 +85,7 @@ samples: compiler
|
|||
@$(MAKE) -C $(project_dir)/samples all
|
||||
|
||||
|
||||
tests: compiler
|
||||
check: compiler
|
||||
@$(MAKE) -C $(project_dir)/autotest all
|
||||
|
||||
install: compiler
|
||||
|
@ -93,16 +93,16 @@ install: compiler
|
|||
@$(MKDIR_PARENT) $(DESTDIR)$(bindir)
|
||||
$(INSTALL_PROGRAM) $(project_dir)/bin/oscar64 $(DESTDIR)$(bindir)
|
||||
@$(MKDIR_PARENT) $(DESTDIR)$(includedir)/oscar64/{audio,c64,c128,cx16,gfx,nes,opp,plus4,vic20}
|
||||
$(INSTALL_DATA) $(project_dir)/include/*.{h,c} $(DESTDIR)$(includedir)/oscar64
|
||||
$(INSTALL_DATA) $(project_dir)/include/audio/*.{h,c} $(DESTDIR)$(includedir)/oscar64/audio
|
||||
$(INSTALL_DATA) $(project_dir)/include/c64/*.{h,c} $(DESTDIR)$(includedir)/oscar64/c64
|
||||
$(INSTALL_DATA) $(project_dir)/include/c128/*.{h,c} $(DESTDIR)$(includedir)/oscar64/c128
|
||||
$(INSTALL_DATA) $(project_dir)/include/cx16/*.{h,c} $(DESTDIR)$(includedir)/oscar64/cx16
|
||||
$(INSTALL_DATA) $(project_dir)/include/gfx/*.{h,c} $(DESTDIR)$(includedir)/oscar64/gfx
|
||||
$(INSTALL_DATA) $(project_dir)/include/nes/*.{h,c} $(DESTDIR)$(includedir)/oscar64/nes
|
||||
$(INSTALL_DATA) $(project_dir)/include/opp/*.{h,cpp} $(DESTDIR)$(includedir)/oscar64/opp
|
||||
$(INSTALL_DATA) $(project_dir)/include/plus4/*.{h,c} $(DESTDIR)$(includedir)/oscar64/plus4
|
||||
$(INSTALL_DATA) $(project_dir)/include/vic20/*.{h,c} $(DESTDIR)$(includedir)/oscar64/vic20
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/*.h $(project_dir)/include/*.c) $(DESTDIR)$(includedir)/oscar64
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/audio/*.h $(project_dir)/include/audio/*.c) $(DESTDIR)$(includedir)/oscar64/audio
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/c64/*.h $(project_dir)/include/c64/*.c) $(DESTDIR)$(includedir)/oscar64/c64
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/c128/*.h $(project_dir)/include/c128/*.c) $(DESTDIR)$(includedir)/oscar64/c128
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/cx16/*.h $(project_dir)/include/cx16/*.c) $(DESTDIR)$(includedir)/oscar64/cx16
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/gfx/*.h $(project_dir)/include/gfx/*.c) $(DESTDIR)$(includedir)/oscar64/gfx
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/nes/*.h $(project_dir)/include/nes/*.c) $(DESTDIR)$(includedir)/oscar64/nes
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/opp/*.h $(project_dir)/include/opp/*.cpp) $(DESTDIR)$(includedir)/oscar64/opp
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/plus4/*.h $(project_dir)/include/plus4/*.c) $(DESTDIR)$(includedir)/oscar64/plus4
|
||||
$(INSTALL_DATA) $(wildcard $(project_dir)/include/vic20/*.h $(project_dir)/include/vic20/*.c) $(DESTDIR)$(includedir)/oscar64/vic20
|
||||
|
||||
|
||||
uninstall:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
16
oscar64.sln
16
oscar64.sln
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31624.102
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.13.35931.197
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oscar64", "oscar64\oscar64.vcxproj", "{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}"
|
||||
EndProject
|
||||
|
@ -23,10 +23,14 @@ Global
|
|||
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x64.Build.0 = Release|x64
|
||||
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.ActiveCfg = Release|Win32
|
||||
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.Build.0 = Release|Win32
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.ActiveCfg = Debug
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.ActiveCfg = Release
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.ActiveCfg = Release
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.Build.0 = Debug|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.Build.0 = Debug|x86
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.ActiveCfg = Release|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.Build.0 = Release|x64
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.ActiveCfg = Release|x86
|
||||
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -421,9 +421,33 @@ protected:
|
|||
array = a2;
|
||||
}
|
||||
|
||||
for (int i = size; i < to; i++) array[i] = T{};
|
||||
|
||||
size = to;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void Partition(const F & f, int l, int r)
|
||||
{
|
||||
if (r > l + 1)
|
||||
{
|
||||
int pi = l;
|
||||
T p(array[pi]);
|
||||
|
||||
for (int i = l + 1; i < r; i++)
|
||||
{
|
||||
if (f(array[i], p))
|
||||
{
|
||||
array[pi++] = array[i];
|
||||
array[i] = array[pi];
|
||||
}
|
||||
}
|
||||
array[pi] = p;
|
||||
|
||||
Partition(f, l, pi);
|
||||
Partition(f, pi + 1, r);
|
||||
}
|
||||
}
|
||||
public:
|
||||
ExpandingArray(void)
|
||||
{
|
||||
|
@ -596,6 +620,24 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
void Fill(const T& t)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
array[i] = t;
|
||||
}
|
||||
|
||||
void Clear(void)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
array[i] = T{};
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void Sort(const F & f)
|
||||
{
|
||||
Partition(f, 0, size);
|
||||
}
|
||||
|
||||
__forceinline T& operator[](int n)
|
||||
{
|
||||
assert(n >= 0 && n < size);
|
||||
|
|
|
@ -293,7 +293,7 @@ const char* AsmInstructionNames[NUM_ASM_INS_TYPES] = {
|
|||
"INV", "BYT"
|
||||
};
|
||||
|
||||
int AsmInsModeSize[NUM_ASM_INS_MODES] = {
|
||||
int AsmInsModeSize[NUM_ASM_INS_MODES_X] = {
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
|
@ -306,6 +306,8 @@ int AsmInsModeSize[NUM_ASM_INS_MODES] = {
|
|||
2,
|
||||
2,
|
||||
2,
|
||||
0,
|
||||
2
|
||||
};
|
||||
|
||||
void InitAssembler(void)
|
||||
|
|
|
@ -31,7 +31,9 @@ enum AsmInsMode
|
|||
|
||||
NUM_ASM_INS_MODES,
|
||||
|
||||
ASMIM_IMMEDIATE_ADDRESS
|
||||
ASMIM_IMMEDIATE_ADDRESS,
|
||||
|
||||
NUM_ASM_INS_MODES_X,
|
||||
};
|
||||
|
||||
struct AsmInsData
|
||||
|
@ -45,6 +47,8 @@ extern AsmInsData DecInsData[256];
|
|||
|
||||
extern short AsmInsOpcodes[NUM_ASM_INS_TYPES][NUM_ASM_INS_MODES];
|
||||
|
||||
extern int AsmInsModeSize[NUM_ASM_INS_MODES_X];
|
||||
|
||||
extern const char* AsmInstructionNames[NUM_ASM_INS_TYPES];
|
||||
|
||||
AsmInsType FindAsmInstruction(const char * ins);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
class BitVector
|
||||
{
|
||||
|
|
|
@ -3462,94 +3462,151 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
|
|||
{
|
||||
if (ins->mSrc[1].mTemp < 0)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
if (csigned)
|
||||
if (ins->mSrc[1].mType == IT_INT16 || ins->mSrc[1].mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(lins);
|
||||
if (csigned)
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPLES:
|
||||
return BC_BRANCHS_LE;
|
||||
case IA_CMPGS:
|
||||
return BC_BRANCHS_GT;
|
||||
case IA_CMPGES:
|
||||
return BC_BRANCHS_GE;
|
||||
case IA_CMPLS:
|
||||
return BC_BRANCHS_LT;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
case IA_CMPLEU:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
case IA_CMPGU:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPGEU:
|
||||
return BC_JUMPS;
|
||||
case IA_CMPLU:
|
||||
return BC_NOP;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction bins(BC_LEA_ABS);
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
bins.mLinkerObject = ins->mSrc[1].mLinkerObject;
|
||||
bins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
bins.mRelocate = true;
|
||||
mIns.Push(bins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
if (ins->mSrc[0].mType == IT_INT16 || ins->mSrc[0].mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(lins);
|
||||
if (csigned)
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPLES:
|
||||
return BC_BRANCHS_LE;
|
||||
case IA_CMPGS:
|
||||
return BC_BRANCHS_GT;
|
||||
case IA_CMPGES:
|
||||
return BC_BRANCHS_GE;
|
||||
case IA_CMPLS:
|
||||
return BC_BRANCHS_LT;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
case IA_CMPLEU:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
case IA_CMPGU:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPGEU:
|
||||
return BC_JUMPS;
|
||||
case IA_CMPLU:
|
||||
return BC_NOP;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction bins(BC_LEA_ABS);
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
bins.mLinkerObject = ins->mSrc[0].mLinkerObject;
|
||||
bins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
bins.mRelocate = true;
|
||||
mIns.Push(bins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -174,13 +174,13 @@ void Compiler::RegisterRuntime(const Location & loc, const Ident* ident)
|
|||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (!bcdec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
|
||||
linkerObject = bcdec->mLinkerObject;
|
||||
}
|
||||
else if (bcdec->mType == DT_LABEL)
|
||||
{
|
||||
if (!bcdec->mBase->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr);
|
||||
|
||||
linkerObject = bcdec->mBase->mLinkerObject;
|
||||
offset = int(bcdec->mInteger);
|
||||
|
@ -466,7 +466,7 @@ void Compiler::CompileProcedure(InterCodeProcedure* proc)
|
|||
printf("Generate native code <%s>\n", proc->mIdent->mString);
|
||||
|
||||
ncproc->Compile(proc);
|
||||
mNativeProcedures.Push(ncproc);
|
||||
mNativeCodeGenerator->mProcedures.Push(ncproc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -508,6 +508,8 @@ bool Compiler::GenerateCode(void)
|
|||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00e0, 0x00ff);
|
||||
else if (mCompilerOptions & (COPT_EXTENDED_ZERO_PAGE | COPT_TARGET_NES))
|
||||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff);
|
||||
else if (mTargetMachine == TMACH_PET_8K || mTargetMachine == TMACH_PET_16K || mTargetMachine == TMACH_PET_32K)
|
||||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00ed, 0x00f7);
|
||||
else
|
||||
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00f7, 0x00ff);
|
||||
}
|
||||
|
@ -521,6 +523,12 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
if (mCompilerOptions & COPT_NATIVE)
|
||||
regionStartup = mLinker->AddRegion(identStartup, 0x2001, 0x2080);
|
||||
else
|
||||
regionStartup = mLinker->AddRegion(identStartup, 0x2001, 0x2100);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
case TMACH_X16:
|
||||
if (mCompilerOptions & COPT_NATIVE)
|
||||
|
@ -623,6 +631,9 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
regionBytecode = mLinker->AddRegion(identBytecode, 0x2100, 0x2200);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
case TMACH_X16:
|
||||
regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00);
|
||||
|
@ -684,6 +695,9 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x2300, 0xc000);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000);
|
||||
break;
|
||||
|
@ -735,6 +749,14 @@ bool Compiler::GenerateCode(void)
|
|||
{
|
||||
switch (mTargetMachine)
|
||||
{
|
||||
case TMACH_MEGA65:
|
||||
// TODO: Disable M65 cartridges for now.
|
||||
//
|
||||
// if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16))
|
||||
// regionMain = mLinker->AddRegion(identMain, 0x2666, 0xff00);
|
||||
// else
|
||||
regionMain = mLinker->AddRegion(identMain, 0x2080, 0xc000);
|
||||
break;
|
||||
case TMACH_C64:
|
||||
|
||||
if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16))
|
||||
|
@ -910,7 +932,7 @@ bool Compiler::GenerateCode(void)
|
|||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
printf("Generate intermediate code\n");
|
||||
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart, nullptr);
|
||||
for (int i = 0; i < mCompilationUnits->mReferenced.Size(); i++)
|
||||
{
|
||||
Declaration* dec = mCompilationUnits->mReferenced[i];
|
||||
|
@ -993,7 +1015,7 @@ bool Compiler::GenerateCode(void)
|
|||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (!bcdec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
|
||||
mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject;
|
||||
}
|
||||
}
|
||||
|
@ -1036,13 +1058,18 @@ bool Compiler::GenerateCode(void)
|
|||
mCompilationUnits->mSectionStack->mSections.Push(proc->mLinkerObject->mStackSection);
|
||||
}
|
||||
|
||||
mNativeCodeGenerator->OutlineFunctions();
|
||||
|
||||
mNativeCodeGenerator->BuildFunctionProxies();
|
||||
|
||||
for (int i = 0; i < mNativeProcedures.Size(); i++)
|
||||
for (int i = 0; i < mNativeCodeGenerator->mProcedures.Size(); i++)
|
||||
{
|
||||
if (mCompilerOptions & COPT_VERBOSE2)
|
||||
printf("Assemble native code <%s>\n", mNativeProcedures[i]->mInterProc->mIdent->mString);
|
||||
mNativeProcedures[i]->Assemble();
|
||||
{
|
||||
if (mNativeCodeGenerator->mProcedures[i]->mInterProc)
|
||||
printf("Assemble native code <%s>\n", mNativeCodeGenerator->mProcedures[i]->mInterProc->mIdent->mString);
|
||||
}
|
||||
mNativeCodeGenerator->mProcedures[i]->Assemble();
|
||||
}
|
||||
|
||||
LinkerObject* byteCodeObject = nullptr;
|
||||
|
@ -1068,13 +1095,13 @@ bool Compiler::GenerateCode(void)
|
|||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (!bcdec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
|
||||
linkerObject = bcdec->mLinkerObject;
|
||||
}
|
||||
else if (bcdec->mType == DT_LABEL)
|
||||
{
|
||||
if (!bcdec->mBase->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr);
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr);
|
||||
linkerObject = bcdec->mBase->mLinkerObject;
|
||||
offset = int(bcdec->mInteger);
|
||||
}
|
||||
|
@ -1270,7 +1297,7 @@ bool Compiler::WriteErrorFile(const char* targetPath)
|
|||
|
||||
bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
||||
{
|
||||
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200], dbjPath[200];
|
||||
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200], dbjPath[200], cszPath[200];
|
||||
char basePath[200];
|
||||
|
||||
strcpy_s(basePath, targetPath);
|
||||
|
@ -1293,6 +1320,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
strcpy_s(intPath, prgPath);
|
||||
strcpy_s(bcsPath, prgPath);
|
||||
strcpy_s(dbjPath, prgPath);
|
||||
strcpy_s(cszPath, prgPath);
|
||||
|
||||
strcat_s(mapPath, "map");
|
||||
strcat_s(asmPath, "asm");
|
||||
|
@ -1300,6 +1328,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
strcat_s(intPath, "int");
|
||||
strcat_s(bcsPath, "bcs");
|
||||
strcat_s(dbjPath, "dbj");
|
||||
strcat_s(cszPath, "csz");
|
||||
|
||||
if (mCompilerOptions & COPT_TARGET_PRG)
|
||||
{
|
||||
|
@ -1382,6 +1411,9 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
|
|||
if (mCompilerOptions & COPT_DEBUGINFO)
|
||||
WriteDbjFile(dbjPath);
|
||||
|
||||
if (mCompilerOptions & COPT_PROFILEINFO)
|
||||
WriteCszFile(cszPath);
|
||||
|
||||
if (!(mCompilerOptions & COPT_NATIVE))
|
||||
{
|
||||
if (mCompilerOptions & COPT_VERBOSE)
|
||||
|
@ -1448,6 +1480,111 @@ static void DumpReferences(FILE* file, Declaration* dec)
|
|||
|
||||
}
|
||||
|
||||
bool Compiler::WriteCszFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
fopen_s(&file, filename, "wb");
|
||||
if (file)
|
||||
{
|
||||
for (int i = 0; i < mInterCodeModule->mProcedures.Size(); i++)
|
||||
{
|
||||
InterCodeProcedure* p(mInterCodeModule->mProcedures[i]);
|
||||
if (p->mLinkerObject && p->mIdent && p->mDeclaration)
|
||||
{
|
||||
LinkerObject* lo = p->mLinkerObject;
|
||||
|
||||
struct SourceCount
|
||||
{
|
||||
const char* mFileName;
|
||||
int mLine, mAddress;
|
||||
int mBytes;
|
||||
};
|
||||
|
||||
ExpandingArray<SourceCount> ea;
|
||||
|
||||
for (int j = 0; j < lo->mCodeLocations.Size(); j++)
|
||||
{
|
||||
const CodeLocation& co(lo->mCodeLocations[j]);
|
||||
const Location* ls = &(co.mLocation);
|
||||
while (ls->mFrom)
|
||||
ls = ls->mFrom;
|
||||
|
||||
int k = 0;
|
||||
while (k < ea.Size() && (ea[k].mFileName != ls->mFileName || ea[k].mLine != ls->mLine))
|
||||
k++;
|
||||
if (k == ea.Size())
|
||||
{
|
||||
SourceCount sc;
|
||||
sc.mFileName = ls->mFileName;
|
||||
sc.mLine = ls->mLine;
|
||||
sc.mBytes = 0;
|
||||
sc.mAddress = co.mStart + lo->mAddress;
|
||||
ea.Push(sc);
|
||||
}
|
||||
|
||||
ea[k].mBytes += co.mEnd - co.mStart;
|
||||
}
|
||||
|
||||
if (ea.Size())
|
||||
{
|
||||
ea.Sort([](const SourceCount& l, const SourceCount& r)->bool {
|
||||
return l.mFileName == r.mFileName ? l.mLine < r.mLine : l.mAddress < r.mAddress;
|
||||
});
|
||||
|
||||
FILE* fsrc;
|
||||
fopen_s(&fsrc, ea[0].mFileName, "r");
|
||||
if (fsrc)
|
||||
{
|
||||
fprintf(file, "<%s, %s>\n", p->mDeclaration->mQualIdent->mString, ea[0].mFileName);
|
||||
#if 0
|
||||
for (int i = 0; i < ea.Size(); i++)
|
||||
{
|
||||
fprintf(file, "%s:%d : %d\n", ea[i].mFileName, ea[i].mLine, ea[i].mBytes);
|
||||
}
|
||||
#endif
|
||||
int k = 0, l = 1;
|
||||
char line[1024];
|
||||
while (k < ea.Size() && fgets(line, 1024, fsrc))
|
||||
{
|
||||
size_t ll = strlen(line);
|
||||
while (ll > 0 && (line[ll - 1] == '\r' || line[ll - 1] == '\n'))
|
||||
ll--;
|
||||
line[ll] = 0;
|
||||
|
||||
if (l < ea[k].mLine)
|
||||
{
|
||||
if (k > 0)
|
||||
fprintf(file, "%5d,---- ( ) : %s\n", l, line);
|
||||
}
|
||||
else
|
||||
{
|
||||
int ks = k, sum = 0;
|
||||
do {
|
||||
sum += ea[ks].mBytes;
|
||||
ks++;
|
||||
} while (ks < ea.Size() && ea[ks].mFileName != ea[0].mFileName);
|
||||
|
||||
fprintf(file, "%5d,%04x (%3d) : %s\n", l, ea[k].mAddress, ea[k].mBytes, line);
|
||||
|
||||
k = ks;
|
||||
}
|
||||
l++;
|
||||
}
|
||||
|
||||
fclose(fsrc);
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::WriteDbjFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
|
|
|
@ -29,7 +29,6 @@ public:
|
|||
GlobalOptimizer* mGlobalOptimizer;
|
||||
|
||||
GrowingArray<ByteCodeProcedure*> mByteCodeFunctions;
|
||||
ExpandingArray<NativeCodeProcedure*> mNativeProcedures;
|
||||
|
||||
TargetMachine mTargetMachine;
|
||||
uint64 mCompilerOptions;
|
||||
|
@ -61,4 +60,5 @@ public:
|
|||
void CompleteTemplateExpansion(void);
|
||||
|
||||
bool WriteDbjFile(const char* filename);
|
||||
bool WriteCszFile(const char* filename);
|
||||
};
|
||||
|
|
|
@ -14,6 +14,8 @@ static const uint64 COPT_OPTIMIZE_AUTO_ZEROPAGE = 1ULL << 8;
|
|||
static const uint64 COPT_OPTIMIZE_CONST_PARAMS = 1ULL << 9;
|
||||
static const uint64 COPT_OPTIMIZE_MERGE_CALLS = 1ULL << 10;
|
||||
static const uint64 COPT_OPTIMIZE_GLOBAL = 1ULL << 11;
|
||||
static const uint64 COPT_OPTIMIZE_OUTLINE = 1ULL << 12;
|
||||
static const uint64 COPT_OPTIMIZE_PAGE_CROSSING = 1ULL << 13;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_CODE_SIZE = 1ULL << 16;
|
||||
static const uint64 COPT_NATIVE = 1ULL << 17;
|
||||
|
@ -41,13 +43,16 @@ static const uint64 COPT_CPLUSPLUS = 1ULL << 52;
|
|||
static const uint64 COPT_PETSCII = 1ULL << 53;
|
||||
static const uint64 COPT_ERROR_FILES = 1ULL << 54;
|
||||
|
||||
static const uint64 COPT_PROFILEINFO = 1ULL << 55;
|
||||
static const uint64 COPT_STRICT = 1ULL << 56;
|
||||
|
||||
|
||||
|
||||
static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_CODE_SIZE | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;
|
||||
static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_CODE_SIZE | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;// | COPT_OPTIMIZE_OUTLINE;
|
||||
|
||||
static const uint64 COPT_OPTIMIZE_SPEED = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_UNROLL | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_ASSEMBLER | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;
|
||||
|
||||
|
@ -74,7 +79,8 @@ enum TargetMachine
|
|||
TMACH_NES_MMC1,
|
||||
TMACH_NES_MMC3,
|
||||
TMACH_ATARI,
|
||||
TMACH_X16
|
||||
TMACH_X16,
|
||||
TMACH_MEGA65
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ int CompressLZO(uint8* dst, const uint8* source, int size)
|
|||
while (pi < 127 && pos < size)
|
||||
{
|
||||
int bi = pi, bj = 0;
|
||||
for (int i = 1; i < (pos < 255 ? pos : 255); i++)
|
||||
for (int i = 1; i <= (pos < 255 ? pos : 255); i++)
|
||||
{
|
||||
int j = 0;
|
||||
while (j < 127 && pos + j < size && source[pos - i + j] == source[pos + j])
|
||||
|
|
|
@ -651,6 +651,7 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
|
|||
{
|
||||
mProcType = exp->mLeft->mDecType;
|
||||
|
||||
Expression* pex = exp->mRight;
|
||||
Declaration* cdec = exp->mLeft->mDecType->mParams;
|
||||
|
||||
int pos = 0;
|
||||
|
@ -659,6 +660,28 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
|
|||
mParams[pos].PutPtr(Value(&mResult));
|
||||
pos = 2;
|
||||
|
||||
if (pex->mType == EX_LIST)
|
||||
pex = pex->mRight;
|
||||
else
|
||||
pex = nullptr;
|
||||
cdec = cdec->mNext;
|
||||
|
||||
while (pex && pex->mType == EX_LIST)
|
||||
{
|
||||
if (!AddParam(pos, pex->mLeft, cdec))
|
||||
return exp;
|
||||
|
||||
pex = pex->mRight;
|
||||
if (cdec)
|
||||
cdec = cdec->mNext;
|
||||
}
|
||||
|
||||
if (pex)
|
||||
{
|
||||
if (!AddParam(pos, pex, cdec))
|
||||
return exp;
|
||||
}
|
||||
|
||||
mHeap = new ExpandingArray<Value*>();
|
||||
|
||||
Execute(exp->mLeft->mDecValue->mValue);
|
||||
|
@ -754,6 +777,9 @@ bool ConstexprInterpreter::AddParam(int& pos, Expression* pex, Declaration* dec)
|
|||
|
||||
Expression* ConstexprInterpreter::EvalCall(Expression* exp)
|
||||
{
|
||||
if (!exp->mLeft->mDecValue || !exp->mLeft->mDecValue->mValue)
|
||||
return exp;
|
||||
|
||||
mProcType = exp->mLeft->mDecType;
|
||||
|
||||
Expression* pex = exp->mRight;
|
||||
|
@ -1020,6 +1046,9 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalUnary(Expression* exp, con
|
|||
break;
|
||||
case TK_MUL:
|
||||
return vl.GetPtr();
|
||||
case TK_SIZEOF:
|
||||
v.PutInt(vl.mDecType->mSize);
|
||||
break;
|
||||
default:
|
||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible operator", TokenNames[exp->mToken]);
|
||||
}
|
||||
|
@ -1168,6 +1197,26 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons
|
|||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::exp(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "sqrt"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::sqrt(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "atan"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::atan(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "atan2"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::atan2(mParams[0].GetFloat(), mParams[1].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "pow"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::pow(mParams[0].GetFloat(), mParams[1].GetFloat()));
|
||||
}
|
||||
else
|
||||
mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,17 @@ DeclarationScope::~DeclarationScope(void)
|
|||
delete[] mHash;
|
||||
}
|
||||
|
||||
DeclarationScope* DeclarationScope::Clone(void) const
|
||||
{
|
||||
DeclarationScope* scope = new DeclarationScope(mParent, mLevel, mName);
|
||||
for (int i = 0; i < mHashSize; i++)
|
||||
{
|
||||
if (mHash[i].mIdent)
|
||||
scope->Insert(mHash[i].mIdent, mHash[i].mDec);
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
const Ident* DeclarationScope::Mangle(const Ident* ident) const
|
||||
{
|
||||
if (mName && ident)
|
||||
|
@ -145,7 +156,7 @@ void DeclarationScope::End(const Location& loc)
|
|||
}
|
||||
|
||||
Expression::Expression(const Location& loc, ExpressionType type)
|
||||
: mLocation(loc), mEndLocation(loc), mType(type), mLeft(nullptr), mRight(nullptr), mConst(false), mDecType(nullptr), mDecValue(nullptr), mToken(TK_NONE)
|
||||
: mLocation(loc), mEndLocation(loc), mType(type), mLeft(nullptr), mRight(nullptr), mConst(false), mDecType(nullptr), mDecValue(nullptr), mToken(TK_NONE), mFlags(0)
|
||||
{
|
||||
static uint32 gUID = 0;
|
||||
mUID = gUID++;
|
||||
|
@ -263,6 +274,9 @@ void Expression::Dump(int ident) const
|
|||
case EX_FOR:
|
||||
printf("FOR");
|
||||
break;
|
||||
case EX_FORBODY:
|
||||
printf("FORBODY");
|
||||
break;
|
||||
case EX_DO:
|
||||
printf("DO");
|
||||
break;
|
||||
|
@ -335,6 +349,9 @@ void Expression::Dump(int ident) const
|
|||
case EX_LABEL:
|
||||
printf("LABEL %s", mDecValue->mIdent->mString);
|
||||
break;
|
||||
case EX_AGGREGATE:
|
||||
printf("AGGREGATE");
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
@ -387,6 +404,17 @@ bool Expression::IsRValue(void) const
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Expression::IsVolatile(void) const
|
||||
{
|
||||
if (mDecType->mFlags & DTF_VOLATILE)
|
||||
return true;
|
||||
if (mLeft && mLeft->IsVolatile())
|
||||
return true;
|
||||
if (mRight && mRight->IsVolatile())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Expression::IsConstRef(void) const
|
||||
{
|
||||
if (mDecType->mType == DT_TYPE_RVALUEREF || mDecType->mType == DT_TYPE_REFERENCE)
|
||||
|
@ -477,6 +505,63 @@ Expression* Expression::LogicInvertExpression(void)
|
|||
}
|
||||
}
|
||||
|
||||
void Expression::ReplaceVariable(Declaration* pvar, Declaration* nvar)
|
||||
{
|
||||
if (mLeft) mLeft->ReplaceVariable(pvar, nvar);
|
||||
if (mRight) mRight->ReplaceVariable(pvar, nvar);
|
||||
|
||||
if (mType == EX_VARIABLE && mDecValue == pvar)
|
||||
mDecValue = nvar;
|
||||
}
|
||||
|
||||
Expression* Expression::ToAlternateThis(Declaration* pthis, Declaration* nthis)
|
||||
{
|
||||
Expression* left = mLeft ? mLeft->ToAlternateThis(pthis, nthis) : nullptr;
|
||||
Expression* right = mRight ? mRight->ToAlternateThis(pthis, nthis) : nullptr;
|
||||
Declaration* decType = mDecType, * decValue = mDecValue;
|
||||
|
||||
Declaration* lp = pthis, * np = nthis;
|
||||
while (lp)
|
||||
{
|
||||
if (decType == lp->mBase)
|
||||
decType = np->mBase;
|
||||
else if (decType == lp->mBase->mBase)
|
||||
decType = np->mBase->mBase;
|
||||
if (decValue == lp)
|
||||
decValue = np;
|
||||
|
||||
lp = lp->mNext;
|
||||
np = np->mNext;
|
||||
}
|
||||
|
||||
if (mType == EX_QUALIFY && mLeft->mDecType != left->mDecType)
|
||||
{
|
||||
Declaration* pe = mLeft->mDecType->mParams, * ne = left->mDecType->mParams;
|
||||
while (pe && ne && pe != mDecValue)
|
||||
{
|
||||
pe = pe->mNext;
|
||||
ne = ne->mNext;
|
||||
}
|
||||
decValue = ne;
|
||||
decType = ne->mBase;
|
||||
}
|
||||
|
||||
if (left == mLeft && right == mRight && decType == mDecType && decValue == mDecValue)
|
||||
return this;
|
||||
else
|
||||
{
|
||||
Expression* nexp = new Expression(mLocation, mType);
|
||||
nexp->mLeft = left;
|
||||
nexp->mRight = right;
|
||||
nexp->mDecType = decType;
|
||||
nexp->mDecValue = decValue;
|
||||
nexp->mToken = mToken;
|
||||
nexp->mConst = mConst;
|
||||
|
||||
return nexp;
|
||||
}
|
||||
}
|
||||
|
||||
Expression* Expression::ConstantDereference(Errors* errors, LinkerSection* dataSection)
|
||||
{
|
||||
if (mType == EX_VARIABLE)
|
||||
|
@ -594,6 +679,19 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
|
||||
return this;
|
||||
}
|
||||
else if (mType == EX_PREFIX && mToken == TK_SIZEOF)
|
||||
{
|
||||
if (mLeft->mDecType->mFlags & DTF_DEFINED)
|
||||
{
|
||||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
|
||||
dec->mBase = TheSignedIntTypeDeclaration;
|
||||
dec->mInteger = mLeft->mDecType->mSize;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = dec->mBase;
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
else if (mType == EX_PREFIX && mLeft->mType == EX_CONSTANT)
|
||||
{
|
||||
|
||||
|
@ -677,14 +775,29 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
ex->mDecType = mDecType;
|
||||
return ex;
|
||||
}
|
||||
else if (mType == EX_PREFIX && mToken == TK_BINARY_AND && mLeft->mType == EX_INDEX && mLeft->mLeft->mType == EX_VARIABLE && (mLeft->mLeft->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL)) && mLeft->mRight->mType == EX_CONSTANT)
|
||||
else if (mType == EX_PREFIX && mToken == TK_BINARY_AND && mLeft->mType == EX_INDEX &&
|
||||
mLeft->mLeft->mType == EX_VARIABLE && mLeft->mLeft->mDecType->mType == DT_TYPE_ARRAY &&
|
||||
(mLeft->mLeft->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL)) && mLeft->mRight->mType == EX_CONSTANT)
|
||||
{
|
||||
Declaration* vdec = mLeft->mLeft->mDecValue;
|
||||
|
||||
Expression* ex = new Expression(mLocation, EX_VARIABLE);
|
||||
Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF);
|
||||
dec->mFlags = mLeft->mLeft->mDecValue->mFlags;
|
||||
dec->mBase = mLeft->mLeft->mDecValue;
|
||||
dec->mSize = mLeft->mLeft->mDecType->mBase->mSize - int(mLeft->mRight->mDecValue->mInteger) * dec->mSize;
|
||||
dec->mOffset = int(mLeft->mRight->mDecValue->mInteger) * dec->mSize;
|
||||
|
||||
if (vdec->mType == DT_VARIABLE_REF)
|
||||
{
|
||||
dec->mFlags = vdec->mFlags;
|
||||
dec->mBase = vdec->mBase;
|
||||
dec->mSize = mLeft->mLeft->mDecType->mBase->mSize - int(mLeft->mRight->mDecValue->mInteger) * dec->mSize;
|
||||
dec->mOffset = int(mLeft->mRight->mDecValue->mInteger) * dec->mSize + vdec->mOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
dec->mFlags = vdec->mFlags;
|
||||
dec->mBase = vdec;
|
||||
dec->mSize = mLeft->mLeft->mDecType->mBase->mSize - int(mLeft->mRight->mDecValue->mInteger) * dec->mSize;
|
||||
dec->mOffset = int(mLeft->mRight->mDecValue->mInteger) * dec->mSize;
|
||||
}
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = mLeft->mLeft->mDecType;
|
||||
return ex;
|
||||
|
@ -808,11 +921,19 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
{
|
||||
int64 ival = 0, ileft = mLeft->mDecValue->mInteger, iright = mRight->mDecValue->mInteger;
|
||||
|
||||
bool signop =
|
||||
(mLeft->mDecValue->mBase->mSize < 2 || (mLeft->mDecValue->mBase->mFlags & DTF_SIGNED)) &&
|
||||
(mRight->mDecValue->mBase->mSize < 2 || (mRight->mDecValue->mBase->mFlags & DTF_SIGNED));
|
||||
Declaration* dtype = TheSignedIntTypeDeclaration;
|
||||
if (mLeft->mDecValue->mBase->mSize > mRight->mDecValue->mBase->mSize)
|
||||
dtype = mLeft->mDecValue->mBase;
|
||||
else if (mLeft->mDecValue->mBase->mSize < mRight->mDecValue->mBase->mSize)
|
||||
dtype = mRight->mDecValue->mBase;
|
||||
else if (mLeft->mDecValue->mBase->mSize > 1)
|
||||
{
|
||||
if ((mLeft->mDecValue->mBase->mFlags & DTF_SIGNED) && !(mRight->mDecValue->mBase->mFlags & DTF_SIGNED))
|
||||
dtype = mRight->mDecValue->mBase;
|
||||
else
|
||||
dtype = mLeft->mDecValue->mBase;
|
||||
}
|
||||
|
||||
bool promote = true;
|
||||
switch (mToken)
|
||||
{
|
||||
case TK_ADD:
|
||||
|
@ -826,27 +947,25 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
break;
|
||||
case TK_DIV:
|
||||
if (iright == 0)
|
||||
errors->Error(mLocation, EERR_INVALID_VALUE, "Constant division by zero");
|
||||
else if (signop)
|
||||
return this;
|
||||
else if (dtype->mFlags & DTF_SIGNED)
|
||||
ival = ileft / iright;
|
||||
else
|
||||
ival = (uint64)ileft / (uint64)iright;
|
||||
break;
|
||||
case TK_MOD:
|
||||
if (iright == 0)
|
||||
errors->Error(mLocation, EERR_INVALID_VALUE, "Constant division by zero");
|
||||
else if (signop)
|
||||
return this;
|
||||
else if (dtype->mFlags & DTF_SIGNED)
|
||||
ival = ileft % iright;
|
||||
else
|
||||
ival = (uint64)ileft % (uint64)iright;
|
||||
break;
|
||||
case TK_LEFT_SHIFT:
|
||||
ival = ileft << iright;
|
||||
promote = false;
|
||||
break;
|
||||
case TK_RIGHT_SHIFT:
|
||||
ival = ileft >> iright;
|
||||
promote = false;
|
||||
break;
|
||||
case TK_BINARY_AND:
|
||||
ival = ileft & iright;
|
||||
|
@ -863,29 +982,14 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
|
||||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
|
||||
if (promote)
|
||||
{
|
||||
if (mLeft->mDecValue->mBase->mSize <= 2 && mRight->mDecValue->mBase->mSize <= 2)
|
||||
dec->mBase = ival < 32768 ? TheSignedIntTypeDeclaration : TheUnsignedIntTypeDeclaration;
|
||||
else
|
||||
dec->mBase = ival < 2147483648 ? TheSignedLongTypeDeclaration : TheUnsignedLongTypeDeclaration;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mLeft->mDecValue->mBase->mSize < 2)
|
||||
dec->mBase = TheSignedIntTypeDeclaration;
|
||||
else
|
||||
dec->mBase = mLeft->mDecValue->mBase;
|
||||
}
|
||||
|
||||
dec->mInteger = ival;
|
||||
dec->mBase = dtype;
|
||||
dec->mInteger = signextend(ival, dec->mBase);
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = dec->mBase;
|
||||
return ex;
|
||||
}
|
||||
else if ((mLeft->mDecValue->mType == DT_CONST_INTEGER || mLeft->mDecValue->mType == DT_CONST_FLOAT) && (mRight->mDecValue->mType == DT_CONST_INTEGER || mRight->mDecValue->mType == DT_CONST_FLOAT))
|
||||
{
|
||||
|
||||
double dval;
|
||||
double dleft = mLeft->mDecValue->mType == DT_CONST_INTEGER ? mLeft->mDecValue->mInteger : mLeft->mDecValue->mNumber;
|
||||
double dright = mRight->mDecValue->mType == DT_CONST_INTEGER ? mRight->mDecValue->mInteger : mRight->mDecValue->mNumber;
|
||||
|
@ -940,6 +1044,20 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
ex->mDecType = dec->mBase;
|
||||
return ex;
|
||||
}
|
||||
else if (mLeft->mDecValue->mType == DT_CONST_ADDRESS && mRight->mDecValue->mType == DT_CONST_ADDRESS && mToken == TK_SUB)
|
||||
{
|
||||
if (mLeft->mDecType->mType == DT_TYPE_POINTER && mRight->mDecType->mType == DT_TYPE_POINTER &&
|
||||
mLeft->mDecType->mBase->IsConstSame(mRight->mDecType->mBase))
|
||||
{
|
||||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
|
||||
dec->mBase = TheSignedIntTypeDeclaration;
|
||||
dec->mInteger = (mLeft->mDecValue->mInteger - mRight->mDecValue->mInteger) / mLeft->mDecType->mBase->mSize;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = dec->mBase;
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if (mLeft->mDecValue->mType == DT_CONST_POINTER && mRight->mDecValue->mType == DT_CONST_INTEGER && (mToken == TK_ADD || mToken == TK_SUB))
|
||||
{
|
||||
|
@ -1020,6 +1138,26 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
|
||||
}
|
||||
}
|
||||
else if (mType == EX_LOGICAL_AND && mLeft->mType == EX_CONSTANT)
|
||||
{
|
||||
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
if (mLeft->mDecValue->mInteger == 0)
|
||||
return mLeft;
|
||||
else
|
||||
return mRight->ConstantFold(errors, dataSection);
|
||||
}
|
||||
}
|
||||
else if (mType == EX_LOGICAL_OR && mLeft->mType == EX_CONSTANT)
|
||||
{
|
||||
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
if (mLeft->mDecValue->mInteger != 0)
|
||||
return mLeft;
|
||||
else
|
||||
return mRight->ConstantFold(errors, dataSection);
|
||||
}
|
||||
}
|
||||
else if (mType == EX_CONDITIONAL && mLeft->mType == EX_CONSTANT)
|
||||
{
|
||||
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
|
||||
|
@ -1055,7 +1193,7 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
return ex;
|
||||
}
|
||||
else if (mType == EX_BINARY && mToken == TK_ADD && mLeft->mType == EX_VARIABLE && mLeft->mDecValue->mType == DT_VARIABLE && (mLeft->mDecValue->mFlags & DTF_CONST) &&
|
||||
mLeft->mDecValue && mRight->mDecValue && mLeft->mDecValue->mValue->mType == EX_CONSTANT &&
|
||||
mLeft->mDecValue && mRight->mDecValue && mLeft->mDecValue->mValue && mLeft->mDecValue->mValue->mType == EX_CONSTANT &&
|
||||
mLeft->mDecType->mType == DT_TYPE_POINTER && mRight->mType == EX_CONSTANT && mRight->mDecValue->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
mLeft = mLeft->mDecValue->mValue;
|
||||
|
@ -1108,19 +1246,23 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
else if (mType == EX_INDEX && mLeft->mType == EX_VARIABLE && mLeft->mDecValue->mType == DT_VARIABLE_REF && (mLeft->mDecValue->mFlags & DTF_GLOBAL) &&
|
||||
mLeft->mDecType->mType == DT_TYPE_ARRAY && mLeft->mDecType->mStride == 0 &&
|
||||
mRight->mType == EX_CONSTANT && mRight->mDecValue->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
int offset = mLeft->mDecValue->mOffset + int(mDecType->mSize * mRight->mDecValue->mInteger);
|
||||
{
|
||||
int offset = mLeft->mDecValue->mOffset + int(mDecType->mSize * mRight->mDecValue->mInteger);
|
||||
|
||||
Expression* ex = new Expression(mLocation, EX_VARIABLE);
|
||||
Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF);
|
||||
dec->mFlags = mLeft->mDecValue->mFlags;
|
||||
dec->mBase = mLeft->mDecValue->mBase;
|
||||
dec->mOffset = offset;
|
||||
dec->mSize = mDecType->mSize;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = mDecType;
|
||||
return ex;
|
||||
}
|
||||
Expression* ex = new Expression(mLocation, EX_VARIABLE);
|
||||
Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF);
|
||||
dec->mFlags = mLeft->mDecValue->mFlags;
|
||||
dec->mBase = mLeft->mDecValue->mBase;
|
||||
dec->mOffset = offset;
|
||||
dec->mSize = mDecType->mSize;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = mDecType;
|
||||
return ex;
|
||||
}
|
||||
else if (mType == EX_VARIABLE && mDecType->IsSimpleType() && (mDecValue->mFlags & DTF_CONST) && mDecValue->mValue && mDecValue->mValue->mType == EX_INITIALIZATION && mDecValue->mValue->mRight->mType == EX_CONSTANT)
|
||||
{
|
||||
return mDecValue->mValue->mRight;
|
||||
}
|
||||
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_INTRINSIC) && mRight && mRight->mType == EX_CONSTANT)
|
||||
{
|
||||
Declaration* decf = mLeft->mDecValue, * decp = mRight->mDecValue;
|
||||
|
@ -1129,6 +1271,7 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
if (decp->mType == DT_CONST_FLOAT || decp->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
double d = decp->mType == DT_CONST_FLOAT ? decp->mNumber : decp->mInteger;
|
||||
double e = 0.0;
|
||||
|
||||
bool check = false;
|
||||
|
||||
|
@ -1148,6 +1291,10 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
d = log(d);
|
||||
else if (!strcmp(iname->mString, "exp"))
|
||||
d = exp(d);
|
||||
else if (!strcmp(iname->mString, "sqrt"))
|
||||
d = sqrt(d);
|
||||
else if (!strcmp(iname->mString, "atan"))
|
||||
d = atan(d);
|
||||
else
|
||||
return this;
|
||||
|
||||
|
@ -1160,6 +1307,36 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
return ex;
|
||||
}
|
||||
}
|
||||
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_INTRINSIC) && mRight &&
|
||||
mRight->mType == EX_LIST && mRight->mLeft->mType == EX_CONSTANT && mRight->mRight->mType == EX_CONSTANT)
|
||||
{
|
||||
Declaration* decf = mLeft->mDecValue, * decp1 = mRight->mLeft->mDecValue, * decp2 = mRight->mRight->mDecValue;
|
||||
const Ident* iname = decf->mQualIdent;
|
||||
|
||||
if ((decp1->mType == DT_CONST_FLOAT || decp1->mType == DT_CONST_INTEGER) &&
|
||||
(decp2->mType == DT_CONST_FLOAT || decp2->mType == DT_CONST_INTEGER))
|
||||
{
|
||||
double d1 = decp1->mType == DT_CONST_FLOAT ? decp1->mNumber : decp1->mInteger;
|
||||
double d2 = decp2->mType == DT_CONST_FLOAT ? decp2->mNumber : decp2->mInteger;
|
||||
|
||||
bool check = false;
|
||||
|
||||
if (!strcmp(iname->mString, "pow"))
|
||||
d1 = pow(d1, d2);
|
||||
else if (!strcmp(iname->mString, "atan2"))
|
||||
d1 = atan2(d1, d2);
|
||||
else
|
||||
return this;
|
||||
|
||||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration* dec = new Declaration(mLocation, DT_CONST_FLOAT);
|
||||
dec->mBase = TheFloatTypeDeclaration;
|
||||
dec->mNumber = d1;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = dec->mBase;
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_CONSTEXPR) && dataSection)
|
||||
{
|
||||
ConstexprInterpreter cinter(mLocation, errors, dataSection);
|
||||
|
@ -1184,6 +1361,7 @@ Declaration::Declaration(const Location& loc, DecType type)
|
|||
mConst(nullptr), mMutable(nullptr), mVolatile(nullptr),
|
||||
mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr), mMoveConstructor(nullptr), mMoveAssignment(nullptr),
|
||||
mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr),
|
||||
mVectorMoveConstructor(nullptr), mVectorMoveAssignment(nullptr),
|
||||
mVTable(nullptr), mTemplate(nullptr), mForwardParam(nullptr), mForwardCall(nullptr),
|
||||
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mFriends(nullptr),
|
||||
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
|
||||
|
@ -1205,7 +1383,7 @@ int Declaration::Stride(void) const
|
|||
{
|
||||
if (mStride > 0)
|
||||
return mStride;
|
||||
else if (mBase)
|
||||
else if (mBase && mBase->mType != DT_TYPE_VOID)
|
||||
return mBase->mSize;
|
||||
else
|
||||
return 1;
|
||||
|
@ -1308,6 +1486,51 @@ Declaration* Declaration::ConstCast(Declaration* ntype)
|
|||
pdec->mSize = 2;
|
||||
return pdec;
|
||||
}
|
||||
else if (mType == DT_VARIABLE && mBase->mType == DT_TYPE_ARRAY)
|
||||
{
|
||||
Expression* ex = new Expression(mLocation, EX_VARIABLE);
|
||||
ex->mDecType = mBase;
|
||||
ex->mDecValue = this;
|
||||
|
||||
Declaration* pdec = this->Clone();
|
||||
pdec->mType = DT_CONST_POINTER;
|
||||
pdec->mValue = ex;
|
||||
pdec->mBase = ntype;
|
||||
pdec->mSize = 2;
|
||||
|
||||
return pdec;
|
||||
}
|
||||
else if (mType == DT_VARIABLE_REF)
|
||||
{
|
||||
Declaration* vtype = mBase->mBase;
|
||||
while (vtype && vtype->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
Declaration* dec = vtype->mParams;
|
||||
while (dec && dec->mOffset != mOffset)
|
||||
dec = dec->mNext;
|
||||
if (dec)
|
||||
vtype = dec->mBase;
|
||||
else
|
||||
vtype = nullptr;
|
||||
}
|
||||
|
||||
if (vtype && vtype->mType == DT_TYPE_ARRAY)
|
||||
{
|
||||
Expression* ex = new Expression(mLocation, EX_VARIABLE);
|
||||
ex->mDecType = mBase->mBase;
|
||||
ex->mDecValue = this;
|
||||
|
||||
Declaration* pdec = this->Clone();
|
||||
pdec->mType = DT_CONST_POINTER;
|
||||
pdec->mValue = ex;
|
||||
pdec->mBase = ntype;
|
||||
pdec->mSize = 2;
|
||||
|
||||
return pdec;
|
||||
}
|
||||
else
|
||||
return this;
|
||||
}
|
||||
else
|
||||
return this;
|
||||
}
|
||||
|
@ -1453,7 +1676,9 @@ const Ident* Declaration::FullIdent(void)
|
|||
Declaration* dec = mBase->mParams;
|
||||
while (dec)
|
||||
{
|
||||
tident = tident->Mangle(dec->mBase->MangleIdent()->mString);
|
||||
const Ident* mident = dec->mBase->MangleIdent();
|
||||
if (mident)
|
||||
tident = tident->Mangle(mident->mString);
|
||||
dec = dec->mNext;
|
||||
if (dec)
|
||||
tident = tident->Mangle(",");
|
||||
|
@ -1589,25 +1814,30 @@ const Ident* Declaration::MangleIdent(void)
|
|||
}
|
||||
|
||||
dec = dec->mNext;
|
||||
if (dec)
|
||||
if (mMangleIdent && dec)
|
||||
mMangleIdent = mMangleIdent->Mangle(",");
|
||||
}
|
||||
}
|
||||
else
|
||||
mMangleIdent = Ident::Unique("void");
|
||||
}
|
||||
else
|
||||
else if (mQualIdent)
|
||||
mMangleIdent = mQualIdent;
|
||||
else
|
||||
mMangleIdent = mIdent;
|
||||
|
||||
if (mTemplate)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (mFlags & DTF_CONST)
|
||||
mMangleIdent = mMangleIdent->PreMangle("const ");
|
||||
if (mFlags & DTF_VOLATILE)
|
||||
mMangleIdent = mMangleIdent->PreMangle("volatile ");
|
||||
if (mMangleIdent)
|
||||
{
|
||||
if (mFlags & DTF_CONST)
|
||||
mMangleIdent = mMangleIdent->PreMangle("const ");
|
||||
if (mFlags & DTF_VOLATILE)
|
||||
mMangleIdent = mMangleIdent->PreMangle("volatile ");
|
||||
}
|
||||
}
|
||||
|
||||
return mMangleIdent;
|
||||
|
@ -1668,19 +1898,8 @@ Declaration* Declaration::ExpandTemplate(DeclarationScope* scope)
|
|||
return this;
|
||||
}
|
||||
|
||||
bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
|
||||
bool Declaration::ResolveTemplateParameterList(Expression* pexp, Declaration* pdec, bool preliminary)
|
||||
{
|
||||
Declaration* pdec = tdec->mBase->mParams;
|
||||
|
||||
// Insert partially resolved templates
|
||||
Declaration* ptdec = tdec->mTemplate->mParams;
|
||||
while (ptdec)
|
||||
{
|
||||
if (ptdec->mBase)
|
||||
mScope->Insert(ptdec->mIdent, ptdec->mBase);
|
||||
ptdec = ptdec->mNext;
|
||||
}
|
||||
|
||||
Declaration* phead = nullptr, * ptail = nullptr;
|
||||
int pcnt = 0;
|
||||
|
||||
|
@ -1716,7 +1935,7 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!ResolveTemplate(ex->mDecType, pdec->mBase))
|
||||
if (!ResolveTemplate(ex->mDecType, pdec->mBase, false, preliminary))
|
||||
return false;
|
||||
|
||||
pdec = pdec->mNext;
|
||||
|
@ -1730,6 +1949,9 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
|
|||
{
|
||||
if (pdec->mType == DT_PACK_ARGUMENT)
|
||||
{
|
||||
if (preliminary)
|
||||
return true;
|
||||
|
||||
Declaration* tpdec = new Declaration(pdec->mLocation, DT_PACK_TYPE);
|
||||
if (pdec->mBase->mType == DT_TYPE_REFERENCE)
|
||||
tpdec->mIdent = pdec->mBase->mBase->mIdent;
|
||||
|
@ -1743,6 +1965,25 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
|
|||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
|
||||
{
|
||||
Declaration* pdec = tdec->mBase->mParams;
|
||||
|
||||
// Insert partially resolved templates
|
||||
Declaration* ptdec = tdec->mTemplate->mParams;
|
||||
while (ptdec)
|
||||
{
|
||||
if (ptdec->mBase)
|
||||
mScope->Insert(ptdec->mIdent, ptdec->mBase);
|
||||
ptdec = ptdec->mNext;
|
||||
}
|
||||
|
||||
if (!ResolveTemplateParameterList(pexp, pdec, true) || !ResolveTemplateParameterList(pexp, pdec, false))
|
||||
return false;
|
||||
|
||||
Declaration* ppdec = nullptr;
|
||||
ptdec = tdec->mTemplate->mParams;
|
||||
while (ptdec)
|
||||
|
@ -1785,7 +2026,7 @@ bool Declaration::CanResolveTemplate(Expression* pexp, Declaration* tdec)
|
|||
|
||||
if (pdec)
|
||||
{
|
||||
if (!ResolveTemplate(ex->mDecType, pdec->mBase))
|
||||
if (!ResolveTemplate(ex->mDecType, pdec->mBase, false, false))
|
||||
return false;
|
||||
|
||||
if (pdec->mType != DT_PACK_ARGUMENT)
|
||||
|
@ -1801,19 +2042,19 @@ bool Declaration::CanResolveTemplate(Expression* pexp, Declaration* tdec)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
||||
bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec, bool same, bool preliminary)
|
||||
{
|
||||
if (tdec->IsSame(fdec))
|
||||
return true;
|
||||
else if (fdec->IsReference())
|
||||
return ResolveTemplate(fdec->mBase, tdec);
|
||||
return ResolveTemplate(fdec->mBase, tdec, same, preliminary);
|
||||
else if (tdec->mType == DT_TYPE_FUNCTION)
|
||||
{
|
||||
if (fdec->mType == DT_TYPE_FUNCTION)
|
||||
{
|
||||
if (fdec->mBase)
|
||||
{
|
||||
if (!tdec->mBase || !ResolveTemplate(fdec->mBase, tdec->mBase))
|
||||
if (!tdec->mBase || !ResolveTemplate(fdec->mBase, tdec->mBase, true, preliminary))
|
||||
return false;
|
||||
}
|
||||
else if (tdec->mBase)
|
||||
|
@ -1852,7 +2093,7 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
|||
if (!fpdec)
|
||||
return false;
|
||||
|
||||
if (!ResolveTemplate(fpdec->mBase, tpdec->mBase))
|
||||
if (!ResolveTemplate(fpdec->mBase, tpdec->mBase, true, preliminary))
|
||||
return false;
|
||||
|
||||
fpdec = fpdec->mNext;
|
||||
|
@ -1868,16 +2109,16 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
|||
}
|
||||
else if (tdec->mType == DT_TYPE_REFERENCE)
|
||||
{
|
||||
return ResolveTemplate(fdec, tdec->mBase);
|
||||
return ResolveTemplate(fdec, tdec->mBase, true, preliminary);
|
||||
}
|
||||
else if (tdec->mType == DT_TYPE_RVALUEREF)
|
||||
{
|
||||
return ResolveTemplate(fdec, tdec->mBase);
|
||||
return ResolveTemplate(fdec, tdec->mBase, true, preliminary);
|
||||
}
|
||||
else if (tdec->mType == DT_TYPE_POINTER)
|
||||
{
|
||||
if (fdec->mType == DT_TYPE_POINTER || fdec->mType == DT_TYPE_ARRAY)
|
||||
return ResolveTemplate(fdec->mBase, tdec->mBase);
|
||||
return ResolveTemplate(fdec->mBase, tdec->mBase, true, preliminary);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
@ -1897,10 +2138,12 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
|||
if (pdec->mType == DT_TYPE_STRUCT)
|
||||
pdec = pdec->mScope->Lookup(tdec->mIdent);
|
||||
}
|
||||
else if (preliminary && !same)
|
||||
return true;
|
||||
else
|
||||
pdec = mScope->Insert(tdec->mIdent, fdec);
|
||||
|
||||
if (pdec && !pdec->IsSame(fdec))
|
||||
if (pdec && !(same ? pdec->IsSame(fdec) : pdec->CanAssign(fdec)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -1941,6 +2184,21 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
|||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (tdec->mType == DT_TYPE_ARRAY && fdec->mType == DT_TYPE_ARRAY && tdec->mTemplate && tdec->mBase->IsConstSame(fdec->mBase))
|
||||
{
|
||||
Declaration* ifdec = new Declaration(fdec->mLocation, DT_CONST_INTEGER);
|
||||
ifdec->mBase = TheSignedIntTypeDeclaration;
|
||||
ifdec->mSize = 2;
|
||||
ifdec->mInteger = fdec->mSize / fdec->mBase->mSize;
|
||||
|
||||
Declaration * ipdec = mScope->Insert(tdec->mTemplate->mIdent, ifdec);
|
||||
if (ipdec && !ipdec->IsSame(ifdec))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
else if (tdec->mType == DT_TYPE_STRUCT && fdec->mType == DT_TYPE_STRUCT && tdec->mTemplate)
|
||||
{
|
||||
|
@ -2006,13 +2264,27 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
|||
tpdec = tpdec->mNext;
|
||||
}
|
||||
|
||||
return !fpdec && !tpdec;
|
||||
if (fpdec)
|
||||
return false;
|
||||
else if (!tpdec)
|
||||
return true;
|
||||
else if (tpdec->mBase->mType == DT_PACK_TEMPLATE)
|
||||
{
|
||||
Declaration*tppack = new Declaration(tpdec->mLocation, DT_PACK_TYPE);
|
||||
Declaration* pdec = mScope->Insert(tpdec->mBase->mIdent, tppack);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
ftdec = ftdec->mNext;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (!same && tdec->CanAssign(fdec))
|
||||
return true;
|
||||
else
|
||||
return tdec->IsSame(fdec);
|
||||
}
|
||||
|
@ -2025,6 +2297,8 @@ Declaration* Declaration::Clone(void)
|
|||
ndec->mOffset = mOffset;
|
||||
ndec->mStride = mStride;
|
||||
ndec->mStripe = mStripe;
|
||||
ndec->mBits = mBits;
|
||||
ndec->mShift = mShift;
|
||||
ndec->mBase = mBase;
|
||||
ndec->mFlags = mFlags;
|
||||
ndec->mScope = mScope;
|
||||
|
@ -2044,6 +2318,7 @@ Declaration* Declaration::Clone(void)
|
|||
ndec->mMaxValue = mMaxValue;
|
||||
ndec->mCompilerOptions = mCompilerOptions;
|
||||
ndec->mParser = mParser;
|
||||
ndec->mNumVars = mNumVars;
|
||||
|
||||
return ndec;
|
||||
}
|
||||
|
@ -2095,6 +2370,8 @@ Declaration* Declaration::ToStriped(int stripe)
|
|||
ndec->mOffset = mOffset * stripe;
|
||||
ndec->mStride = mStride;
|
||||
ndec->mStripe = stripe;
|
||||
ndec->mBits = mBits;
|
||||
ndec->mShift = mShift;
|
||||
ndec->mFlags = mFlags;
|
||||
ndec->mIdent = mIdent;
|
||||
ndec->mQualIdent = mQualIdent;
|
||||
|
@ -2122,6 +2399,24 @@ Declaration* Declaration::ToStriped(int stripe)
|
|||
prev = pnec;
|
||||
p = p->mNext;
|
||||
}
|
||||
|
||||
Declaration* pndec = ndec->BuildPointer(mLocation);
|
||||
|
||||
mScope->Iterate([=](const Ident* ident, Declaration* vdec) {
|
||||
if (vdec->mType == DT_CONST_FUNCTION)
|
||||
{
|
||||
ndec->mScope->Insert(ident, vdec->ToAlternateThis(pndec));
|
||||
}
|
||||
});
|
||||
|
||||
ndec->mDestructor = mDestructor ? mDestructor->ToAlternateThis(pndec) : nullptr;
|
||||
ndec->mDefaultConstructor = mDefaultConstructor ? mDefaultConstructor->ToAlternateThis(pndec) : nullptr;
|
||||
ndec->mCopyConstructor = mCopyConstructor ? mCopyConstructor->ToAlternateThis(pndec) : nullptr;
|
||||
ndec->mMoveConstructor = mMoveConstructor ? mMoveConstructor->ToAlternateThis(pndec) : nullptr;
|
||||
ndec->mVectorConstructor = mVectorConstructor ? mVectorConstructor->ToAlternateThis(pndec, 2) : nullptr;
|
||||
ndec->mVectorDestructor = mVectorDestructor ? mVectorDestructor->ToAlternateThis(pndec, 2) : nullptr;
|
||||
ndec->mVectorCopyConstructor = mVectorCopyConstructor ? mVectorCopyConstructor->ToAlternateThis(pndec, 2) : nullptr;
|
||||
ndec->mVectorMoveConstructor = mVectorMoveConstructor ? mVectorMoveConstructor->ToAlternateThis(pndec, 2) : nullptr;
|
||||
}
|
||||
else if (mType == DT_TYPE_FUNCTION)
|
||||
{
|
||||
|
@ -2152,6 +2447,8 @@ Declaration* Declaration::ToVolatileType(void)
|
|||
ndec->mSize = mSize;
|
||||
ndec->mStride = mStride;
|
||||
ndec->mBase = mBase;
|
||||
ndec->mBits = mBits;
|
||||
ndec->mShift = mShift;
|
||||
ndec->mFlags = mFlags | DTF_VOLATILE;
|
||||
ndec->mScope = mScope;
|
||||
ndec->mParams = mParams;
|
||||
|
@ -2187,6 +2484,7 @@ Declaration* Declaration::ToVolatileType(void)
|
|||
ndec->mVectorConstructor = mVectorConstructor;
|
||||
ndec->mVectorDestructor = mVectorDestructor;
|
||||
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
|
||||
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
|
||||
ndec->mVTable = mVTable;
|
||||
|
||||
mVolatile = ndec;
|
||||
|
@ -2205,7 +2503,13 @@ Declaration* Declaration::ToConstType(void)
|
|||
Declaration* ndec = new Declaration(mLocation, mType);
|
||||
ndec->mSize = mSize;
|
||||
ndec->mStride = mStride;
|
||||
ndec->mBase = mBase;
|
||||
ndec->mStripe = mStripe;
|
||||
if (mType == DT_TYPE_ARRAY)
|
||||
ndec->mBase = mBase->ToConstType();
|
||||
else
|
||||
ndec->mBase = mBase;
|
||||
ndec->mBits = mBits;
|
||||
ndec->mShift = mShift;
|
||||
ndec->mFlags = mFlags | DTF_CONST;
|
||||
ndec->mScope = mScope;
|
||||
ndec->mParams = mParams;
|
||||
|
@ -2220,6 +2524,7 @@ Declaration* Declaration::ToConstType(void)
|
|||
ndec->mVectorConstructor = mVectorConstructor;
|
||||
ndec->mVectorDestructor = mVectorDestructor;
|
||||
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
|
||||
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
|
||||
ndec->mVTable = mVTable;
|
||||
|
||||
ndec->mMutable = this;
|
||||
|
@ -2229,6 +2534,35 @@ Declaration* Declaration::ToConstType(void)
|
|||
return mConst;
|
||||
}
|
||||
|
||||
Declaration* Declaration::ToAlternateThis(Declaration* pthis, int nthis)
|
||||
{
|
||||
Declaration* ndec = this->Clone();
|
||||
|
||||
if (mType == DT_CONST_FUNCTION)
|
||||
{
|
||||
ndec->mBase = mBase->ToAlternateThis(pthis, nthis);
|
||||
if (mValue)
|
||||
ndec->mValue = mValue->ToAlternateThis(mBase->mParams, ndec->mBase->mParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
Declaration* nparam = ndec->mParams->Clone();
|
||||
Declaration* npp = nparam;
|
||||
Declaration* kpp = ndec->mParams->mNext;
|
||||
while (kpp)
|
||||
{
|
||||
npp->mNext = kpp->Clone();
|
||||
npp = npp->mNext;
|
||||
kpp = npp->mNext;
|
||||
}
|
||||
nparam->mBase = pthis;
|
||||
if (nthis == 2)
|
||||
nparam->mNext->mBase = pthis;
|
||||
ndec->mParams = nparam;
|
||||
}
|
||||
return ndec;
|
||||
}
|
||||
|
||||
Declaration* Declaration::ToMutableType(void)
|
||||
{
|
||||
if (!(mFlags & DTF_CONST))
|
||||
|
@ -2239,8 +2573,11 @@ Declaration* Declaration::ToMutableType(void)
|
|||
Declaration* ndec = new Declaration(mLocation, mType);
|
||||
ndec->mSize = mSize;
|
||||
ndec->mStride = mStride;
|
||||
ndec->mStripe = mStripe;
|
||||
ndec->mBase = mBase;
|
||||
ndec->mFlags = mFlags | DTF_CONST;
|
||||
ndec->mBits = mBits;
|
||||
ndec->mShift = mShift;
|
||||
ndec->mFlags = mFlags & ~DTF_CONST;
|
||||
ndec->mScope = mScope;
|
||||
ndec->mParams = mParams;
|
||||
ndec->mIdent = mIdent;
|
||||
|
@ -2254,6 +2591,7 @@ Declaration* Declaration::ToMutableType(void)
|
|||
ndec->mVectorConstructor = mVectorConstructor;
|
||||
ndec->mVectorDestructor = mVectorDestructor;
|
||||
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
|
||||
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
|
||||
ndec->mVTable = mVTable;
|
||||
|
||||
ndec->mConst = this;
|
||||
|
@ -2583,6 +2921,9 @@ bool Declaration::IsSame(const Declaration* dec) const
|
|||
if (mType != dec->mType)
|
||||
return false;
|
||||
|
||||
if ((mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)) != (dec->mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)))
|
||||
return false;
|
||||
|
||||
if (!(mFlags & dec->mFlags & DTF_DEFINED) && mType == DT_TYPE_STRUCT)
|
||||
return mIdent == dec->mIdent;
|
||||
|
||||
|
@ -2591,9 +2932,6 @@ bool Declaration::IsSame(const Declaration* dec) const
|
|||
if (mStripe != dec->mStripe)
|
||||
return false;
|
||||
|
||||
if ((mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)) != (dec->mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)))
|
||||
return false;
|
||||
|
||||
if (mType == DT_CONST_INTEGER)
|
||||
return mInteger == dec->mInteger;
|
||||
else if (mType == DT_TYPE_INTEGER)
|
||||
|
@ -2640,7 +2978,7 @@ bool Declaration::IsSame(const Declaration* dec) const
|
|||
|
||||
return true;
|
||||
}
|
||||
else if (mType == DT_TYPE_TEMPLATE)
|
||||
else if (mType == DT_TYPE_TEMPLATE || mType == DT_PACK_TEMPLATE)
|
||||
{
|
||||
return mIdent == dec->mIdent;
|
||||
}
|
||||
|
@ -2773,7 +3111,7 @@ bool Declaration::CanAssign(const Declaration* fromType) const
|
|||
if (mScope == fromType->mScope || (mIdent == fromType->mIdent && mSize == fromType->mSize))
|
||||
return true;
|
||||
if (fromType->mBase)
|
||||
return this->CanAssign(fromType->mBase);
|
||||
return this->CanAssign(fromType->mBase->mBase);
|
||||
return false;
|
||||
}
|
||||
else if (mType == DT_TYPE_ARRAY && fromType->mType == DT_TYPE_ARRAY)
|
||||
|
@ -2810,6 +3148,10 @@ bool Declaration::CanAssign(const Declaration* fromType) const
|
|||
{
|
||||
return true;
|
||||
}
|
||||
else if (mBase->mType == DT_TYPE_FUNCTION && fromType->mType == DT_TYPE_ASSEMBLER)
|
||||
{
|
||||
return (mBase->mBase->mType == DT_TYPE_VOID && !mBase->mBase->mParams);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -2836,6 +3178,52 @@ bool Declaration::IsIndexed(void) const
|
|||
return mType == DT_TYPE_ARRAY || mType == DT_TYPE_POINTER;
|
||||
}
|
||||
|
||||
bool Declaration::ContainsArray(void) const
|
||||
{
|
||||
if (mType == DT_TYPE_ARRAY)
|
||||
return true;
|
||||
else if (mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
Declaration* p = mParams;
|
||||
while (p)
|
||||
{
|
||||
if (p->mType == DT_ELEMENT && p->mBase->ContainsArray())
|
||||
return true;
|
||||
p = p->mNext;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Declaration::IsShortIntStruct(void) const
|
||||
{
|
||||
if (mType == DT_TYPE_STRUCT && mSize <= 4 && !mDestructor && !mCopyConstructor)
|
||||
{
|
||||
Declaration* em = mParams;
|
||||
while (em)
|
||||
{
|
||||
if (em->mType == DT_ELEMENT && em->mBase->IsIntegerType() && em->mBits == 0)
|
||||
em = em->mNext;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (strcmp(mIdent->mString, "connection")) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Declaration::HasConstructor(void) const
|
||||
{
|
||||
return mType == DT_TYPE_STRUCT && mScope && mScope->Lookup(mIdent->PreMangle("+"));
|
||||
}
|
||||
|
||||
bool Declaration::IsComplexStruct(void) const
|
||||
{
|
||||
return mType == DT_TYPE_STRUCT && !IsShortIntStruct();
|
||||
}
|
||||
|
||||
bool Declaration::IsSimpleType(void) const
|
||||
{
|
||||
|
@ -2855,14 +3243,17 @@ Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
|
|||
Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration;
|
||||
Expression* TheVoidExpression;
|
||||
Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration;
|
||||
Declaration* TheTrueConstDeclaration, * TheFalseConstDeclaration;
|
||||
|
||||
void InitDeclarations(void)
|
||||
{
|
||||
static Location noloc;
|
||||
TheVoidTypeDeclaration = new Declaration(noloc, DT_TYPE_VOID);
|
||||
TheVoidTypeDeclaration->mSize = 0;
|
||||
TheVoidTypeDeclaration->mFlags = DTF_DEFINED;
|
||||
|
||||
TheConstVoidTypeDeclaration = new Declaration(noloc, DT_TYPE_VOID);
|
||||
TheConstVoidTypeDeclaration->mSize = 0;
|
||||
TheConstVoidTypeDeclaration->mFlags = DTF_DEFINED | DTF_CONST;
|
||||
|
||||
TheVoidPointerTypeDeclaration = new Declaration(noloc, DT_TYPE_POINTER);
|
||||
|
@ -2954,4 +3345,13 @@ void InitDeclarations(void)
|
|||
TheZeroFloatConstDeclaration->mBase = TheFloatTypeDeclaration;
|
||||
TheZeroFloatConstDeclaration->mSize = 4;
|
||||
|
||||
TheTrueConstDeclaration = new Declaration(noloc, DT_CONST_INTEGER);
|
||||
TheTrueConstDeclaration->mBase = TheBoolTypeDeclaration;
|
||||
TheTrueConstDeclaration->mSize = 1;
|
||||
TheTrueConstDeclaration->mInteger = 1;
|
||||
|
||||
TheFalseConstDeclaration = new Declaration(noloc, DT_CONST_INTEGER);
|
||||
TheFalseConstDeclaration->mBase = TheBoolTypeDeclaration;
|
||||
TheFalseConstDeclaration->mSize = 1;
|
||||
TheFalseConstDeclaration->mInteger = 0;
|
||||
}
|
||||
|
|
|
@ -126,6 +126,8 @@ static const uint64 DTF_VAR_ALIASING = (1ULL << 48);
|
|||
static const uint64 DTF_FPARAM_UNUSED = (1ULL << 49);
|
||||
static const uint64 DTF_DEPRECATED = (1ULL << 50);
|
||||
static const uint64 DTF_FUNC_NO_RETURN = (1ULL << 51);
|
||||
static const uint64 DTF_PLACED = (1ULL << 52);
|
||||
static const uint64 DTF_NO_PAGE_CROSS = (1ULL << 53);
|
||||
|
||||
|
||||
|
||||
|
@ -165,6 +167,8 @@ public:
|
|||
ScopeLevel mLevel;
|
||||
const Ident * mName;
|
||||
|
||||
DeclarationScope* Clone(void) const;
|
||||
|
||||
DeclarationScope* mParent;
|
||||
protected:
|
||||
struct Entry
|
||||
|
@ -214,6 +218,7 @@ enum ExpressionType
|
|||
EX_IF,
|
||||
EX_ELSE,
|
||||
EX_FOR,
|
||||
EX_FORBODY,
|
||||
EX_DO,
|
||||
EX_SCOPE,
|
||||
EX_BREAK,
|
||||
|
@ -237,9 +242,16 @@ enum ExpressionType
|
|||
EX_PACK,
|
||||
EX_PACK_TYPE,
|
||||
EX_LABEL,
|
||||
EX_GOTO
|
||||
EX_GOTO,
|
||||
EX_AGGREGATE
|
||||
};
|
||||
|
||||
static const uint32 ANAFL_LHS = (1U << 0);
|
||||
static const uint32 ANAFL_RHS = (1U << 1);
|
||||
static const uint32 ANAFL_ASSIGN = (1U << 2);
|
||||
static const uint32 ANAFL_ALIAS = (1U << 3);
|
||||
|
||||
|
||||
class Expression
|
||||
{
|
||||
public:
|
||||
|
@ -256,17 +268,23 @@ public:
|
|||
AsmInsType mAsmInsType;
|
||||
AsmInsMode mAsmInsMode;
|
||||
bool mConst;
|
||||
uint32 mFlags;
|
||||
|
||||
Expression* LogicInvertExpression(void);
|
||||
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr);
|
||||
Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection);
|
||||
bool HasSideEffects(void) const;
|
||||
Expression* ListAppend(Expression* lexp);
|
||||
Expression* ToAlternateThis(Declaration* pthis, Declaration* nthis);
|
||||
|
||||
void ReplaceVariable(Declaration* pvar, Declaration* nvar);
|
||||
|
||||
bool IsSame(const Expression* exp) const;
|
||||
bool IsRValue(void) const;
|
||||
bool IsLValue(void) const;
|
||||
bool IsConstRef(void) const;
|
||||
bool IsVolatile(void) const;
|
||||
|
||||
|
||||
void Dump(int ident) const;
|
||||
};
|
||||
|
@ -284,7 +302,7 @@ public:
|
|||
Token mToken;
|
||||
Declaration * mBase, * mParams, * mParamPack, * mNext, * mPrev, * mConst, * mMutable, * mVolatile;
|
||||
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment;
|
||||
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
|
||||
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment, * mVectorMoveConstructor, * mVectorMoveAssignment;
|
||||
Declaration * mVTable, * mClass, * mTemplate;
|
||||
Declaration * mForwardParam, * mForwardCall;
|
||||
|
||||
|
@ -326,12 +344,17 @@ public:
|
|||
bool IsSimpleType(void) const;
|
||||
bool IsReference(void) const;
|
||||
bool IsIndexed(void) const;
|
||||
bool ContainsArray(void) const;
|
||||
bool IsShortIntStruct(void) const;
|
||||
bool IsComplexStruct(void) const;
|
||||
bool HasConstructor(void) const;
|
||||
|
||||
void SetDefined(void);
|
||||
|
||||
Declaration* ToConstType(void);
|
||||
Declaration* ToMutableType(void);
|
||||
Declaration* ToVolatileType(void);
|
||||
Declaration* ToAlternateThis(Declaration* pthis, int nthis = 1);
|
||||
|
||||
Declaration* ToStriped(int stripe);
|
||||
Declaration* ToStriped(Errors* errors);
|
||||
|
@ -355,8 +378,9 @@ public:
|
|||
DecType ValueType(void) const;
|
||||
|
||||
bool CanResolveTemplate(Expression* pexp, Declaration* tdec);
|
||||
bool ResolveTemplate(Declaration* fdec, Declaration * tdec);
|
||||
bool ResolveTemplate(Declaration* fdec, Declaration * tdec, bool same, bool preliminary);
|
||||
bool ResolveTemplate(Expression* pexp, Declaration* tdec);
|
||||
bool ResolveTemplateParameterList(Expression* pexp, Declaration* pdec, bool preliminary);
|
||||
|
||||
Declaration* ExpandTemplate(DeclarationScope* scope);
|
||||
|
||||
|
@ -374,5 +398,6 @@ extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoid
|
|||
extern Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
|
||||
extern Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration;
|
||||
extern Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration;
|
||||
extern Declaration* TheTrueConstDeclaration, * TheFalseConstDeclaration;
|
||||
extern Expression* TheVoidExpression;
|
||||
|
||||
|
|
|
@ -4,11 +4,18 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
Errors::Errors(void)
|
||||
: mErrorCount(0)
|
||||
: mErrorCount(0), mMinLevel(EINFO_GENERIC), mDisabled(EERR_GENERIC)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ErrorID Errors::SetMinLevel(ErrorID id)
|
||||
{
|
||||
ErrorID pid = mMinLevel;
|
||||
mMinLevel = id;
|
||||
return pid;
|
||||
}
|
||||
|
||||
void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2)
|
||||
{
|
||||
if (!info1)
|
||||
|
@ -22,41 +29,44 @@ void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const Iden
|
|||
|
||||
void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const char* info1, const char * info2)
|
||||
{
|
||||
const char* level = "info";
|
||||
if (eid >= EERR_GENERIC)
|
||||
if (eid >= mMinLevel && !(eid < EERR_GENERIC && mDisabled[eid]))
|
||||
{
|
||||
level = "error";
|
||||
mErrorCount++;
|
||||
}
|
||||
else if (eid >= EWARN_GENERIC)
|
||||
{
|
||||
level = "warning";
|
||||
}
|
||||
const char* level = "info";
|
||||
if (eid >= EERR_GENERIC)
|
||||
{
|
||||
level = "error";
|
||||
mErrorCount++;
|
||||
}
|
||||
else if (eid >= EWARN_GENERIC)
|
||||
{
|
||||
level = "warning";
|
||||
}
|
||||
|
||||
if (loc.mFileName)
|
||||
{
|
||||
if (!info1)
|
||||
fprintf(stderr, "%s(%d, %d) : %s %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg);
|
||||
else if (!info2)
|
||||
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1);
|
||||
if (loc.mFileName)
|
||||
{
|
||||
if (!info1)
|
||||
fprintf(stderr, "%s(%d, %d) : %s %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg);
|
||||
else if (!info2)
|
||||
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1);
|
||||
else
|
||||
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s' != '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1, info2);
|
||||
|
||||
if (loc.mFrom)
|
||||
Error(*(loc.mFrom), EINFO_EXPANDED, "While expanding here");
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s' != '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1, info2);
|
||||
{
|
||||
if (!info1)
|
||||
fprintf(stderr, "oscar64: %s %d: %s\n", level, eid, msg);
|
||||
else if (!info2)
|
||||
fprintf(stderr, "oscar64: %s %d: %s '%s'\n", level, eid, msg, info1);
|
||||
else
|
||||
fprintf(stderr, "oscar64: %s %d: %s '%s' != '%s'\n", level, eid, msg, info1, info2);
|
||||
}
|
||||
|
||||
if (loc.mFrom)
|
||||
Error(*(loc.mFrom), EINFO_EXPANDED, "While expanding here");
|
||||
if (mErrorCount > 10 || eid >= EFATAL_GENERIC)
|
||||
exit(20);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!info1)
|
||||
fprintf(stderr, "oscar64: %s %d: %s\n", level, eid, msg);
|
||||
else if (!info2)
|
||||
fprintf(stderr, "oscar64: %s %d: %s '%s'\n", level, eid, msg, info1);
|
||||
else
|
||||
fprintf(stderr, "oscar64: %s %d: %s '%s' != '%s'\n", level, eid, msg, info1, info2);
|
||||
}
|
||||
|
||||
if (mErrorCount > 10 || eid >= EFATAL_GENERIC)
|
||||
exit(20);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "NumberSet.h"
|
||||
|
||||
|
||||
class Location
|
||||
{
|
||||
public:
|
||||
|
@ -10,7 +13,11 @@ public:
|
|||
Location() : mFileName(nullptr), mLine(0), mColumn(0), mFrom(nullptr) {}
|
||||
Location(const Location& loc, const Location* from)
|
||||
: mFileName(loc.mFileName), mLine(loc.mLine), mColumn(loc.mColumn), mFrom(from)
|
||||
{}
|
||||
{
|
||||
static volatile int k;
|
||||
if (from)
|
||||
k = from->mLine;
|
||||
}
|
||||
};
|
||||
|
||||
class Ident;
|
||||
|
@ -44,6 +51,8 @@ enum ErrorID
|
|||
EWARN_DEFAULT_COPY_DEPRECATED,
|
||||
EWARN_INSUFFICIENT_MEMORY,
|
||||
EWARN_FUNCTION_NOT_INLINED,
|
||||
EWARN_INVALID_VOID_POINTER_ARITHMETIC,
|
||||
EWARN_DIVISION_BY_ZERO,
|
||||
|
||||
EERR_GENERIC = 3000,
|
||||
EERR_FILE_NOT_FOUND,
|
||||
|
@ -103,7 +112,7 @@ enum ErrorID
|
|||
ERRR_INSTANTIATE_ABSTRACT_CLASS,
|
||||
ERRR_INVALID_GOTO,
|
||||
EERR_INVALID_INITIALIZER,
|
||||
|
||||
ERRR_INVALID_VOID_POINTER_ARITHMETIC,
|
||||
|
||||
EERR_INVALID_CONSTEXPR,
|
||||
EERR_DOUBLE_FREE,
|
||||
|
@ -118,9 +127,13 @@ enum ErrorID
|
|||
EERR_INVALID_CLASS_INITIALIZER,
|
||||
EERR_CALL_OF_DELETED_FUNCTION,
|
||||
|
||||
EERR_STATIC_ASSERT,
|
||||
|
||||
EFATAL_GENERIC = 4000,
|
||||
EFATAL_OUT_OF_MEMORY,
|
||||
EFATAL_MACRO_EXPANSION_DEPTH,
|
||||
|
||||
ERROR_MAX = 5000
|
||||
};
|
||||
|
||||
class Errors
|
||||
|
@ -128,7 +141,12 @@ class Errors
|
|||
public:
|
||||
Errors(void);
|
||||
|
||||
ErrorID SetMinLevel(ErrorID id);
|
||||
|
||||
int mErrorCount;
|
||||
ErrorID mMinLevel;
|
||||
|
||||
NumberSet mDisabled;
|
||||
|
||||
void Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2 = nullptr);
|
||||
void Error(const Location& loc, ErrorID eid, const char* msg, const char* info1 = nullptr, const char* info2 = nullptr);
|
||||
|
|
|
@ -393,7 +393,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
|
||||
if (procDec->mValue && procDec->mValue->mType == EX_DISPATCH)
|
||||
{
|
||||
Declaration* maxf = nullptr;
|
||||
Declaration* maxf = nullptr, * reff = nullptr;
|
||||
|
||||
bool stackCall = false;
|
||||
|
||||
|
@ -402,7 +402,10 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
Declaration* cf = procDec->mCalled[i];
|
||||
|
||||
if (cf->mBase->mFlags & DTF_STACKCALL)
|
||||
{
|
||||
stackCall = true;
|
||||
reff = cf;
|
||||
}
|
||||
|
||||
if (!maxf)
|
||||
maxf = cf;
|
||||
|
@ -410,6 +413,9 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
maxf = cf;
|
||||
}
|
||||
|
||||
if (!reff)
|
||||
reff = maxf;
|
||||
|
||||
for (int i = 0; i < procDec->mCalled.Size(); i++)
|
||||
{
|
||||
Declaration* cf = procDec->mCalled[i];
|
||||
|
@ -420,9 +426,9 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
cf->mBase->mFlags |= DTF_STACKCALL;
|
||||
}
|
||||
|
||||
if (cf != maxf)
|
||||
if (cf != reff)
|
||||
{
|
||||
Declaration* fp = cf->mBase->mParams, * mp = maxf->mBase->mParams;
|
||||
Declaration* fp = cf->mBase->mParams, * mp = reff->mBase->mParams;
|
||||
while (fp)
|
||||
{
|
||||
fp->mVarIndex = mp->mVarIndex;
|
||||
|
@ -431,10 +437,11 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
}
|
||||
|
||||
assert(!mp);
|
||||
|
||||
cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase;
|
||||
cf->mBase->mFastCallSize = cf->mFastCallSize = maxf->mBase->mFastCallSize;
|
||||
}
|
||||
|
||||
if (cf != maxf)
|
||||
cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase;
|
||||
}
|
||||
|
||||
procDec->mFastCallBase = procDec->mBase->mFastCallBase;
|
||||
|
@ -474,7 +481,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
fplimit += 256;
|
||||
}
|
||||
|
||||
if (procDec->mBase->mBase->mType == DT_TYPE_STRUCT)
|
||||
if (procDec->mBase->mBase->IsComplexStruct())
|
||||
{
|
||||
if (nbase < numfpzero && nbase + 2 > numfpzero)
|
||||
nbase = numfpzero;
|
||||
|
@ -658,7 +665,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
|
|||
if (mCompilerOptions & COPT_OPTIMIZE_CONST_EXPRESSIONS)
|
||||
dec->mFlags |= DTF_FUNC_CONSTEXPR;
|
||||
dec->mFlags |= DTF_FUNC_PURE;
|
||||
Analyze(exp, dec, false, false);
|
||||
Analyze(exp, dec, 0);
|
||||
|
||||
Declaration* pdec = dec->mBase->mParams;
|
||||
int vi = 0;
|
||||
|
@ -678,7 +685,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
|
|||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent);
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->FullIdent());
|
||||
if (cexp)
|
||||
mErrors->Error(cexp->mLocation, EINFO_CALLED_FROM, "Called from here");
|
||||
|
||||
|
@ -754,7 +761,7 @@ void GlobalAnalyzer::AnalyzeGlobalVariable(Declaration* dec)
|
|||
|
||||
if (dec->mValue)
|
||||
{
|
||||
Analyze(dec->mValue, dec, false, false);
|
||||
Analyze(dec->mValue, dec, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -764,17 +771,19 @@ void GlobalAnalyzer::AnalyzeInit(Declaration* mdec)
|
|||
while (mdec)
|
||||
{
|
||||
if (mdec->mValue)
|
||||
RegisterProc(Analyze(mdec->mValue, mdec, false, false));
|
||||
RegisterProc(Analyze(mdec->mValue, mdec, 0));
|
||||
else if (mdec->mParams)
|
||||
AnalyzeInit(mdec->mParams);
|
||||
mdec = mdec->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, bool lhs, bool aliasing)
|
||||
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uint32 flags)
|
||||
{
|
||||
Declaration* ldec, * rdec;
|
||||
|
||||
exp->mFlags = flags;
|
||||
|
||||
switch (exp->mType)
|
||||
{
|
||||
case EX_ERROR:
|
||||
|
@ -792,7 +801,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
}
|
||||
else if (exp->mDecValue->mType == DT_CONST_POINTER)
|
||||
{
|
||||
ldec = Analyze(exp->mDecValue->mValue, procDec, true, true);
|
||||
ldec = Analyze(exp->mDecValue->mValue, procDec, ANAFL_LHS | ANAFL_ALIAS);
|
||||
if (ldec->mType == DT_VARIABLE)
|
||||
ldec->mFlags |= DTF_VAR_ALIASING;
|
||||
RegisterProc(ldec);
|
||||
|
@ -816,7 +825,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (mCompilerOptions & COPT_DEBUGINFO)
|
||||
exp->mDecValue->mReferences.Push(exp);
|
||||
|
||||
if (aliasing)
|
||||
if (flags & ANAFL_ALIAS)
|
||||
{
|
||||
Declaration* dec = exp->mDecValue;
|
||||
while (dec->mType == DT_VARIABLE_REF)
|
||||
|
@ -833,14 +842,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (!(type->mFlags & DTF_CONST))
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
procDec->mFlags &= ~DTF_FUNC_PURE;
|
||||
|
||||
AnalyzeGlobalVariable(exp->mDecValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
exp->mDecValue->mFlags |= DTF_VAR_ADDRESS;
|
||||
|
||||
if (!(exp->mDecValue->mFlags & DTF_ANALYZED))
|
||||
|
@ -854,8 +863,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_ASSIGNMENT:
|
||||
procDec->mComplexity += 5 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, true, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
|
||||
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
|
||||
if (exp->mLeft->mType == EX_VARIABLE && exp->mRight->mType == EX_CALL && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
|
||||
exp->mLeft->mDecValue->mFlags |= DTF_VAR_ALIASING;
|
||||
RegisterProc(rdec);
|
||||
|
@ -864,33 +873,33 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_BINARY:
|
||||
procDec->mComplexity += 10 * exp->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, lhs, false);
|
||||
rdec = Analyze(exp->mRight, procDec, lhs, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
rdec = Analyze(exp->mRight, procDec, flags & ~ANAFL_ALIAS);
|
||||
return ldec;
|
||||
|
||||
case EX_RELATIONAL:
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_RHS);
|
||||
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
|
||||
return TheBoolTypeDeclaration;
|
||||
|
||||
case EX_PREINCDEC:
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
return Analyze(exp->mLeft, procDec, true, false);
|
||||
return Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
|
||||
case EX_PREFIX:
|
||||
if (exp->mToken == TK_BINARY_AND)
|
||||
{
|
||||
ldec = Analyze(exp->mLeft, procDec, true, true);
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_ALIAS);
|
||||
if (ldec->mType == DT_VARIABLE)
|
||||
ldec->mFlags |= DTF_VAR_ALIASING;
|
||||
}
|
||||
else if (exp->mToken == TK_MUL)
|
||||
{
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
procDec->mFlags &= ~DTF_FUNC_PURE;
|
||||
|
||||
return exp->mDecType;
|
||||
|
@ -899,10 +908,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
{
|
||||
return TheUnsignedCharTypeDeclaration;
|
||||
}
|
||||
else if (exp->mToken == TK_SIZEOF)
|
||||
{
|
||||
return TheUnsignedIntTypeDeclaration;
|
||||
}
|
||||
else
|
||||
{
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
return Analyze(exp->mLeft, procDec, false, false);
|
||||
return Analyze(exp->mLeft, procDec, 0);
|
||||
}
|
||||
break;
|
||||
case EX_POSTFIX:
|
||||
|
@ -911,31 +924,31 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_POSTINCDEC:
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
return Analyze(exp->mLeft, procDec, true, false);
|
||||
return Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
|
||||
case EX_INDEX:
|
||||
procDec->mComplexity += 10 * exp->mRight->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, lhs, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT)
|
||||
{
|
||||
ldec = ldec->mBase;
|
||||
if (ldec->mType == DT_TYPE_POINTER)
|
||||
{
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
procDec->mFlags &= ~DTF_FUNC_PURE;
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
}
|
||||
}
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
if (ldec->mBase)
|
||||
return ldec->mBase;
|
||||
break;
|
||||
case EX_QUALIFY:
|
||||
Analyze(exp->mLeft, procDec, lhs, aliasing);
|
||||
Analyze(exp->mLeft, procDec, flags);
|
||||
return exp->mDecValue->mBase;
|
||||
case EX_DISPATCH:
|
||||
procDec->mFlags |= DTF_PREVENT_INLINE;
|
||||
Analyze(exp->mLeft, procDec, lhs, false);
|
||||
Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
// RegisterCall(procDec, exp->mLeft->mDecType);
|
||||
break;
|
||||
case EX_VCALL:
|
||||
|
@ -946,7 +959,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_INLINE:
|
||||
procDec->mComplexity += 10;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue)
|
||||
{
|
||||
|
||||
|
@ -1033,7 +1046,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (pex->mType == EX_CALL && IsStackParam(pex->mDecType) && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)))
|
||||
ldec->mBase->mFlags |= DTF_STACKCALL;
|
||||
|
||||
RegisterProc(Analyze(pex, procDec, pdec && pdec->mBase->IsReference(), false));
|
||||
RegisterProc(Analyze(pex, procDec, (pdec && pdec->mBase->IsReference()) ? ANAFL_LHS : 0));
|
||||
|
||||
if (pdec)
|
||||
pdec = pdec->mNext;
|
||||
|
@ -1047,12 +1060,12 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
break;
|
||||
case EX_LIST:
|
||||
case EX_COMMA:
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, false, false));
|
||||
return Analyze(exp->mRight, procDec, false, false);
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, 0));
|
||||
return Analyze(exp->mRight, procDec, 0);
|
||||
case EX_RETURN:
|
||||
if (exp->mLeft)
|
||||
{
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference(), false));
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference() ? ANAFL_LHS : 0));
|
||||
if (procDec->mBase->mBase && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
|
||||
{
|
||||
if (procDec->mBase->mBase->mMoveConstructor)
|
||||
|
@ -1073,47 +1086,47 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (exp->mType == EX_SEQUENCE)
|
||||
{
|
||||
if (exp->mLeft)
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
exp = exp->mRight;
|
||||
}
|
||||
else
|
||||
return Analyze(exp, procDec, false, false);
|
||||
return Analyze(exp, procDec, 0);
|
||||
|
||||
} while (exp);
|
||||
break;
|
||||
|
||||
case EX_SCOPE:
|
||||
Analyze(exp->mLeft, procDec, false, false);
|
||||
Analyze(exp->mLeft, procDec, 0);
|
||||
break;
|
||||
|
||||
case EX_CONSTRUCT:
|
||||
if (exp->mLeft->mLeft)
|
||||
Analyze(exp->mLeft->mLeft, procDec, false, false);
|
||||
Analyze(exp->mLeft->mLeft, procDec, 0);
|
||||
if (exp->mLeft->mRight)
|
||||
Analyze(exp->mLeft->mRight, procDec, false, false);
|
||||
Analyze(exp->mLeft->mRight, procDec, 0);
|
||||
if (exp->mRight)
|
||||
return Analyze(exp->mRight, procDec, false, false);
|
||||
return Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
|
||||
case EX_CLEANUP:
|
||||
Analyze(exp->mRight, procDec, false, false);
|
||||
return Analyze(exp->mLeft, procDec, lhs, false);
|
||||
Analyze(exp->mRight, procDec, 0);
|
||||
return Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
|
||||
case EX_WHILE:
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
|
||||
procDec->mComplexity += 20;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_IF:
|
||||
procDec->mComplexity += 20;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight->mLeft, procDec, 0);
|
||||
if (exp->mRight->mRight)
|
||||
rdec = Analyze(exp->mRight->mRight, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_ELSE:
|
||||
break;
|
||||
|
@ -1123,18 +1136,23 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
procDec->mComplexity += 30;
|
||||
|
||||
if (exp->mLeft->mRight)
|
||||
ldec = Analyze(exp->mLeft->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft->mRight, procDec, 0);
|
||||
if (exp->mLeft->mLeft->mLeft)
|
||||
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
if (exp->mLeft->mLeft->mRight)
|
||||
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_FORBODY:
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
if (exp->mRight)
|
||||
Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_DO:
|
||||
procDec->mComplexity += 20;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_BREAK:
|
||||
case EX_CONTINUE:
|
||||
|
@ -1143,18 +1161,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_TYPE:
|
||||
break;
|
||||
case EX_TYPECAST:
|
||||
return Analyze(exp->mLeft, procDec, false, false);
|
||||
return Analyze(exp->mLeft, procDec, 0);
|
||||
break;
|
||||
case EX_LOGICAL_AND:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_LOGICAL_OR:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_LOGICAL_NOT:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
break;
|
||||
case EX_ASSEMBLER:
|
||||
procDec->mFlags |= DTF_FUNC_ASSEMBLER;
|
||||
|
@ -1165,14 +1183,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_UNDEFINED:
|
||||
break;
|
||||
case EX_SWITCH:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
exp = exp->mRight;
|
||||
while (exp)
|
||||
{
|
||||
procDec->mComplexity += 10;
|
||||
|
||||
if (exp->mLeft->mRight)
|
||||
rdec = Analyze(exp->mLeft->mRight, procDec, false, false);
|
||||
rdec = Analyze(exp->mLeft->mRight, procDec, 0);
|
||||
exp = exp->mRight;
|
||||
}
|
||||
break;
|
||||
|
@ -1183,9 +1201,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_CONDITIONAL:
|
||||
procDec->mComplexity += exp->mDecType->mSize * 10;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
RegisterProc(Analyze(exp->mRight->mLeft, procDec, lhs, aliasing));
|
||||
RegisterProc(Analyze(exp->mRight->mRight, procDec, lhs, aliasing));
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
RegisterProc(Analyze(exp->mRight->mLeft, procDec, flags));
|
||||
RegisterProc(Analyze(exp->mRight->mRight, procDec, flags));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ protected:
|
|||
int CallerInvokes(Declaration* called);
|
||||
int CallerInvokes(Declaration* caller, Declaration* called);
|
||||
|
||||
Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs, bool aliasing);
|
||||
Declaration* Analyze(Expression* exp, Declaration* procDec, uint32 flags);
|
||||
|
||||
bool IsStackParam(const Declaration* pdec) const;
|
||||
bool MarkCycle(Declaration* rootDec, Declaration* procDec);
|
||||
|
|
|
@ -60,7 +60,7 @@ void GlobalOptimizer::Reset(void)
|
|||
mFunctions.SetSize(0);
|
||||
mGlobalVariables.SetSize(0);
|
||||
mCalledFunctions.SetSize(0);
|
||||
mCalledFunctions.SetSize(0);
|
||||
mCallingFunctions.SetSize(0);
|
||||
}
|
||||
|
||||
void GlobalOptimizer::PropagateParamCommas(Expression*& fexp, Expression*& exp)
|
||||
|
@ -189,7 +189,7 @@ bool GlobalOptimizer::CheckUnusedLocals(Expression*& exp)
|
|||
if (vexp->mType == EX_VARIABLE)
|
||||
{
|
||||
Declaration* vdec = vexp->mDecValue;
|
||||
if (vdec->mType == DT_VARIABLE && !(vdec->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(vdec->mOptFlags & OPTF_VAR_USED))
|
||||
if (vdec->mType == DT_VARIABLE && !(vdec->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(vdec->mOptFlags & OPTF_VAR_USED) && !exp->mRight->IsVolatile())
|
||||
{
|
||||
exp = exp->mRight;
|
||||
return true;
|
||||
|
@ -243,6 +243,19 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
|
|||
bool changed = false;
|
||||
if (exp)
|
||||
{
|
||||
if (ReplaceParamConst(exp->mLeft, param))
|
||||
changed = true;
|
||||
if (ReplaceParamConst(exp->mRight, param))
|
||||
changed = true;
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (exp->mLeft)
|
||||
exp->mLeft = exp->mLeft->ConstantFold(mErrors, nullptr);
|
||||
if (exp->mRight)
|
||||
exp->mRight = exp->mRight->ConstantFold(mErrors, nullptr);
|
||||
}
|
||||
|
||||
if (exp->mType == EX_VARIABLE && exp->mDecValue == param)
|
||||
{
|
||||
exp->mType = EX_CONSTANT;
|
||||
|
@ -251,10 +264,6 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
|
|||
changed = true;
|
||||
}
|
||||
|
||||
if (ReplaceParamConst(exp->mLeft, param))
|
||||
changed = true;
|
||||
if (ReplaceParamConst(exp->mRight, param))
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
@ -266,14 +275,22 @@ bool GlobalOptimizer::ReplaceGlobalConst(Expression* exp)
|
|||
{
|
||||
if (exp->mType == EX_VARIABLE && (exp->mDecValue->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(exp->mDecValue->mOptFlags & (OPTF_VAR_MODIFIED | OPTF_VAR_ADDRESS)) && exp->mDecValue->mValue)
|
||||
{
|
||||
|
||||
Expression* cexp = exp->mDecValue->mValue;
|
||||
if (cexp->mType == EX_CONSTANT &&
|
||||
(cexp->mDecValue->mType == DT_CONST_ADDRESS || cexp->mDecValue->mType == DT_CONST_INTEGER ||
|
||||
cexp->mDecValue->mType == DT_CONST_POINTER || cexp->mDecValue->mType == DT_CONST_FLOAT))
|
||||
if (cexp->mType == EX_CONSTANT)
|
||||
{
|
||||
exp->mType = EX_CONSTANT;
|
||||
exp->mDecValue = cexp->mDecValue;
|
||||
changed = true;
|
||||
|
||||
if (cexp->mDecValue->mType == DT_CONST_ADDRESS || cexp->mDecValue->mType == DT_CONST_INTEGER ||
|
||||
cexp->mDecValue->mType == DT_CONST_POINTER || cexp->mDecValue->mType == DT_CONST_FLOAT)
|
||||
{
|
||||
exp->mType = EX_CONSTANT;
|
||||
exp->mDecValue = cexp->mDecValue->ConstCast(exp->mDecType);
|
||||
changed = true;
|
||||
}
|
||||
else if (exp->mDecValue->mBase->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
exp->mDecValue->mBase = exp->mDecValue->mBase->ToConstType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,7 +341,7 @@ bool GlobalOptimizer::Optimize(void)
|
|||
|
||||
if (!(func->mOptFlags & OPTF_FUNC_VARIABLE) && !(func->mBase->mFlags & DTF_VIRTUAL))
|
||||
{
|
||||
if (!(func->mOptFlags & OPTF_VAR_USED) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
|
||||
if (!(func->mOptFlags & (OPTF_VAR_USED | OPTF_VAR_ADDRESS)) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
|
||||
{
|
||||
#if DUMP_OPTS
|
||||
printf("Remove return value\n");
|
||||
|
@ -382,6 +399,7 @@ bool GlobalOptimizer::Optimize(void)
|
|||
{
|
||||
if (ReplaceParamConst(func->mValue, pdec))
|
||||
{
|
||||
func->mValue = func->mValue->ConstantFold(mErrors, nullptr);
|
||||
#if DUMP_OPTS
|
||||
printf("Const parameter %s\n", pdec->mIdent ? pdec->mIdent->mString : "_");
|
||||
#endif
|
||||
|
@ -444,7 +462,7 @@ void GlobalOptimizer::AnalyzeProcedure(Expression* exp, Declaration* procDec)
|
|||
Analyze(exp, procDec, false);
|
||||
}
|
||||
else
|
||||
mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->mQualIdent);
|
||||
mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->FullIdent());
|
||||
|
||||
procDec->mOptFlags &= ~OPTF_ANALYZING;
|
||||
}
|
||||
|
@ -596,9 +614,6 @@ void GlobalOptimizer::RegisterProc(Declaration* to)
|
|||
}
|
||||
}
|
||||
|
||||
static const uint32 ANAFL_LHS = (1U << 0);
|
||||
static const uint32 ANAFL_RHS = (1U << 1);
|
||||
|
||||
Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uint32 flags)
|
||||
{
|
||||
Declaration* ldec, * rdec;
|
||||
|
@ -644,8 +659,10 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
|
||||
if (flags & ANAFL_LHS)
|
||||
exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS;
|
||||
if (exp->mDecValue->mBase->IsReference() && (flags & ANAFL_ASSIGN))
|
||||
exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
|
||||
|
||||
if (exp->mDecValue->mType == DT_ARGUMENT)
|
||||
if (exp->mDecValue->mType == DT_ARGUMENT && (flags & ANAFL_LHS))
|
||||
{
|
||||
exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD;
|
||||
exp->mDecValue->mForwardParam = nullptr;
|
||||
|
@ -655,7 +672,12 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
case EX_INITIALIZATION:
|
||||
case EX_ASSIGNMENT:
|
||||
if (exp->mToken == TK_ASSIGN)
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
|
||||
{
|
||||
if (exp->mType == EX_ASSIGNMENT)
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_ASSIGN | flags);
|
||||
else
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
|
||||
}
|
||||
else
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS | flags);
|
||||
|
||||
|
@ -803,6 +825,22 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
pdec->mOptFlags |= OPTF_VAR_CONST;
|
||||
}
|
||||
}
|
||||
else if (pex->mType == EX_VARIABLE && pdec->mBase->mType == DT_TYPE_POINTER && pex->mDecType->mType == DT_TYPE_ARRAY && (pex->mDecValue->mFlags & (DTF_GLOBAL | DTF_STATIC)) && pdec->mBase->CanAssign(pex->mDecType))
|
||||
{
|
||||
if (pdec->mOptFlags & OPTF_VAR_CONST)
|
||||
{
|
||||
if (pdec->mValue->mType != EX_VARIABLE || pdec->mValue->mDecValue != pex->mDecValue)
|
||||
{
|
||||
pdec->mOptFlags |= OPTF_VAR_NOCONST;
|
||||
pdec->mOptFlags &= ~OPTF_VAR_CONST;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pdec->mValue = pex;
|
||||
pdec->mOptFlags |= OPTF_VAR_CONST;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pdec->mOptFlags |= OPTF_VAR_NOCONST;
|
||||
|
@ -948,13 +986,20 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
if (exp->mLeft->mLeft->mRight)
|
||||
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_FORBODY:
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
if (exp->mRight)
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_DO:
|
||||
ldec = Analyze(exp->mRight, procDec, 0);
|
||||
rdec = Analyze(exp->mLeft, procDec, ANAFL_RHS);
|
||||
break;
|
||||
case EX_BREAK:
|
||||
case EX_CONTINUE:
|
||||
break;
|
||||
case EX_ASSUME:
|
||||
return Analyze(exp->mLeft, procDec, ANAFL_RHS);
|
||||
break;
|
||||
case EX_TYPE:
|
||||
break;
|
||||
|
|
|
@ -47,7 +47,7 @@ const Ident* Ident::Unique(const char* str)
|
|||
|
||||
const Ident* Ident::PreMangle(const char* str) const
|
||||
{
|
||||
char buffer[200];
|
||||
char buffer[1000];
|
||||
strcpy_s(buffer, str);
|
||||
strcat_s(buffer, mString);
|
||||
return Unique(buffer);
|
||||
|
@ -55,14 +55,14 @@ const Ident* Ident::PreMangle(const char* str) const
|
|||
|
||||
const Ident* Ident::Unique(const char* str, int id)
|
||||
{
|
||||
char buffer[200];
|
||||
char buffer[1000];
|
||||
sprintf_s(buffer, "%s#%d", str, id);
|
||||
return Unique(buffer);
|
||||
}
|
||||
|
||||
const Ident* Ident::Mangle(const char* str) const
|
||||
{
|
||||
char buffer[200];
|
||||
char buffer[1000];
|
||||
strcpy_s(buffer, mString);
|
||||
strcat_s(buffer, str);
|
||||
return Unique(buffer);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -169,6 +169,7 @@ public:
|
|||
} mMinState, mMaxState;
|
||||
|
||||
bool Same(const IntegerValueRange& range) const;
|
||||
bool Weaker(const IntegerValueRange& range) const;
|
||||
bool Merge(const IntegerValueRange& range, bool head, bool initial);
|
||||
void Expand(const IntegerValueRange& range);
|
||||
void Union(const IntegerValueRange& range);
|
||||
|
@ -198,7 +199,7 @@ public:
|
|||
|
||||
|
||||
|
||||
typedef GrowingArray<IntegerValueRange> GrowingIntegerValueRangeArray;
|
||||
typedef ExpandingArray<IntegerValueRange> GrowingIntegerValueRangeArray;
|
||||
|
||||
class ValueSet
|
||||
{
|
||||
|
@ -380,7 +381,7 @@ public:
|
|||
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator;
|
||||
GrowingInstructionArray mInstructions;
|
||||
|
||||
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath, mValueRangeValid;
|
||||
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath, mValueRangeValid, mPatched, mLoopDebug;
|
||||
mutable int mMark;
|
||||
|
||||
NumberSet mLocalUsedTemps, mLocalModifiedTemps;
|
||||
|
@ -423,14 +424,15 @@ public:
|
|||
InterCodeBasicBlock* Clone(void);
|
||||
|
||||
void Append(InterInstruction * code);
|
||||
void AppendBeforeBranch(InterInstruction* code);
|
||||
void AppendBeforeBranch(InterInstruction* code, bool loopindex = false);
|
||||
const InterInstruction* FindByDst(int dst) const;
|
||||
void Close(InterCodeBasicBlock* trueJump, InterCodeBasicBlock* falseJump);
|
||||
|
||||
void CollectEntries(void);
|
||||
void CollectEntryBlocks(InterCodeBasicBlock* from);
|
||||
void GenerateTraces(bool expand, bool compact);
|
||||
void GenerateTraces(int expand, bool compact);
|
||||
void BuildDominatorTree(InterCodeBasicBlock * from);
|
||||
bool StripLoopHead(void);
|
||||
|
||||
bool MergeSameConditionTraces(void);
|
||||
|
||||
|
@ -448,6 +450,7 @@ public:
|
|||
void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps);
|
||||
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
|
||||
bool ForwardConstTemps(const GrowingInstructionPtrArray& ctemps);
|
||||
bool PropagateConstCompareResults(void);
|
||||
|
||||
bool EarlyBranchElimination(const GrowingInstructionPtrArray& ctemps);
|
||||
|
||||
|
@ -480,6 +483,8 @@ public:
|
|||
|
||||
bool CheckSingleBlockLimitedLoop(InterCodeBasicBlock*& pblock, int64 & nloop);
|
||||
|
||||
bool TempIsUnsigned(int temp);
|
||||
|
||||
void RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
|
||||
void BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
|
||||
void UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
|
||||
|
@ -515,6 +520,8 @@ public:
|
|||
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars, const GrowingInterCodeProcedurePtrArray& staticProcs, FastNumberSet& fsingle);
|
||||
bool EliminateDeadBranches(void);
|
||||
|
||||
bool EliminateIntegerSumAliasTemps(const GrowingInstructionPtrArray& tvalue);
|
||||
|
||||
bool MergeIndexedLoadStore(const GrowingInstructionPtrArray& tvalue);
|
||||
bool SimplifyIntegerNumeric(const GrowingInstructionPtrArray& tvalue, int& spareTemps);
|
||||
bool SimplifyPointerOffsets(void);
|
||||
|
@ -623,29 +630,42 @@ public:
|
|||
void SingleBlockLoopUnrolling(void);
|
||||
bool SingleBlockLoopPointerSplit(int& spareTemps);
|
||||
bool SingleBlockLoopPointerToByte(int& spareTemps);
|
||||
bool SingleBlockLoopSinking(int& spareTemps);
|
||||
bool CollectLoopBody(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*> & body);
|
||||
bool CollectLoopBodyRecursive(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*>& body);
|
||||
void CollectLoopPath(const ExpandingArray<InterCodeBasicBlock*>& body, ExpandingArray<InterCodeBasicBlock*>& path);
|
||||
void InnerLoopOptimization(const NumberSet& aliasedParams);
|
||||
void ConstLoopOptimization(void);
|
||||
bool EmptyLoopOptimization(void);
|
||||
void EliminateDoubleLoopCounter(void);
|
||||
void PushMoveOutOfLoop(void);
|
||||
bool MoveConditionOutOfLoop(void);
|
||||
void SingleLoopCountZeroCheck(void);
|
||||
void InnerLoopCountZeroCheck(void);
|
||||
bool PostDecLoopOptimization(void);
|
||||
bool Flatten2DLoop(void);
|
||||
|
||||
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue);
|
||||
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue, bool loops);
|
||||
void RemoveUnusedMallocs(void);
|
||||
|
||||
bool PullStoreUpToConstAddress(void);
|
||||
|
||||
bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray<InterCodeBasicBlock*>& body);
|
||||
bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, ExpandingArray<InterCodeBasicBlock*>& body);
|
||||
|
||||
bool CollectGenericLoop(ExpandingArray<InterCodeBasicBlock*>& lblocks);
|
||||
bool CollectSingleEntryGenericLoop(ExpandingArray<InterCodeBasicBlock*>& lblocks);
|
||||
void CollectReachable(ExpandingArray<InterCodeBasicBlock*>& lblock);
|
||||
|
||||
bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
|
||||
bool MergeLoopTails(void);
|
||||
|
||||
bool ChangeTrueJump(InterCodeBasicBlock* block);
|
||||
bool ChangeFalseJump(InterCodeBasicBlock* block);
|
||||
|
||||
InterCodeBasicBlock* CheckIsSimpleIntRangeBranch(const GrowingIntegerValueRangeArray & irange);
|
||||
InterCodeBasicBlock* CheckIsConstBranch(const GrowingInstructionPtrArray& cins);
|
||||
bool ShortcutConstBranches(const GrowingInstructionPtrArray& cins);
|
||||
bool ShortcutDuplicateBranches(void);
|
||||
|
||||
InterCodeBasicBlock* BuildLoopPrefix(void);
|
||||
void BuildLoopSuffix(void);
|
||||
|
@ -656,6 +676,7 @@ public:
|
|||
void FollowJumps(void);
|
||||
|
||||
bool ShortLeaMerge(int& spareTemps);
|
||||
bool ShortLeaCleanup(void);
|
||||
|
||||
bool IsEqual(const InterCodeBasicBlock* block) const;
|
||||
|
||||
|
@ -692,6 +713,7 @@ protected:
|
|||
GrowingIntegerValueRangeArray mLocalValueRange, mReverseValueRange;
|
||||
|
||||
void ResetVisited(void);
|
||||
void ResetPatched(void);
|
||||
void ResetEntryBlocks(void);
|
||||
public:
|
||||
InterCodeBasicBlock * mEntryBlock;
|
||||
|
@ -753,7 +775,7 @@ public:
|
|||
void Disassemble(const char* name, bool dumpSets = false);
|
||||
protected:
|
||||
void BuildLocalAliasTable(void);
|
||||
void BuildTraces(bool expand, bool dominators = true, bool compact = false);
|
||||
void BuildTraces(int expand, bool dominators = true, bool compact = false);
|
||||
void TrimBlocks(void);
|
||||
void EarlyBranchElimination(void);
|
||||
void BuildDataFlowSets(void);
|
||||
|
@ -774,7 +796,9 @@ protected:
|
|||
void SimplifyIntegerNumeric(FastNumberSet& activeSet);
|
||||
void SingleBlockLoopPointerSplit(FastNumberSet& activeSet);
|
||||
void SingleBlockLoopPointerToByte(FastNumberSet& activeSet);
|
||||
void SingleBlockLoopSinking(FastNumberSet& activeSet);
|
||||
void MergeIndexedLoadStore(void);
|
||||
void EliminateIntegerSumAliasTemps(void);
|
||||
void EliminateAliasValues();
|
||||
void LoadStoreForwarding(InterMemory paramMemory);
|
||||
void ReduceRecursionTempSpilling(InterMemory paramMemory);
|
||||
|
@ -794,9 +818,10 @@ protected:
|
|||
void CheckUsedDefinedTemps(void);
|
||||
void WarnUsedUndefinedVariables(void);
|
||||
void WarnInvalidValueRanges(void);
|
||||
void PropagateMemoryAliasingInfo(void);
|
||||
void PropagateMemoryAliasingInfo(bool loops);
|
||||
void MoveConditionsOutOfLoop(void);
|
||||
void ShortcutConstBranches(void);
|
||||
void ShortcutDuplicateBranches(void);
|
||||
void EliminateDoubleLoopCounter(void);
|
||||
void StructReturnPropagation(void);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -45,7 +45,7 @@ public:
|
|||
uint64 mCompilerOptions;
|
||||
|
||||
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
|
||||
void TranslateAssembler(InterCodeModule* mod, Expression * exp, GrowingArray<Declaration *> * refvars);
|
||||
void TranslateAssembler(InterCodeModule* mod, Declaration* adec,GrowingArray<Declaration *> * refvars);
|
||||
void InitGlobalVariable(InterCodeModule* mod, Declaration* dec);
|
||||
void InitLocalVariable(InterCodeProcedure* proc, Declaration* dec, int index);
|
||||
void InitParameter(InterCodeProcedure* proc, Declaration* dec, int index);
|
||||
|
@ -94,12 +94,12 @@ protected:
|
|||
void BuildSwitchTree(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock* block, InlineMapper * inlineMapper, ExValue v, const SwitchNodeArray& nodes, int left, int right, int vleft, int vright, InterCodeBasicBlock* dblock);
|
||||
|
||||
ExValue ToValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v);
|
||||
ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, int level = 0);
|
||||
ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, int level = 0, int limit = 0);
|
||||
ExValue CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, Declaration * type, bool checkTrunc = true);
|
||||
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, GotoNode*& gotos, const BranchTarget & breakBlock, const BranchTarget& continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr);
|
||||
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, DestructStack*& destack, GotoNode*& gotos, InlineMapper* inlineMapper);
|
||||
ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr, ExValue* lrexp);
|
||||
void CopyStruct(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper, bool moving);
|
||||
void CopyStruct (InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper, bool moving);
|
||||
void CopyStructSimple(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock * block, InlineMapper* inlineMapper, ExValue vl, ExValue vr);
|
||||
void StoreValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue vl, ExValue vr);
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ bool LinkerReference::operator!=(const LinkerReference& ref)
|
|||
}
|
||||
|
||||
LinkerObject::LinkerObject(void)
|
||||
: mReferences(nullptr), mNumTemporaries(0), mSize(0), mAlignment(1), mStackSection(nullptr), mIdent(nullptr), mFullIdent(nullptr), mStartUsed(0x10000), mEndUsed(0x00000), mMemory(nullptr)
|
||||
: mReferences(nullptr), mNumTemporaries(0), mSize(0), mStripe(0), mAlignment(1), mStackSection(nullptr), mIdent(nullptr), mFullIdent(nullptr), mStartUsed(0x10000), mEndUsed(0x00000), mMemory(nullptr)
|
||||
, mPrefix(nullptr), mSuffix(nullptr), mProc(nullptr), mNativeProc(nullptr)
|
||||
{}
|
||||
|
||||
|
@ -54,6 +54,23 @@ LinkerObject::~LinkerObject(void)
|
|||
|
||||
}
|
||||
|
||||
LinkerObject* LinkerObject::CloneAssembler(Linker* linker) const
|
||||
{
|
||||
LinkerObject* lo = linker->AddObject(mLocation, mIdent, mSection, mType, mAlignment);
|
||||
lo->AddData(mData, mSize);
|
||||
lo->mFlags = mFlags;
|
||||
|
||||
for (int i = 0; i < mReferences.Size(); i++)
|
||||
{
|
||||
LinkerReference ref = *(mReferences[i]);
|
||||
if (ref.mObject == this) ref.mObject = lo;
|
||||
if (ref.mRefObject == this) ref.mRefObject = lo;
|
||||
lo->AddReference(ref);
|
||||
}
|
||||
|
||||
return lo;
|
||||
}
|
||||
|
||||
void LinkerObject::AddReference(const LinkerReference& ref)
|
||||
{
|
||||
LinkerReference* nref = new LinkerReference(ref);
|
||||
|
@ -633,7 +650,7 @@ bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj, bool merge, boo
|
|||
int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
||||
int end = start + lobj->mSize;
|
||||
|
||||
if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00) && !(lobj->mSection->mFlags & LSECF_PACKED))
|
||||
if (((lobj->mFlags & LOBJF_NEVER_CROSS) || !(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mSection->mFlags & LSECF_PACKED)) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00))
|
||||
;
|
||||
else if (end <= mFreeChunks[i].mEnd)
|
||||
{
|
||||
|
@ -685,7 +702,7 @@ bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj, bool merge, boo
|
|||
int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
||||
int end = start + lobj->mSize;
|
||||
|
||||
if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && !retry && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mFlags & LOBJF_FORCE_ALIGN) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00) && !(lobj->mSection->mFlags & LSECF_PACKED))
|
||||
if (((lobj->mFlags & LOBJF_NEVER_CROSS) || !(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && !retry && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mSection->mFlags & LSECF_PACKED)) && !(lobj->mFlags & LOBJF_FORCE_ALIGN) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00))
|
||||
{
|
||||
start = (start + 0x00ff) & 0xff00;
|
||||
end = start + lobj->mSize;
|
||||
|
@ -1886,6 +1903,8 @@ bool Linker::WriteDbjFile(FILE* file)
|
|||
return true;
|
||||
}
|
||||
|
||||
static const char hexchars[] = "0123456789abcdef";
|
||||
|
||||
bool Linker::WriteLblFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
|
@ -1899,7 +1918,28 @@ bool Linker::WriteLblFile(const char* filename)
|
|||
if (obj->mFlags & LOBJF_REFERENCED)
|
||||
{
|
||||
if (obj->mIdent)
|
||||
fprintf(file, "al %04x .%s\n", obj->mAddress, obj->mIdent->mString);
|
||||
{
|
||||
char buffer[400];
|
||||
char nbuffer[500];
|
||||
|
||||
strcpy_s(buffer, obj->mIdent->mString);
|
||||
int i = 0, j = 0;
|
||||
while (buffer[i])
|
||||
{
|
||||
if (buffer[i] >= '0' && buffer[i] <= '9' || buffer[i] >= 'a' && buffer[i] <= 'z' || buffer[i] >= 'A' && buffer[i] <= 'Z' || buffer[i] == '_' || buffer[i] == ':')
|
||||
nbuffer[j++] = buffer[i];
|
||||
else
|
||||
{
|
||||
nbuffer[j++] = '?';
|
||||
nbuffer[j++] = hexchars[(buffer[i] >> 4) & 0x0f];
|
||||
nbuffer[j++] = hexchars[buffer[i] & 0x0f];
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
nbuffer[j] = 0;
|
||||
fprintf(file, "al %04x .%s\n", obj->mAddress, nbuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -156,6 +156,7 @@ static const uint32 LOBJF_NO_CROSS = 0x00000080;
|
|||
static const uint32 LOBJF_ZEROPAGE = 0x00000100;
|
||||
static const uint32 LOBJF_FORCE_ALIGN = 0x00000200;
|
||||
static const uint32 LOBJF_ZEROPAGESET = 0x00000400;
|
||||
static const uint32 LOBJF_NEVER_CROSS = 0x00000800;
|
||||
|
||||
static const uint32 LOBJF_ARG_REG_A = 0x00001000;
|
||||
static const uint32 LOBJF_ARG_REG_X = 0x00002000;
|
||||
|
@ -163,6 +164,7 @@ static const uint32 LOBJF_ARG_REG_Y = 0x00004000;
|
|||
|
||||
static const uint32 LOBJF_RET_REG_A = 0x00010000;
|
||||
static const uint32 LOBJF_RET_REG_X = 0x00020000;
|
||||
static const uint32 LOBJF_RET_REG_Y = 0x00020000;
|
||||
|
||||
static const uint32 LOBJF_LOCAL_VAR = 0x00100000;
|
||||
static const uint32 LOBJF_LOCAL_USED = 0x00200000;
|
||||
|
@ -190,7 +192,7 @@ public:
|
|||
LinkerObjectType mType;
|
||||
int mID, mMapID;
|
||||
int mAddress, mRefAddress;
|
||||
int mSize, mAlignment, mStartUsed, mEndUsed;
|
||||
int mSize, mAlignment, mStripe, mStartUsed, mEndUsed;
|
||||
LinkerSection * mSection;
|
||||
LinkerRegion * mRegion;
|
||||
uint8 * mData, * mMemory;
|
||||
|
@ -212,6 +214,8 @@ public:
|
|||
LinkerObject(void);
|
||||
~LinkerObject(void);
|
||||
|
||||
LinkerObject* CloneAssembler(Linker * linker) const;
|
||||
|
||||
void AddData(const uint8* data, int size);
|
||||
void AddLocations(const ExpandingArray<CodeLocation>& locations);
|
||||
uint8* AddSpace(int size);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,6 +9,9 @@ class NativeCodeBasicBlock;
|
|||
class NativeCodeGenerator;
|
||||
class NativeCodeInstruction;
|
||||
|
||||
class NativeCodeMapper;
|
||||
class SuffixTree;
|
||||
|
||||
enum NativeRegisterDataMode
|
||||
{
|
||||
NRDM_UNKNOWN,
|
||||
|
@ -130,31 +133,42 @@ static const uint32 NCIF_ALIASING = 0x00000800;
|
|||
static const uint32 NCIF_USE_CPU_REG_A = 0x00001000;
|
||||
static const uint32 NCIF_USE_CPU_REG_X = 0x00002000;
|
||||
static const uint32 NCIF_USE_CPU_REG_Y = 0x00004000;
|
||||
static const uint32 NCIF_USE_CPU_REG_C = 0x00008000;
|
||||
|
||||
static const uint32 NCIF_PROVIDE_CPU_REG_A = 0x00010000;
|
||||
static const uint32 NCIF_PROVIDE_CPU_REG_X = 0x00020000;
|
||||
static const uint32 NCIF_PROVIDE_CPU_REG_Y = 0x00040000;
|
||||
static const uint32 NCIF_PROVIDE_CPU_REG_C = 0x00080000;
|
||||
|
||||
// use a 32bit zero page register indexed by X for JSR
|
||||
static const uint32 NCIF_USE_ZP_32_X = 0x00008000;
|
||||
static const uint32 NICF_USE_ZP_ADDR = 0x00010000;
|
||||
static const uint32 NICF_USE_WORKREGS = 0x00020000;
|
||||
static const uint32 NCIF_USE_ZP_32_X = 0x00100000;
|
||||
static const uint32 NICF_USE_ZP_ADDR = 0x00200000;
|
||||
static const uint32 NICF_USE_WORKREGS = 0x00400000;
|
||||
|
||||
static const uint32 NCIF_BREAKPOINT = 0x00040000;
|
||||
static const uint32 NCIF_BREAKPOINT = 0x00800000;
|
||||
|
||||
class NativeCodeInstruction
|
||||
{
|
||||
public:
|
||||
NativeCodeInstruction(void);
|
||||
NativeCodeInstruction(const InterInstruction * ins, AsmInsType type, AsmInsMode mode = ASMIM_IMPLIED, int64 address = 0, LinkerObject * linkerObject = nullptr, uint32 flags = NCIF_LOWER | NCIF_UPPER, int param = 0);
|
||||
NativeCodeInstruction(const InterInstruction * ins, AsmInsType type, AsmInsMode mode = ASMIM_IMPLIED, int64 address = 0, LinkerObject * linkerObject = nullptr, uint32 flags = NCIF_LOWER | NCIF_UPPER, int param = 0, int minv = 0, int maxv = 255);
|
||||
NativeCodeInstruction(const InterInstruction* ins, AsmInsType type, const NativeCodeInstruction & addr);
|
||||
|
||||
AsmInsType mType;
|
||||
AsmInsMode mMode;
|
||||
AsmInsType mType;
|
||||
AsmInsMode mMode;
|
||||
|
||||
int mAddress, mParam;
|
||||
uint32 mFlags;
|
||||
uint32 mLive;
|
||||
LinkerObject * mLinkerObject;
|
||||
int mAddress, mParam;
|
||||
uint32 mFlags;
|
||||
uint32 mLive;
|
||||
LinkerObject * mLinkerObject;
|
||||
const InterInstruction * mIns;
|
||||
uint8 mMinVal, mMaxVal;
|
||||
|
||||
void Disassemble(FILE* file) const;
|
||||
void DisassembleAddress(FILE* file) const;
|
||||
|
||||
void CopyMode(const NativeCodeInstruction& ins);
|
||||
void CopyModeAndRange(const NativeCodeInstruction& ins);
|
||||
|
||||
void Assemble(NativeCodeBasicBlock* block);
|
||||
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
||||
|
@ -191,6 +205,7 @@ public:
|
|||
bool UsesZeroPage(int address) const;
|
||||
bool ReferencesZeroPage(int address) const;
|
||||
|
||||
bool SameLinkerObjectVariableRange(const NativeCodeInstruction& ins, bool sameXY = false) const;
|
||||
|
||||
bool ChangesGlobalMemory(void) const;
|
||||
bool UsesMemoryOf(const NativeCodeInstruction& ins) const;
|
||||
|
@ -205,7 +220,7 @@ public:
|
|||
bool IsShift(void) const;
|
||||
bool IsShiftOrInc(void) const;
|
||||
bool IsSimpleJSR(void) const;
|
||||
bool MayBeMovedBefore(const NativeCodeInstruction& ins);
|
||||
bool MayBeMovedBefore(const NativeCodeInstruction& ins) const;
|
||||
|
||||
bool ReplaceYRegWithXReg(void);
|
||||
bool ReplaceXRegWithYReg(void);
|
||||
|
@ -216,6 +231,12 @@ public:
|
|||
void BuildCollisionTable(NumberSet& liveTemps, NumberSet* collisionSets);
|
||||
|
||||
uint32 NeedsLive(void) const;
|
||||
|
||||
uint32 CodeHash(void) const;
|
||||
bool CodeSame(const NativeCodeInstruction& ins);
|
||||
|
||||
protected:
|
||||
const char* AddrName(char* buffer) const;
|
||||
};
|
||||
|
||||
struct NativeCodeLoadStorePair
|
||||
|
@ -246,10 +267,12 @@ public:
|
|||
ExpandingArray<NativeCodeBasicBlock*> mEntryBlocks;
|
||||
|
||||
int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset, mTemp;
|
||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit;
|
||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchUsed, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit;
|
||||
bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX, mChecked;
|
||||
NativeCodeBasicBlock * mDominator, * mSameBlock;
|
||||
|
||||
int mAsmFromJump;
|
||||
|
||||
NativeCodeBasicBlock* mLoopHeadBlock, * mLoopTailBlock;
|
||||
|
||||
NativeRegisterDataSet mDataSet, mNDataSet, mFDataSet;
|
||||
|
@ -262,21 +285,27 @@ public:
|
|||
|
||||
NativeCodeInstruction mALSIns, mXLSIns, mYLSIns;
|
||||
|
||||
void Disassemble(FILE* file);
|
||||
void DisassembleBody(FILE* file);
|
||||
|
||||
NativeCodeInstruction DecodeNative(const InterInstruction* ins, LinkerObject * lobj, int& offset) const;
|
||||
|
||||
int PutBranch(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, AsmInsType code, int offset);
|
||||
int PutJump(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, int offset, AsmInsType code = ASMIT_INV);
|
||||
int JumpByteSize(NativeCodeBasicBlock * target, int offset, bool second);
|
||||
int BranchByteSize(NativeCodeBasicBlock* target, int from, int to);
|
||||
int PutBranch(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, AsmInsType code, int from, int to);
|
||||
int PutJump(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, int from, int to, AsmInsType code = ASMIT_INV);
|
||||
int JumpByteSize(NativeCodeBasicBlock * target, int from, int to, bool second, bool final);
|
||||
int CheckFinalBranchByteSize(NativeCodeBasicBlock* target, int from, int to) const;
|
||||
int BranchByteSize(NativeCodeBasicBlock* target, int from, int to, bool final) const;
|
||||
|
||||
NativeCodeBasicBlock* SplitAt(int at);
|
||||
|
||||
NativeCodeBasicBlock* BypassEmptyBlocks(void);
|
||||
|
||||
int LeadsInto(NativeCodeBasicBlock* block, int dist);
|
||||
NativeCodeBasicBlock* PlaceSequence(ExpandingArray<NativeCodeBasicBlock*>& placement, NativeCodeBasicBlock* block);
|
||||
void BuildPlacement(ExpandingArray<NativeCodeBasicBlock*>& placement);
|
||||
void OptimizePlacement(void);
|
||||
void InitialOffset(int& total);
|
||||
bool CalculateOffset(int& total);
|
||||
bool CalculateOffset(int& total, bool final);
|
||||
|
||||
void CopyCode(NativeCodeProcedure* proc, uint8* target);
|
||||
void Assemble(void);
|
||||
|
@ -299,6 +328,8 @@ public:
|
|||
bool UsesZeroPage(int address, int from = 0, int to = 65536) const;
|
||||
bool ReferencesZeroPage(int address, int from = 0, int to = 65536) const;
|
||||
|
||||
bool ChangesMemory(const NativeCodeInstruction& ins, int from = 0, int to = 65536) const;
|
||||
bool ReferencesMemory(const NativeCodeInstruction& ins, int from = 0, int to = 65536) const;
|
||||
|
||||
bool RemoveNops(void);
|
||||
bool PeepHoleOptimizer(int pass);
|
||||
|
@ -317,18 +348,20 @@ public:
|
|||
bool PeepHoleOptimizerIterate(int pass);
|
||||
bool PeepHoleOptimizerExits(int pass);
|
||||
|
||||
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter);
|
||||
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter, int center);
|
||||
bool BlockSizeCopyReduction(NativeCodeProcedure* proc, int & si, int & di);
|
||||
|
||||
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, bool full);
|
||||
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock * prevBlock, NativeCodeBasicBlock* exitBlock, bool full);
|
||||
bool RemoveSimpleLoopUnusedIndex(void);
|
||||
bool OptimizeLoopCarryOver(void);
|
||||
bool OptimizeLoopRegisterWrapAround(void);
|
||||
|
||||
bool OptimizeSingleEntryLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prev, NativeCodeBasicBlock* tail, ExpandingArray<NativeCodeBasicBlock*>& blocks);
|
||||
bool OptimizeSingleEntryLoop(NativeCodeProcedure* proc);
|
||||
|
||||
bool OptimizeSimpleLoop(NativeCodeProcedure* proc, bool full);
|
||||
bool OptimizeSimpleForLoop(void);
|
||||
bool SimpleLoopReversal(NativeCodeProcedure* proc);
|
||||
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, ExpandingArray<NativeCodeBasicBlock*>& blocks);
|
||||
bool OptimizeXYSimpleLoop(void);
|
||||
|
@ -340,9 +373,11 @@ public:
|
|||
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
|
||||
NativeCodeBasicBlock* CollectInnerLoop(NativeCodeBasicBlock* head, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
|
||||
bool OptimizeGenericLoop(NativeCodeProcedure* proc);
|
||||
bool CollectGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
bool CollectSingleEntryGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
int CorrectXOffset(const InterInstruction * ins, int yoffset, int at);
|
||||
int CorrectYOffset(const InterInstruction * ins, int yoffset, int at);
|
||||
bool OptimizeGenericLoop(void);
|
||||
bool CollectGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
bool CollectSingleEntryGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
void CollectReachable(ExpandingArray<NativeCodeBasicBlock*>& lblock);
|
||||
|
||||
bool OptimizeFindLoop(NativeCodeProcedure* proc);
|
||||
|
@ -358,7 +393,7 @@ public:
|
|||
void CheckFrameIndex(const InterInstruction * ins, int & reg, int & index, int size, int treg = 0);
|
||||
void LoadValueToReg(InterCodeProcedure* proc, const InterInstruction * ins, int reg, const NativeCodeInstruction * ainsl, const NativeCodeInstruction* ainsh);
|
||||
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction* ins, InterType type, int reg);
|
||||
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction* ins, const InterOperand & op, InterType type, int reg);
|
||||
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction* ins, const InterOperand & op, InterType type, int reg, bool checkRange = true);
|
||||
|
||||
void LoadConstant(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||
void StoreValue(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||
|
@ -376,7 +411,7 @@ public:
|
|||
NativeCodeBasicBlock* BinaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
|
||||
void UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
|
||||
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0, bool addrvalid);
|
||||
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0, bool addrvalid, bool addrused = false);
|
||||
void LoadStoreOpAbsolute2D(InterCodeProcedure* proc, const InterInstruction* lins1, const InterInstruction* lins2, const InterInstruction* mins);
|
||||
void SignExtendAddImmediate(InterCodeProcedure* proc, const InterInstruction* xins, const InterInstruction* ains);
|
||||
void BinaryDivModPair(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins1, const InterInstruction* ins2);
|
||||
|
@ -393,6 +428,7 @@ public:
|
|||
|
||||
void LoadByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* rins);
|
||||
void StoreByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* rins);
|
||||
void CopyByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* riins, const InterInstruction* wiins, const InterInstruction* rins, const InterInstruction* wins);
|
||||
|
||||
void CallAssembler(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
void CallFunction(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
|
@ -405,6 +441,7 @@ public:
|
|||
int ShortSignedDivide(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins, const InterInstruction* sins, int mul);
|
||||
|
||||
bool CheckPredAccuStore(int reg);
|
||||
bool CheckIsInAccu(int reg);
|
||||
|
||||
NumberSet mLocalRequiredRegs, mLocalProvidedRegs;
|
||||
NumberSet mEntryRequiredRegs, mEntryProvidedRegs;
|
||||
|
@ -426,9 +463,7 @@ public:
|
|||
void CountEntries(NativeCodeBasicBlock* fromJump);
|
||||
NativeCodeBasicBlock * ForwardAccuBranch(bool eq, bool ne, bool pl, bool mi, int limit);
|
||||
bool MergeBasicBlocks(void);
|
||||
void RemoveJumpToBranch(void);
|
||||
|
||||
void MarkLoopHead(void);
|
||||
bool RemoveJumpToBranch(void);
|
||||
|
||||
struct DominatorStacks
|
||||
{
|
||||
|
@ -502,7 +537,9 @@ public:
|
|||
bool CombineImmediateADCUp(int at);
|
||||
bool CombineImmediateADCUpX(int at);
|
||||
bool MoveTXADCDown(int at);
|
||||
bool MoveTXALogicTAXDown(int at);
|
||||
bool FoldShiftORAIntoLoadImmUp(int at);
|
||||
bool ReverseShiftByteOrder(int at);
|
||||
|
||||
bool FindAccuExitValue(int& at);
|
||||
bool MoveLoadXAbsUpCrossBlock(int at);
|
||||
|
@ -536,6 +573,7 @@ public:
|
|||
bool CombineSameYtoX(int xpos, int ypos, int end);
|
||||
|
||||
bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains);
|
||||
int FindImmediateGlobalStore(int at, const NativeCodeInstruction& ins);
|
||||
|
||||
bool JoinXYCrossBlock(void);
|
||||
bool CanCombineSameXtoYCrossBlock(int from);
|
||||
|
@ -556,6 +594,13 @@ public:
|
|||
|
||||
bool ReverseReplaceTAX(int at);
|
||||
|
||||
bool CanReplaceExitAccuWithX(NativeCodeBasicBlock * target);
|
||||
bool CanReplaceExitAccuWithY(NativeCodeBasicBlock* target);
|
||||
void ReplaceExitAccuWithX(NativeCodeBasicBlock* target);
|
||||
void ReplaceExitAccuWithY(NativeCodeBasicBlock* target);
|
||||
|
||||
bool ReverseLoadAccuToRegXY(void);
|
||||
|
||||
void ResetModifiedDataSet(NativeRegisterDataSet& data);
|
||||
|
||||
bool ValueForwarding(NativeCodeProcedure* proc, const NativeRegisterDataSet& data, bool global, bool final);
|
||||
|
@ -565,6 +610,9 @@ public:
|
|||
bool OffsetValueForwarding(const ValueNumberingDataSet & data);
|
||||
bool AbsoluteValueForwarding(const ExpandingArray<NativeCodeLoadStorePair>& npairs);
|
||||
bool IndexXYValueForwarding(int xreg, int xoffset, int xvalue, int yreg, int yoffset, int yvalue);
|
||||
bool ReduceIndexXYZeroShuffle(NativeCodeBasicBlock* from, int xreg, int yreg);
|
||||
bool CheckLoopIndexXRegisters(NativeCodeBasicBlock* head, int xreg);
|
||||
bool CheckLoopIndexYRegisters(NativeCodeBasicBlock* head, int yreg);
|
||||
|
||||
void MarkLocalUsedLinkerObjects(void);
|
||||
bool RemoveLocalUnusedLinkerObjects(void);
|
||||
|
@ -584,7 +632,14 @@ public:
|
|||
bool HasTailSTY(int& addr, int& index) const;
|
||||
bool HasTailSTAX16(int& addr, int& index0) const;
|
||||
|
||||
bool HasTailSTAInto(int& addr, int& index, NativeCodeBasicBlock* tblock) const;
|
||||
bool HasTailSTXInto(int& addr, int& index, NativeCodeBasicBlock* tblock) const;
|
||||
bool HasTailSTYInto(int& addr, int& index, NativeCodeBasicBlock* tblock) const;
|
||||
|
||||
bool HasTailSTAGlobal(NativeCodeInstruction & ins, int& index) const;
|
||||
|
||||
bool MayBeMovedBeforeBlock(int at);
|
||||
bool MayBeMovedBeforeBlock(int at, const NativeCodeInstruction & ins);
|
||||
bool MayBeMovedBeforeBlock(int start, int end);
|
||||
bool SafeInjectSequenceFromBack(NativeCodeBasicBlock* block, int start, int end);
|
||||
bool JoinCommonBranchCodeSequences(void);
|
||||
|
@ -688,6 +743,8 @@ public:
|
|||
bool EliminateDeadLoops(void);
|
||||
bool LoopRegisterWrapAround(void);
|
||||
bool CrossBlockFlagsForwarding(void);
|
||||
bool MoveStoresBeforeDiamond(void);
|
||||
bool MoveStoresBehindCondition(void);
|
||||
|
||||
bool SinglePathRegisterForwardY(NativeCodeBasicBlock* path, int yreg);
|
||||
bool SinglePathRegisterForward(void);
|
||||
|
@ -720,8 +777,9 @@ public:
|
|||
bool CanGlobalSwapXY(void);
|
||||
bool GlobalSwapXY(void);
|
||||
bool LocalSwapXY(void);
|
||||
bool UntangleXYUsage(void);
|
||||
bool UntangleXYUsage(bool final);
|
||||
bool AlternateXXUsage(void);
|
||||
bool ShortSwapXY(void);
|
||||
|
||||
bool IsSimpleSubExpression(int at, NativeSimpleSubExpression & ex);
|
||||
bool PropagateCommonSubExpression(void);
|
||||
|
@ -745,10 +803,20 @@ public:
|
|||
bool CheckPatchFailUse(void);
|
||||
|
||||
bool CheckPatchFailLoop(const NativeCodeBasicBlock* block, const NativeCodeBasicBlock* head, int reg, bool changed);
|
||||
bool CheckPatchFailLoopPair(const NativeCodeBasicBlock* block, const NativeCodeBasicBlock* head, int reg, bool changed);
|
||||
|
||||
bool JoinSameBranch(NativeCodeBasicBlock* block);
|
||||
bool MergeSameBranch(void);
|
||||
|
||||
bool CheckBoolBitPropagation(const NativeCodeBasicBlock* block, int at, int reg);
|
||||
bool PatchBoolBitPropagation(const NativeCodeBasicBlock* block, int at, int reg);
|
||||
|
||||
bool CollectRegBoolInstructionsForward(int reg, ExpandingArray<NativeCodeBasicBlock*>& cblocks, ExpandingArray<NativeCodeInstruction*>& lins);
|
||||
bool CollectRegBoolInstructionsBackward(int reg, ExpandingArray<NativeCodeBasicBlock*>& cblocks, ExpandingArray<NativeCodeInstruction*>& lins);
|
||||
|
||||
bool CollectCheckRegOriginBlocks(int at, int reg, ExpandingArray<NativeCodeBasicBlock*>& lblocks, ExpandingArray<NativeCodeInstruction*>& lins);
|
||||
bool PatchBitBoolConstOrigin(void);
|
||||
|
||||
// reg : base register pair to replace
|
||||
// index: index register
|
||||
// at : start position in block
|
||||
|
@ -758,9 +826,20 @@ public:
|
|||
bool CheckGlobalAddressSumYPointer(const NativeCodeBasicBlock * block, int reg, int index, int at, int yval);
|
||||
bool PatchGlobalAddressSumYPointer(const NativeCodeBasicBlock* block, int reg, int index, int at, int yval, LinkerObject * lobj, int address, uint32 flags = NCIF_LOWER | NCIF_UPPER);
|
||||
|
||||
// reg : register to replace
|
||||
// at : start position in block
|
||||
// ains : instruction loading original data
|
||||
// cycles : max number of cycles saving
|
||||
bool CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains, int cycles);
|
||||
bool PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains);
|
||||
|
||||
// rins : instruction storing the data
|
||||
// at : start position in block
|
||||
// ains : instruction loading original data
|
||||
// cycles : max number of cycles saving
|
||||
bool CheckSingleUseGlobalLoadStruct(const NativeCodeBasicBlock* block, const NativeCodeInstruction& rins, int at, const NativeCodeInstruction& ains, bool cleared, bool poisoned);
|
||||
bool PatchSingleUseGlobalLoadStruct(const NativeCodeBasicBlock* block, const NativeCodeInstruction& rins, int at, const NativeCodeInstruction& ains);
|
||||
|
||||
// reg : base register pair to replace
|
||||
// base: new base register
|
||||
// iins : indexing instruction
|
||||
|
@ -804,6 +883,10 @@ public:
|
|||
|
||||
void PropagateAddGlobalCarry(void);
|
||||
|
||||
bool EliminateNonAliasedLocalStores(void);
|
||||
bool CheckNonAliasedLocalStore(int at, const NativeCodeInstruction& sins);
|
||||
|
||||
|
||||
void RegisterFunctionCalls(void);
|
||||
bool MergeFunctionCalls(void);
|
||||
|
||||
|
@ -813,6 +896,9 @@ public:
|
|||
void CheckBlocks(bool sequence = false);
|
||||
void CheckAsmCode(void);
|
||||
void CheckVisited(void);
|
||||
|
||||
int* mSuffixString;
|
||||
void AddToSuffixTree(NativeCodeMapper& mapper, SuffixTree * tree);
|
||||
};
|
||||
|
||||
class NativeCodeProcedure
|
||||
|
@ -827,6 +913,10 @@ class NativeCodeProcedure
|
|||
NativeCodeGenerator* mGenerator;
|
||||
|
||||
InterCodeProcedure* mInterProc;
|
||||
LinkerObject* mLinkerObject;
|
||||
const Ident* mIdent;
|
||||
Location mLocation;
|
||||
uint64 mCompilerOptions;
|
||||
|
||||
int mProgStart, mProgSize, mIndex, mFrameOffset, mStackExpand;
|
||||
int mFastCallBase;
|
||||
|
@ -838,10 +928,15 @@ class NativeCodeProcedure
|
|||
ExpandingArray<CodeLocation> mCodeLocations;
|
||||
|
||||
|
||||
void DisassembleDebug(const char* name);
|
||||
void Disassemble(FILE* file);
|
||||
|
||||
void Compile(InterCodeProcedure* proc);
|
||||
void Optimize(void);
|
||||
void Assemble(void);
|
||||
|
||||
void AddToSuffixTree(NativeCodeMapper& mapper, SuffixTree* tree);
|
||||
|
||||
NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
|
||||
NativeCodeBasicBlock* AllocateBlock(void);
|
||||
|
||||
|
@ -907,6 +1002,8 @@ public:
|
|||
Linker* mLinker;
|
||||
LinkerSection* mRuntimeSection;
|
||||
|
||||
ExpandingArray<NativeCodeProcedure*> mProcedures;
|
||||
|
||||
ExpandingArray<Runtime> mRuntime;
|
||||
ExpandingArray<MulTable> mMulTables;
|
||||
ExpandingArray<FloatTable> mFloatTables;
|
||||
|
@ -925,6 +1022,8 @@ public:
|
|||
|
||||
FunctionCall* mFunctionCalls;
|
||||
|
||||
void OutlineFunctions(void);
|
||||
|
||||
void RegisterFunctionCall(NativeCodeBasicBlock* block, int at);
|
||||
void BuildFunctionProxies(void);
|
||||
bool MergeFunctionCall(NativeCodeBasicBlock* block, int at);
|
||||
|
|
|
@ -0,0 +1,379 @@
|
|||
#include "NativeCodeOutliner.h"
|
||||
|
||||
|
||||
NativeCodeMapper::NativeCodeMapper(void)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
mHash[i] = nullptr;
|
||||
}
|
||||
|
||||
NativeCodeMapper::~NativeCodeMapper(void)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
InsNode* n = mHash[i];
|
||||
while (n)
|
||||
{
|
||||
InsNode* m = n;
|
||||
n = n->mNext;
|
||||
delete m;
|
||||
}
|
||||
mHash[i] = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void NativeCodeMapper::Reset(void)
|
||||
{
|
||||
mBlocks.SetSize(0);
|
||||
}
|
||||
|
||||
int NativeCodeMapper::MapBasicBlock(NativeCodeBasicBlock* block)
|
||||
{
|
||||
mBlocks.Push(block);
|
||||
return -mBlocks.Size();
|
||||
}
|
||||
|
||||
int NativeCodeMapper::MapInstruction(const NativeCodeInstruction& ins, LinkerSection* ls)
|
||||
{
|
||||
int hash = ins.CodeHash() % HashSize;
|
||||
InsNode* n = mHash[hash];
|
||||
while (n)
|
||||
{
|
||||
if (mIns[n->mIndex].CodeSame(ins) && n->mSection == ls)
|
||||
return n->mIndex;
|
||||
n = n->mNext;
|
||||
}
|
||||
n = new InsNode();
|
||||
n->mIndex = mIns.Size();
|
||||
n->mSection = ls;
|
||||
mIns.Push(ins);
|
||||
n->mNext = mHash[hash];
|
||||
mHash[hash] = n;
|
||||
return n->mIndex;
|
||||
}
|
||||
|
||||
SuffixTree::SuffixTree(const int* str, int s, SuffixTree* n)
|
||||
{
|
||||
mSeg = str;
|
||||
mSize = s;
|
||||
mNext = n;
|
||||
mParent = nullptr;
|
||||
mFirst = nullptr;
|
||||
}
|
||||
|
||||
SuffixTree::~SuffixTree(void)
|
||||
{
|
||||
delete[] mFirst;
|
||||
}
|
||||
|
||||
void SuffixTree::AddParents(SuffixTree* parent)
|
||||
{
|
||||
mParent = parent;
|
||||
if (mFirst)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* n = mFirst[i];
|
||||
while (n)
|
||||
{
|
||||
n->AddParents(this);
|
||||
n = n->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SuffixTree::AddSuffix(const int* str, int s)
|
||||
{
|
||||
int hi = str[0] & (HashSize - 1);
|
||||
SuffixTree* c = mFirst ? mFirst[hi] : nullptr;
|
||||
while (c && c->mSeg[0] != str[0])
|
||||
c = c->mNext;
|
||||
|
||||
if (c)
|
||||
{
|
||||
int k = 1;
|
||||
while (k < c->mSize && str[k] == c->mSeg[k])
|
||||
k++;
|
||||
if (k == c->mSize)
|
||||
c->AddSuffix(str + k, s - k);
|
||||
else
|
||||
{
|
||||
SuffixTree * n = new SuffixTree(c->mSeg + k, c->mSize - k, nullptr);
|
||||
if (c->mFirst)
|
||||
{
|
||||
n->mFirst = new SuffixTree * [HashSize];
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
n->mFirst[i] = c->mFirst[i];
|
||||
c->mFirst[i] = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c->mFirst = new SuffixTree * [HashSize];
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
c->mFirst[i] = nullptr;
|
||||
}
|
||||
c->mFirst[c->mSeg[k] & (HashSize - 1)] = n;
|
||||
int hk = str[k] & (HashSize - 1);
|
||||
c->mFirst[hk] = new SuffixTree(str + k, s - k, c->mFirst[hk]);
|
||||
c->mSize = k;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mFirst)
|
||||
{
|
||||
mFirst = new SuffixTree * [HashSize];
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
mFirst[i] = nullptr;
|
||||
}
|
||||
|
||||
mFirst[hi] = new SuffixTree(str, s, mFirst[hi]);
|
||||
}
|
||||
}
|
||||
|
||||
void SuffixTree::AddString(const int* str)
|
||||
{
|
||||
int s = 0;
|
||||
while(str[s] >= 0)
|
||||
s++;
|
||||
s++;
|
||||
|
||||
int i = 0;
|
||||
while (str[i] >= 0)
|
||||
{
|
||||
AddSuffix(str + i, s - i);
|
||||
i++;
|
||||
}
|
||||
AddSuffix(str + i, 1);
|
||||
}
|
||||
|
||||
void SuffixTree::CollectSuffix(NativeCodeMapper& map, int offset, ExpandingArray<SuffixSegment>& segs)
|
||||
{
|
||||
offset += mSize;
|
||||
if (mFirst)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* t = mFirst[i];
|
||||
|
||||
while (t)
|
||||
{
|
||||
t->CollectSuffix(map, offset, segs);
|
||||
t = t->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* block = map.mBlocks[-(mSeg[mSize - 1] + 1)];
|
||||
|
||||
SuffixSegment seg;
|
||||
seg.mBlock = block;
|
||||
seg.mStart = offset;
|
||||
seg.mEnd = block->mIns.Size() + 1;
|
||||
segs.Push(seg);
|
||||
}
|
||||
}
|
||||
|
||||
int SuffixTree::LongestMatch(NativeCodeMapper& map, int size, int isize, int& msize, SuffixTree*& mtree)
|
||||
{
|
||||
if (mFirst)
|
||||
{
|
||||
isize += mSize;
|
||||
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
if (mSeg[i] >= 0)
|
||||
size += AsmInsModeSize[map.mIns[mSeg[i]].mMode];
|
||||
}
|
||||
|
||||
assert(size < 10000);
|
||||
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* t = mFirst[i];
|
||||
while (t)
|
||||
{
|
||||
cnt += t->LongestMatch(map, size, isize, msize, mtree);
|
||||
t = t->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
if (size >= 6 && (size - 3) * (cnt - 1) > msize)
|
||||
{
|
||||
// Second run to cross check for overlaps
|
||||
ExpandingArray<SuffixSegment> segs;
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* t = mFirst[i];
|
||||
while (t)
|
||||
{
|
||||
t->CollectSuffix(map, 0, segs);
|
||||
t = t->mNext;
|
||||
}
|
||||
}
|
||||
segs.Sort([](const SuffixSegment& l, const SuffixSegment& r)->bool {
|
||||
return l.mBlock == r.mBlock ? l.mStart < r.mStart : ptrdiff_t(l.mBlock) < ptrdiff_t(r.mBlock);
|
||||
});
|
||||
|
||||
for (int i = 0; i + 1 < segs.Size(); i++)
|
||||
{
|
||||
if (segs[i].mBlock == segs[i + 1].mBlock && segs[i].mStart + isize > segs[i + 1].mStart)
|
||||
cnt--;
|
||||
}
|
||||
|
||||
if (cnt > 1 && (size - 3) * (cnt - 1) > msize)
|
||||
{
|
||||
msize = (size - 3) * (cnt - 1);
|
||||
mtree = this;
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SuffixTree::Print(FILE * file, NativeCodeMapper& map, int depth)
|
||||
{
|
||||
for (int i = 0; i < depth; i++)
|
||||
fprintf(file, ".");
|
||||
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
fprintf(file, "[");
|
||||
|
||||
if (mSeg[i] >= 0)
|
||||
map.mIns[mSeg[i]].Disassemble(file);
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* block = map.mBlocks[- (mSeg[i] + 1)];
|
||||
fprintf(file, "%s,%d", block->mProc->mInterProc->mIdent->mString, block->mIndex);
|
||||
}
|
||||
fprintf(file, "]");
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
|
||||
if (mFirst)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* n = mFirst[i];
|
||||
while (n)
|
||||
{
|
||||
n->Print(file, map, depth + 1);
|
||||
n = n->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SuffixTree::ParentPrint(FILE* file, NativeCodeMapper& map)
|
||||
{
|
||||
if (mParent)
|
||||
mParent->ParentPrint(file, map);
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
if (mSeg[i] >= 0)
|
||||
map.mIns[mSeg[i]].Disassemble(file);
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* block = map.mBlocks[-(mSeg[i] + 1)];
|
||||
fprintf(file, "%s,%d", block->mProc->mInterProc->mIdent->mString, block->mIndex);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
int SuffixTree::ParentCodeSize(NativeCodeMapper& map) const
|
||||
{
|
||||
int size = 0;
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
if (mSeg[i] >= 0)
|
||||
size += AsmInsModeSize[map.mIns[mSeg[i]].mMode];
|
||||
}
|
||||
|
||||
if (mParent)
|
||||
size += mParent->ParentCodeSize(map);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void SuffixTree::ParentCollect(NativeCodeMapper& map, NativeCodeBasicBlock* block)
|
||||
{
|
||||
if (mParent)
|
||||
mParent->ParentCollect(map, block);
|
||||
for (int i = 0; i < mSize; i++)
|
||||
block->mIns.Push(map.mIns[mSeg[i]]);
|
||||
}
|
||||
|
||||
void SuffixTree::ReplaceCalls(NativeCodeMapper& map, ExpandingArray<SuffixSegment>& segs)
|
||||
{
|
||||
if (mFirst)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* n = mFirst[i];
|
||||
while (n)
|
||||
{
|
||||
n->ChildReplaceCalls(map, this, 0, segs);
|
||||
n = n->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SuffixTree::ChildReplaceCalls(NativeCodeMapper& map, SuffixTree* tree, int offset, ExpandingArray<SuffixSegment>& segs)
|
||||
{
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
if (mSeg[i] >= 0)
|
||||
offset ++;
|
||||
}
|
||||
|
||||
if (mFirst)
|
||||
{
|
||||
for (int i = 0; i < HashSize; i++)
|
||||
{
|
||||
SuffixTree* n = mFirst[i];
|
||||
while (n)
|
||||
{
|
||||
n->ChildReplaceCalls(map, tree, offset, segs);
|
||||
n = n->mNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* block = map.mBlocks[-(mSeg[mSize - 1] + 1)];
|
||||
tree->ParentReplaceCalls(map, block, offset, 0, segs);
|
||||
}
|
||||
}
|
||||
|
||||
void SuffixTree::ParentReplaceCalls(NativeCodeMapper& map, NativeCodeBasicBlock* block, int offset, int size, ExpandingArray<SuffixSegment>& segs)
|
||||
{
|
||||
for (int i = 0; i < mSize; i++)
|
||||
{
|
||||
if (mSeg[i] >= 0)
|
||||
size ++;
|
||||
}
|
||||
if (mParent)
|
||||
mParent->ParentReplaceCalls(map, block, offset, size, segs);
|
||||
else
|
||||
{
|
||||
int at = block->mIns.Size() - offset - size;
|
||||
|
||||
SuffixSegment seg;
|
||||
seg.mBlock = block;
|
||||
seg.mStart = at;
|
||||
seg.mEnd = at + size;
|
||||
segs.Push(seg);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
|
||||
#include "NativeCodeGenerator.h"
|
||||
#include "Array.h"
|
||||
|
||||
class NativeCodeMapper
|
||||
{
|
||||
public:
|
||||
NativeCodeMapper(void);
|
||||
~NativeCodeMapper(void);
|
||||
|
||||
void Reset(void);
|
||||
|
||||
int MapInstruction(const NativeCodeInstruction& ins, LinkerSection * ls);
|
||||
int MapBasicBlock(NativeCodeBasicBlock* block);
|
||||
|
||||
ExpandingArray<NativeCodeInstruction> mIns;
|
||||
ExpandingArray<NativeCodeBasicBlock*> mBlocks;
|
||||
protected:
|
||||
static const int HashSize = 256;
|
||||
|
||||
struct InsNode
|
||||
{
|
||||
int mIndex;
|
||||
LinkerSection * mSection;
|
||||
InsNode* mNext;
|
||||
};
|
||||
|
||||
InsNode * mHash[HashSize];
|
||||
};
|
||||
|
||||
struct SuffixSegment
|
||||
{
|
||||
NativeCodeBasicBlock * mBlock;
|
||||
int mStart, mEnd;
|
||||
};
|
||||
|
||||
class SuffixTree
|
||||
{
|
||||
public:
|
||||
const int * mSeg;
|
||||
int mSize;
|
||||
|
||||
static const int HashSize = 32;
|
||||
|
||||
SuffixTree* mNext, * mParent, ** mFirst;
|
||||
|
||||
SuffixTree(const int* str, int s, SuffixTree* n);
|
||||
~SuffixTree(void);
|
||||
|
||||
void AddParents(SuffixTree* parent);
|
||||
|
||||
void AddSuffix(const int* str, int s);
|
||||
void AddString(const int* str);
|
||||
|
||||
void Print(FILE* file, NativeCodeMapper & map, int depth);
|
||||
void ParentPrint(FILE* file, NativeCodeMapper& map);
|
||||
int LongestMatch(NativeCodeMapper& map, int size, int isize, int & msize, SuffixTree *& mtree);
|
||||
void CollectSuffix(NativeCodeMapper& map, int offset, ExpandingArray<SuffixSegment>& segs);
|
||||
int ParentCodeSize(NativeCodeMapper& map) const;
|
||||
void ParentCollect(NativeCodeMapper& map, NativeCodeBasicBlock * block);
|
||||
void ReplaceCalls(NativeCodeMapper& map, ExpandingArray<SuffixSegment> & segs);
|
||||
void ChildReplaceCalls(NativeCodeMapper& map, SuffixTree * tree, int offset, ExpandingArray<SuffixSegment>& segs);
|
||||
void ParentReplaceCalls(NativeCodeMapper& map, NativeCodeBasicBlock* block, int offset, int size, ExpandingArray<SuffixSegment>& segs);
|
||||
|
||||
};
|
2396
oscar64/Parser.cpp
2396
oscar64/Parser.cpp
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,7 @@ public:
|
|||
~Parser(void);
|
||||
|
||||
Parser* Clone(void);
|
||||
Parser * mParent;
|
||||
|
||||
DeclarationScope * mGlobals, * mScope, * mTemplateScope, * mCaptureScope;
|
||||
int mLocalIndex;
|
||||
|
@ -24,6 +25,8 @@ public:
|
|||
uint64 mCompilerOptionStack[32];
|
||||
int mCompilerOptionSP;
|
||||
|
||||
Location FullLocation(const Location& loc);
|
||||
|
||||
void Parse(void);
|
||||
protected:
|
||||
bool ExpectToken(Token token);
|
||||
|
@ -77,12 +80,13 @@ protected:
|
|||
Expression* DefaultInitExpression(Expression* vexp);
|
||||
Expression* ParseVarInitExpression(Expression* lexp, bool inner = false);
|
||||
Expression* CloneVarInitExpression(Expression* vexp, Expression* iexp, Expression * qexp);
|
||||
Expression* CopyElision(Expression* vexp, Expression* rexp);
|
||||
|
||||
Declaration* ParsePostfixDeclaration(void);
|
||||
Declaration* ReverseDeclaration(Declaration* odec, Declaration* bdec);
|
||||
|
||||
Expression* ParseFunction(Declaration* dec);
|
||||
Expression* ParseAssembler(void);
|
||||
Expression* ParseAssembler(Declaration * vdassm = nullptr);
|
||||
|
||||
Expression* ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset);
|
||||
Expression* ParseAssemblerMulOperand(Declaration* pcasm, int pcoffset);
|
||||
|
@ -133,7 +137,10 @@ protected:
|
|||
|
||||
Declaration* ParseTypeID(bool tid, Declaration * bdec = nullptr);
|
||||
|
||||
Expression* ParseConstruction(Declaration* type);
|
||||
|
||||
Expression* ParseCastExpression(Expression* exp);
|
||||
Expression* ParseIdentExpression(const Location & eloc, Declaration* dec, bool lhs, bool tid = false);
|
||||
Expression* ParseSimpleExpression(bool lhs, bool tid = false);
|
||||
Expression* ParsePrefixExpression(bool lhs);
|
||||
Expression* ParsePostfixExpression(bool lhs);
|
||||
|
@ -152,9 +159,10 @@ protected:
|
|||
Expression* ParseRExpression(void);
|
||||
|
||||
Expression* ExpandArgumentPack(Expression * exp, Declaration* dec);
|
||||
Expression* ParseListExpression(bool lhs);
|
||||
Expression* ParseListExpression(bool lhs, Declaration * params = nullptr);
|
||||
|
||||
Expression* ParseParenthesisExpression(void);
|
||||
void ParseStaticAssert(void);
|
||||
|
||||
Errors* mErrors;
|
||||
Scanner* mScanner;
|
||||
|
|
|
@ -44,7 +44,7 @@ bool SourceFile::ReadLineLZO(char* line, ptrdiff_t limit)
|
|||
while (pi < 127 && mPos < mFill)
|
||||
{
|
||||
int bi = pi, bj = 0;
|
||||
for (int i = 1; i < mPos; i++)
|
||||
for (int i = 1; i <= (mPos < 255 ? mPos : 255); i++)
|
||||
{
|
||||
int j = 0;
|
||||
while (j < 127 && mPos + j < mFill && mBuffer[mPos - i + j] == mBuffer[mPos + j])
|
||||
|
@ -327,6 +327,16 @@ struct CTMHeader9
|
|||
uint8 mColors[7];
|
||||
};
|
||||
|
||||
struct CTTHeader9
|
||||
{
|
||||
uint8 mDispMode;
|
||||
uint8 mColorMethod;
|
||||
uint8 mFlags;
|
||||
uint8 mFgridWidth[2], mFGridHeight[2];
|
||||
char mFGridConfig;
|
||||
uint8 mColors[6];
|
||||
};
|
||||
|
||||
#if 0
|
||||
#pragma pack(push, 1)
|
||||
struct SPDHeader5
|
||||
|
@ -420,6 +430,7 @@ void SourceFile::ReadSpritePad(Errors* errors, const Location& location, SourceF
|
|||
if (spdHeader.mID[0] == 'S' && spdHeader.mID[1] == 'P' && spdHeader.mID[2] == 'D')
|
||||
{
|
||||
int numSprites = 0;
|
||||
int numTiles = 0, tileSize = 0;
|
||||
|
||||
switch (spdHeader.mVersion[0])
|
||||
{
|
||||
|
@ -428,6 +439,8 @@ void SourceFile::ReadSpritePad(Errors* errors, const Location& location, SourceF
|
|||
SPDHeader5 spdHeader5;
|
||||
fread(&spdHeader5, sizeof(SPDHeader5), 1, mFile);
|
||||
numSprites = spdHeader5.mNumSprites;
|
||||
numTiles = spdHeader5.mNumTiles;
|
||||
tileSize = spdHeader5.mTileHeight * spdHeader5.mTileWidth;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
|
@ -435,6 +448,8 @@ void SourceFile::ReadSpritePad(Errors* errors, const Location& location, SourceF
|
|||
SPDHeader3 spdHeader3;
|
||||
fread(&spdHeader3, sizeof(SPDHeader3), 1, mFile);
|
||||
numSprites = spdHeader3.mNumSprites;
|
||||
numTiles = spdHeader3.mNumTiles;
|
||||
tileSize = spdHeader3.mTileHeight * spdHeader3.mTileWidth;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
|
@ -454,6 +469,21 @@ void SourceFile::ReadSpritePad(Errors* errors, const Location& location, SourceF
|
|||
mLimit = 64 * numSprites;
|
||||
return;
|
||||
}
|
||||
else if (decoder == SFD_SPD_TILES)
|
||||
{
|
||||
fseek(mFile, 64 * numSprites, SEEK_CUR);
|
||||
mMemSize = numTiles * tileSize;
|
||||
mLimit = mMemSize;
|
||||
mMemPos = 0;
|
||||
mMemData = new uint8[mMemSize];
|
||||
for (int i = 0; i < mMemSize; i++)
|
||||
{
|
||||
int16 d;
|
||||
fread(&d, 2, 1, mFile);
|
||||
mMemData[i] = uint8(d);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
errors->Error(location, EERR_UNIMPLEMENTED, "SPD file format not recognized");
|
||||
|
@ -466,6 +496,7 @@ void SourceFile::ReadCharPad(Errors* errors, const Location& location, SourceFil
|
|||
CTMHeader ctmHeader;
|
||||
CTMHeader8 ctmHeader8;
|
||||
CTMHeader9 ctmHeader9;
|
||||
CTTHeader9 cttHeader9;
|
||||
uint16 ctmMarker, numChars, numTiles;
|
||||
char tileWidth, tileHeight;
|
||||
|
||||
|
@ -476,10 +507,20 @@ void SourceFile::ReadCharPad(Errors* errors, const Location& location, SourceFil
|
|||
fread(&ctmHeader8, sizeof(CTMHeader8), 1, mFile);
|
||||
break;
|
||||
case 9:
|
||||
fread(&ctmHeader9, sizeof(CTMHeader9), 1, mFile);
|
||||
ctmHeader8.mDispMode = ctmHeader9.mDispMode;
|
||||
ctmHeader8.mColorMethod = ctmHeader9.mColorMethod;
|
||||
ctmHeader8.mFlags = ctmHeader9.mFlags;
|
||||
if (ctmHeader.mID[2] == 'T')
|
||||
{
|
||||
fread(&cttHeader9, sizeof(CTTHeader9), 1, mFile);
|
||||
ctmHeader8.mDispMode = cttHeader9.mDispMode;
|
||||
ctmHeader8.mColorMethod = cttHeader9.mColorMethod;
|
||||
ctmHeader8.mFlags = cttHeader9.mFlags;
|
||||
}
|
||||
else
|
||||
{
|
||||
fread(&ctmHeader9, sizeof(CTMHeader9), 1, mFile);
|
||||
ctmHeader8.mDispMode = ctmHeader9.mDispMode;
|
||||
ctmHeader8.mColorMethod = ctmHeader9.mColorMethod;
|
||||
ctmHeader8.mFlags = ctmHeader9.mFlags;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -725,6 +766,7 @@ void SourceFile::Limit(Errors* errors, const Location& location, SourceFileDecod
|
|||
break;
|
||||
|
||||
case SFD_SPD_SPRITES:
|
||||
case SFD_SPD_TILES:
|
||||
ReadSpritePad(errors, location, decoder);
|
||||
break;
|
||||
|
||||
|
|
|
@ -34,7 +34,8 @@ enum SourceFileDecoder
|
|||
SFD_CTM_TILES_16,
|
||||
SFD_CTM_MAP_8,
|
||||
SFD_CTM_MAP_16,
|
||||
SFD_SPD_SPRITES
|
||||
SFD_SPD_SPRITES,
|
||||
SFD_SPD_TILES,
|
||||
};
|
||||
|
||||
class SourceFile
|
||||
|
|
|
@ -51,6 +51,7 @@ const char* TokenNames[] =
|
|||
"'extern'",
|
||||
"'inline'",
|
||||
"'__assume'",
|
||||
"'static_assert'",
|
||||
|
||||
"__asm",
|
||||
"__interrupt",
|
||||
|
@ -173,6 +174,7 @@ const char* TokenNames[] =
|
|||
"'friend'",
|
||||
"'constexpr'",
|
||||
"'typename'",
|
||||
"'decltype'",
|
||||
};
|
||||
|
||||
|
||||
|
@ -355,7 +357,7 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
|
|||
mToken = TK_NONE;
|
||||
mUngetToken = TK_NONE;
|
||||
mReplay = nullptr;
|
||||
mRecord = mRecordLast = nullptr;
|
||||
mRecord = mRecordLast = mRecordPrev = nullptr;
|
||||
|
||||
mOnceDict = new MacroDict();
|
||||
|
||||
|
@ -372,13 +374,13 @@ Scanner::~Scanner(void)
|
|||
|
||||
void Scanner::BeginRecord(void)
|
||||
{
|
||||
mRecord = mRecordLast = new TokenSequence(this);
|
||||
mRecord = mRecordLast = mRecordPrev = new TokenSequence(this);
|
||||
}
|
||||
|
||||
TokenSequence* Scanner::CompleteRecord(void)
|
||||
{
|
||||
TokenSequence* seq = mRecord;
|
||||
mRecord = mRecordLast = nullptr;
|
||||
mRecord = mRecordLast = mRecordPrev = nullptr;
|
||||
return seq;
|
||||
}
|
||||
|
||||
|
@ -483,6 +485,8 @@ void Scanner::UngetToken(Token token)
|
|||
{
|
||||
mUngetToken = mToken;
|
||||
mToken = token;
|
||||
if (mRecord)
|
||||
mRecordLast = mRecordPrev;
|
||||
}
|
||||
|
||||
void Scanner::NextToken(void)
|
||||
|
@ -491,10 +495,8 @@ void Scanner::NextToken(void)
|
|||
{
|
||||
mToken = mUngetToken;
|
||||
mUngetToken = TK_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mReplay)
|
||||
else if (mReplay)
|
||||
{
|
||||
mLocation = mReplay->mLocation;
|
||||
mToken = mReplay->mToken;
|
||||
|
@ -515,6 +517,7 @@ void Scanner::NextToken(void)
|
|||
|
||||
if (mRecord)
|
||||
{
|
||||
mRecordPrev = mRecordLast;
|
||||
mRecordLast->mNext = new TokenSequence(this);
|
||||
mRecordLast = mRecordLast->mNext;
|
||||
}
|
||||
|
@ -820,28 +823,36 @@ void Scanner::NextPreToken(void)
|
|||
}
|
||||
else if (mToken == TK_PREP_IDENT)
|
||||
{
|
||||
Macro* def = nullptr;
|
||||
if (mDefineArguments)
|
||||
def = mDefineArguments->Lookup(mTokenIdent);
|
||||
if (!def)
|
||||
def = mDefines->Lookup(mTokenIdent);
|
||||
|
||||
if (def)
|
||||
if (mTokenIdent->mString[0])
|
||||
{
|
||||
if (def->mNumArguments == -1)
|
||||
Macro* def = nullptr;
|
||||
if (mDefineArguments)
|
||||
def = mDefineArguments->Lookup(mTokenIdent);
|
||||
if (!def)
|
||||
def = mDefines->Lookup(mTokenIdent);
|
||||
|
||||
if (def)
|
||||
{
|
||||
mToken = TK_STRING;
|
||||
int i = 0;
|
||||
while ((mTokenString[i] = def->mString[i]))
|
||||
i++;
|
||||
mTokenStringSize = i;
|
||||
return;
|
||||
if (def->mNumArguments == -1)
|
||||
{
|
||||
mToken = TK_STRING;
|
||||
int i = 0;
|
||||
while ((mTokenString[i] = def->mString[i]))
|
||||
i++;
|
||||
mTokenStringSize = i;
|
||||
return;
|
||||
}
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
|
||||
}
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
|
||||
}
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
|
||||
{
|
||||
mToken = TK_HASH;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (mToken == TK_PREP_UNDEF)
|
||||
{
|
||||
|
@ -986,6 +997,8 @@ void Scanner::NextPreToken(void)
|
|||
decoder = SFD_CTM_MAP_16;
|
||||
else if (!strcmp(mTokenIdent->mString, "spd_sprites"))
|
||||
decoder = SFD_SPD_SPRITES;
|
||||
else if (!strcmp(mTokenIdent->mString, "spd_tiles"))
|
||||
decoder = SFD_SPD_TILES;
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Invalid embed compression mode", mTokenIdent);
|
||||
|
||||
|
@ -1112,46 +1125,70 @@ void Scanner::NextPreToken(void)
|
|||
while (mTokenChar == ' ')
|
||||
NextChar();
|
||||
|
||||
while (mTokenChar == '#' && mLine[mOffset] == '#')
|
||||
if (mTokenChar == '#' && mLine[mOffset] == '#')
|
||||
{
|
||||
mOffset++;
|
||||
NextChar();
|
||||
|
||||
char tkbase[256];
|
||||
strcpy_s(tkbase, mTokenIdent->mString);
|
||||
|
||||
ptrdiff_t n = 0;
|
||||
char tkident[256];
|
||||
while (IsIdentChar(mTokenChar))
|
||||
{
|
||||
if (n < 255)
|
||||
tkident[n++] = mTokenChar;
|
||||
do {
|
||||
mOffset++;
|
||||
NextChar();
|
||||
}
|
||||
tkident[n] = 0;
|
||||
|
||||
const Ident* ntkident = Ident::Unique(tkident);
|
||||
ptrdiff_t n = 0;
|
||||
char tkident[256];
|
||||
while (IsIdentChar(mTokenChar))
|
||||
{
|
||||
if (n < 255)
|
||||
tkident[n++] = mTokenChar;
|
||||
NextChar();
|
||||
}
|
||||
tkident[n] = 0;
|
||||
|
||||
Macro* def = nullptr;
|
||||
if (mDefineArguments)
|
||||
def = mDefineArguments->Lookup(ntkident);
|
||||
if (!def)
|
||||
def = mDefines->Lookup(ntkident);
|
||||
const Ident* ntkident = Ident::Unique(tkident);
|
||||
|
||||
if (def)
|
||||
strcat_s(tkbase, def->mString);
|
||||
else
|
||||
strcat_s(tkbase, tkident);
|
||||
Macro* def = nullptr;
|
||||
if (mDefineArguments)
|
||||
def = mDefineArguments->Lookup(ntkident);
|
||||
if (!def)
|
||||
def = mDefines->Lookup(ntkident);
|
||||
|
||||
n = strlen(tkbase);
|
||||
while (n > 0 && tkbase[n - 1] == ' ')
|
||||
n--;
|
||||
tkbase[n] = 0;
|
||||
if (def)
|
||||
strcat_s(tkbase, def->mString);
|
||||
else
|
||||
strcat_s(tkbase, tkident);
|
||||
|
||||
mTokenIdent = Ident::Unique(tkbase);
|
||||
n = strlen(tkbase);
|
||||
while (n > 0 && tkbase[n - 1] == ' ')
|
||||
n--;
|
||||
tkbase[n] = 0;
|
||||
|
||||
while (mTokenChar == ' ')
|
||||
NextChar();
|
||||
|
||||
} while (mTokenChar == '#' && mLine[mOffset] == '#');
|
||||
|
||||
ptrdiff_t n = strlen(tkbase);
|
||||
char* str = new char[n + 1];
|
||||
strcpy_s(str, n + 1, tkbase);
|
||||
|
||||
MacroExpansion* ex = new MacroExpansion();
|
||||
ex->mDefinedArguments = mDefineArguments;
|
||||
|
||||
ex->mLine = mLine;
|
||||
ex->mOffset = mOffset;
|
||||
ex->mLink = mMacroExpansion;
|
||||
ex->mChar = mTokenChar;
|
||||
|
||||
mMacroExpansion = ex;
|
||||
mMacroExpansionDepth++;
|
||||
if (mMacroExpansionDepth > 1024)
|
||||
mErrors->Error(mLocation, EFATAL_MACRO_EXPANSION_DEPTH, "Maximum macro expansion depth exceeded", mTokenIdent);
|
||||
mLine = str;
|
||||
mOffset = 0;
|
||||
NextChar();
|
||||
}
|
||||
|
||||
return;
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1796,6 +1833,8 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_ASM;
|
||||
else if (!strcmp(tkident, "__assume"))
|
||||
mToken = TK_ASSUME;
|
||||
else if (!strcmp(tkident, "static_assert"))
|
||||
mToken = TK_STATIC_ASSERT;
|
||||
else if (!strcmp(tkident, "__interrupt"))
|
||||
mToken = TK_INTERRUPT;
|
||||
else if (!strcmp(tkident, "__hwinterrupt"))
|
||||
|
@ -1844,6 +1883,8 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_CONSTEXPR;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "typename"))
|
||||
mToken = TK_TYPENAME;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "decltype"))
|
||||
mToken = TK_DECLTYPE;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
|
||||
{
|
||||
NextRawToken();
|
||||
|
@ -1973,7 +2014,7 @@ void Scanner::NextRawToken(void)
|
|||
|
||||
default:
|
||||
// dirty little hack to implement token preview, got to fix
|
||||
// this with an infinit preview sequence at one point
|
||||
// this with an infinite preview sequence at one point
|
||||
mUngetToken = mToken;
|
||||
mToken = TK_OPERATOR;
|
||||
return;
|
||||
|
|
|
@ -49,6 +49,7 @@ enum Token
|
|||
TK_EXTERN,
|
||||
TK_INLINE,
|
||||
TK_ASSUME,
|
||||
TK_STATIC_ASSERT,
|
||||
|
||||
TK_ASM,
|
||||
TK_INTERRUPT,
|
||||
|
@ -172,6 +173,7 @@ enum Token
|
|||
TK_FRIEND,
|
||||
TK_CONSTEXPR,
|
||||
TK_TYPENAME,
|
||||
TK_DECLTYPE,
|
||||
|
||||
NUM_TOKENS
|
||||
};
|
||||
|
@ -315,7 +317,7 @@ protected:
|
|||
Token mUngetToken;
|
||||
|
||||
const TokenSequence* mReplay;
|
||||
TokenSequence* mRecord, * mRecordLast;
|
||||
TokenSequence* mRecord, * mRecordLast, * mRecordPrev;
|
||||
|
||||
void StringToken(char terminator, char mode);
|
||||
void CharToken(char mode);
|
||||
|
|
|
@ -76,7 +76,7 @@ int main2(int argc, const char** argv)
|
|||
|
||||
#else
|
||||
strcpy(strProductName, "oscar64");
|
||||
strcpy(strProductVersion, "1.31.255");
|
||||
strcpy(strProductVersion, "1.31.261");
|
||||
|
||||
#ifdef __APPLE__
|
||||
uint32_t length = sizeof(basePath);
|
||||
|
@ -111,38 +111,12 @@ int main2(int argc, const char** argv)
|
|||
GrowingArray<const char*> dataFiles(nullptr);
|
||||
GrowingArray<bool> dataFileCompressed(false);
|
||||
|
||||
bool emulate = false, profile = false, customCRT = false;
|
||||
int trace = 0;
|
||||
|
||||
compiler->mPreprocessor->AddPath(basePath);
|
||||
strcpy_s(includePath, basePath);
|
||||
{
|
||||
FILE* crtFile;
|
||||
char crtFileNamePath[FILENAME_MAX];
|
||||
crtFileNamePath[FILENAME_MAX - 1] = '\0';
|
||||
strcpy_s(crtFileNamePath, basePath);
|
||||
strcat_s(crtFileNamePath, "include/crt.h");
|
||||
|
||||
if (!fopen_s(&crtFile, crtFileNamePath, "r"))
|
||||
strcat_s(includePath, "include/");
|
||||
else
|
||||
{
|
||||
strcpy_s(crtFileNamePath, basePath);
|
||||
strcat_s(crtFileNamePath, "include/oscar64/crt.h");
|
||||
|
||||
if (!fopen_s(&crtFile, crtFileNamePath, "r"))
|
||||
strcat_s(includePath, "include/oscar64/");
|
||||
else
|
||||
{
|
||||
printf("Could not locate Oscar64 includes under %s\n", basePath);
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
fclose(crtFile);
|
||||
}
|
||||
compiler->mPreprocessor->AddPath(includePath);
|
||||
strcpy_s(crtPath, includePath);
|
||||
strcat_s(crtPath, "crt.c");
|
||||
|
||||
bool emulate = false, profile = false;
|
||||
int trace = 0;
|
||||
strcat_s(includePath, "include");
|
||||
|
||||
targetPath[0] = 0;
|
||||
diskPath[0] = 0;
|
||||
|
@ -185,6 +159,10 @@ int main2(int argc, const char** argv)
|
|||
{
|
||||
compiler->mPreprocessor->AddPath(arg + 3);
|
||||
}
|
||||
else if (arg[1] == 'i' && arg[2] == 'i' && arg[3] == '=')
|
||||
{
|
||||
strcpy_s(includePath, arg + 4);
|
||||
}
|
||||
else if (arg[1] == 'f' && arg[2] == '=')
|
||||
{
|
||||
dataFiles.Push(arg + 3);
|
||||
|
@ -206,6 +184,7 @@ int main2(int argc, const char** argv)
|
|||
else if (arg[1] == 'r' && arg[2] == 't' && arg[3] == '=')
|
||||
{
|
||||
strcpy_s(crtPath, arg + 4);
|
||||
customCRT = true;
|
||||
}
|
||||
else if (arg[1] == 'd' && arg[2] == '6' && arg[3] == '4' && arg[4] == '=')
|
||||
{
|
||||
|
@ -253,6 +232,8 @@ int main2(int argc, const char** argv)
|
|||
compiler->mCompilerOptions |= COPT_OPTIMIZE_ASSEMBLER;
|
||||
else if (arg[2] == 'i' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_AUTO_INLINE;
|
||||
else if (arg[2] == 'i' && arg[3] == 'i' && !arg[4])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_INLINE_ALL;
|
||||
else if (arg[2] == 'z' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_AUTO_ZEROPAGE;
|
||||
else if (arg[2] == 'p' && !arg[3])
|
||||
|
@ -261,6 +242,10 @@ int main2(int argc, const char** argv)
|
|||
compiler->mCompilerOptions |= COPT_OPTIMIZE_GLOBAL;
|
||||
else if (arg[2] == 'm' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_MERGE_CALLS;
|
||||
else if (arg[2] == 'o' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_OUTLINE;
|
||||
else if (arg[2] == 'x' && !arg[3])
|
||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_PAGE_CROSSING;
|
||||
else
|
||||
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid command line argument", arg);
|
||||
}
|
||||
|
@ -297,6 +282,10 @@ int main2(int argc, const char** argv)
|
|||
{
|
||||
compiler->mCompilerOptions |= COPT_DEBUGINFO;
|
||||
}
|
||||
else if (arg[1] == 'g' && arg[2] == 'p' && !arg[3])
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_DEBUGINFO | COPT_PROFILEINFO;
|
||||
}
|
||||
else if (arg[1] == 'v')
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_VERBOSE;
|
||||
|
@ -317,7 +306,13 @@ int main2(int argc, const char** argv)
|
|||
{
|
||||
compiler->mCompilerOptions |= COPT_CPLUSPLUS;
|
||||
compiler->AddDefine(Ident::Unique("__cplusplus"), "1");
|
||||
compiler->AddDefine(Ident::Unique("__cplusplus__"), "1");
|
||||
}
|
||||
else if (arg[1] == 's' && arg[2] == 't' && arg[3] == 'r' && arg[4] == 'i' && arg[5] == 'c' && arg[6] == 't' && !arg[7])
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_STRICT;
|
||||
compiler->AddDefine(Ident::Unique("__strict__"), "1");
|
||||
}
|
||||
else if (arg[1] == 'r' && arg[2] == 'm' && arg[3] == 'p' && !arg[4])
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_ERROR_FILES;
|
||||
|
@ -335,6 +330,7 @@ int main2(int argc, const char** argv)
|
|||
{
|
||||
compiler->mCompilerOptions |= COPT_CPLUSPLUS;
|
||||
compiler->AddDefine(Ident::Unique("__cplusplus"), "1");
|
||||
compiler->AddDefine(Ident::Unique("__cplusplus__"), "1");
|
||||
}
|
||||
|
||||
compiler->mCompilationUnits->AddUnit(loc, argv[i], nullptr);
|
||||
|
@ -431,6 +427,12 @@ int main2(int argc, const char** argv)
|
|||
compiler->mTargetMachine = TMACH_PLUS4;
|
||||
compiler->AddDefine(Ident::Unique("__PLUS4__"), "1");
|
||||
}
|
||||
else if (!strcmp(targetMachine, "mega65"))
|
||||
{
|
||||
strcpy_s(basicStart, "0x2001");
|
||||
compiler->mTargetMachine = TMACH_MEGA65;
|
||||
compiler->AddDefine(Ident::Unique("__MEGA65__"), "1");
|
||||
}
|
||||
else if (!strcmp(targetMachine, "x16"))
|
||||
{
|
||||
strcpy_s(basicStart, "0x0801");
|
||||
|
@ -549,12 +551,41 @@ int main2(int argc, const char** argv)
|
|||
strftime(dstring, sizeof(tstring) - 1, "\"%b %d %Y\"", &t);
|
||||
strftime(tstring, sizeof(dstring) - 1, "\"%H:%M:%S\"", &t);
|
||||
|
||||
compiler->AddDefine(Ident::Unique("__DATE__"), dstring);
|
||||
compiler->AddDefine(Ident::Unique("__TIME__"), tstring);
|
||||
compiler->AddDefine(Ident::Unique("__DATE__"), _strdup(dstring));
|
||||
compiler->AddDefine(Ident::Unique("__TIME__"), _strdup(tstring));
|
||||
}
|
||||
|
||||
// Add runtime module
|
||||
|
||||
compiler->mPreprocessor->AddPath(includePath);
|
||||
|
||||
if (!customCRT)
|
||||
{
|
||||
FILE* crtFile;
|
||||
char crtFileNamePath[FILENAME_MAX];
|
||||
crtFileNamePath[FILENAME_MAX - 1] = '\0';
|
||||
strcpy_s(crtFileNamePath, includePath);
|
||||
strcat_s(crtFileNamePath, "/crt.h");
|
||||
|
||||
if (fopen_s(&crtFile, crtFileNamePath, "r"))
|
||||
{
|
||||
strcpy_s(crtFileNamePath, basePath);
|
||||
strcat_s(crtFileNamePath, "include/oscar64/crt.h");
|
||||
|
||||
if (!fopen_s(&crtFile, crtFileNamePath, "r"))
|
||||
strcat_s(includePath, "include/oscar64/");
|
||||
else
|
||||
{
|
||||
printf("Could not locate Oscar64 includes under %s\n", basePath);
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
fclose(crtFile);
|
||||
|
||||
strcpy_s(crtPath, includePath);
|
||||
strcat_s(crtPath, "/crt.c");
|
||||
}
|
||||
|
||||
if (crtPath[0])
|
||||
compiler->mCompilationUnits->AddUnit(loc, crtPath, nullptr);
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,31,255,0
|
||||
PRODUCTVERSION 1,31,255,0
|
||||
FILEVERSION 1,31,261,0
|
||||
PRODUCTVERSION 1,31,261,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -43,12 +43,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "oscar64"
|
||||
VALUE "FileDescription", "oscar64 compiler"
|
||||
VALUE "FileVersion", "1.31.255.0"
|
||||
VALUE "FileVersion", "1.31.261.0"
|
||||
VALUE "InternalName", "oscar64.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "oscar64.exe"
|
||||
VALUE "ProductName", "oscar64"
|
||||
VALUE "ProductVersion", "1.31.255.0"
|
||||
VALUE "ProductVersion", "1.31.261.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -189,6 +189,7 @@
|
|||
<ClCompile Include="Linker.cpp" />
|
||||
<ClCompile Include="MachineTypes.cpp" />
|
||||
<ClCompile Include="NativeCodeGenerator.cpp" />
|
||||
<ClCompile Include="NativeCodeOutliner.cpp" />
|
||||
<ClCompile Include="NumberSet.cpp" />
|
||||
<ClCompile Include="oscar64.cpp" />
|
||||
<ClCompile Include="Parser.cpp" />
|
||||
|
@ -218,6 +219,7 @@
|
|||
<ClInclude Include="Linker.h" />
|
||||
<ClInclude Include="MachineTypes.h" />
|
||||
<ClInclude Include="NativeCodeGenerator.h" />
|
||||
<ClInclude Include="NativeCodeOutliner.h" />
|
||||
<ClInclude Include="NumberSet.h" />
|
||||
<ClInclude Include="Parser.h" />
|
||||
<ClInclude Include="Preprocessor.h" />
|
||||
|
|
|
@ -87,6 +87,9 @@
|
|||
<ClCompile Include="Compression.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NativeCodeOutliner.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Array.h">
|
||||
|
@ -170,6 +173,9 @@
|
|||
<ClInclude Include="Compression.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NativeCodeOutliner.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="oscar64.rc">
|
||||
|
|
|
@ -220,12 +220,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_23B2892D4F99800BBD8DB9210ECF6B0F"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_24F2466589154E2DAA108C2EDB3BB432"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -286,12 +280,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_31D185B4E4448BB9122BE23BE0C259A8"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_3277DE1463544F67B7E7390175F8A9CF"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -412,6 +400,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4B482689C546CDFC92F367BA507E7ADE"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4B8FC526E6CC47FC8321D0191BFDBEDC"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -430,6 +424,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4E94486A43C1D1C032A05ED1E6F1FCEF"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4E9503F4F8F343739E4685C2066B3AD0"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -454,12 +454,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_55D2A0DA296A07FFD056F9B0C3671317"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_5832EB4DC2134FF0BB7872666547CA0B"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -532,6 +526,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_65687B00DD49EEBBFFECE831614822A9"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_67C8F824E02B4211B315AB32AB7ABBB1"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -634,12 +634,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_7E4677138841AB7F15DEADCDE137C3A1"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_7E6F12A2B7A647199FCBA7CBDF4E94D2"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -724,12 +718,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_8F9D1B22CCDDE3C1C2E92F178E8AD418"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_90171C7FE48D426E8664B043F5E75D6B"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -808,6 +796,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A1455504C259EDA9662CE90C07369CC5"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A14BC161099E420286E6A1595596D0F0"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -832,6 +826,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A2F68033370E18CD792ECD1F91357C1B"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A32310DEFD4E41118CD7D36A8614C0D4"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -844,12 +844,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A3FC19061EE356D91CA54089DF69D2ED"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A566398810C1458E8E063A81FA88D46F"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -892,6 +886,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_AD3AED76152E705799261747B7FD2015"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_AE023AEA6C444140B19CD627DDC2CB87"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -958,12 +958,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_BB6C841EC4662FACDA8C15CBE509E50F"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_BBECB7DB41D84A34B2837C5E7EC7FAD4"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -988,6 +982,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_C0E88FBB7B883ED27FFB3C60DBE114B8"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_C239EFB1C3A646809AD2740ABDE747B0"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -1084,7 +1084,13 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_CF200F5BD2D7FF90606D390FBF182D8D"
|
||||
"MsmKey" = "8:_D04F8D80984DFA3EA342FE8FA1B7CC91"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_D057B4CD935875ECE7F0A91620660D07"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
|
@ -1342,12 +1348,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_FA51546D227188A30196C2FBB877CF97"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -2137,26 +2137,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_23B2892D4F99800BBD8DB9210ECF6B0F"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-locale-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-locale-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_24F2466589154E2DAA108C2EDB3BB432"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\oscar.c"
|
||||
|
@ -2357,26 +2337,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_31D185B4E4448BB9122BE23BE0C259A8"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-math-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-math-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3277DE1463544F67B7E7390175F8A9CF"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\rasterirq\\autocrawler.c"
|
||||
|
@ -2777,6 +2737,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4B482689C546CDFC92F367BA507E7ADE"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4B8FC526E6CC47FC8321D0191BFDBEDC"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\resources\\scifiglyph.bin"
|
||||
|
@ -2837,6 +2817,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4E94486A43C1D1C032A05ED1E6F1FCEF"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-locale-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-locale-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4E9503F4F8F343739E4685C2066B3AD0"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\plus4\\ted.c"
|
||||
|
@ -2917,26 +2917,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_55D2A0DA296A07FFD056F9B0C3671317"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-heap-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-heap-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5832EB4DC2134FF0BB7872666547CA0B"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\sprites\\make.bat"
|
||||
|
@ -3177,6 +3157,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_65687B00DD49EEBBFFECE831614822A9"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_67C8F824E02B4211B315AB32AB7ABBB1"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\games\\breakout.c"
|
||||
|
@ -3517,26 +3517,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7E4677138841AB7F15DEADCDE137C3A1"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7E6F12A2B7A647199FCBA7CBDF4E94D2"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\kernalio\\filewrite.c"
|
||||
|
@ -3817,26 +3797,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8F9D1B22CCDDE3C1C2E92F178E8AD418"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-convert-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-convert-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_90171C7FE48D426E8664B043F5E75D6B"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\c128\\mmu.c"
|
||||
|
@ -4097,6 +4057,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A1455504C259EDA9662CE90C07369CC5"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-time-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-time-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A14BC161099E420286E6A1595596D0F0"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\opp\\ofstream.h"
|
||||
|
@ -4177,6 +4157,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A2F68033370E18CD792ECD1F91357C1B"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A32310DEFD4E41118CD7D36A8614C0D4"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\limits.h"
|
||||
|
@ -4217,26 +4217,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A3FC19061EE356D91CA54089DF69D2ED"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A566398810C1458E8E063A81FA88D46F"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\stddef.h"
|
||||
|
@ -4377,6 +4357,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AD3AED76152E705799261747B7FD2015"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-math-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-math-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AE023AEA6C444140B19CD627DDC2CB87"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\cx16\\vera.h"
|
||||
|
@ -4597,26 +4597,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BB6C841EC4662FACDA8C15CBE509E50F"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BBECB7DB41D84A34B2837C5E7EC7FAD4"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\hires\\make.bat"
|
||||
|
@ -4697,6 +4677,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C0E88FBB7B883ED27FFB3C60DBE114B8"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-string-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-string-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C239EFB1C3A646809AD2740ABDE747B0"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\c64\\types.h"
|
||||
|
@ -5017,10 +5017,30 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CF200F5BD2D7FF90606D390FBF182D8D"
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D04F8D80984DFA3EA342FE8FA1B7CC91"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-time-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-time-l1-1-0.dll"
|
||||
"SourcePath" = "8:api-ms-win-crt-heap-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-heap-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D057B4CD935875ECE7F0A91620660D07"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-convert-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-convert-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
|
@ -5877,26 +5897,6 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FA51546D227188A30196C2FBB877CF97"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-string-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-string-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FCF3696486DC430EA7BFACA8BE9731E7"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\ctype.c"
|
||||
|
@ -6310,15 +6310,15 @@
|
|||
{
|
||||
"Name" = "8:Microsoft Visual Studio"
|
||||
"ProductName" = "8:oscar64"
|
||||
"ProductCode" = "8:{DF8EA500-AEE0-466B-A4A7-4AF4F3DFDA84}"
|
||||
"PackageCode" = "8:{70789022-7FA0-4A4F-B592-F9074ACA6673}"
|
||||
"ProductCode" = "8:{1B9A0E10-DEA6-4276-AC91-17782FE44D94}"
|
||||
"PackageCode" = "8:{51BFE576-50D1-4F8F-AE7A-9FF07396F53D}"
|
||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||
"AspNetVersion" = "8:2.0.50727.0"
|
||||
"RestartWWWService" = "11:FALSE"
|
||||
"RemovePreviousVersions" = "11:TRUE"
|
||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||
"InstallAllUsers" = "11:FALSE"
|
||||
"ProductVersion" = "8:1.31.255"
|
||||
"ProductVersion" = "8:1.31.261"
|
||||
"Manufacturer" = "8:oscar64"
|
||||
"ARPHELPTELEPHONE" = "8:"
|
||||
"ARPHELPLINK" = "8:"
|
||||
|
|
|
@ -29,7 +29,7 @@ const char MissileChars[] = {
|
|||
#define Charset ((char *)0xd800)
|
||||
|
||||
// Joystick and crosshair control
|
||||
int CrossX = 160, CrossY = 100;
|
||||
volatile int CrossX = 160, CrossY = 100;
|
||||
bool CrossP = false;
|
||||
char CrossDelay = 0;
|
||||
|
||||
|
@ -553,20 +553,22 @@ __interrupt void joy_interrupt()
|
|||
joy_poll(0);
|
||||
|
||||
// Move crosshair coordinates
|
||||
CrossX += 2 * joyx[0]; CrossY += 2 * joyy[0];
|
||||
int cx = CrossX + 2 * joyx[0], cy = CrossY + 2 * joyy[0];
|
||||
|
||||
// Stop at edges of screen
|
||||
if (CrossX < 8)
|
||||
CrossX = 8;
|
||||
else if (CrossX > 312)
|
||||
CrossX = 312;
|
||||
if (CrossY < 20)
|
||||
CrossY = 20;
|
||||
else if (CrossY > 172)
|
||||
CrossY = 172;
|
||||
if (cx < 8)
|
||||
cx = 8;
|
||||
else if (cx > 312)
|
||||
cx = 312;
|
||||
if (cy < 20)
|
||||
cy = 20;
|
||||
else if (cy > 172)
|
||||
cy = 172;
|
||||
|
||||
// Move crosshair sprite
|
||||
spr_move(0, CrossX + 14, CrossY + 40);
|
||||
spr_move(0, cx + 14, cy + 40);
|
||||
CrossX = cx;
|
||||
CrossY = cy;
|
||||
|
||||
// Check button
|
||||
if (joyb[0])
|
||||
|
@ -697,15 +699,17 @@ void game_play(void)
|
|||
// Check if fire request
|
||||
if (CrossP)
|
||||
{
|
||||
int cx = CrossX, cy = CrossY;
|
||||
|
||||
// Find launch site
|
||||
int sx = 160;
|
||||
if (CrossX < 120)
|
||||
if (cx < 120)
|
||||
sx = 24;
|
||||
else if (CrossX > 200)
|
||||
else if (cx > 200)
|
||||
sx = 296;
|
||||
|
||||
// Fire missile
|
||||
missile_start(sx, 184, CrossX, CrossY);
|
||||
missile_start(sx, 184, cx, cy);
|
||||
|
||||
// Reset request
|
||||
CrossP = false;
|
||||
|
|
|
@ -48,7 +48,7 @@ struct Point
|
|||
};
|
||||
|
||||
|
||||
Point tcorners[8], pcorners[8];
|
||||
__striped Point tcorners[8], pcorners[8];
|
||||
|
||||
void drawCube(void)
|
||||
{
|
||||
|
@ -77,6 +77,45 @@ void hideCube(void)
|
|||
}
|
||||
}
|
||||
|
||||
void xorCube(void)
|
||||
{
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
if (!(i & 1))
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 1].x, tcorners[i | 1].y, 0xff, LINOP_XOR);
|
||||
if (!(i & 2))
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 2].x, tcorners[i | 2].y, 0xff, LINOP_XOR);
|
||||
if (!(i & 4))
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 4].x, tcorners[i | 4].y, 0xff, LINOP_XOR);
|
||||
pcorners[i] = tcorners[i];
|
||||
}
|
||||
}
|
||||
|
||||
void xor2Cube(void)
|
||||
{
|
||||
for(char i=0; i<8; i++)
|
||||
{
|
||||
if (!(i & 1))
|
||||
{
|
||||
bm_line(&Screen, &cr, pcorners[i].x, pcorners[i].y, pcorners[i | 1].x, pcorners[i | 1].y, 0xff, LINOP_XOR);
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 1].x, tcorners[i | 1].y, 0xff, LINOP_XOR);
|
||||
}
|
||||
if (!(i & 2))
|
||||
{
|
||||
bm_line(&Screen, &cr, pcorners[i].x, pcorners[i].y, pcorners[i | 2].x, pcorners[i | 2].y, 0xff, LINOP_XOR);
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 2].x, tcorners[i | 2].y, 0xff, LINOP_XOR);
|
||||
}
|
||||
if (!(i & 4))
|
||||
{
|
||||
bm_line(&Screen, &cr, pcorners[i].x, pcorners[i].y, pcorners[i | 4].x, pcorners[i | 4].y, 0xff, LINOP_XOR);
|
||||
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 4].x, tcorners[i | 4].y, 0xff, LINOP_XOR);
|
||||
}
|
||||
}
|
||||
|
||||
for(char i=0; i<8; i++)
|
||||
pcorners[i] = tcorners[i];
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
F12Vector3 corners[8];
|
||||
|
@ -112,8 +151,15 @@ int main(void)
|
|||
tcorners[i].y = lmuldiv16s(vd.v[1], 140, vd.v[2] + 4 * FIX12_ONE) + 100;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (k)
|
||||
xor2Cube();
|
||||
else
|
||||
xorCube();
|
||||
#else
|
||||
hideCube();
|
||||
drawCube();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ void init(void)
|
|||
// Install IRQ trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
cia_init();
|
||||
|
||||
// All RAM
|
||||
mmap_set(MMAP_RAM);
|
||||
|
||||
|
@ -60,7 +62,6 @@ void init(void)
|
|||
spr_move(1, 24, 50);
|
||||
|
||||
// Disable system interrupt and init mouse
|
||||
cia_init();
|
||||
mouse_init();
|
||||
|
||||
bm_init(&sbm, Hires, 40, 25);
|
||||
|
|
|
@ -22,7 +22,7 @@ __interrupt void doscroll(void)
|
|||
vic.color_border++;
|
||||
|
||||
// Update raster IRQ for scroll line with new horizontal scroll offset
|
||||
rirq_data(&scroll, 0, 7 - (x & 7));
|
||||
rirq_data(&scroll, 1, 7 - (x & 7));
|
||||
// Copy scrolled version of text when switching over char border
|
||||
if ((x & 7) == 0)
|
||||
memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40);
|
||||
|
@ -37,11 +37,13 @@ int main(void)
|
|||
rirq_init(true);
|
||||
|
||||
// Build switch to scroll line IRQ
|
||||
rirq_build(&scroll, 1);
|
||||
rirq_build(&scroll, 2);
|
||||
// Delay for one line to get to right border
|
||||
rirq_delay(&scroll, 11);
|
||||
// Change control register two with this IRQ
|
||||
rirq_write(&scroll, 0, &vic.ctrl2, 0);
|
||||
rirq_write(&scroll, 1, &vic.ctrl2, 0);
|
||||
// Put it onto the scroll line
|
||||
rirq_set(0, 50 + 24 * 8, &scroll);
|
||||
rirq_set(0, 49 + 24 * 8, &scroll);
|
||||
|
||||
// Build the switch to normal IRQ
|
||||
rirq_build(&restore, 2);
|
||||
|
|
|
@ -20,11 +20,13 @@ int main(void)
|
|||
rirq_init(true);
|
||||
|
||||
// Build switch to scroll line IRQ
|
||||
rirq_build(&scroll, 1);
|
||||
rirq_build(&scroll, 2);
|
||||
// Delay for one line to get to right border
|
||||
rirq_delay(&scroll, 11);
|
||||
// Change control register two with this IRQ
|
||||
rirq_write(&scroll, 0, &vic.ctrl2, 0);
|
||||
rirq_write(&scroll, 1, &vic.ctrl2, 0);
|
||||
// Put it onto the scroll line
|
||||
rirq_set(0, 50 + 24 * 8, &scroll);
|
||||
rirq_set(0, 49 + 24 * 8, &scroll);
|
||||
|
||||
// Build the switch to normal IRQ
|
||||
rirq_build(&bottom, 1);
|
||||
|
@ -46,7 +48,7 @@ int main(void)
|
|||
// wait for raster reaching bottom of screen
|
||||
rirq_wait();
|
||||
// Update raster IRQ for scroll line with new horizontal scroll offset
|
||||
rirq_data(&scroll, 0, 7 - (x & 7));
|
||||
rirq_data(&scroll, 1, 7 - (x & 7));
|
||||
// Copy scrolled version of text when switching over char border
|
||||
if ((x & 7) == 0)
|
||||
memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40);
|
||||
|
|
|
@ -27,7 +27,7 @@ ScreenRow * const color = (ScreenRow *)0xd800;
|
|||
// Move the screen one character to the left
|
||||
void scrollLeft(void)
|
||||
{
|
||||
// Loop horizontaly
|
||||
// Loop horizontally
|
||||
for(char x=0; x<39; x++)
|
||||
{
|
||||
// Unroll vertical loop 16 times
|
||||
|
|
|
@ -64,6 +64,7 @@ const char * scrolltext[] = {
|
|||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
};
|
||||
|
||||
|
||||
|
@ -198,7 +199,7 @@ int main(void)
|
|||
// Update interrupt position
|
||||
for(char i=0; i<5; i++)
|
||||
{
|
||||
int ty = 48 * i + 46 + oy;
|
||||
int ty = 48 * i + 45 + oy;
|
||||
|
||||
// No interrupts below screen bottom
|
||||
if (ty < 250)
|
||||
|
@ -246,7 +247,7 @@ int main(void)
|
|||
case 42:
|
||||
readline(line, lpos);
|
||||
lpos++;
|
||||
if (lpos == 28)
|
||||
if (lpos == 27)
|
||||
lpos = 0;
|
||||
break;
|
||||
case 45:
|
||||
|
|
Loading…
Reference in New Issue