Compare commits

..

No commits in common. "main" and "v1.31.258" have entirely different histories.

80 changed files with 2504 additions and 13544 deletions

View File

@ -1,67 +0,0 @@
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
)

View File

@ -4,7 +4,7 @@ Oscar64 is a C/C++ cross compiler running on a modern system (such as a Windows
The purpose of this compiler is to eliminate the need to write 6502 assembler code to achieve high code density and fast execution speed. It continues to improve with all the games, demos and tools written by it. It supports disk overlays and banked cartridges for larger projects.
The C64 executes 442 dhrystone V2.2 iteration per second, when compiled with Oscar64 and -O3 (which shows that the ancient dhrystone benchmark is no match to an optimizing compiler).
The C64 executes 418 dhrystone V2.2 iteration per second, when compiled with Oscar64 and -O3 (which shows that the ancient dhrystone benchmark is no match to an optimizing compiler).
[Full reference manual](oscar64.md)
[Additional samples and tutorials](https://github.com/drmortalwombat/OscarTutorials)

View File

@ -1,8 +1,5 @@
rem @echo off
@call :test rolrortest.cpp
@if %errorlevel% neq 0 goto :error
@call :test bitfields.cpp
@if %errorlevel% neq 0 goto :error
@ -18,9 +15,6 @@ 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
@ -39,7 +33,7 @@ rem @echo off
@call :testh opp_list.cpp
@if %errorlevel% neq 0 goto :error
@call :testn opp_functional.cpp
@call :testh opp_functional.cpp
@if %errorlevel% neq 0 goto :error
@call :testh operatoroverload.cpp
@ -57,7 +51,7 @@ rem @echo off
@call :testh constructortest.cpp
@if %errorlevel% neq 0 goto :error
@call :testn copyconstructor.cpp
@call :testh copyconstructor.cpp
@if %errorlevel% neq 0 goto :error
@call :testh copyassign.cpp
@ -280,15 +274,6 @@ 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
@ -346,12 +331,6 @@ 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
@ -391,10 +370,4 @@ 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

View File

@ -1,5 +1,4 @@
#include <assert.h>
#include <stdio.h>
int t, n;
@ -162,7 +161,7 @@ void test_return_value(void)
C2 c(test_ret_v());
}
assert(n == 6 && t == 0);
assert(n == 4 && t == 0);
}
void test_return_reference(void)
@ -185,7 +184,7 @@ void test_retparam_value(void)
test_param_fv(test_ret_v());
}
assert(n == 6 && t == 0);
assert(n == 4 && t == 0);
}
void test_retparam_reference(void)
@ -201,6 +200,7 @@ void test_retparam_reference(void)
int main(void)
{
#if 0
test_dcopy_init();
test_copy_init();
test_minit();
@ -208,8 +208,9 @@ int main(void)
test_param_value();
test_param_ref();
test_return_value();
#endif
test_retparam_value();
test_retparam_reference();
// test_retparam_reference();
return 0;
}

View File

@ -50,11 +50,5 @@ 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

View File

@ -1,78 +0,0 @@
#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;
}

View File

@ -64,15 +64,5 @@ 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;
}

View File

@ -1,76 +0,0 @@
#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;
}

View File

@ -63,33 +63,6 @@ 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;
@ -215,71 +188,7 @@ bool nge1(long a)
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)
void cmp(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);
@ -294,27 +203,6 @@ void cmpc(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);
@ -345,21 +233,6 @@ 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);
@ -454,10 +327,6 @@ int main(void)
cmp1(256);
cmp1(10000);
cmp1(20000);
cmp1(1000000l);
cmp1(2000000l);
cmp1(100000000l);
cmp1(200000000l);
cmp1(-1);
cmp1(-2);
cmp1(-3);
@ -465,34 +334,6 @@ 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;

View File

@ -10,7 +10,7 @@ enum SIDFXState
SIDFX_WAIT
};
__striped static struct SIDFXChannel
static struct SIDFXChannel
{
const SIDFX * volatile com;
byte delay, priority;
@ -27,7 +27,6 @@ void sidfx_init(void)
channels[i].com = nullptr;
channels[i].state = SIDFX_IDLE;
channels[i].priority = 0;
channels[i].delay = 1;
}
}
@ -36,11 +35,6 @@ 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;
@ -53,7 +47,6 @@ 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;
@ -66,95 +59,71 @@ 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)
{
if (channels[ch].state)
switch (channels[ch].state)
{
const SIDFX * com = channels[ch].com;
channels[ch].delay--;
if (channels[ch].delay)
{
if (com->dfreq)
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:
{
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;
const SIDFX * com = channels[ch].com;
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].delay = com->time0;
channels[ch].state = SIDFX_PLAY;
channels[ch].freq += com->dfreq;
sid.voices[ch].freq = channels[ch].freq;
}
break;
case SIDFX_PLAY:
if (com->time0)
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)
{
sid.voices[ch].ctrl = com->ctrl & ~SID_CTRL_GATE;
channels[ch].delay = com->time0 - 1;
channels[ch].delay = com->time0;
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;
@ -162,30 +131,45 @@ inline void sidfx_loop_ch(byte ch)
}
else
{
com = nullptr;
channels[ch].state = SIDFX_RESET_0;
channels[ch].com = nullptr;
channels[ch].state = SIDFX_RESET_0;
}
break;
case SIDFX_WAIT:
if (channels[ch].cnt)
}
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)
{
com++;
channels[ch].cnt--;
channels[ch].com = com;
channels[ch].priority = com->priority;
if (com->ctrl & SID_CTRL_GATE)
if (com->time0)
channels[ch].state = SIDFX_RESET_0;
else
channels[ch].state = SIDFX_READY;
}
else
{
com = nullptr;
channels[ch].com = nullptr;
channels[ch].state = SIDFX_RESET_0;
}
break;
}
}
break;
}
}

View File

@ -20,8 +20,6 @@ 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);

View File

@ -69,7 +69,7 @@ BANKINLINE bool krnio_open(char fnum, char device, char channel)
{
krnio_pstatus[fnum] = KRNIO_OK;
return char(__asm
return __asm
{
lda #0
sta accu
@ -94,7 +94,8 @@ BANKINLINE bool krnio_open(char fnum, char device, char channel)
BANKOUT
E2:
});
};
}
#pragma native(krnio_open)
@ -130,7 +131,7 @@ BANKINLINE krnioerr krnio_status(void)
BANKINLINE bool krnio_load(char fnum, char device, char channel)
{
return char(__asm
return __asm
{
BANKIN
lda fnum
@ -148,14 +149,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 char(__asm
return __asm
{
BANKIN
lda #0
@ -174,14 +175,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 char(__asm
return __asm
{
BANKIN
ldx fnum
@ -192,14 +193,14 @@ BANKINLINE bool krnio_chkout(char fnum)
rol
eor #1
sta accu
});
};
}
#pragma native(krnio_chkout)
BANKINLINE bool krnio_chkin(char fnum)
{
return char(__asm
return __asm
{
BANKIN
ldx fnum
@ -210,7 +211,7 @@ BANKINLINE bool krnio_chkin(char fnum)
rol
eor #1
sta accu
});
};
}
#pragma native(krnio_chkin)
@ -229,14 +230,14 @@ BANKINLINE void krnio_clrchn(void)
BANKINLINE bool krnio_chrout(char ch)
{
return char(__asm
return __asm
{
BANKIN
lda ch
jsr $ffd2 // chrout
sta accu
BANKOUT
});
};
}
#pragma native(krnio_chrout)
@ -421,7 +422,7 @@ int krnio_gets(char fnum, char * data, int num)
if (krnio_chkin(fnum))
{
krnioerr err = KRNIO_OK;
krnioerr err;
int i = 0;
int ch;
while (i + 1 < num)

View File

@ -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]; // Sort order of interrupt index, offset by one
byte rasterIRQRows[NUM_IRQS + 1];
byte rasterIRQIndex[NUM_IRQS + 1];
#ifdef ZPAGE_IRQS
__zeropage
#endif
byte rasterIRQNext[NUM_IRQS + 1]; // Rasterline of interrupt, terminated by 0xff
byte rasterIRQLow[NUM_IRQS]; // Address of interrupt code
byte rasterIRQNext[NUM_IRQS + 1];
byte rasterIRQLow[NUM_IRQS];
byte rasterIRQHigh[NUM_IRQS];
#ifdef ZPAGE_IRQS
@ -22,70 +22,7 @@ __zeropage
#endif
byte nextIRQ;
// nextIRQ is the index of the next expected IRQ, or $ff if no IRQ is scheduled
__asm rirq_isr_ram_io
{
stx plrx + 1
ldx nextIRQ
bmi exi
sta plra + 1
sty plry + 1
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
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
__asm irq0
{
pha
txa
@ -93,16 +30,20 @@ __asm rirq_isr_io
tya
pha
kentry:
asl $d019
ldx nextIRQ
bmi exi
l1:
lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y
stx ji + 1
ldx rasterIRQHigh, y
stx ji + 2
tax
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji:
jsr $0000
@ -110,20 +51,21 @@ ji:
inc nextIRQ
ldx nextIRQ
ldy rasterIRQNext, x
asl $d019
cpy #$ff
lda rasterIRQNext, x
cmp #$ff
beq e2
// carry is cleared at this point
dey
sty $d012
dey
cpy $d012
bcc l1
tay
sbc #2
cmp $d012
bcc l1
exd:
dey
ex:
sty $d012
pla
tay
pla
@ -131,22 +73,25 @@ exd:
pla
rti
exi:
asl $d019
jmp exd
e2:
inc rirq_count
ldy rasterIRQNext
dey
sty $d012
ldx npos
stx tpos
inc rirq_count
tay
bit $d011
bpl ex
e1:
ldx #0
stx nextIRQ
beq exd
ldy rasterIRQNext
jmp exd
}
__asm rirq_isr_noio
__asm irq2
{
pha
txa
@ -160,15 +105,20 @@ kentry:
lda #$35
sta $01
asl $d019
ldx nextIRQ
bmi exi
l1:
lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y
stx ji + 1
ldx rasterIRQHigh, y
stx ji + 2
tax
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji:
jsr $0000
@ -176,20 +126,21 @@ ji:
inc nextIRQ
ldx nextIRQ
ldy rasterIRQNext, x
asl $d019
cpy #$ff
lda rasterIRQNext, x
cmp #$ff
beq e2
// carry is cleared at this point
tay
dey
sbc #2
cmp $d012
bcc l1
sty $d012
dey
cpy $d012
bcc l1
exd:
ex:
pla
sta $01
@ -200,35 +151,45 @@ exd:
pla
rti
exi:
asl $d019
jmp exd
e2:
ldx npos
stx tpos
inc rirq_count
bit $d011
bmi e1
sta $d012
jmp ex
e1:
ldx #0
stx nextIRQ
ldy rasterIRQNext
dey
sty $d012
ldx #0
stx nextIRQ
beq exd
jmp ex
}
__asm rirq_isr_kernal_io
__asm irq1
{
lda $d019
bpl ex2
ldx nextIRQ
bmi exi
l1:
lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y
stx ji + 1
ldx rasterIRQHigh, y
stx ji + 2
tax
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji:
jsr $0000
@ -237,36 +198,45 @@ jx:
inc nextIRQ
ldx nextIRQ
ldy rasterIRQNext, x
asl $d019
cpy #$ff
lda rasterIRQNext, x
cmp #$ff
beq e2
dey
dey
sty $d012
dey
cpy $d012
tay
sec
sbc #4
cmp $d012
bcc l1
exd:
jmp $ea81
exi:
asl $d019
jmp $ea81
e2:
inc rirq_count
ldy rasterIRQNext
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
jmp $ea81
ex2:
@ -275,7 +245,7 @@ ex2:
jmp $ea31
}
__asm rirq_isr_kernal_noio
__asm irq3
{
lda $01
pha
@ -286,14 +256,17 @@ __asm rirq_isr_kernal_noio
bpl ex2
ldx nextIRQ
bmi exi
l1:
lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y
stx ji + 1
ldx rasterIRQHigh, y
stx ji + 2
tax
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji:
jsr $0000
@ -302,40 +275,49 @@ jx:
inc nextIRQ
ldx nextIRQ
ldy rasterIRQNext, x
asl $d019
cpy #$ff
lda rasterIRQNext, x
cmp #$ff
beq e2
dey
tay
sec
sbc #4
cmp $d012
bcc l1
dey
sty $d012
dey
cpy $d012
bcc l1
exd:
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
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
@ -365,8 +347,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_LDX, 0);
asm_ab(ic->code + 4, ASM_CMP, 0xd012);
asm_im(ic->code + 2, ASM_LDA, 0);
asm_ab(ic->code + 4, ASM_CPX, 0xd012);
asm_rl(ic->code + 7, ASM_BCS, -5);
asm_ab(ic->code + 9, ASM_STY, 0x0000);
@ -380,7 +362,7 @@ void rirq_build(RIRQCode * ic, byte size)
}
else
{
asm_ab(ic->code + 12, ASM_STX, 0x0000);
asm_ab(ic->code + 12, ASM_STA, 0x0000);
byte p = 15;
for(byte i=2; i<size; i++)
@ -500,7 +482,7 @@ void rirq_init_kernal(void)
sei
}
*(void **)0x0314 = rirq_isr_kernal_io;
*(void **)0x0314 = irq1;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
@ -508,7 +490,7 @@ void rirq_init_kernal(void)
}
void rirq_init_kernal_noio(void)
void rirq_init_kernal_io(void)
{
rirq_init_tables();
@ -517,7 +499,7 @@ void rirq_init_kernal_noio(void)
sei
}
*(void **)0x0314 = rirq_isr_kernal_noio;
*(void **)0x0314 = irq3;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
@ -534,8 +516,8 @@ void rirq_init_crt(void)
sei
}
*(void **)0x0314 = rirq_isr_io.kentry;
*(void **)0xfffe = rirq_isr_io;
*(void **)0x0314 = irq0.kentry;
*(void **)0xfffe = irq0;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
@ -543,7 +525,7 @@ void rirq_init_crt(void)
}
void rirq_init_crt_noio(void)
void rirq_init_crt_io(void)
{
rirq_init_tables();
@ -552,8 +534,8 @@ void rirq_init_crt_noio(void)
sei
}
*(void **)0x0314 = rirq_isr_noio.kentry;
*(void **)0xfffe = rirq_isr_noio;
*(void **)0x0314 = irq2.kentry;
*(void **)0xfffe = irq2;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
@ -570,7 +552,7 @@ void rirq_init_io(void)
sei
}
*(void **)0xfffe = rirq_isr_ram_io;
*(void **)0xfffe = irq0;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
@ -587,7 +569,7 @@ void rirq_init_memmap(void)
sei
}
*(void **)0xfffe = rirq_isr_noio;
*(void **)0xfffe = irq2;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
@ -605,18 +587,12 @@ void rirq_init(bool kernalIRQ)
void rirq_wait(void)
{
char i0 = rirq_pcount;
char i1;
do {
i1 = rirq_count;
} while (i0 == i1);
rirq_pcount = i1;
while (tpos != npos) ;
npos++;
}
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++)
@ -664,17 +640,15 @@ void rirq_sort(bool inirq)
}
#endif
rirq_pcount = rirq_count;
npos++;
if (inirq)
nextIRQ = NUM_IRQS - 1;
else
{
byte yp = rasterIRQNext[0];
nextIRQ = 0;
byte yp = rasterIRQNext[nextIRQ];
if (yp != 0xff)
{
vic.raster = yp - 1;
nextIRQ = 0;
}
}
}
@ -689,7 +663,6 @@ void rirq_start(void)
lda #100
sta $d012
asl $d019
cli
}
}

View File

@ -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_noio(void);
void rirq_init_kernal_io(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_noio(void);
void rirq_init_crt_io(void);
// Raster IRQ through RAM vector, with ROM disabled and IO range always enabled
// does not call kernal continuation
@ -179,7 +179,7 @@ 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 operations.
// the vertical position of one of the interrupt operatins.
// Set the inirq flag to true when calling this from an interrupt
void rirq_sort(bool inirq = false);

View File

@ -171,12 +171,6 @@ 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;

View File

@ -68,8 +68,6 @@ 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

View File

@ -114,21 +114,4 @@ 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)

View File

@ -118,9 +118,6 @@ 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))

View File

@ -131,18 +131,6 @@ __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
@ -224,10 +212,11 @@ void putpch(char c)
c ^= 0xa0;
c ^= 0x20;
#else
c ^= 0x20;
if (c >= 97)
c ^= 0x20;
#endif
if (giocharmap == IOCHM_PETSCII_1)
if (giocharmap == IOCHM_PETSCII_2)
c &= 0xdf;
}
}
@ -279,19 +268,11 @@ 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)
@ -352,32 +333,13 @@ 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
ldy cx
clc
jsr bsplot
}
#endif
}
}
void textcolor(char c)

View File

@ -667,19 +667,21 @@ 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
sec
lda tmp + 6
sbc tmp + 2
sta tmp + 6
lda tmp + 7
sbc tmp + 3
sta tmp + 7
W1: dey
bne L1
rol accu
@ -756,11 +758,6 @@ __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
@ -778,7 +775,6 @@ WM:
stx accu + 1
sta accu
rts
WB: lda tmp + 0
W0:
sec
ror
@ -3076,7 +3072,7 @@ __asm inp_binop_sub_f32
#pragma bytecode(BC_BINOP_SUB_F32, inp_binop_sub_f32)
__asm crt_fmul8
__asm fmul8
{
sec
ror
@ -3110,7 +3106,7 @@ W1:
rts
}
__asm crt_fmul
__asm fmul
{
lda accu
ora accu + 1
@ -3151,13 +3147,13 @@ W2:
beq W5
bne W6
W4:
jsr crt_fmul8
jsr fmul8
lda tmp + 1
W6:
jsr crt_fmul8
jsr fmul8
W5:
lda tmp + 2
jsr crt_fmul8
jsr fmul8
sec
lda tmp + 8
@ -3214,12 +3210,12 @@ __asm inp_binop_mul_f32
{
jsr freg.split_exp
sty tmpy
jsr crt_fmul
jsr fmul
ldy tmpy
jmp startup.exec
}
__asm crt_fdiv
__asm fdiv
{
lda accu
ora accu + 1
@ -3341,13 +3337,13 @@ ZERO:
__asm inp_binop_div_f32
{
jsr freg.split_exp
jsr crt_fdiv
jsr fdiv
jmp startup.exec
}
#pragma bytecode(BC_BINOP_DIV_F32, inp_binop_div_f32)
__asm crt_fcmp
__asm fcmp
{
lda accu + 3
eor tmp + 3
@ -4062,9 +4058,9 @@ __asm load32
#pragma runtime(fmergea, freg.merge_aexp)
#pragma runtime(fadd, faddsub.fadd)
#pragma runtime(fsub, faddsub.fsub)
#pragma runtime(fmul, crt_fmul)
#pragma runtime(fdiv, crt_fdiv)
#pragma runtime(fcmp, crt_fcmp)
#pragma runtime(fmul, fmul)
#pragma runtime(fdiv, fdiv)
#pragma runtime(fcmp, fcmp)
#pragma runtime(ffromi, sint16_to_float)
#pragma runtime(ffromu, uint16_to_float)
#pragma runtime(ftoi, f32_to_i16)
@ -4562,7 +4558,7 @@ struct Heap {
#pragma section(heap, 0x0000, HeapStart, HeapEnd)
__asm crt_malloc
__asm malloc
{
// make room for two additional bytes
// to store pointer to end of used memory
@ -4789,14 +4785,14 @@ hc2:
__asm inp_malloc
{
sty tmpy
jsr crt_malloc
jsr malloc
ldy tmpy
jmp startup.exec
}
#pragma bytecode(BC_MALLOC, inp_malloc)
__asm crt_free
__asm free
{
// check nullptr free
@ -5013,21 +5009,21 @@ nostart:
__asm inp_free
{
sty tmpy
jsr crt_free
jsr free
ldy tmpy
jmp startup.exec
}
#pragma bytecode(BC_FREE, inp_free)
__asm crt_breakpoint
__asm breakpoint
{
rts
}
#pragma runtime(malloc, crt_malloc)
#pragma runtime(free, crt_free)
#pragma runtime(breakpoint, crt_breakpoint)
#pragma runtime(malloc, malloc)
#pragma runtime(free, free)
#pragma runtime(breakpoint, breakpoint)
#if 0

View File

@ -123,9 +123,8 @@ int lmul4f12s(int x, int y)
lda #0
sta accu + 1
bcc W4
L2:
bcc W4
tay
clc
lda accu + 1
@ -166,7 +165,7 @@ W1:
bcc W2
tay
// sec ; we know it is set here
sec
lda accu + 1
sbc y
sta accu + 1

View File

@ -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,105 +579,82 @@ 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)
{
bool delta8 = false;
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);
if (dx)
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)
{
// 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);
}
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_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, 12);
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 13);
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);
}
}
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
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);
}
}
// l --

View File

@ -110,12 +110,12 @@ float atan2(float p, float q)
return s;
}
#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
#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
float exp(float f)
{
@ -143,12 +143,12 @@ float exp(float f)
return s * x.f;
}
#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
#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
float log(float f)
{

View File

@ -33,15 +33,10 @@ 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")

View File

@ -1,59 +0,0 @@
#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

View File

@ -4,7 +4,6 @@
#include <new>
#include <stdlib.h>
#include <opp/utility.h>
#include <oscar.h>
namespace opp {
@ -12,8 +11,8 @@ template <class T, int N>
class static_vector
{
protected:
enum { m = N } _size;
char _space[N * sizeof(T)];
enum { m = N } _size;
public:
typedef T element_type;
@ -21,28 +20,23 @@ 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<n; i++)
for(size_t i=0; i<_size; i++)
new (data + i)T(vdata[i]);
}
~static_vector(void)
{
T * data = (T*)_space;
size_t n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
data[i].~T();
}
@ -51,12 +45,10 @@ public:
if (this != &v)
{
T * data = (T*)_space, * vdata = (T*)(v._space);
size_t n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
data[i].~T();
_size = v._size;
n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
new (data + i)T(vdata[i]);
}
return *this;
@ -77,11 +69,6 @@ public:
return _size == 0;
}
bool full(void) const
{
return _size == N;
}
size_t capacity(void) const
{
return N;
@ -89,8 +76,6 @@ public:
void resize(size_t n);
void clear(void);
T & at(size_t at)
{
return ((T*)_space)[at];
@ -181,8 +166,6 @@ 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);
@ -194,50 +177,34 @@ 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 if (n > 0)
else
{
for(size_t i=_size; i<n; i++)
new(data + i)T();
new(data + i)T;
_size = n;
}
_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);
}
@ -245,28 +212,14 @@ 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;
@ -287,12 +240,9 @@ 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--;

View File

@ -21,14 +21,13 @@ 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)
{
size_t n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
new (_data + i)T(v._data[i]);
}
@ -51,16 +50,14 @@ public:
{
if (this != &v)
{
size_t n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
_data[i].~T();
free(_data);
_data = (T*)malloc(v._size * sizeof(T));
_size = v._size;
_capacity = v._size;
n = _size;
for(size_t i=0; i<n; i++)
for(size_t i=0; i<_size; i++)
new (_data + i)T(v._data[i]);
}
return *this;
@ -97,8 +94,6 @@ public:
return _capacity;
}
void clear(void);
void resize(size_t n);
void reserve(size_t n);
@ -195,8 +190,6 @@ 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);
@ -211,7 +204,7 @@ protected:
template <class T>
__noinline void vector<T>::reserve(size_t n)
void vector<T>::reserve(size_t n)
{
if (n > _capacity)
{
@ -228,15 +221,7 @@ __noinline void vector<T>::reserve(size_t n)
}
template <class T>
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)
void vector<T>::resize(size_t n)
{
if (n < _size)
{
@ -247,7 +232,7 @@ __noinline 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
@ -301,27 +286,12 @@ 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;
@ -348,7 +318,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--;

View File

@ -129,10 +129,3 @@ __native const char * oscar_expand_lzo_buf(char * dp, const char * sp)
return sp + 1;
}
void debugcrash(void)
{
__asm volatile {
byt $02
}
}

View File

@ -18,8 +18,6 @@ void breakpoint(void);
#pragma intrinsic(breakpoint)
void debugcrash(void);
#pragma compile("oscar.c")
#endif

View File

@ -556,17 +556,6 @@ 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)
{

View File

@ -3,7 +3,6 @@
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
void putchar(char c);
@ -19,10 +18,6 @@ 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, ...);

View File

@ -544,7 +544,7 @@ unsigned heapfree(void)
}
#if 0
struct Heap {q
struct Heap {
unsigned int size;
Heap * next;
} * freeHeap;
@ -667,97 +667,6 @@ 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)

View File

@ -45,8 +45,6 @@ void free(void * ptr);
void * calloc(int num, int size);
void * realloc(void * ptr, unsigned size);
unsigned heapfree(void);
unsigned int rand(void);

View File

@ -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) -m 755
INSTALL_DATA = $(INSTALL) -m 644
INSTALL_PROGRAM = $(INSTALL) --mode=755
INSTALL_DATA = $(INSTALL) --mode=644
DESTDIR =
prefix = /usr/local
exec_prefix = $(prefix)
@ -38,7 +38,7 @@ else
endif
all: compiler samples check
all: --prep-build-dir compiler samples tests
$(srcdir)/%.o: $(project_dir)/oscar64/%.cpp
@ -56,7 +56,7 @@ $(srcdir)/%.d: $(project_dir)/oscar64/%.cpp
$(RM) $@.$$$$
compiler: --prep-build-dir $(objects)
compiler: $(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
check: compiler
tests: 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) $(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
$(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
uninstall:

View File

@ -15,7 +15,7 @@ When I started this project, I was under the assumption that the 6502 would make
The original plan was thus to compile to an intermediate language that would be interpreted, offering the 16bit support without the added code cost. This turned out to work great from a code size perspective, but the performance was poor. So I decided to give compiling to native code a shot.
Most of the 6502 limitations can be overcome by careful code analysis and optimizations.
Most of the 6502 limitations can be overcome by carefull code analysis and optimizations.
* A second data stack relieves the CPU stack.
* Static call graph analysis removes the need for a stack completely
@ -28,7 +28,7 @@ In the end, it turned out that the native code is not only significantly faster
## Limits and Errors
There are still several open areas, but most targets have been reached. The current Dhrystone performance is 94 iterations per second with byte code (10993) and 442 iterations with native code (8952 Bytes). This clearly shows that Dhrystone is not a valid benchmark for optimizing compilers, because it puts the 6502 on par with a 4MHz 8088 or 68k, which it clearly is not.
There are still several open areas, but most targets have been reached. The current Dhrystone performance is 94 iterations per second with byte code (10993) and 405 iterations with native code (9173 Bytes). This clearly shows that Dhrystone is not a valid benchmark for optimizing compilers, because it puts the 6502 on par with a 4MHz 8088 or 68k, which it clearly is not.
### Language
@ -110,7 +110,6 @@ The compiler is command line driven, and creates an executable .prg file.
* -v : verbose output for diagnostics
* -v2 : more verbose output
* -i : additional include paths
* -ii : set default include path
* -o : optional output file name
* -rt : alternative runtime library, replaces the crt.c (or empty for none)
* -e : execute the result in the integrated emulator
@ -129,8 +128,6 @@ The compiler is command line driven, and creates an executable .prg file.
* -Oa : optimize inline assembler (part of O2/O3)
* -Oz : enable auto placement of global variables in zero page (part of O3)
* -Op : optimize constant parameters
* -Oo : optimize size using "outliner" (extract repeated code sequences into functions)
* -Ox : optimize pointer arithmetic by blocking shorter arrays to not cross page boundaries
* -g : create source level debug info and add source line numbers to asm listing
* -gp : create source level debug info and add source line numbers to asm listing and static profile data
* -tf : target format, may be prg, crt or bin
@ -177,7 +174,6 @@ A list of source files can be provided.
* nes_mmc3 : Nintendo entertainment system, MMC3, 512K PROM, 256K CROM
* atari : Atari 8bit systems, (0x2000..0xbc00)
* x16 : Commander X16, (0x0800..0x9f00)
* mega65 : Mega 65, (0x2000..0xc000)
### C64 Cartridge formats
@ -337,17 +333,6 @@ The .asm file is a great resource when debugging from within e.g. the VICE monit
The compiler has various extensions to simplify developing for the C64.
## Pragmas
Warnings can be turned on or off using the warning pragma. The scope of the pragma is currently global in most cases, so if it is turned off at some place, it is off everywhere.
#pragma warning(disable: 2000,2001)
A message can be displayed during compilation with the message pragma
#pragma message("Hello User")
## Embedding binary data
The compiler supports the #embed preprocessor directive to import binary data. It converts a section of an external binary file into a sequence of numbers that can be placed into an initializer of an array.
@ -498,8 +483,6 @@ Set optimizer options that are active for the functions after it
* maxinline : inline any function suitable
* constparams : enable constant parameter folding into called functions
* noconstparams : disable constant parameter folding into called functions
* outline : enable outliner
* nooutline : disable outliner
* 0 : no optimization
* 1 : default optimizations
* 2 : aggressive optimizations
@ -751,11 +734,6 @@ Regions can also be used to place assets such as character sets at fixed locatio
The #pragma data(), #pragma code() and #pragma bss() control the placement of the generated objects into sections other than the default sections.
A global variable or function can be aligned on a given power of two start with the align pragma. This is most useful if a page crossing is problematic. The compiler may also be able to generate more efficient code, if a larger variable is page aligned.
#pragma align(myvar, 8)
#pragma align(myfunc, 256)
### Additional BSS sections
Additional bss sections can be defined on request.
@ -763,7 +741,7 @@ Additional bss sections can be defined on request.
#pragma section( mybss, 0, , , bss )
#pragma region( mybssregion, 0xc000, 0xd000, , , {mybss} )
They will not be cleared on startup, so all variables placed in these segments will be uninitialized. A common use for these sections is overlapping runtime variables with compressed load time assests that get expanded to their actual location during startup.
They will not be cleared on startup, so all variables placed in these segments will be unitialized. A common use for these sections is overlapping runtime variables with compressed load time assests that get expanded to their actual location during startup.
### Heap and Stack sections
@ -830,7 +808,7 @@ With NROM mappers, the prg and chr code is put into cartridge bank zero.
#pragma data(data)
The 32KByte of prg code starts at 0x8000 and goes up to 0xff80. A startup section from 0xff80 to 0xfff9 is taken from the crt.c.
The 32KByte of prg code starts at 0x8000 and goes upto 0xff80. A startup section from 0xff80 to 0xfff9 is taken from the crt.c.
A six byte boot section is placed from 0xfffa to 0xffff in all modes, which has to be populated by the game code with the appropriate pointers.
@ -954,11 +932,6 @@ The compiler provides two levels of interrupt safe functions. The specifier __i
return 0
}
### Assembler optimizer
The compiler uses various optimizations on inline assembler that may not have the expected result in all cases. The optimizer can be disabled for a range of code with e.g. #pragma optimize(noasm) or for an individual __asm statement by using __asm volatile {}.
The assembler optimizer is enabled with optimization levels O2 and up.
# Helping the compiler optimizing
The compiler does various optimization when compiling the code, but there are some rules to follow, things to avoid and hints to place to help the compiler to generate optimal code.

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35931.197
# Visual Studio Version 16
VisualStudioVersion = 16.0.31624.102
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oscar64", "oscar64\oscar64.vcxproj", "{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}"
EndProject
@ -23,14 +23,10 @@ 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|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
{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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -421,13 +421,11 @@ 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)
void Parition(const F & f, int l, int r)
{
if (r > l + 1)
{
@ -444,8 +442,8 @@ protected:
}
array[pi] = p;
Partition(f, l, pi);
Partition(f, pi + 1, r);
Parition(f, l, pi);
Parition(f, pi + 1, r);
}
}
public:
@ -620,22 +618,10 @@ 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);
Parition(f, 0, size);
}
__forceinline T& operator[](int n)

View File

@ -293,7 +293,7 @@ const char* AsmInstructionNames[NUM_ASM_INS_TYPES] = {
"INV", "BYT"
};
int AsmInsModeSize[NUM_ASM_INS_MODES_X] = {
int AsmInsModeSize[NUM_ASM_INS_MODES] = {
1,
2,
2,
@ -306,8 +306,6 @@ int AsmInsModeSize[NUM_ASM_INS_MODES_X] = {
2,
2,
2,
0,
2
};
void InitAssembler(void)

View File

@ -31,9 +31,7 @@ enum AsmInsMode
NUM_ASM_INS_MODES,
ASMIM_IMMEDIATE_ADDRESS,
NUM_ASM_INS_MODES_X,
ASMIM_IMMEDIATE_ADDRESS
};
struct AsmInsData
@ -47,8 +45,6 @@ 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);

View File

@ -3,7 +3,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
class BitVector
{

View File

@ -3462,151 +3462,94 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
{
if (ins->mSrc[1].mTemp < 0)
{
if (ins->mSrc[1].mType == IT_INT16 || ins->mSrc[1].mMemory == IM_ABSOLUTE)
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 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[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 cins(BC_BINOP_CMPSI_16);
cins.mValue = int(ins->mSrc[1].mIntConst);
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[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;
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
}
code = TransposeBranchCondition(code);
}
else
{

View File

@ -466,7 +466,7 @@ void Compiler::CompileProcedure(InterCodeProcedure* proc)
printf("Generate native code <%s>\n", proc->mIdent->mString);
ncproc->Compile(proc);
mNativeCodeGenerator->mProcedures.Push(ncproc);
mNativeProcedures.Push(ncproc);
}
else
{
@ -508,8 +508,6 @@ 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);
}
@ -523,12 +521,6 @@ 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)
@ -631,9 +623,6 @@ 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);
@ -695,9 +684,6 @@ 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;
@ -749,14 +735,6 @@ 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))
@ -1058,18 +1036,13 @@ bool Compiler::GenerateCode(void)
mCompilationUnits->mSectionStack->mSections.Push(proc->mLinkerObject->mStackSection);
}
mNativeCodeGenerator->OutlineFunctions();
mNativeCodeGenerator->BuildFunctionProxies();
for (int i = 0; i < mNativeCodeGenerator->mProcedures.Size(); i++)
for (int i = 0; i < mNativeProcedures.Size(); i++)
{
if (mCompilerOptions & COPT_VERBOSE2)
{
if (mNativeCodeGenerator->mProcedures[i]->mInterProc)
printf("Assemble native code <%s>\n", mNativeCodeGenerator->mProcedures[i]->mInterProc->mIdent->mString);
}
mNativeCodeGenerator->mProcedures[i]->Assemble();
printf("Assemble native code <%s>\n", mNativeProcedures[i]->mInterProc->mIdent->mString);
mNativeProcedures[i]->Assemble();
}
LinkerObject* byteCodeObject = nullptr;

View File

@ -29,6 +29,7 @@ public:
GlobalOptimizer* mGlobalOptimizer;
GrowingArray<ByteCodeProcedure*> mByteCodeFunctions;
ExpandingArray<NativeCodeProcedure*> mNativeProcedures;
TargetMachine mTargetMachine;
uint64 mCompilerOptions;

View File

@ -14,8 +14,6 @@ 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;
@ -52,7 +50,7 @@ static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE |
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;// | COPT_OPTIMIZE_OUTLINE;
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_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;
@ -79,8 +77,7 @@ enum TargetMachine
TMACH_NES_MMC1,
TMACH_NES_MMC3,
TMACH_ATARI,
TMACH_X16,
TMACH_MEGA65
TMACH_X16
};

View File

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

View File

@ -651,7 +651,6 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
{
mProcType = exp->mLeft->mDecType;
Expression* pex = exp->mRight;
Declaration* cdec = exp->mLeft->mDecType->mParams;
int pos = 0;
@ -660,28 +659,6 @@ 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);
@ -777,9 +754,6 @@ 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;
@ -1046,9 +1020,6 @@ 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]);
}
@ -1197,26 +1168,6 @@ 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);
}

View File

@ -31,17 +31,6 @@ 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)
@ -156,7 +145,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), mFlags(0)
: mLocation(loc), mEndLocation(loc), mType(type), mLeft(nullptr), mRight(nullptr), mConst(false), mDecType(nullptr), mDecValue(nullptr), mToken(TK_NONE)
{
static uint32 gUID = 0;
mUID = gUID++;
@ -274,9 +263,6 @@ void Expression::Dump(int ident) const
case EX_FOR:
printf("FOR");
break;
case EX_FORBODY:
printf("FORBODY");
break;
case EX_DO:
printf("DO");
break;
@ -505,63 +491,6 @@ 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)
@ -679,19 +608,6 @@ 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)
{
@ -775,29 +691,14 @@ 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->mDecType->mType == DT_TYPE_ARRAY &&
(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->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);
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;
}
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;
ex->mDecValue = dec;
ex->mDecType = mLeft->mLeft->mDecType;
return ex;
@ -921,19 +822,11 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
{
int64 ival = 0, ileft = mLeft->mDecValue->mInteger, iright = mRight->mDecValue->mInteger;
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 signop =
(mLeft->mDecValue->mBase->mSize < 2 || (mLeft->mDecValue->mBase->mFlags & DTF_SIGNED)) &&
(mRight->mDecValue->mBase->mSize < 2 || (mRight->mDecValue->mBase->mFlags & DTF_SIGNED));
bool promote = true;
switch (mToken)
{
case TK_ADD:
@ -947,25 +840,27 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
break;
case TK_DIV:
if (iright == 0)
return this;
else if (dtype->mFlags & DTF_SIGNED)
errors->Error(mLocation, EERR_INVALID_VALUE, "Constant division by zero");
else if (signop)
ival = ileft / iright;
else
ival = (uint64)ileft / (uint64)iright;
break;
case TK_MOD:
if (iright == 0)
return this;
else if (dtype->mFlags & DTF_SIGNED)
errors->Error(mLocation, EERR_INVALID_VALUE, "Constant division by zero");
else if (signop)
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;
@ -982,14 +877,29 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
dec->mBase = dtype;
dec->mInteger = signextend(ival, dec->mBase);
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;
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;
@ -1044,20 +954,6 @@ 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))
{
@ -1138,26 +1034,6 @@ 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)
@ -1193,7 +1069,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 && mLeft->mDecValue->mValue->mType == EX_CONSTANT &&
mLeft->mDecValue && mRight->mDecValue && 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;
@ -1246,23 +1122,19 @@ 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;
}
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;
}
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_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_INTRINSIC) && mRight && mRight->mType == EX_CONSTANT)
{
Declaration* decf = mLeft->mDecValue, * decp = mRight->mDecValue;
@ -1271,7 +1143,6 @@ 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;
@ -1291,10 +1162,6 @@ 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;
@ -1307,36 +1174,6 @@ 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);
@ -1361,7 +1198,6 @@ 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),
@ -1383,7 +1219,7 @@ int Declaration::Stride(void) const
{
if (mStride > 0)
return mStride;
else if (mBase && mBase->mType != DT_TYPE_VOID)
else if (mBase)
return mBase->mSize;
else
return 1;
@ -1486,51 +1322,6 @@ 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;
}
@ -1676,9 +1467,7 @@ const Ident* Declaration::FullIdent(void)
Declaration* dec = mBase->mParams;
while (dec)
{
const Ident* mident = dec->mBase->MangleIdent();
if (mident)
tident = tident->Mangle(mident->mString);
tident = tident->Mangle(dec->mBase->MangleIdent()->mString);
dec = dec->mNext;
if (dec)
tident = tident->Mangle(",");
@ -1814,30 +1603,25 @@ const Ident* Declaration::MangleIdent(void)
}
dec = dec->mNext;
if (mMangleIdent && dec)
if (dec)
mMangleIdent = mMangleIdent->Mangle(",");
}
}
else
mMangleIdent = Ident::Unique("void");
}
else if (mQualIdent)
mMangleIdent = mQualIdent;
else
mMangleIdent = mIdent;
mMangleIdent = mQualIdent;
if (mTemplate)
{
}
if (mMangleIdent)
{
if (mFlags & DTF_CONST)
mMangleIdent = mMangleIdent->PreMangle("const ");
if (mFlags & DTF_VOLATILE)
mMangleIdent = mMangleIdent->PreMangle("volatile ");
}
if (mFlags & DTF_CONST)
mMangleIdent = mMangleIdent->PreMangle("const ");
if (mFlags & DTF_VOLATILE)
mMangleIdent = mMangleIdent->PreMangle("volatile ");
}
return mMangleIdent;
@ -1898,8 +1682,19 @@ Declaration* Declaration::ExpandTemplate(DeclarationScope* scope)
return this;
}
bool Declaration::ResolveTemplateParameterList(Expression* pexp, Declaration* pdec, bool preliminary)
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;
}
Declaration* phead = nullptr, * ptail = nullptr;
int pcnt = 0;
@ -1935,7 +1730,7 @@ bool Declaration::ResolveTemplateParameterList(Expression* pexp, Declaration* pd
}
else
{
if (!ResolveTemplate(ex->mDecType, pdec->mBase, false, preliminary))
if (!ResolveTemplate(ex->mDecType, pdec->mBase))
return false;
pdec = pdec->mNext;
@ -1949,9 +1744,6 @@ bool Declaration::ResolveTemplateParameterList(Expression* pexp, Declaration* pd
{
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;
@ -1965,25 +1757,6 @@ bool Declaration::ResolveTemplateParameterList(Expression* pexp, Declaration* pd
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)
@ -2026,7 +1799,7 @@ bool Declaration::CanResolveTemplate(Expression* pexp, Declaration* tdec)
if (pdec)
{
if (!ResolveTemplate(ex->mDecType, pdec->mBase, false, false))
if (!ResolveTemplate(ex->mDecType, pdec->mBase))
return false;
if (pdec->mType != DT_PACK_ARGUMENT)
@ -2042,19 +1815,19 @@ bool Declaration::CanResolveTemplate(Expression* pexp, Declaration* tdec)
return true;
}
bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec, bool same, bool preliminary)
bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
{
if (tdec->IsSame(fdec))
return true;
else if (fdec->IsReference())
return ResolveTemplate(fdec->mBase, tdec, same, preliminary);
return ResolveTemplate(fdec->mBase, tdec);
else if (tdec->mType == DT_TYPE_FUNCTION)
{
if (fdec->mType == DT_TYPE_FUNCTION)
{
if (fdec->mBase)
{
if (!tdec->mBase || !ResolveTemplate(fdec->mBase, tdec->mBase, true, preliminary))
if (!tdec->mBase || !ResolveTemplate(fdec->mBase, tdec->mBase))
return false;
}
else if (tdec->mBase)
@ -2093,7 +1866,7 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec, bool sam
if (!fpdec)
return false;
if (!ResolveTemplate(fpdec->mBase, tpdec->mBase, true, preliminary))
if (!ResolveTemplate(fpdec->mBase, tpdec->mBase))
return false;
fpdec = fpdec->mNext;
@ -2109,16 +1882,16 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec, bool sam
}
else if (tdec->mType == DT_TYPE_REFERENCE)
{
return ResolveTemplate(fdec, tdec->mBase, true, preliminary);
return ResolveTemplate(fdec, tdec->mBase);
}
else if (tdec->mType == DT_TYPE_RVALUEREF)
{
return ResolveTemplate(fdec, tdec->mBase, true, preliminary);
return ResolveTemplate(fdec, tdec->mBase);
}
else if (tdec->mType == DT_TYPE_POINTER)
{
if (fdec->mType == DT_TYPE_POINTER || fdec->mType == DT_TYPE_ARRAY)
return ResolveTemplate(fdec->mBase, tdec->mBase, true, preliminary);
return ResolveTemplate(fdec->mBase, tdec->mBase);
else
return false;
}
@ -2138,12 +1911,10 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec, bool sam
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 && !(same ? pdec->IsSame(fdec) : pdec->CanAssign(fdec)))
if (pdec && !pdec->IsSame(fdec))
return false;
return true;
@ -2184,21 +1955,6 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec, bool sam
}
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)
{
@ -2264,27 +2020,13 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec, bool sam
tpdec = tpdec->mNext;
}
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;
return !fpdec && !tpdec;
}
ftdec = ftdec->mNext;
}
return false;
}
else if (!same && tdec->CanAssign(fdec))
return true;
else
return tdec->IsSame(fdec);
}
@ -2297,8 +2039,6 @@ 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;
@ -2318,7 +2058,6 @@ Declaration* Declaration::Clone(void)
ndec->mMaxValue = mMaxValue;
ndec->mCompilerOptions = mCompilerOptions;
ndec->mParser = mParser;
ndec->mNumVars = mNumVars;
return ndec;
}
@ -2370,8 +2109,6 @@ 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;
@ -2398,25 +2135,7 @@ Declaration* Declaration::ToStriped(int stripe)
ndec->mParams = pnec;
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)
{
@ -2447,8 +2166,6 @@ 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;
@ -2484,7 +2201,6 @@ Declaration* Declaration::ToVolatileType(void)
ndec->mVectorConstructor = mVectorConstructor;
ndec->mVectorDestructor = mVectorDestructor;
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
ndec->mVTable = mVTable;
mVolatile = ndec;
@ -2504,12 +2220,7 @@ Declaration* Declaration::ToConstType(void)
ndec->mSize = mSize;
ndec->mStride = mStride;
ndec->mStripe = mStripe;
if (mType == DT_TYPE_ARRAY)
ndec->mBase = mBase->ToConstType();
else
ndec->mBase = mBase;
ndec->mBits = mBits;
ndec->mShift = mShift;
ndec->mBase = mBase;
ndec->mFlags = mFlags | DTF_CONST;
ndec->mScope = mScope;
ndec->mParams = mParams;
@ -2524,7 +2235,6 @@ Declaration* Declaration::ToConstType(void)
ndec->mVectorConstructor = mVectorConstructor;
ndec->mVectorDestructor = mVectorDestructor;
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
ndec->mVTable = mVTable;
ndec->mMutable = this;
@ -2534,35 +2244,6 @@ 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))
@ -2575,9 +2256,7 @@ Declaration* Declaration::ToMutableType(void)
ndec->mStride = mStride;
ndec->mStripe = mStripe;
ndec->mBase = mBase;
ndec->mBits = mBits;
ndec->mShift = mShift;
ndec->mFlags = mFlags & ~DTF_CONST;
ndec->mFlags = mFlags | DTF_CONST;
ndec->mScope = mScope;
ndec->mParams = mParams;
ndec->mIdent = mIdent;
@ -2591,7 +2270,6 @@ Declaration* Declaration::ToMutableType(void)
ndec->mVectorConstructor = mVectorConstructor;
ndec->mVectorDestructor = mVectorDestructor;
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
ndec->mVTable = mVTable;
ndec->mConst = this;
@ -2921,9 +2599,6 @@ 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;
@ -2932,6 +2607,9 @@ 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)
@ -2978,7 +2656,7 @@ bool Declaration::IsSame(const Declaration* dec) const
return true;
}
else if (mType == DT_TYPE_TEMPLATE || mType == DT_PACK_TEMPLATE)
else if (mType == DT_TYPE_TEMPLATE)
{
return mIdent == dec->mIdent;
}
@ -3111,7 +2789,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->mBase);
return this->CanAssign(fromType->mBase);
return false;
}
else if (mType == DT_TYPE_ARRAY && fromType->mType == DT_TYPE_ARRAY)
@ -3148,10 +2826,6 @@ 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;
@ -3178,52 +2852,6 @@ 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
{
@ -3243,17 +2871,14 @@ 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);
@ -3345,13 +2970,4 @@ 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;
}

View File

@ -127,7 +127,6 @@ 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);
@ -167,8 +166,6 @@ public:
ScopeLevel mLevel;
const Ident * mName;
DeclarationScope* Clone(void) const;
DeclarationScope* mParent;
protected:
struct Entry
@ -218,7 +215,6 @@ enum ExpressionType
EX_IF,
EX_ELSE,
EX_FOR,
EX_FORBODY,
EX_DO,
EX_SCOPE,
EX_BREAK,
@ -246,12 +242,6 @@ enum ExpressionType
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:
@ -268,16 +258,12 @@ 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;
@ -285,7 +271,6 @@ public:
bool IsConstRef(void) const;
bool IsVolatile(void) const;
void Dump(int ident) const;
};
@ -302,7 +287,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, * mVectorMoveConstructor, * mVectorMoveAssignment;
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
Declaration * mVTable, * mClass, * mTemplate;
Declaration * mForwardParam, * mForwardCall;
@ -344,17 +329,12 @@ 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);
@ -378,9 +358,8 @@ public:
DecType ValueType(void) const;
bool CanResolveTemplate(Expression* pexp, Declaration* tdec);
bool ResolveTemplate(Declaration* fdec, Declaration * tdec, bool same, bool preliminary);
bool ResolveTemplate(Declaration* fdec, Declaration * tdec);
bool ResolveTemplate(Expression* pexp, Declaration* tdec);
bool ResolveTemplateParameterList(Expression* pexp, Declaration* pdec, bool preliminary);
Declaration* ExpandTemplate(DeclarationScope* scope);
@ -398,6 +377,5 @@ 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;

View File

@ -4,18 +4,11 @@
#include <stdlib.h>
Errors::Errors(void)
: mErrorCount(0), mMinLevel(EINFO_GENERIC), mDisabled(EERR_GENERIC)
: mErrorCount(0)
{
}
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)
@ -29,44 +22,41 @@ 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)
{
if (eid >= mMinLevel && !(eid < EERR_GENERIC && mDisabled[eid]))
const char* level = "info";
if (eid >= EERR_GENERIC)
{
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);
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
{
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);
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);
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
{
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);
}

View File

@ -1,8 +1,5 @@
#pragma once
#include "NumberSet.h"
class Location
{
public:
@ -13,11 +10,7 @@ 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;
@ -51,8 +44,6 @@ 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,
@ -112,7 +103,7 @@ enum ErrorID
ERRR_INSTANTIATE_ABSTRACT_CLASS,
ERRR_INVALID_GOTO,
EERR_INVALID_INITIALIZER,
ERRR_INVALID_VOID_POINTER_ARITHMETIC,
EERR_INVALID_CONSTEXPR,
EERR_DOUBLE_FREE,
@ -127,13 +118,9 @@ 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
@ -141,12 +128,7 @@ 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);

View File

@ -393,7 +393,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
if (procDec->mValue && procDec->mValue->mType == EX_DISPATCH)
{
Declaration* maxf = nullptr, * reff = nullptr;
Declaration* maxf = nullptr;
bool stackCall = false;
@ -402,10 +402,7 @@ 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;
@ -413,9 +410,6 @@ 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];
@ -426,9 +420,9 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
cf->mBase->mFlags |= DTF_STACKCALL;
}
if (cf != reff)
if (cf != maxf)
{
Declaration* fp = cf->mBase->mParams, * mp = reff->mBase->mParams;
Declaration* fp = cf->mBase->mParams, * mp = maxf->mBase->mParams;
while (fp)
{
fp->mVarIndex = mp->mVarIndex;
@ -437,11 +431,10 @@ 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;
@ -481,7 +474,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
fplimit += 256;
}
if (procDec->mBase->mBase->IsComplexStruct())
if (procDec->mBase->mBase->mType == DT_TYPE_STRUCT)
{
if (nbase < numfpzero && nbase + 2 > numfpzero)
nbase = numfpzero;
@ -665,7 +658,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, 0);
Analyze(exp, dec, false, false);
Declaration* pdec = dec->mBase->mParams;
int vi = 0;
@ -685,7 +678,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
}
else
{
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->FullIdent());
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent);
if (cexp)
mErrors->Error(cexp->mLocation, EINFO_CALLED_FROM, "Called from here");
@ -761,7 +754,7 @@ void GlobalAnalyzer::AnalyzeGlobalVariable(Declaration* dec)
if (dec->mValue)
{
Analyze(dec->mValue, dec, 0);
Analyze(dec->mValue, dec, false, false);
}
}
}
@ -771,19 +764,17 @@ void GlobalAnalyzer::AnalyzeInit(Declaration* mdec)
while (mdec)
{
if (mdec->mValue)
RegisterProc(Analyze(mdec->mValue, mdec, 0));
RegisterProc(Analyze(mdec->mValue, mdec, false, false));
else if (mdec->mParams)
AnalyzeInit(mdec->mParams);
mdec = mdec->mNext;
}
}
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uint32 flags)
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, bool lhs, bool aliasing)
{
Declaration* ldec, * rdec;
exp->mFlags = flags;
switch (exp->mType)
{
case EX_ERROR:
@ -801,7 +792,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
}
else if (exp->mDecValue->mType == DT_CONST_POINTER)
{
ldec = Analyze(exp->mDecValue->mValue, procDec, ANAFL_LHS | ANAFL_ALIAS);
ldec = Analyze(exp->mDecValue->mValue, procDec, true, true);
if (ldec->mType == DT_VARIABLE)
ldec->mFlags |= DTF_VAR_ALIASING;
RegisterProc(ldec);
@ -825,7 +816,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
if (mCompilerOptions & COPT_DEBUGINFO)
exp->mDecValue->mReferences.Push(exp);
if (flags & ANAFL_ALIAS)
if (aliasing)
{
Declaration* dec = exp->mDecValue;
while (dec->mType == DT_VARIABLE_REF)
@ -842,14 +833,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
if (!(type->mFlags & DTF_CONST))
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (flags & ANAFL_LHS)
if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE;
AnalyzeGlobalVariable(exp->mDecValue);
}
else
{
if (flags & ANAFL_LHS)
if (lhs)
exp->mDecValue->mFlags |= DTF_VAR_ADDRESS;
if (!(exp->mDecValue->mFlags & DTF_ANALYZED))
@ -863,8 +854,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_ASSIGNMENT:
procDec->mComplexity += 5 * exp->mLeft->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
ldec = Analyze(exp->mLeft, procDec, true, false);
rdec = Analyze(exp->mRight, procDec, false, false);
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);
@ -873,33 +864,33 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_BINARY:
procDec->mComplexity += 10 * exp->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
rdec = Analyze(exp->mRight, procDec, flags & ~ANAFL_ALIAS);
ldec = Analyze(exp->mLeft, procDec, lhs, false);
rdec = Analyze(exp->mRight, procDec, lhs, false);
return ldec;
case EX_RELATIONAL:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, ANAFL_RHS);
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
return TheBoolTypeDeclaration;
case EX_PREINCDEC:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
return Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
return Analyze(exp->mLeft, procDec, true, false);
case EX_PREFIX:
if (exp->mToken == TK_BINARY_AND)
{
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_ALIAS);
ldec = Analyze(exp->mLeft, procDec, true, true);
if (ldec->mType == DT_VARIABLE)
ldec->mFlags |= DTF_VAR_ALIASING;
}
else if (exp->mToken == TK_MUL)
{
ldec = Analyze(exp->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false, false);
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (flags & ANAFL_LHS)
if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE;
return exp->mDecType;
@ -908,14 +899,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
{
return TheUnsignedCharTypeDeclaration;
}
else if (exp->mToken == TK_SIZEOF)
{
return TheUnsignedIntTypeDeclaration;
}
else
{
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
return Analyze(exp->mLeft, procDec, 0);
return Analyze(exp->mLeft, procDec, false, false);
}
break;
case EX_POSTFIX:
@ -924,31 +911,31 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_POSTINCDEC:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
return Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
return Analyze(exp->mLeft, procDec, true, false);
case EX_INDEX:
procDec->mComplexity += 10 * exp->mRight->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
ldec = Analyze(exp->mLeft, procDec, lhs, false);
if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT)
{
ldec = ldec->mBase;
if (ldec->mType == DT_TYPE_POINTER)
{
if (flags & ANAFL_LHS)
if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE;
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
}
}
rdec = Analyze(exp->mRight, procDec, 0);
rdec = Analyze(exp->mRight, procDec, false, false);
if (ldec->mBase)
return ldec->mBase;
break;
case EX_QUALIFY:
Analyze(exp->mLeft, procDec, flags);
Analyze(exp->mLeft, procDec, lhs, aliasing);
return exp->mDecValue->mBase;
case EX_DISPATCH:
procDec->mFlags |= DTF_PREVENT_INLINE;
Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
Analyze(exp->mLeft, procDec, lhs, false);
// RegisterCall(procDec, exp->mLeft->mDecType);
break;
case EX_VCALL:
@ -959,7 +946,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_INLINE:
procDec->mComplexity += 10;
ldec = Analyze(exp->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false, false);
if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue)
{
@ -1046,7 +1033,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
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()) ? ANAFL_LHS : 0));
RegisterProc(Analyze(pex, procDec, pdec && pdec->mBase->IsReference(), false));
if (pdec)
pdec = pdec->mNext;
@ -1060,12 +1047,12 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
break;
case EX_LIST:
case EX_COMMA:
RegisterProc(Analyze(exp->mLeft, procDec, 0));
return Analyze(exp->mRight, procDec, 0);
RegisterProc(Analyze(exp->mLeft, procDec, false, false));
return Analyze(exp->mRight, procDec, false, false);
case EX_RETURN:
if (exp->mLeft)
{
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference() ? ANAFL_LHS : 0));
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference(), false));
if (procDec->mBase->mBase && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
{
if (procDec->mBase->mBase->mMoveConstructor)
@ -1086,47 +1073,47 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
if (exp->mType == EX_SEQUENCE)
{
if (exp->mLeft)
ldec = Analyze(exp->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false, false);
exp = exp->mRight;
}
else
return Analyze(exp, procDec, 0);
return Analyze(exp, procDec, false, false);
} while (exp);
break;
case EX_SCOPE:
Analyze(exp->mLeft, procDec, 0);
Analyze(exp->mLeft, procDec, false, false);
break;
case EX_CONSTRUCT:
if (exp->mLeft->mLeft)
Analyze(exp->mLeft->mLeft, procDec, 0);
Analyze(exp->mLeft->mLeft, procDec, false, false);
if (exp->mLeft->mRight)
Analyze(exp->mLeft->mRight, procDec, 0);
Analyze(exp->mLeft->mRight, procDec, false, false);
if (exp->mRight)
return Analyze(exp->mRight, procDec, 0);
return Analyze(exp->mRight, procDec, false, false);
break;
case EX_CLEANUP:
Analyze(exp->mRight, procDec, 0);
return Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
Analyze(exp->mRight, procDec, false, false);
return Analyze(exp->mLeft, procDec, lhs, false);
case EX_WHILE:
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, 0);
rdec = Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
break;
case EX_IF:
procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, 0);
rdec = Analyze(exp->mRight->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight->mLeft, procDec, false, false);
if (exp->mRight->mRight)
rdec = Analyze(exp->mRight->mRight, procDec, 0);
rdec = Analyze(exp->mRight->mRight, procDec, false, false);
break;
case EX_ELSE:
break;
@ -1136,23 +1123,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
procDec->mComplexity += 30;
if (exp->mLeft->mRight)
ldec = Analyze(exp->mLeft->mRight, procDec, 0);
ldec = Analyze(exp->mLeft->mRight, procDec, false, false);
if (exp->mLeft->mLeft->mLeft)
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, 0);
rdec = Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
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)
Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, false, false);
break;
case EX_DO:
procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, 0);
rdec = Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
break;
case EX_BREAK:
case EX_CONTINUE:
@ -1161,18 +1143,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_TYPE:
break;
case EX_TYPECAST:
return Analyze(exp->mLeft, procDec, 0);
return Analyze(exp->mLeft, procDec, false, false);
break;
case EX_LOGICAL_AND:
ldec = Analyze(exp->mLeft, procDec, 0);
rdec = Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
break;
case EX_LOGICAL_OR:
ldec = Analyze(exp->mLeft, procDec, 0);
rdec = Analyze(exp->mRight, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
break;
case EX_LOGICAL_NOT:
ldec = Analyze(exp->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false, false);
break;
case EX_ASSEMBLER:
procDec->mFlags |= DTF_FUNC_ASSEMBLER;
@ -1183,14 +1165,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_UNDEFINED:
break;
case EX_SWITCH:
ldec = Analyze(exp->mLeft, procDec, 0);
ldec = Analyze(exp->mLeft, procDec, false, false);
exp = exp->mRight;
while (exp)
{
procDec->mComplexity += 10;
if (exp->mLeft->mRight)
rdec = Analyze(exp->mLeft->mRight, procDec, 0);
rdec = Analyze(exp->mLeft->mRight, procDec, false, false);
exp = exp->mRight;
}
break;
@ -1201,9 +1183,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_CONDITIONAL:
procDec->mComplexity += exp->mDecType->mSize * 10;
ldec = Analyze(exp->mLeft, procDec, 0);
RegisterProc(Analyze(exp->mRight->mLeft, procDec, flags));
RegisterProc(Analyze(exp->mRight->mRight, procDec, flags));
ldec = Analyze(exp->mLeft, procDec, false, false);
RegisterProc(Analyze(exp->mRight->mLeft, procDec, lhs, aliasing));
RegisterProc(Analyze(exp->mRight->mRight, procDec, lhs, aliasing));
break;
}

View File

@ -35,7 +35,7 @@ protected:
int CallerInvokes(Declaration* called);
int CallerInvokes(Declaration* caller, Declaration* called);
Declaration* Analyze(Expression* exp, Declaration* procDec, uint32 flags);
Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs, bool aliasing);
bool IsStackParam(const Declaration* pdec) const;
bool MarkCycle(Declaration* rootDec, Declaration* procDec);

View File

@ -60,7 +60,7 @@ void GlobalOptimizer::Reset(void)
mFunctions.SetSize(0);
mGlobalVariables.SetSize(0);
mCalledFunctions.SetSize(0);
mCallingFunctions.SetSize(0);
mCalledFunctions.SetSize(0);
}
void GlobalOptimizer::PropagateParamCommas(Expression*& fexp, Expression*& exp)
@ -243,19 +243,6 @@ 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;
@ -264,6 +251,10 @@ 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;
}
@ -275,22 +266,14 @@ 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)
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->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();
}
exp->mType = EX_CONSTANT;
exp->mDecValue = cexp->mDecValue->ConstCast(exp->mDecType);
changed = true;
}
}
@ -341,7 +324,7 @@ bool GlobalOptimizer::Optimize(void)
if (!(func->mOptFlags & OPTF_FUNC_VARIABLE) && !(func->mBase->mFlags & DTF_VIRTUAL))
{
if (!(func->mOptFlags & (OPTF_VAR_USED | OPTF_VAR_ADDRESS)) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
if (!(func->mOptFlags & OPTF_VAR_USED) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
{
#if DUMP_OPTS
printf("Remove return value\n");
@ -399,7 +382,6 @@ 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
@ -462,7 +444,7 @@ void GlobalOptimizer::AnalyzeProcedure(Expression* exp, Declaration* procDec)
Analyze(exp, procDec, false);
}
else
mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->FullIdent());
mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->mQualIdent);
procDec->mOptFlags &= ~OPTF_ANALYZING;
}
@ -614,6 +596,9 @@ 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;
@ -659,8 +644,6 @@ 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 && (flags & ANAFL_LHS))
{
@ -672,12 +655,7 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_INITIALIZATION:
case EX_ASSIGNMENT:
if (exp->mToken == TK_ASSIGN)
{
if (exp->mType == EX_ASSIGNMENT)
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_ASSIGN | flags);
else
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
}
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
else
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS | flags);
@ -825,22 +803,6 @@ 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;
@ -986,20 +948,13 @@ 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;

View File

@ -47,7 +47,7 @@ const Ident* Ident::Unique(const char* str)
const Ident* Ident::PreMangle(const char* str) const
{
char buffer[1000];
char buffer[200];
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[1000];
char buffer[200];
sprintf_s(buffer, "%s#%d", str, id);
return Unique(buffer);
}
const Ident* Ident::Mangle(const char* str) const
{
char buffer[1000];
char buffer[200];
strcpy_s(buffer, mString);
strcat_s(buffer, str);
return Unique(buffer);

File diff suppressed because it is too large Load Diff

View File

@ -169,7 +169,6 @@ 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);
@ -199,7 +198,7 @@ public:
typedef ExpandingArray<IntegerValueRange> GrowingIntegerValueRangeArray;
typedef GrowingArray<IntegerValueRange> GrowingIntegerValueRangeArray;
class ValueSet
{
@ -381,7 +380,7 @@ public:
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator;
GrowingInstructionArray mInstructions;
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath, mValueRangeValid, mPatched, mLoopDebug;
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath, mValueRangeValid;
mutable int mMark;
NumberSet mLocalUsedTemps, mLocalModifiedTemps;
@ -424,15 +423,14 @@ public:
InterCodeBasicBlock* Clone(void);
void Append(InterInstruction * code);
void AppendBeforeBranch(InterInstruction* code, bool loopindex = false);
void AppendBeforeBranch(InterInstruction* code);
const InterInstruction* FindByDst(int dst) const;
void Close(InterCodeBasicBlock* trueJump, InterCodeBasicBlock* falseJump);
void CollectEntries(void);
void CollectEntryBlocks(InterCodeBasicBlock* from);
void GenerateTraces(int expand, bool compact);
void GenerateTraces(bool expand, bool compact);
void BuildDominatorTree(InterCodeBasicBlock * from);
bool StripLoopHead(void);
bool MergeSameConditionTraces(void);
@ -450,7 +448,6 @@ 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);
@ -483,8 +480,6 @@ 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);
@ -520,8 +515,6 @@ 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);
@ -630,42 +623,29 @@ 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, bool loops);
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue);
void RemoveUnusedMallocs(void);
bool PullStoreUpToConstAddress(void);
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 CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray<InterCodeBasicBlock*>& body);
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);
@ -676,7 +656,6 @@ public:
void FollowJumps(void);
bool ShortLeaMerge(int& spareTemps);
bool ShortLeaCleanup(void);
bool IsEqual(const InterCodeBasicBlock* block) const;
@ -713,7 +692,6 @@ protected:
GrowingIntegerValueRangeArray mLocalValueRange, mReverseValueRange;
void ResetVisited(void);
void ResetPatched(void);
void ResetEntryBlocks(void);
public:
InterCodeBasicBlock * mEntryBlock;
@ -775,7 +753,7 @@ public:
void Disassemble(const char* name, bool dumpSets = false);
protected:
void BuildLocalAliasTable(void);
void BuildTraces(int expand, bool dominators = true, bool compact = false);
void BuildTraces(bool expand, bool dominators = true, bool compact = false);
void TrimBlocks(void);
void EarlyBranchElimination(void);
void BuildDataFlowSets(void);
@ -796,9 +774,7 @@ 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);
@ -818,10 +794,9 @@ protected:
void CheckUsedDefinedTemps(void);
void WarnUsedUndefinedVariables(void);
void WarnInvalidValueRanges(void);
void PropagateMemoryAliasingInfo(bool loops);
void PropagateMemoryAliasingInfo(void);
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

View File

@ -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, int limit = 0);
ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, int level = 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);

View File

@ -45,7 +45,7 @@ bool LinkerReference::operator!=(const LinkerReference& ref)
}
LinkerObject::LinkerObject(void)
: mReferences(nullptr), mNumTemporaries(0), mSize(0), mStripe(0), mAlignment(1), mStackSection(nullptr), mIdent(nullptr), mFullIdent(nullptr), mStartUsed(0x10000), mEndUsed(0x00000), mMemory(nullptr)
: mReferences(nullptr), mNumTemporaries(0), mSize(0), mAlignment(1), mStackSection(nullptr), mIdent(nullptr), mFullIdent(nullptr), mStartUsed(0x10000), mEndUsed(0x00000), mMemory(nullptr)
, mPrefix(nullptr), mSuffix(nullptr), mProc(nullptr), mNativeProc(nullptr)
{}
@ -54,23 +54,6 @@ 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);
@ -650,7 +633,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 (((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))
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))
;
else if (end <= mFreeChunks[i].mEnd)
{
@ -702,7 +685,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 (((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))
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))
{
start = (start + 0x00ff) & 0xff00;
end = start + lobj->mSize;
@ -1903,8 +1886,6 @@ bool Linker::WriteDbjFile(FILE* file)
return true;
}
static const char hexchars[] = "0123456789abcdef";
bool Linker::WriteLblFile(const char* filename)
{
FILE* file;
@ -1918,28 +1899,7 @@ bool Linker::WriteLblFile(const char* filename)
if (obj->mFlags & LOBJF_REFERENCED)
{
if (obj->mIdent)
{
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);
}
fprintf(file, "al %04x .%s\n", obj->mAddress, obj->mIdent->mString);
}
}

View File

@ -156,7 +156,6 @@ 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;
@ -164,7 +163,6 @@ 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;
@ -192,7 +190,7 @@ public:
LinkerObjectType mType;
int mID, mMapID;
int mAddress, mRefAddress;
int mSize, mAlignment, mStripe, mStartUsed, mEndUsed;
int mSize, mAlignment, mStartUsed, mEndUsed;
LinkerSection * mSection;
LinkerRegion * mRegion;
uint8 * mData, * mMemory;
@ -214,8 +212,6 @@ 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

View File

@ -9,9 +9,6 @@ class NativeCodeBasicBlock;
class NativeCodeGenerator;
class NativeCodeInstruction;
class NativeCodeMapper;
class SuffixTree;
enum NativeRegisterDataMode
{
NRDM_UNKNOWN,
@ -133,42 +130,31 @@ 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 = 0x00100000;
static const uint32 NICF_USE_ZP_ADDR = 0x00200000;
static const uint32 NICF_USE_WORKREGS = 0x00400000;
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_BREAKPOINT = 0x00800000;
static const uint32 NCIF_BREAKPOINT = 0x00040000;
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, int minv = 0, int maxv = 255);
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, 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);
@ -205,7 +191,6 @@ 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;
@ -220,7 +205,7 @@ public:
bool IsShift(void) const;
bool IsShiftOrInc(void) const;
bool IsSimpleJSR(void) const;
bool MayBeMovedBefore(const NativeCodeInstruction& ins) const;
bool MayBeMovedBefore(const NativeCodeInstruction& ins);
bool ReplaceYRegWithXReg(void);
bool ReplaceXRegWithYReg(void);
@ -231,12 +216,6 @@ 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
@ -267,7 +246,7 @@ 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, mPatchUsed, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit;
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit;
bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX, mChecked;
NativeCodeBasicBlock * mDominator, * mSameBlock;
@ -285,16 +264,12 @@ 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 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;
int BranchByteSize(NativeCodeBasicBlock* target, int from, int to, bool final);
NativeCodeBasicBlock* SplitAt(int at);
@ -303,7 +278,6 @@ public:
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 final);
@ -328,8 +302,6 @@ 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);
@ -348,20 +320,18 @@ public:
bool PeepHoleOptimizerIterate(int pass);
bool PeepHoleOptimizerExits(int pass);
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter, int center);
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter);
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);
@ -373,11 +343,9 @@ public:
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
NativeCodeBasicBlock* CollectInnerLoop(NativeCodeBasicBlock* head, 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);
bool OptimizeGenericLoop(NativeCodeProcedure* proc);
bool CollectGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
bool CollectSingleEntryGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
void CollectReachable(ExpandingArray<NativeCodeBasicBlock*>& lblock);
bool OptimizeFindLoop(NativeCodeProcedure* proc);
@ -411,7 +379,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, bool addrused = false);
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0, bool addrvalid);
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);
@ -428,7 +396,6 @@ 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);
@ -441,7 +408,6 @@ 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;
@ -463,7 +429,9 @@ public:
void CountEntries(NativeCodeBasicBlock* fromJump);
NativeCodeBasicBlock * ForwardAccuBranch(bool eq, bool ne, bool pl, bool mi, int limit);
bool MergeBasicBlocks(void);
bool RemoveJumpToBranch(void);
void RemoveJumpToBranch(void);
void MarkLoopHead(void);
struct DominatorStacks
{
@ -539,7 +507,6 @@ public:
bool MoveTXADCDown(int at);
bool MoveTXALogicTAXDown(int at);
bool FoldShiftORAIntoLoadImmUp(int at);
bool ReverseShiftByteOrder(int at);
bool FindAccuExitValue(int& at);
bool MoveLoadXAbsUpCrossBlock(int at);
@ -573,7 +540,6 @@ 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);
@ -593,13 +559,6 @@ public:
int FindFreeAccu(int at) const;
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);
@ -610,9 +569,6 @@ 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);
@ -632,14 +588,7 @@ 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);
@ -743,8 +692,6 @@ 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);
@ -777,9 +724,8 @@ public:
bool CanGlobalSwapXY(void);
bool GlobalSwapXY(void);
bool LocalSwapXY(void);
bool UntangleXYUsage(bool final);
bool UntangleXYUsage(void);
bool AlternateXXUsage(void);
bool ShortSwapXY(void);
bool IsSimpleSubExpression(int at, NativeSimpleSubExpression & ex);
bool PropagateCommonSubExpression(void);
@ -803,20 +749,10 @@ 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
@ -826,20 +762,9 @@ 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
@ -883,10 +808,6 @@ public:
void PropagateAddGlobalCarry(void);
bool EliminateNonAliasedLocalStores(void);
bool CheckNonAliasedLocalStore(int at, const NativeCodeInstruction& sins);
void RegisterFunctionCalls(void);
bool MergeFunctionCalls(void);
@ -896,9 +817,6 @@ public:
void CheckBlocks(bool sequence = false);
void CheckAsmCode(void);
void CheckVisited(void);
int* mSuffixString;
void AddToSuffixTree(NativeCodeMapper& mapper, SuffixTree * tree);
};
class NativeCodeProcedure
@ -913,10 +831,6 @@ class NativeCodeProcedure
NativeCodeGenerator* mGenerator;
InterCodeProcedure* mInterProc;
LinkerObject* mLinkerObject;
const Ident* mIdent;
Location mLocation;
uint64 mCompilerOptions;
int mProgStart, mProgSize, mIndex, mFrameOffset, mStackExpand;
int mFastCallBase;
@ -928,15 +842,10 @@ 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);
@ -1002,8 +911,6 @@ public:
Linker* mLinker;
LinkerSection* mRuntimeSection;
ExpandingArray<NativeCodeProcedure*> mProcedures;
ExpandingArray<Runtime> mRuntime;
ExpandingArray<MulTable> mMulTables;
ExpandingArray<FloatTable> mFloatTables;
@ -1022,8 +929,6 @@ public:
FunctionCall* mFunctionCalls;
void OutlineFunctions(void);
void RegisterFunctionCall(NativeCodeBasicBlock* block, int at);
void BuildFunctionProxies(void);
bool MergeFunctionCall(NativeCodeBasicBlock* block, int at);

View File

@ -1,379 +0,0 @@
#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);
}
}

View File

@ -1,66 +0,0 @@
#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);
};

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,6 @@ public:
~Parser(void);
Parser* Clone(void);
Parser * mParent;
DeclarationScope * mGlobals, * mScope, * mTemplateScope, * mCaptureScope;
int mLocalIndex;
@ -25,8 +24,6 @@ public:
uint64 mCompilerOptionStack[32];
int mCompilerOptionSP;
Location FullLocation(const Location& loc);
void Parse(void);
protected:
bool ExpectToken(Token token);
@ -80,13 +77,12 @@ 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(Declaration * vdassm = nullptr);
Expression* ParseAssembler(void);
Expression* ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset);
Expression* ParseAssemblerMulOperand(Declaration* pcasm, int pcoffset);
@ -137,10 +133,7 @@ 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);
@ -162,7 +155,6 @@ protected:
Expression* ParseListExpression(bool lhs, Declaration * params = nullptr);
Expression* ParseParenthesisExpression(void);
void ParseStaticAssert(void);
Errors* mErrors;
Scanner* mScanner;

View File

@ -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 < 255 ? mPos : 255); i++)
for (int i = 1; i < mPos; i++)
{
int j = 0;
while (j < 127 && mPos + j < mFill && mBuffer[mPos - i + j] == mBuffer[mPos + j])
@ -327,16 +327,6 @@ 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
@ -496,7 +486,6 @@ void SourceFile::ReadCharPad(Errors* errors, const Location& location, SourceFil
CTMHeader ctmHeader;
CTMHeader8 ctmHeader8;
CTMHeader9 ctmHeader9;
CTTHeader9 cttHeader9;
uint16 ctmMarker, numChars, numTiles;
char tileWidth, tileHeight;
@ -507,20 +496,10 @@ void SourceFile::ReadCharPad(Errors* errors, const Location& location, SourceFil
fread(&ctmHeader8, sizeof(CTMHeader8), 1, mFile);
break;
case 9:
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;
}
fread(&ctmHeader9, sizeof(CTMHeader9), 1, mFile);
ctmHeader8.mDispMode = ctmHeader9.mDispMode;
ctmHeader8.mColorMethod = ctmHeader9.mColorMethod;
ctmHeader8.mFlags = ctmHeader9.mFlags;
break;
}

View File

@ -51,7 +51,6 @@ const char* TokenNames[] =
"'extern'",
"'inline'",
"'__assume'",
"'static_assert'",
"__asm",
"__interrupt",
@ -174,7 +173,6 @@ const char* TokenNames[] =
"'friend'",
"'constexpr'",
"'typename'",
"'decltype'",
};
@ -357,7 +355,7 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
mToken = TK_NONE;
mUngetToken = TK_NONE;
mReplay = nullptr;
mRecord = mRecordLast = mRecordPrev = nullptr;
mRecord = mRecordLast = nullptr;
mOnceDict = new MacroDict();
@ -374,13 +372,13 @@ Scanner::~Scanner(void)
void Scanner::BeginRecord(void)
{
mRecord = mRecordLast = mRecordPrev = new TokenSequence(this);
mRecord = mRecordLast = new TokenSequence(this);
}
TokenSequence* Scanner::CompleteRecord(void)
{
TokenSequence* seq = mRecord;
mRecord = mRecordLast = mRecordPrev = nullptr;
mRecord = mRecordLast = nullptr;
return seq;
}
@ -485,8 +483,6 @@ void Scanner::UngetToken(Token token)
{
mUngetToken = mToken;
mToken = token;
if (mRecord)
mRecordLast = mRecordPrev;
}
void Scanner::NextToken(void)
@ -495,8 +491,10 @@ void Scanner::NextToken(void)
{
mToken = mUngetToken;
mUngetToken = TK_NONE;
return;
}
else if (mReplay)
if (mReplay)
{
mLocation = mReplay->mLocation;
mToken = mReplay->mToken;
@ -517,7 +515,6 @@ void Scanner::NextToken(void)
if (mRecord)
{
mRecordPrev = mRecordLast;
mRecordLast->mNext = new TokenSequence(this);
mRecordLast = mRecordLast->mNext;
}
@ -823,36 +820,28 @@ void Scanner::NextPreToken(void)
}
else if (mToken == TK_PREP_IDENT)
{
if (mTokenIdent->mString[0])
{
Macro* def = nullptr;
if (mDefineArguments)
def = mDefineArguments->Lookup(mTokenIdent);
if (!def)
def = mDefines->Lookup(mTokenIdent);
Macro* def = nullptr;
if (mDefineArguments)
def = mDefineArguments->Lookup(mTokenIdent);
if (!def)
def = mDefines->Lookup(mTokenIdent);
if (def)
if (def)
{
if (def->mNumArguments == -1)
{
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);
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
{
mToken = TK_HASH;
return;
}
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
}
else if (mToken == TK_PREP_UNDEF)
{
@ -1125,70 +1114,46 @@ void Scanner::NextPreToken(void)
while (mTokenChar == ' ')
NextChar();
if (mTokenChar == '#' && mLine[mOffset] == '#')
while (mTokenChar == '#' && mLine[mOffset] == '#')
{
mOffset++;
NextChar();
char tkbase[256];
strcpy_s(tkbase, mTokenIdent->mString);
do {
mOffset++;
ptrdiff_t n = 0;
char tkident[256];
while (IsIdentChar(mTokenChar))
{
if (n < 255)
tkident[n++] = mTokenChar;
NextChar();
}
tkident[n] = 0;
ptrdiff_t n = 0;
char tkident[256];
while (IsIdentChar(mTokenChar))
{
if (n < 255)
tkident[n++] = mTokenChar;
NextChar();
}
tkident[n] = 0;
const Ident* ntkident = Ident::Unique(tkident);
const Ident* ntkident = Ident::Unique(tkident);
Macro* def = nullptr;
if (mDefineArguments)
def = mDefineArguments->Lookup(ntkident);
if (!def)
def = mDefines->Lookup(ntkident);
Macro* def = nullptr;
if (mDefineArguments)
def = mDefineArguments->Lookup(ntkident);
if (!def)
def = mDefines->Lookup(ntkident);
if (def)
strcat_s(tkbase, def->mString);
else
strcat_s(tkbase, tkident);
if (def)
strcat_s(tkbase, def->mString);
else
strcat_s(tkbase, tkident);
n = strlen(tkbase);
while (n > 0 && tkbase[n - 1] == ' ')
n--;
tkbase[n] = 0;
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();
mTokenIdent = Ident::Unique(tkbase);
}
else
return;
return;
}
}
else
@ -1833,8 +1798,6 @@ 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"))
@ -1883,8 +1846,6 @@ 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();
@ -2014,7 +1975,7 @@ void Scanner::NextRawToken(void)
default:
// dirty little hack to implement token preview, got to fix
// this with an infinite preview sequence at one point
// this with an infinit preview sequence at one point
mUngetToken = mToken;
mToken = TK_OPERATOR;
return;

View File

@ -49,7 +49,6 @@ enum Token
TK_EXTERN,
TK_INLINE,
TK_ASSUME,
TK_STATIC_ASSERT,
TK_ASM,
TK_INTERRUPT,
@ -173,7 +172,6 @@ enum Token
TK_FRIEND,
TK_CONSTEXPR,
TK_TYPENAME,
TK_DECLTYPE,
NUM_TOKENS
};
@ -317,7 +315,7 @@ protected:
Token mUngetToken;
const TokenSequence* mReplay;
TokenSequence* mRecord, * mRecordLast, * mRecordPrev;
TokenSequence* mRecord, * mRecordLast;
void StringToken(char terminator, char mode);
void CharToken(char mode);

View File

@ -76,7 +76,7 @@ int main2(int argc, const char** argv)
#else
strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.31.261");
strcpy(strProductVersion, "1.31.258");
#ifdef __APPLE__
uint32_t length = sizeof(basePath);
@ -111,12 +111,38 @@ 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);
strcat_s(includePath, "include");
{
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;
targetPath[0] = 0;
diskPath[0] = 0;
@ -159,10 +185,6 @@ 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);
@ -184,7 +206,6 @@ 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] == '=')
{
@ -232,8 +253,6 @@ 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])
@ -242,10 +261,6 @@ 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);
}
@ -427,12 +442,6 @@ 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");
@ -557,35 +566,6 @@ int main2(int argc, const char** argv)
// 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);

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,31,261,0
PRODUCTVERSION 1,31,261,0
FILEVERSION 1,31,258,0
PRODUCTVERSION 1,31,258,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.31.261.0"
VALUE "FileVersion", "1.31.258.0"
VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.31.261.0"
VALUE "ProductVersion", "1.31.258.0"
END
END
BLOCK "VarFileInfo"

View File

@ -189,7 +189,6 @@
<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" />
@ -219,7 +218,6 @@
<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" />

View File

@ -87,9 +87,6 @@
<ClCompile Include="Compression.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NativeCodeOutliner.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Array.h">
@ -173,9 +170,6 @@
<ClInclude Include="Compression.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NativeCodeOutliner.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="oscar64.rc">

View File

@ -34,12 +34,6 @@
}
"Entry"
{
"MsmKey" = "8:_03D7013B0D39A89CEA9D267005ADCE39"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_04ABABC55200450383686DD782DD1548"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -400,12 +394,6 @@
}
"Entry"
{
"MsmKey" = "8:_4B482689C546CDFC92F367BA507E7ADE"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_4B8FC526E6CC47FC8321D0191BFDBEDC"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -424,12 +412,6 @@
}
"Entry"
{
"MsmKey" = "8:_4E94486A43C1D1C032A05ED1E6F1FCEF"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_4E9503F4F8F343739E4685C2066B3AD0"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -526,12 +508,6 @@
}
"Entry"
{
"MsmKey" = "8:_65687B00DD49EEBBFFECE831614822A9"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_67C8F824E02B4211B315AB32AB7ABBB1"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -760,14 +736,14 @@
}
"Entry"
{
"MsmKey" = "8:_9B2E1BB3CD154CEFB214378A64B0B00C"
"OwnerKey" = "8:_UNDEFINED"
"MsmKey" = "8:_98B942589E984AAD381F87F18DDB79D3"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_9CA4DFBA483A862FBF3DAEDE506D7DBD"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmKey" = "8:_9B2E1BB3CD154CEFB214378A64B0B00C"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
@ -796,14 +772,14 @@
}
"Entry"
{
"MsmKey" = "8:_A1455504C259EDA9662CE90C07369CC5"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmKey" = "8:_A14BC161099E420286E6A1595596D0F0"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_A14BC161099E420286E6A1595596D0F0"
"OwnerKey" = "8:_UNDEFINED"
"MsmKey" = "8:_A16BC2645A14DC0435B7119153B32DE8"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
@ -826,12 +802,6 @@
}
"Entry"
{
"MsmKey" = "8:_A2F68033370E18CD792ECD1F91357C1B"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_A32310DEFD4E41118CD7D36A8614C0D4"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -886,12 +856,6 @@
}
"Entry"
{
"MsmKey" = "8:_AD3AED76152E705799261747B7FD2015"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_AE023AEA6C444140B19CD627DDC2CB87"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -940,6 +904,12 @@
}
"Entry"
{
"MsmKey" = "8:_B61CD152136A6E3CE5FF69D29E7A3F7B"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_B85448D515F0487FB6845119AE346F1D"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -982,12 +952,6 @@
}
"Entry"
{
"MsmKey" = "8:_C0E88FBB7B883ED27FFB3C60DBE114B8"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_C239EFB1C3A646809AD2740ABDE747B0"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -1084,18 +1048,6 @@
}
"Entry"
{
"MsmKey" = "8:_D04F8D80984DFA3EA342FE8FA1B7CC91"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_D057B4CD935875ECE7F0A91620660D07"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_D0E45B48D76B4407B0BDE4378C1DB2C7"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
@ -1517,26 +1469,6 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_03D7013B0D39A89CEA9D267005ADCE39"
{
"SourcePath" = "8:VCRUNTIME140.dll"
"TargetName" = "8:VCRUNTIME140.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}:_04ABABC55200450383686DD782DD1548"
{
"SourcePath" = "8:..\\samples\\games\\lander.c"
@ -2737,26 +2669,6 @@
"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"
@ -2817,26 +2729,6 @@
"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"
@ -3157,26 +3049,6 @@
"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"
@ -3937,6 +3809,26 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_98B942589E984AAD381F87F18DDB79D3"
{
"SourcePath" = "8:ucrtbased.dll"
"TargetName" = "8:ucrtbased.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}:_9B2E1BB3CD154CEFB214378A64B0B00C"
{
"SourcePath" = "8:..\\include\\plus4\\ted.h"
@ -3957,26 +3849,6 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_9CA4DFBA483A862FBF3DAEDE506D7DBD"
{
"SourcePath" = "8:VCRUNTIME140_1.dll"
"TargetName" = "8:VCRUNTIME140_1.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}:_9D0D7A63D6C848CD85489D6E7C43AFAD"
{
"SourcePath" = "8:..\\include\\stdio.h"
@ -4057,26 +3929,6 @@
"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"
@ -4097,6 +3949,26 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A16BC2645A14DC0435B7119153B32DE8"
{
"SourcePath" = "8:VCRUNTIME140D.dll"
"TargetName" = "8:VCRUNTIME140D.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}:_A18504BA88CE40128ED44BD1854F0A33"
{
"SourcePath" = "8:..\\samples\\memmap\\easyflashreloc.c"
@ -4157,26 +4029,6 @@
"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"
@ -4357,26 +4209,6 @@
"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"
@ -4537,6 +4369,26 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B61CD152136A6E3CE5FF69D29E7A3F7B"
{
"SourcePath" = "8:VCRUNTIME140_1D.dll"
"TargetName" = "8:VCRUNTIME140_1D.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}:_B85448D515F0487FB6845119AE346F1D"
{
"SourcePath" = "8:..\\samples\\resources\\landersprites.bin"
@ -4677,26 +4529,6 @@
"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,46 +4849,6 @@
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D04F8D80984DFA3EA342FE8FA1B7CC91"
{
"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:"
"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}:_D0E45B48D76B4407B0BDE4378C1DB2C7"
{
"SourcePath" = "8:..\\include\\stdlib.h"
@ -6310,15 +6102,15 @@
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64"
"ProductCode" = "8:{1B9A0E10-DEA6-4276-AC91-17782FE44D94}"
"PackageCode" = "8:{51BFE576-50D1-4F8F-AE7A-9FF07396F53D}"
"ProductCode" = "8:{BBF3BEE6-9351-480B-984C-51319BB16F9E}"
"PackageCode" = "8:{98A4BDA9-D4BD-4151-A418-4BC06DFC3F00}"
"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.261"
"ProductVersion" = "8:1.31.258"
"Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:"

View File

@ -29,7 +29,7 @@ const char MissileChars[] = {
#define Charset ((char *)0xd800)
// Joystick and crosshair control
volatile int CrossX = 160, CrossY = 100;
int CrossX = 160, CrossY = 100;
bool CrossP = false;
char CrossDelay = 0;
@ -553,22 +553,20 @@ __interrupt void joy_interrupt()
joy_poll(0);
// Move crosshair coordinates
int cx = CrossX + 2 * joyx[0], cy = CrossY + 2 * joyy[0];
CrossX += 2 * joyx[0]; CrossY += 2 * joyy[0];
// Stop at edges of screen
if (cx < 8)
cx = 8;
else if (cx > 312)
cx = 312;
if (cy < 20)
cy = 20;
else if (cy > 172)
cy = 172;
if (CrossX < 8)
CrossX = 8;
else if (CrossX > 312)
CrossX = 312;
if (CrossY < 20)
CrossY = 20;
else if (CrossY > 172)
CrossY = 172;
// Move crosshair sprite
spr_move(0, cx + 14, cy + 40);
CrossX = cx;
CrossY = cy;
spr_move(0, CrossX + 14, CrossY + 40);
// Check button
if (joyb[0])
@ -699,17 +697,15 @@ void game_play(void)
// Check if fire request
if (CrossP)
{
int cx = CrossX, cy = CrossY;
// Find launch site
int sx = 160;
if (cx < 120)
if (CrossX < 120)
sx = 24;
else if (cx > 200)
else if (CrossX > 200)
sx = 296;
// Fire missile
missile_start(sx, 184, cx, cy);
missile_start(sx, 184, CrossX, CrossY);
// Reset request
CrossP = false;

View File

@ -48,7 +48,7 @@ struct Point
};
__striped Point tcorners[8], pcorners[8];
Point tcorners[8], pcorners[8];
void drawCube(void)
{
@ -77,45 +77,6 @@ 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];
@ -151,15 +112,8 @@ 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
}

View File

@ -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, 1, 7 - (x & 7));
rirq_data(&scroll, 0, 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,13 +37,11 @@ int main(void)
rirq_init(true);
// Build switch to scroll line IRQ
rirq_build(&scroll, 2);
// Delay for one line to get to right border
rirq_delay(&scroll, 11);
rirq_build(&scroll, 1);
// Change control register two with this IRQ
rirq_write(&scroll, 1, &vic.ctrl2, 0);
rirq_write(&scroll, 0, &vic.ctrl2, 0);
// Put it onto the scroll line
rirq_set(0, 49 + 24 * 8, &scroll);
rirq_set(0, 50 + 24 * 8, &scroll);
// Build the switch to normal IRQ
rirq_build(&restore, 2);

View File

@ -20,13 +20,11 @@ int main(void)
rirq_init(true);
// Build switch to scroll line IRQ
rirq_build(&scroll, 2);
// Delay for one line to get to right border
rirq_delay(&scroll, 11);
rirq_build(&scroll, 1);
// Change control register two with this IRQ
rirq_write(&scroll, 1, &vic.ctrl2, 0);
rirq_write(&scroll, 0, &vic.ctrl2, 0);
// Put it onto the scroll line
rirq_set(0, 49 + 24 * 8, &scroll);
rirq_set(0, 50 + 24 * 8, &scroll);
// Build the switch to normal IRQ
rirq_build(&bottom, 1);
@ -48,7 +46,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, 1, 7 - (x & 7));
rirq_data(&scroll, 0, 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);

View File

@ -27,7 +27,7 @@ ScreenRow * const color = (ScreenRow *)0xd800;
// Move the screen one character to the left
void scrollLeft(void)
{
// Loop horizontally
// Loop horizontaly
for(char x=0; x<39; x++)
{
// Unroll vertical loop 16 times

View File

@ -64,7 +64,6 @@ const char * scrolltext[] = {
"",
"",
"",
""
};
@ -199,7 +198,7 @@ int main(void)
// Update interrupt position
for(char i=0; i<5; i++)
{
int ty = 48 * i + 45 + oy;
int ty = 48 * i + 46 + oy;
// No interrupts below screen bottom
if (ty < 250)
@ -247,7 +246,7 @@ int main(void)
case 42:
readline(line, lpos);
lpos++;
if (lpos == 27)
if (lpos == 28)
lpos = 0;
break;
case 45: