Compare commits
113 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
6ed4adb0ed | ||
|
f16c24363c | ||
|
fd7e68573c | ||
|
f1873f0794 | ||
|
a01d98e584 | ||
|
c7a53a5be6 | ||
|
4633631d7e | ||
|
100608e0ac | ||
|
35a0b36a0d | ||
|
5470db3a5f | ||
|
d6802f3cb9 | ||
|
5b4e0c2b55 | ||
|
8175fae67a | ||
|
13c90eb542 | ||
|
f98665c577 | ||
|
8843f3feba | ||
|
514cf59398 | ||
|
03c133cd48 | ||
|
880abea32e | ||
|
fc9a8f2a89 | ||
|
40c467d958 | ||
|
4bde6385b8 | ||
|
688ef958e3 | ||
|
6da7223472 | ||
|
a1d4bc8375 | ||
|
197e2a91be | ||
|
4d9d628b67 | ||
|
f720feebbf | ||
|
6076808f5e | ||
|
0af17f0f40 | ||
|
81e5321bfc | ||
|
27d3666285 | ||
|
c6b794db3a | ||
|
1fa4c39a20 | ||
|
0ba148b6bb | ||
|
65540da3f7 | ||
|
e660757824 | ||
|
05a6d16dde | ||
|
79ec9af3f2 | ||
|
8f37df448f | ||
|
d710a71ba0 | ||
|
8dd211b662 | ||
|
398ed22b09 | ||
|
6f1da4335b | ||
|
c86dc364b1 | ||
|
70eb7a5eab | ||
|
c1cd2ba57e | ||
|
00da0ef87d | ||
|
be9abbf510 | ||
|
0b72e6b2f2 | ||
|
6ea39d7bfa | ||
|
c0abe031ee | ||
|
fe667863b2 | ||
|
e514e05dc8 | ||
|
d978d0a483 | ||
|
37cacdafa7 | ||
|
78e3696663 | ||
|
a0215a4f21 | ||
|
2310416c46 | ||
|
52db653ec1 | ||
|
6fe76e478f | ||
|
ba05ec743d | ||
|
05ef25a61e | ||
|
b26cc4ede7 | ||
|
8dc5f703e8 | ||
|
c05d7e47f4 | ||
|
9dc8489693 | ||
|
f443c97f70 | ||
|
4837ceb73f | ||
|
42299c9406 | ||
|
850bbfc31a | ||
|
1e95f51469 | ||
|
e525e5d62e | ||
|
18deb8846d | ||
|
34ce9afeae | ||
|
d0411b7d52 | ||
|
34fda8c9b5 | ||
|
b4a357e44f | ||
|
2b224f262b | ||
|
3c306e0899 | ||
|
e82ab0c7ca | ||
|
983064c694 | ||
|
9230d95bad | ||
|
8b0790588b | ||
|
0a9c43757a | ||
|
fccfe35c4f | ||
|
064fed63f5 | ||
|
f43f471124 | ||
|
f99abb32e2 | ||
|
18f044e90c | ||
|
5b961c031c | ||
|
500cce511f | ||
|
885d6ff706 | ||
|
efc182ce27 | ||
|
06ef87fe63 | ||
|
f3d8251072 | ||
|
0d5efc90ed | ||
|
30b8e4e970 | ||
|
3da1ddf5da | ||
|
bfdd1b85fb | ||
|
686d468d32 | ||
|
23b15678cd | ||
|
d1054abd90 | ||
|
d358c8359b | ||
|
9e9494ebf9 | ||
|
015ada7a33 | ||
|
12e832ebd3 | ||
|
e327d2a148 | ||
|
366f9686dd | ||
|
a2927401bc | ||
|
bbb339d641 | ||
|
8e76334c20 | ||
|
739f1e2161 |
|
@ -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 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).
|
||||
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).
|
||||
|
||||
[Full reference manual](oscar64.md)
|
||||
[Additional samples and tutorials](https://github.com/drmortalwombat/OscarTutorials)
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
rem @echo off
|
||||
|
||||
@call :test rolrortest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test bitfields.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -15,6 +18,9 @@ rem @echo off
|
|||
@call :testh opp_vector.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_static_vector.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_vector_string.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -33,7 +39,7 @@ rem @echo off
|
|||
@call :testh opp_list.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_functional.cpp
|
||||
@call :testn opp_functional.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh operatoroverload.cpp
|
||||
|
@ -51,7 +57,7 @@ rem @echo off
|
|||
@call :testh constructortest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh copyconstructor.cpp
|
||||
@call :testn copyconstructor.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh copyassign.cpp
|
||||
|
@ -274,6 +280,15 @@ exit /b %errorlevel%
|
|||
..\bin\oscar64 -e -O2 -n -dHEAPCHECK %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O0 -bc %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
@ -334,6 +349,9 @@ exit /b %errorlevel%
|
|||
..\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
|
||||
|
@ -376,4 +394,7 @@ exit /b %errorlevel%
|
|||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@exit /b 0
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int t, n;
|
||||
|
||||
|
@ -161,7 +162,7 @@ void test_return_value(void)
|
|||
C2 c(test_ret_v());
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
assert(n == 6 && t == 0);
|
||||
}
|
||||
|
||||
void test_return_reference(void)
|
||||
|
@ -184,7 +185,7 @@ void test_retparam_value(void)
|
|||
test_param_fv(test_ret_v());
|
||||
}
|
||||
|
||||
assert(n == 4 && t == 0);
|
||||
assert(n == 6 && t == 0);
|
||||
}
|
||||
|
||||
void test_retparam_reference(void)
|
||||
|
@ -200,7 +201,6 @@ void test_retparam_reference(void)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
#if 0
|
||||
test_dcopy_init();
|
||||
test_copy_init();
|
||||
test_minit();
|
||||
|
@ -208,9 +208,8 @@ int main(void)
|
|||
test_param_value();
|
||||
test_param_ref();
|
||||
test_return_value();
|
||||
#endif
|
||||
test_retparam_value();
|
||||
// test_retparam_reference();
|
||||
test_retparam_reference();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -50,5 +50,11 @@ autorefreturn: autorefreturn.cpp
|
|||
$(OSCAR64_CC) -e -Os -n $<
|
||||
$(OSCAR64_CC) -e -O3 -n $<
|
||||
|
||||
copyconstructor: copyconstructor.cpp
|
||||
$(OSCAR64_CC) -e -O2 -n $<
|
||||
$(OSCAR64_CC) -e -O0 -n $<
|
||||
$(OSCAR64_CC) -e -Os -n $<
|
||||
$(OSCAR64_CC) -e -O3 -n $<
|
||||
|
||||
clean:
|
||||
@$(RM) *.asm *.bcs *.int *.lbl *.map *.prg
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
#include <opp/static_vector.h>
|
||||
#include <opp/algorithm.h>
|
||||
#include <assert.h>
|
||||
#include <opp/iostream.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
opp::static_vector<int, 20> a;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
a.push_back(i);
|
||||
|
||||
int s = 0;
|
||||
for(int i=0; i<a.size(); i++)
|
||||
s += a[i];
|
||||
|
||||
assert(s == 45);
|
||||
|
||||
for(int i=0; i<5; i++)
|
||||
a.erase(i);
|
||||
|
||||
s = 0;
|
||||
for(int i=0; i<a.size(); i++)
|
||||
s += a[i];
|
||||
|
||||
assert(s == 1 + 3 + 5 + 7 + 9);
|
||||
|
||||
opp::static_vector<int, 100> v;
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
v.push_back(i);
|
||||
|
||||
assert(v.size() == 10);
|
||||
v.insert(0, 20);
|
||||
assert(v.size() == 11);
|
||||
v.insert(6, 21);
|
||||
assert(v.size() == 12);
|
||||
v.insert(12, 22);
|
||||
|
||||
int * fi = opp::find(v.begin(), v.end(), 21);
|
||||
|
||||
fi = v.insert(fi, 30);
|
||||
fi = v.insert(fi, 31);
|
||||
fi = v.insert(fi, 32);
|
||||
|
||||
assert(v.size() == 16);
|
||||
assert(v[0] == 20);
|
||||
assert(v[15] == 22);
|
||||
assert(v[8] == 32);
|
||||
|
||||
fi = opp::find(v.begin(), v.end(), 32);
|
||||
|
||||
for(int i=0; i<30; i++)
|
||||
{
|
||||
fi = v.insert(fi, i + 40);
|
||||
}
|
||||
|
||||
assert(v.size() == 46);
|
||||
assert(v[28] == 60);
|
||||
|
||||
v.erase(10, 10);
|
||||
|
||||
for(int i : v)
|
||||
opp::cout << i << ", ";
|
||||
opp::cout << "\n";
|
||||
|
||||
assert(v.size() == 36);
|
||||
assert(v[18] == 60);
|
||||
|
||||
v.assign(42, 11);
|
||||
|
||||
assert(v.size() == 42);
|
||||
assert(v[0] == 11);
|
||||
assert(v[15] == 11);
|
||||
assert(v[41] == 11);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -64,5 +64,15 @@ int main(void)
|
|||
opp::cout << i << ", ";
|
||||
opp::cout << "\n";
|
||||
|
||||
assert(v.size() == 36);
|
||||
assert(v[18] == 60);
|
||||
|
||||
v.assign(42, 11);
|
||||
|
||||
assert(v.size() == 42);
|
||||
assert(v[0] == 11);
|
||||
assert(v[15] == 11);
|
||||
assert(v[41] == 11);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
#include <assert.h>
|
||||
|
||||
__noinline unsigned long rollright32(unsigned long a) {
|
||||
unsigned long tmp = a & 1;
|
||||
return ( a >> 1) + (tmp << 31);
|
||||
}
|
||||
|
||||
__noinline unsigned rollright16(unsigned a) {
|
||||
unsigned tmp = a & 1;
|
||||
return ( a >> 1) + (tmp << 15);
|
||||
}
|
||||
|
||||
__noinline char rollright8(char a) {
|
||||
char tmp = a & 1;
|
||||
return ( a >> 1) + (tmp << 7);
|
||||
}
|
||||
|
||||
__noinline unsigned long rollleft32(unsigned long a) {
|
||||
unsigned long tmp = (a >> 31) & 1;
|
||||
return ( a << 1) + tmp;
|
||||
}
|
||||
|
||||
__noinline unsigned rollleft16(unsigned a) {
|
||||
unsigned tmp = (a >> 15) & 1;
|
||||
return ( a << 1) + tmp;
|
||||
}
|
||||
|
||||
__noinline char rollleft8(char a) {
|
||||
char tmp = (a >> 7) & 1;
|
||||
return ( a << 1) + tmp;
|
||||
}
|
||||
|
||||
int main() {
|
||||
unsigned long lv = 0x12345678ul;
|
||||
unsigned val = 0x1234;
|
||||
char c=0x12;
|
||||
|
||||
unsigned long lvt[33];
|
||||
unsigned valt[17];
|
||||
char ct[9];
|
||||
|
||||
lvt[0] = lv;
|
||||
valt[0] = val;
|
||||
ct[0] = c;
|
||||
|
||||
assert(rollleft8(rollright8(c)) == c);
|
||||
assert(rollleft16(rollright16(val)) == val);
|
||||
assert(rollleft32(rollright32(lv)) == lv);
|
||||
|
||||
for(int i=0; i<32; i++)
|
||||
lvt[i + 1] = rollright32(lvt[i]);
|
||||
for(int i=0; i<16; i++)
|
||||
valt[i + 1] = rollright16(valt[i]);
|
||||
for(int i=0; i<8; i++)
|
||||
ct[i + 1] = rollright8(ct[i]);
|
||||
|
||||
for(int i=0; i<=32; i++)
|
||||
{
|
||||
assert(lvt[32 - i] == lv);
|
||||
lv = rollleft32(lv);
|
||||
}
|
||||
|
||||
for(int i=0; i<=16; i++)
|
||||
{
|
||||
assert(valt[16 - i] == val);
|
||||
val = rollleft16(val);
|
||||
}
|
||||
|
||||
for(int i=0; i<=8; i++)
|
||||
{
|
||||
assert(ct[8 - i] == c);
|
||||
c = rollleft8(c);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -63,6 +63,33 @@ bool nge(long a, long b)
|
|||
|
||||
|
||||
|
||||
|
||||
inline bool ieq(long a, long b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
inline bool ilt(long a, long b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
inline bool igt(long a, long b)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
|
||||
inline bool ile(long a, long b)
|
||||
{
|
||||
return a <= b;
|
||||
}
|
||||
|
||||
inline bool ige(long a, long b)
|
||||
{
|
||||
return a >= b;
|
||||
}
|
||||
|
||||
|
||||
bool beqz(long a)
|
||||
{
|
||||
return a == 0;
|
||||
|
@ -188,7 +215,71 @@ bool nge1(long a)
|
|||
|
||||
|
||||
|
||||
void cmp(long a, long b)
|
||||
bool beqm(long a)
|
||||
{
|
||||
return a == -1;
|
||||
}
|
||||
|
||||
bool bltm(long a)
|
||||
{
|
||||
return a < -1;
|
||||
}
|
||||
|
||||
bool bgtm(long a)
|
||||
{
|
||||
return a > -1;
|
||||
}
|
||||
|
||||
bool blem(long a)
|
||||
{
|
||||
return a <= -1;
|
||||
}
|
||||
|
||||
bool bgem(long a)
|
||||
{
|
||||
return a >= -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool neqm(long a)
|
||||
{
|
||||
return a == -1;
|
||||
}
|
||||
|
||||
#pragma native(neqm)
|
||||
|
||||
bool nltm(long a)
|
||||
{
|
||||
return a < -1;
|
||||
}
|
||||
|
||||
#pragma native(nltm)
|
||||
|
||||
bool ngtm(long a)
|
||||
{
|
||||
return a > -1;
|
||||
}
|
||||
|
||||
#pragma native(ngtm)
|
||||
|
||||
bool nlem(long a)
|
||||
{
|
||||
return a <= -1;
|
||||
}
|
||||
|
||||
#pragma native(nlem)
|
||||
|
||||
bool ngem(long a)
|
||||
{
|
||||
return a >= -1;
|
||||
}
|
||||
|
||||
#pragma native(ngem)
|
||||
|
||||
|
||||
|
||||
void cmpc(long a, long b)
|
||||
{
|
||||
bool beqf = beq(a, b), bltf = blt(a, b), bgtf = bgt(a, b), blef = ble(a, b), bgef = bge(a, b);
|
||||
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
|
||||
|
@ -203,6 +294,27 @@ void cmp(long a, long b)
|
|||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
void cmpi(long a, long b)
|
||||
{
|
||||
bool ieqf = ieq(a, b), iltf = ilt(a, b), igtf = igt(a, b), ilef = ile(a, b), igef = ige(a, b);
|
||||
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
|
||||
|
||||
printf("INLINE %ld, %ld : EQ %d LT %d GT %d\r", a, b, ieqf, iltf, igtf);
|
||||
printf("NATIVE %ld, %ld : EQ %d LT %d GT %d\r", a, b, neqf, nltf, ngtf);
|
||||
|
||||
assert(ieqf == neqf);
|
||||
assert(iltf == nltf);
|
||||
assert(igtf == ngtf);
|
||||
assert(ilef == nlef);
|
||||
assert(igef == ngef);
|
||||
}
|
||||
|
||||
void cmp(long a, long b)
|
||||
{
|
||||
cmpc(a, b);
|
||||
cmpi(a, b);
|
||||
}
|
||||
|
||||
void cmpz(long a)
|
||||
{
|
||||
bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(a);
|
||||
|
@ -233,6 +345,21 @@ void cmp1(long a)
|
|||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
void cmpm(long a)
|
||||
{
|
||||
bool beqf = beqm(a), bltf = bltm(a), bgtf = bgtm(a), blef = blem(a), bgef = bgem(a);
|
||||
bool neqf = neqm(a), nltf = nltm(a), ngtf = ngtm(a), nlef = nlem(a), ngef = ngem(a);
|
||||
|
||||
printf("BYTE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, beqf, bltf, bgtf, blef, bgef);
|
||||
printf("NATIVE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, neqf, nltf, ngtf, nlef, ngef);
|
||||
|
||||
assert(beqf == neqf);
|
||||
assert(bltf == nltf);
|
||||
assert(bgtf == ngtf);
|
||||
assert(blef == nlef);
|
||||
assert(bgef == ngef);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
cmp( 0, 1);
|
||||
|
@ -327,6 +454,10 @@ int main(void)
|
|||
cmp1(256);
|
||||
cmp1(10000);
|
||||
cmp1(20000);
|
||||
cmp1(1000000l);
|
||||
cmp1(2000000l);
|
||||
cmp1(100000000l);
|
||||
cmp1(200000000l);
|
||||
cmp1(-1);
|
||||
cmp1(-2);
|
||||
cmp1(-3);
|
||||
|
@ -334,6 +465,34 @@ int main(void)
|
|||
cmp1(-256);
|
||||
cmp1(-10000);
|
||||
cmp1(-20000);
|
||||
cmp1(-1000000l);
|
||||
cmp1(-2000000l);
|
||||
cmp1(-100000000l);
|
||||
cmp1(-200000000l);
|
||||
|
||||
cmpm(0);
|
||||
cmpm(1);
|
||||
cmpm(2);
|
||||
cmpm(3);
|
||||
cmpm(255);
|
||||
cmpm(256);
|
||||
cmpm(10000);
|
||||
cmpm(20000);
|
||||
cmpm(1000000l);
|
||||
cmpm(2000000l);
|
||||
cmpm(100000000l);
|
||||
cmpm(200000000l);
|
||||
cmpm(-1);
|
||||
cmpm(-2);
|
||||
cmpm(-3);
|
||||
cmpm(-255);
|
||||
cmpm(-256);
|
||||
cmpm(-10000);
|
||||
cmpm(-20000);
|
||||
cmpm(-1000000l);
|
||||
cmpm(-2000000l);
|
||||
cmpm(-100000000l);
|
||||
cmpm(-200000000l);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ enum SIDFXState
|
|||
SIDFX_WAIT
|
||||
};
|
||||
|
||||
static struct SIDFXChannel
|
||||
__striped static struct SIDFXChannel
|
||||
{
|
||||
const SIDFX * volatile com;
|
||||
byte delay, priority;
|
||||
|
@ -27,6 +27,7 @@ void sidfx_init(void)
|
|||
channels[i].com = nullptr;
|
||||
channels[i].state = SIDFX_IDLE;
|
||||
channels[i].priority = 0;
|
||||
channels[i].delay = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +36,11 @@ bool sidfx_idle(byte chn)
|
|||
return channels[chn].state == SIDFX_IDLE;
|
||||
}
|
||||
|
||||
char sidfx_cnt(byte chn)
|
||||
{
|
||||
return channels[chn].cnt;
|
||||
}
|
||||
|
||||
void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
|
||||
{
|
||||
SIDFXState ns = channels[chn].state;
|
||||
|
@ -47,6 +53,7 @@ void sidfx_play(byte chn, const SIDFX * fx, byte cnt)
|
|||
return;
|
||||
|
||||
channels[chn].state = SIDFX_IDLE;
|
||||
channels[chn].delay = 1;
|
||||
|
||||
channels[chn].com = fx;
|
||||
channels[chn].cnt = cnt - 1;
|
||||
|
@ -59,71 +66,95 @@ void sidfx_stop(byte chn)
|
|||
{
|
||||
channels[chn].com = nullptr;
|
||||
if (channels[chn].state != SIDFX_IDLE)
|
||||
{
|
||||
channels[chn].state = SIDFX_RESET_0;
|
||||
channels[chn].delay = 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void sidfx_loop_ch(byte ch)
|
||||
{
|
||||
switch (channels[ch].state)
|
||||
if (channels[ch].state)
|
||||
{
|
||||
case SIDFX_IDLE:
|
||||
break;
|
||||
case SIDFX_RESET_0:
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_RESET_1:
|
||||
sid.voices[ch].ctrl = SID_CTRL_TEST;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_READY:
|
||||
const SIDFX * com = channels[ch].com;
|
||||
|
||||
channels[ch].delay--;
|
||||
if (channels[ch].delay)
|
||||
{
|
||||
if (com->dfreq)
|
||||
{
|
||||
const SIDFX * com = channels[ch].com;
|
||||
channels[ch].freq += com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
}
|
||||
if (com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
}
|
||||
|
||||
while (!channels[ch].delay)
|
||||
{
|
||||
switch (channels[ch].state)
|
||||
{
|
||||
case SIDFX_IDLE:
|
||||
channels[ch].delay = 1;
|
||||
break;
|
||||
case SIDFX_RESET_0:
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
if (com)
|
||||
channels[ch].state = SIDFX_READY;
|
||||
else
|
||||
channels[ch].state = SIDFX_IDLE;
|
||||
channels[ch].delay = 1;
|
||||
break;
|
||||
case SIDFX_RESET_1:
|
||||
sid.voices[ch].ctrl = SID_CTRL_TEST;
|
||||
sid.voices[ch].ctrl = 0;
|
||||
sid.voices[ch].attdec = 0;
|
||||
sid.voices[ch].susrel = 0;
|
||||
channels[ch].state = SIDFX_READY;
|
||||
break;
|
||||
case SIDFX_READY:
|
||||
channels[ch].freq = com->freq;
|
||||
channels[ch].pwm = com->pwm;
|
||||
|
||||
sid.voices[ch].freq = com->freq;
|
||||
sid.voices[ch].pwm = com->pwm;
|
||||
sid.voices[ch].attdec = com->attdec;
|
||||
sid.voices[ch].susrel = com->susrel;
|
||||
sid.voices[ch].ctrl = com->ctrl;
|
||||
|
||||
if (com->ctrl & SID_CTRL_GATE)
|
||||
{
|
||||
channels[ch].freq = com->freq;
|
||||
channels[ch].pwm = com->pwm;
|
||||
|
||||
sid.voices[ch].freq = com->freq;
|
||||
sid.voices[ch].pwm = com->pwm;
|
||||
sid.voices[ch].attdec = com->attdec;
|
||||
sid.voices[ch].susrel = com->susrel;
|
||||
sid.voices[ch].ctrl = com->ctrl;
|
||||
|
||||
channels[ch].delay = com->time1;
|
||||
channels[ch].state = SIDFX_PLAY;
|
||||
}
|
||||
else
|
||||
channels[ch].state = SIDFX_IDLE;
|
||||
}
|
||||
break;
|
||||
case SIDFX_PLAY:
|
||||
{
|
||||
const SIDFX * com = channels[ch].com;
|
||||
if (com->dfreq)
|
||||
{
|
||||
channels[ch].freq += com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
channels[ch].delay = com->time0;
|
||||
channels[ch].state = SIDFX_PLAY;
|
||||
}
|
||||
if (com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
|
||||
if (channels[ch].delay)
|
||||
channels[ch].delay--;
|
||||
else if (com->time0)
|
||||
break;
|
||||
case SIDFX_PLAY:
|
||||
if (com->time0)
|
||||
{
|
||||
sid.voices[ch].ctrl = com->ctrl & ~SID_CTRL_GATE;
|
||||
channels[ch].delay = com->time0;
|
||||
channels[ch].delay = com->time0 - 1;
|
||||
channels[ch].state = SIDFX_WAIT;
|
||||
}
|
||||
else if (channels[ch].cnt)
|
||||
{
|
||||
char sr = com->susrel & 0xf0;
|
||||
com++;
|
||||
char ctrl = com->ctrl;
|
||||
if ((com->attdec & 0xef) == 0 && (ctrl & SID_CTRL_GATE) && (com->susrel & 0xf0) > sr)
|
||||
{
|
||||
sid.voices[ch].ctrl = ctrl & ~SID_CTRL_GATE;
|
||||
sid.voices[ch].ctrl = ctrl | SID_CTRL_GATE;
|
||||
}
|
||||
channels[ch].cnt--;
|
||||
channels[ch].com = com;
|
||||
channels[ch].priority = com->priority;
|
||||
|
@ -131,45 +162,30 @@ inline void sidfx_loop_ch(byte ch)
|
|||
}
|
||||
else
|
||||
{
|
||||
channels[ch].com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SIDFX_WAIT:
|
||||
{
|
||||
const SIDFX * com = channels[ch].com;
|
||||
if (com->dfreq)
|
||||
{
|
||||
channels[ch].freq += com->dfreq;
|
||||
sid.voices[ch].freq = channels[ch].freq;
|
||||
}
|
||||
if (com->dpwm)
|
||||
{
|
||||
channels[ch].pwm += com->dpwm;
|
||||
sid.voices[ch].pwm = channels[ch].pwm;
|
||||
}
|
||||
|
||||
if (channels[ch].delay)
|
||||
channels[ch].delay--;
|
||||
else if (channels[ch].cnt)
|
||||
break;
|
||||
case SIDFX_WAIT:
|
||||
if (channels[ch].cnt)
|
||||
{
|
||||
com++;
|
||||
channels[ch].cnt--;
|
||||
channels[ch].com = com;
|
||||
channels[ch].priority = com->priority;
|
||||
if (com->time0)
|
||||
if (com->ctrl & SID_CTRL_GATE)
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
else
|
||||
channels[ch].state = SIDFX_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
channels[ch].com = nullptr;
|
||||
com = nullptr;
|
||||
channels[ch].state = SIDFX_RESET_0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ inline void sidfx_play(byte chn, const SIDFX * fx, byte cnt);
|
|||
|
||||
void sidfx_stop(byte chn);
|
||||
|
||||
char sidfx_cnt(byte chn);
|
||||
|
||||
void sidfx_loop(void);
|
||||
|
||||
void sidfx_loop_2(void);
|
||||
|
|
|
@ -69,7 +69,7 @@ BANKINLINE bool krnio_open(char fnum, char device, char channel)
|
|||
{
|
||||
krnio_pstatus[fnum] = KRNIO_OK;
|
||||
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
lda #0
|
||||
sta accu
|
||||
|
@ -94,8 +94,7 @@ BANKINLINE bool krnio_open(char fnum, char device, char channel)
|
|||
|
||||
BANKOUT
|
||||
E2:
|
||||
};
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_open)
|
||||
|
@ -131,7 +130,7 @@ BANKINLINE krnioerr krnio_status(void)
|
|||
|
||||
BANKINLINE bool krnio_load(char fnum, char device, char channel)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
lda fnum
|
||||
|
@ -149,14 +148,14 @@ BANKINLINE bool krnio_load(char fnum, char device, char channel)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_load)
|
||||
|
||||
BANKINLINE bool krnio_save(char device, const char* start, const char* end)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
lda #0
|
||||
|
@ -175,14 +174,14 @@ BANKINLINE bool krnio_save(char device, const char* start, const char* end)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_save)
|
||||
|
||||
BANKINLINE bool krnio_chkout(char fnum)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
ldx fnum
|
||||
|
@ -193,14 +192,14 @@ BANKINLINE bool krnio_chkout(char fnum)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chkout)
|
||||
|
||||
BANKINLINE bool krnio_chkin(char fnum)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
ldx fnum
|
||||
|
@ -211,7 +210,7 @@ BANKINLINE bool krnio_chkin(char fnum)
|
|||
rol
|
||||
eor #1
|
||||
sta accu
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chkin)
|
||||
|
@ -230,14 +229,14 @@ BANKINLINE void krnio_clrchn(void)
|
|||
|
||||
BANKINLINE bool krnio_chrout(char ch)
|
||||
{
|
||||
return __asm
|
||||
return char(__asm
|
||||
{
|
||||
BANKIN
|
||||
lda ch
|
||||
jsr $ffd2 // chrout
|
||||
sta accu
|
||||
BANKOUT
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#pragma native(krnio_chrout)
|
||||
|
@ -422,7 +421,7 @@ int krnio_gets(char fnum, char * data, int num)
|
|||
|
||||
if (krnio_chkin(fnum))
|
||||
{
|
||||
krnioerr err;
|
||||
krnioerr err = KRNIO_OK;
|
||||
int i = 0;
|
||||
int ch;
|
||||
while (i + 1 < num)
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
#include <c64/asm6502.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
volatile char npos = 1, tpos = 0;
|
||||
volatile byte rirq_count;
|
||||
static byte rirq_pcount;
|
||||
|
||||
byte rasterIRQRows[NUM_IRQS + 1];
|
||||
byte rasterIRQIndex[NUM_IRQS + 1];
|
||||
byte rasterIRQRows[NUM_IRQS + 1];
|
||||
byte rasterIRQIndex[NUM_IRQS + 1]; // Sort order of interrupt index, offset by one
|
||||
#ifdef ZPAGE_IRQS
|
||||
__zeropage
|
||||
#endif
|
||||
byte rasterIRQNext[NUM_IRQS + 1];
|
||||
byte rasterIRQLow[NUM_IRQS];
|
||||
byte rasterIRQNext[NUM_IRQS + 1]; // Rasterline of interrupt, terminated by 0xff
|
||||
byte rasterIRQLow[NUM_IRQS]; // Address of interrupt code
|
||||
byte rasterIRQHigh[NUM_IRQS];
|
||||
|
||||
#ifdef ZPAGE_IRQS
|
||||
|
@ -22,26 +22,25 @@ __zeropage
|
|||
#endif
|
||||
byte nextIRQ;
|
||||
|
||||
__asm irq0
|
||||
// nextIRQ is the index of the next expected IRQ, or $ff if no IRQ is scheduled
|
||||
|
||||
__asm rirq_isr_ram_io
|
||||
{
|
||||
sta plra + 1
|
||||
stx plrx + 1
|
||||
sty plry + 1
|
||||
kentry:
|
||||
asl $d019
|
||||
|
||||
ldx nextIRQ
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
bmi exi
|
||||
|
||||
sta plra + 1
|
||||
sty plry + 1
|
||||
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -49,48 +48,105 @@ ji:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
// carry is cleared at this point
|
||||
|
||||
tay
|
||||
sbc #2
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
exd:
|
||||
dey
|
||||
ex:
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
plry:
|
||||
ldy #0
|
||||
plrx:
|
||||
ldx #0
|
||||
plra:
|
||||
lda #0
|
||||
plrx:
|
||||
ldx #0
|
||||
rti
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp plrx
|
||||
|
||||
// No more interrupts to service
|
||||
e2:
|
||||
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
tay
|
||||
|
||||
bit $d011
|
||||
bpl ex
|
||||
|
||||
e1:
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
ldy rasterIRQNext
|
||||
jmp exd
|
||||
|
||||
beq plry
|
||||
}
|
||||
|
||||
__asm irq2
|
||||
__asm rirq_isr_io
|
||||
{
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
kentry:
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
ldy rasterIRQIndex + 1, x
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
||||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
exd:
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq exd
|
||||
}
|
||||
|
||||
__asm rirq_isr_noio
|
||||
{
|
||||
pha
|
||||
txa
|
||||
|
@ -104,20 +160,15 @@ kentry:
|
|||
lda #$35
|
||||
sta $01
|
||||
|
||||
asl $d019
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -125,21 +176,20 @@ ji:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
// carry is cleared at this point
|
||||
|
||||
tay
|
||||
dey
|
||||
sbc #2
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
ex:
|
||||
|
||||
exd:
|
||||
pla
|
||||
sta $01
|
||||
|
||||
|
@ -150,45 +200,35 @@ ex:
|
|||
pla
|
||||
rti
|
||||
|
||||
e2:
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
ldx npos
|
||||
stx tpos
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
sty $d012
|
||||
jmp ex
|
||||
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq exd
|
||||
}
|
||||
|
||||
__asm irq1
|
||||
__asm rirq_isr_kernal_io
|
||||
{
|
||||
lda $d019
|
||||
bpl ex2
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -197,45 +237,36 @@ jx:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e2
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
tay
|
||||
|
||||
sec
|
||||
sbc #4
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
dey
|
||||
sty $d012
|
||||
w1:
|
||||
jmp ex
|
||||
|
||||
e2:
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
lda rasterIRQNext, x
|
||||
sec
|
||||
sbc #1
|
||||
sta $d012
|
||||
|
||||
ex:
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
|
||||
exd:
|
||||
jmp $ea81
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp $ea81
|
||||
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
jmp $ea81
|
||||
|
||||
ex2:
|
||||
|
@ -244,7 +275,7 @@ ex2:
|
|||
jmp $ea31
|
||||
}
|
||||
|
||||
__asm irq3
|
||||
__asm rirq_isr_kernal_noio
|
||||
{
|
||||
lda $01
|
||||
pha
|
||||
|
@ -255,17 +286,14 @@ __asm irq3
|
|||
bpl ex2
|
||||
|
||||
ldx nextIRQ
|
||||
bmi exi
|
||||
l1:
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
beq e1
|
||||
|
||||
ldy rasterIRQIndex + 1, x
|
||||
tax
|
||||
lda rasterIRQLow, y
|
||||
sta ji + 1
|
||||
lda rasterIRQHigh, y
|
||||
sta ji + 2
|
||||
ldx rasterIRQLow, y
|
||||
stx ji + 1
|
||||
ldx rasterIRQHigh, y
|
||||
stx ji + 2
|
||||
|
||||
ji:
|
||||
jsr $0000
|
||||
|
@ -274,49 +302,40 @@ jx:
|
|||
inc nextIRQ
|
||||
ldx nextIRQ
|
||||
|
||||
lda rasterIRQNext, x
|
||||
cmp #$ff
|
||||
ldy rasterIRQNext, x
|
||||
|
||||
asl $d019
|
||||
|
||||
cpy #$ff
|
||||
beq e2
|
||||
|
||||
tay
|
||||
|
||||
sec
|
||||
sbc #4
|
||||
cmp $d012
|
||||
bcc l1
|
||||
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
w1:
|
||||
jmp ex
|
||||
|
||||
e2:
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
||||
sta $d012
|
||||
|
||||
jmp ex
|
||||
|
||||
e1:
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
lda rasterIRQNext, x
|
||||
sec
|
||||
sbc #1
|
||||
sta $d012
|
||||
|
||||
ex:
|
||||
asl $d019
|
||||
dey
|
||||
cpy $d012
|
||||
bcc l1
|
||||
exd:
|
||||
pla
|
||||
sta $01
|
||||
|
||||
jmp $ea81
|
||||
|
||||
exi:
|
||||
asl $d019
|
||||
jmp exd
|
||||
|
||||
e2:
|
||||
inc rirq_count
|
||||
|
||||
ldy rasterIRQNext
|
||||
dey
|
||||
dey
|
||||
sty $d012
|
||||
ldx #0
|
||||
stx nextIRQ
|
||||
beq exd
|
||||
|
||||
ex2:
|
||||
LDA $DC0D
|
||||
cli
|
||||
|
@ -346,8 +365,8 @@ void rirq_build(RIRQCode * ic, byte size)
|
|||
ic->size = size;
|
||||
|
||||
asm_im(ic->code + 0, ASM_LDY, 0);
|
||||
asm_im(ic->code + 2, ASM_LDA, 0);
|
||||
asm_ab(ic->code + 4, ASM_CPX, 0xd012);
|
||||
asm_im(ic->code + 2, ASM_LDX, 0);
|
||||
asm_ab(ic->code + 4, ASM_CMP, 0xd012);
|
||||
asm_rl(ic->code + 7, ASM_BCS, -5);
|
||||
asm_ab(ic->code + 9, ASM_STY, 0x0000);
|
||||
|
||||
|
@ -361,7 +380,7 @@ void rirq_build(RIRQCode * ic, byte size)
|
|||
}
|
||||
else
|
||||
{
|
||||
asm_ab(ic->code + 12, ASM_STA, 0x0000);
|
||||
asm_ab(ic->code + 12, ASM_STX, 0x0000);
|
||||
|
||||
byte p = 15;
|
||||
for(byte i=2; i<size; i++)
|
||||
|
@ -481,7 +500,7 @@ void rirq_init_kernal(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = irq1;
|
||||
*(void **)0x0314 = rirq_isr_kernal_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -489,7 +508,7 @@ void rirq_init_kernal(void)
|
|||
|
||||
}
|
||||
|
||||
void rirq_init_kernal_io(void)
|
||||
void rirq_init_kernal_noio(void)
|
||||
{
|
||||
rirq_init_tables();
|
||||
|
||||
|
@ -498,7 +517,7 @@ void rirq_init_kernal_io(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = irq3;
|
||||
*(void **)0x0314 = rirq_isr_kernal_noio;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -515,8 +534,8 @@ void rirq_init_crt(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = irq0.kentry;
|
||||
*(void **)0xfffe = irq0;
|
||||
*(void **)0x0314 = rirq_isr_io.kentry;
|
||||
*(void **)0xfffe = rirq_isr_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -524,7 +543,7 @@ void rirq_init_crt(void)
|
|||
|
||||
}
|
||||
|
||||
void rirq_init_crt_io(void)
|
||||
void rirq_init_crt_noio(void)
|
||||
{
|
||||
rirq_init_tables();
|
||||
|
||||
|
@ -533,8 +552,8 @@ void rirq_init_crt_io(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0x0314 = irq2.kentry;
|
||||
*(void **)0xfffe = irq2;
|
||||
*(void **)0x0314 = rirq_isr_noio.kentry;
|
||||
*(void **)0xfffe = rirq_isr_noio;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -551,7 +570,7 @@ void rirq_init_io(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0xfffe = irq0;
|
||||
*(void **)0xfffe = rirq_isr_ram_io;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -568,7 +587,7 @@ void rirq_init_memmap(void)
|
|||
sei
|
||||
}
|
||||
|
||||
*(void **)0xfffe = irq2;
|
||||
*(void **)0xfffe = rirq_isr_noio;
|
||||
|
||||
vic.intr_enable = 1;
|
||||
vic.ctrl1 &= 0x7f;
|
||||
|
@ -586,12 +605,18 @@ void rirq_init(bool kernalIRQ)
|
|||
|
||||
void rirq_wait(void)
|
||||
{
|
||||
while (tpos != npos) ;
|
||||
npos++;
|
||||
char i0 = rirq_pcount;
|
||||
char i1;
|
||||
do {
|
||||
i1 = rirq_count;
|
||||
} while (i0 == i1);
|
||||
rirq_pcount = i1;
|
||||
}
|
||||
|
||||
void rirq_sort(bool inirq)
|
||||
{
|
||||
// disable raster interrupts while sorting
|
||||
nextIRQ = 0xff;
|
||||
#if 1
|
||||
byte maxr = rasterIRQRows[rasterIRQIndex[1]];
|
||||
for(byte i = 2; i<NUM_IRQS + 1; i++)
|
||||
|
@ -639,15 +664,17 @@ void rirq_sort(bool inirq)
|
|||
}
|
||||
#endif
|
||||
|
||||
npos++;
|
||||
rirq_pcount = rirq_count;
|
||||
if (inirq)
|
||||
nextIRQ = NUM_IRQS - 1;
|
||||
else
|
||||
{
|
||||
nextIRQ = 0;
|
||||
byte yp = rasterIRQNext[nextIRQ];
|
||||
byte yp = rasterIRQNext[0];
|
||||
if (yp != 0xff)
|
||||
{
|
||||
vic.raster = yp - 1;
|
||||
nextIRQ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,6 +689,7 @@ void rirq_start(void)
|
|||
lda #100
|
||||
sta $d012
|
||||
|
||||
asl $d019
|
||||
cli
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ void rirq_init_kernal(void);
|
|||
|
||||
// Raster IRQ through kernal, with IO range not always enabled
|
||||
// calls kernal continuation
|
||||
void rirq_init_kernal_io(void);
|
||||
void rirq_init_kernal_noio(void);
|
||||
|
||||
// Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range always enabled
|
||||
// does not call kernal continuation
|
||||
|
@ -162,7 +162,7 @@ void rirq_init_crt(void);
|
|||
|
||||
// Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range not always enabled
|
||||
// does not call kernal continuation
|
||||
void rirq_init_crt_io(void);
|
||||
void rirq_init_crt_noio(void);
|
||||
|
||||
// Raster IRQ through RAM vector, with ROM disabled and IO range always enabled
|
||||
// does not call kernal continuation
|
||||
|
@ -179,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 operatins.
|
||||
// the vertical position of one of the interrupt operations.
|
||||
// Set the inirq flag to true when calling this from an interrupt
|
||||
void rirq_sort(bool inirq = false);
|
||||
|
||||
|
|
|
@ -756,6 +756,11 @@ __asm mul32
|
|||
sta tmp + 6
|
||||
sta tmp + 7
|
||||
|
||||
lda tmp + 3
|
||||
ora tmp + 2
|
||||
ora tmp + 1
|
||||
beq WB
|
||||
|
||||
lda tmp + 0
|
||||
jsr WM
|
||||
lda tmp + 1
|
||||
|
@ -773,6 +778,7 @@ WM:
|
|||
stx accu + 1
|
||||
sta accu
|
||||
rts
|
||||
WB: lda tmp + 0
|
||||
W0:
|
||||
sec
|
||||
ror
|
||||
|
|
|
@ -33,10 +33,15 @@ bool isfinite(float f);
|
|||
#pragma intrinsic(sin)
|
||||
#pragma intrinsic(cos)
|
||||
#pragma intrinsic(tan)
|
||||
#pragma intrinsic(atan)
|
||||
#pragma intrinsic(atan2)
|
||||
|
||||
#pragma intrinsic(log)
|
||||
#pragma intrinsic(exp)
|
||||
|
||||
#pragma intrinsic(pow)
|
||||
#pragma intrinsic(sqrt)
|
||||
|
||||
#pragma compile("math.c")
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <opp/utility.h>
|
||||
#include <oscar.h>
|
||||
|
||||
namespace opp {
|
||||
|
||||
|
@ -11,8 +12,8 @@ template <class T, int N>
|
|||
class static_vector
|
||||
{
|
||||
protected:
|
||||
char _space[N * sizeof(T)];
|
||||
enum { m = N } _size;
|
||||
char _space[N * sizeof(T)];
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
|
@ -20,23 +21,28 @@ public:
|
|||
|
||||
static_vector(size_t n) : _size(n)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (n > N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i) T;
|
||||
new (data + i) T();
|
||||
}
|
||||
|
||||
static_vector(const static_vector & v)
|
||||
: _size(v._size)
|
||||
{
|
||||
size_t n = _size;
|
||||
T * data = (T*)_space, * vdata = (T*)(v._space);
|
||||
for(size_t i=0; i<_size; i++)
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i)T(vdata[i]);
|
||||
}
|
||||
|
||||
~static_vector(void)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
data[i].~T();
|
||||
}
|
||||
|
||||
|
@ -45,10 +51,12 @@ public:
|
|||
if (this != &v)
|
||||
{
|
||||
T * data = (T*)_space, * vdata = (T*)(v._space);
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
data[i].~T();
|
||||
_size = v._size;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (data + i)T(vdata[i]);
|
||||
}
|
||||
return *this;
|
||||
|
@ -69,6 +77,11 @@ public:
|
|||
return _size == 0;
|
||||
}
|
||||
|
||||
bool full(void) const
|
||||
{
|
||||
return _size == N;
|
||||
}
|
||||
|
||||
size_t capacity(void) const
|
||||
{
|
||||
return N;
|
||||
|
@ -76,6 +89,8 @@ public:
|
|||
|
||||
void resize(size_t n);
|
||||
|
||||
void clear(void);
|
||||
|
||||
T & at(size_t at)
|
||||
{
|
||||
return ((T*)_space)[at];
|
||||
|
@ -166,6 +181,8 @@ public:
|
|||
((T*)_space)[_size].~T();
|
||||
}
|
||||
|
||||
void assign(size_t count, const T & t);
|
||||
|
||||
void insert(size_t at, const T & t);
|
||||
|
||||
void erase(size_t at, size_t n = 1);
|
||||
|
@ -177,34 +194,50 @@ public:
|
|||
};
|
||||
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::clear(void)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
data[i].~T();
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::resize(size_t n)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (n > N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
if (n < _size)
|
||||
{
|
||||
for(size_t i=n; i<_size; i++)
|
||||
data[i].~T();
|
||||
_size = n;
|
||||
}
|
||||
else
|
||||
else if (n > 0)
|
||||
{
|
||||
for(size_t i=_size; i<n; i++)
|
||||
new(data + i)T;
|
||||
_size = n;
|
||||
new(data + i)T();
|
||||
}
|
||||
_size = n;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::push_back(const T & t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(t);
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::push_back(T && t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(t);
|
||||
}
|
||||
|
||||
|
@ -212,14 +245,28 @@ template <class T, int N>
|
|||
template <typename ...P>
|
||||
void static_vector<T, N>::emplace_back(const P&... p)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
new ((T*)_space + _size++)T(p...);
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::assign(size_t count, const T & t)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
data[i].~T();
|
||||
for(size_t i=0; i<count; i++)
|
||||
new (data + i)T(t);
|
||||
_size = count;
|
||||
}
|
||||
|
||||
template <class T, int N>
|
||||
void static_vector<T, N>::insert(size_t at, const T & t)
|
||||
{
|
||||
T * data = (T*)_space;
|
||||
new (data + _size)T;
|
||||
new (data + _size)T();
|
||||
for(size_t i=_size; i>at; i--)
|
||||
data[i] = move(data[i - 1]);
|
||||
data[at] = t;
|
||||
|
@ -240,9 +287,12 @@ void static_vector<T, N>::erase(size_t at, size_t n)
|
|||
template <class T, int N>
|
||||
T * static_vector<T, N>::insert(T * at, const T & t)
|
||||
{
|
||||
#ifdef CAPACITYCHECK
|
||||
if (_size >= N) debugcrash();
|
||||
#endif
|
||||
T * data = (T*)_space;
|
||||
T * dp = data + _size;
|
||||
new (dp)T;
|
||||
new (dp)T();
|
||||
while (dp != at)
|
||||
{
|
||||
dp--;
|
||||
|
|
|
@ -27,7 +27,8 @@ public:
|
|||
vector(const vector & v)
|
||||
: _data((T*)malloc(v._size * sizeof(T))), _size(v._size), _capacity(v._size)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (_data + i)T(v._data[i]);
|
||||
}
|
||||
|
||||
|
@ -50,14 +51,16 @@ public:
|
|||
{
|
||||
if (this != &v)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
size_t n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
_data[i].~T();
|
||||
free(_data);
|
||||
|
||||
_data = (T*)malloc(v._size * sizeof(T));
|
||||
_size = v._size;
|
||||
_capacity = v._size;
|
||||
for(size_t i=0; i<_size; i++)
|
||||
n = _size;
|
||||
for(size_t i=0; i<n; i++)
|
||||
new (_data + i)T(v._data[i]);
|
||||
}
|
||||
return *this;
|
||||
|
@ -94,6 +97,8 @@ public:
|
|||
return _capacity;
|
||||
}
|
||||
|
||||
void clear(void);
|
||||
|
||||
void resize(size_t n);
|
||||
|
||||
void reserve(size_t n);
|
||||
|
@ -190,6 +195,8 @@ public:
|
|||
_data[_size].~T();
|
||||
}
|
||||
|
||||
void assign(size_t count, const T & t);
|
||||
|
||||
void insert(size_t at, const T & t);
|
||||
|
||||
void erase(size_t at, size_t n = 1);
|
||||
|
@ -204,7 +211,7 @@ protected:
|
|||
|
||||
|
||||
template <class T>
|
||||
void vector<T>::reserve(size_t n)
|
||||
__noinline void vector<T>::reserve(size_t n)
|
||||
{
|
||||
if (n > _capacity)
|
||||
{
|
||||
|
@ -221,7 +228,15 @@ void vector<T>::reserve(size_t n)
|
|||
}
|
||||
|
||||
template <class T>
|
||||
void vector<T>::resize(size_t n)
|
||||
void vector<T>::clear(void)
|
||||
{
|
||||
for(size_t i=0; i<_size; i++)
|
||||
_data[i].~T();
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
__noinline void vector<T>::resize(size_t n)
|
||||
{
|
||||
if (n < _size)
|
||||
{
|
||||
|
@ -286,6 +301,21 @@ 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)
|
||||
{
|
||||
|
|
|
@ -129,3 +129,10 @@ __native const char * oscar_expand_lzo_buf(char * dp, const char * sp)
|
|||
|
||||
return sp + 1;
|
||||
}
|
||||
|
||||
void debugcrash(void)
|
||||
{
|
||||
__asm volatile {
|
||||
byt $02
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ void breakpoint(void);
|
|||
|
||||
#pragma intrinsic(breakpoint)
|
||||
|
||||
void debugcrash(void);
|
||||
|
||||
#pragma compile("oscar.c")
|
||||
|
||||
#endif
|
||||
|
|
|
@ -556,6 +556,17 @@ int sprintf(char * str, const char * fmt, ...)
|
|||
return d - str;
|
||||
}
|
||||
|
||||
void vprintf(const char * fmt, va_list vlist)
|
||||
{
|
||||
char buff[50];
|
||||
sformat(buff, fmt, (int *)vlist, true);
|
||||
}
|
||||
|
||||
int vsprintf(char * str, const char * fmt, va_list vlist)
|
||||
{
|
||||
char * d = sformat(str, fmt, (int *)vlist, false);
|
||||
return d - str;
|
||||
}
|
||||
|
||||
static inline bool isspace(char c)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void putchar(char c);
|
||||
|
||||
|
@ -18,6 +19,10 @@ void printf(const char * fmt, ...);
|
|||
|
||||
int sprintf(char * str, const char * fmt, ...);
|
||||
|
||||
void vprintf(const char * fmt, va_list vlist);
|
||||
|
||||
int vsprintf(char * str, const char * fmt, va_list vlist);
|
||||
|
||||
int scanf(const char * fmt, ...);
|
||||
|
||||
int sscanf(const char * str, const char * fmt, ...);
|
||||
|
|
|
@ -544,7 +544,7 @@ unsigned heapfree(void)
|
|||
}
|
||||
|
||||
#if 0
|
||||
struct Heap {
|
||||
struct Heap {q
|
||||
unsigned int size;
|
||||
Heap * next;
|
||||
} * freeHeap;
|
||||
|
@ -667,6 +667,97 @@ void * calloc(int num, int size)
|
|||
return p;
|
||||
}
|
||||
|
||||
void * realloc(void * ptr, unsigned size)
|
||||
{
|
||||
if (ptr)
|
||||
{
|
||||
#ifdef HEAPCHECK
|
||||
Heap * pheap = (Heap *)((char *)ptr - 6);
|
||||
Heap * eheap = pheap->next;
|
||||
|
||||
unsigned psize = (char *)eheap - (char *)pheap;
|
||||
|
||||
void * nptr = malloc(size);
|
||||
memcpy(nptr, ptr, psize - 6);
|
||||
free(ptr);
|
||||
return nptr;
|
||||
#else
|
||||
unsigned nsize = (size + 5) & ~3;
|
||||
|
||||
// Get heap info
|
||||
Heap * pheap = (Heap *)((char *)ptr - 2);
|
||||
Heap * eheap = pheap->next;
|
||||
|
||||
unsigned psize = (char *)eheap - (char *)pheap;
|
||||
|
||||
Heap * h = HeapNode.next;
|
||||
Heap * hp = &HeapNode;
|
||||
while (h && h < pheap)
|
||||
{
|
||||
hp = h;
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
if (nsize <= psize)
|
||||
{
|
||||
// check if we should free some memory
|
||||
if (nsize + sizeof(HeapNode) < psize)
|
||||
{
|
||||
Heap * nheap = (Heap *)((char *)pheap + nsize);
|
||||
pheap->next = nheap;
|
||||
|
||||
if (h == eheap)
|
||||
{
|
||||
nheap->end = h->end;
|
||||
nheap->next = h->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
nheap->end = eheap;
|
||||
nheap->next = h;
|
||||
}
|
||||
|
||||
hp->next = nheap;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
else if (h == eheap)
|
||||
{
|
||||
// Free space after this
|
||||
|
||||
// Check if enough space if extending
|
||||
unsigned xsize = (char *)h->end - (char *)pheap;
|
||||
if (xsize >= nsize)
|
||||
{
|
||||
if (xsize > nsize + sizeof(HeapNode))
|
||||
{
|
||||
Heap * nheap = (Heap *)((char *)pheap + nsize);
|
||||
pheap->next = nheap;
|
||||
nheap->end = h->end;
|
||||
nheap->next = h->next;
|
||||
hp->next = nheap;
|
||||
}
|
||||
else
|
||||
{
|
||||
pheap->next = h->end;
|
||||
hp->next = h->next;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void * nptr = malloc(size);
|
||||
memcpy(nptr, ptr, psize - 2);
|
||||
free(ptr);
|
||||
return nptr;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static unsigned seed = 31232;
|
||||
|
||||
unsigned int rand(void)
|
||||
|
|
|
@ -45,6 +45,8 @@ void free(void * ptr);
|
|||
|
||||
void * calloc(int num, int size);
|
||||
|
||||
void * realloc(void * ptr, unsigned size);
|
||||
|
||||
unsigned heapfree(void);
|
||||
|
||||
unsigned int rand(void);
|
||||
|
|
|
@ -38,7 +38,7 @@ else
|
|||
endif
|
||||
|
||||
|
||||
all: --prep-build-dir compiler samples check
|
||||
all: compiler samples check
|
||||
|
||||
|
||||
$(srcdir)/%.o: $(project_dir)/oscar64/%.cpp
|
||||
|
@ -56,7 +56,7 @@ $(srcdir)/%.d: $(project_dir)/oscar64/%.cpp
|
|||
$(RM) $@.$$$$
|
||||
|
||||
|
||||
compiler: $(objects)
|
||||
compiler: --prep-build-dir $(objects)
|
||||
@$(MKDIR_PARENT) $(srcdir)
|
||||
@echo "Linking compiler..."
|
||||
$(CXX) $(CPPFLAGS) $(objects) $(linklibs) -o $(project_dir)/bin/oscar64
|
||||
|
|
|
@ -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 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.
|
||||
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.
|
||||
|
||||
### Language
|
||||
|
||||
|
@ -110,6 +110,7 @@ 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,6 +130,7 @@ The compiler is command line driven, and creates an executable .prg file.
|
|||
* -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
|
||||
|
@ -749,7 +751,7 @@ 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 usefull if a page crossing is problematic. The compiler may also be able to generate more efficient code, if a larger variable is page aligned.
|
||||
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)
|
||||
|
|
|
@ -3462,94 +3462,151 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
|
|||
{
|
||||
if (ins->mSrc[1].mTemp < 0)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
if (csigned)
|
||||
if (ins->mSrc[1].mType == IT_INT16 || ins->mSrc[1].mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(lins);
|
||||
if (csigned)
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPLES:
|
||||
return BC_BRANCHS_LE;
|
||||
case IA_CMPGS:
|
||||
return BC_BRANCHS_GT;
|
||||
case IA_CMPGES:
|
||||
return BC_BRANCHS_GE;
|
||||
case IA_CMPLS:
|
||||
return BC_BRANCHS_LT;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
case IA_CMPLEU:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
case IA_CMPGU:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPGEU:
|
||||
return BC_JUMPS;
|
||||
case IA_CMPLU:
|
||||
return BC_NOP;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
cins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction bins(BC_LEA_ABS);
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
bins.mLinkerObject = ins->mSrc[1].mLinkerObject;
|
||||
bins.mValue = int(ins->mSrc[1].mIntConst);
|
||||
bins.mRelocate = true;
|
||||
mIns.Push(bins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[0].mTemp < 0)
|
||||
{
|
||||
if (ins->mSrc[0].mType == IT_INT16 || ins->mSrc[0].mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(lins);
|
||||
if (csigned)
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPLES:
|
||||
return BC_BRANCHS_LE;
|
||||
case IA_CMPGS:
|
||||
return BC_BRANCHS_GT;
|
||||
case IA_CMPGES:
|
||||
return BC_BRANCHS_GE;
|
||||
case IA_CMPLS:
|
||||
return BC_BRANCHS_LT;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optzero && ins->mSrc[0].mIntConst == 0)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_CMPEQ:
|
||||
case IA_CMPLEU:
|
||||
return BC_BRANCHS_EQ;
|
||||
case IA_CMPNE:
|
||||
case IA_CMPGU:
|
||||
return BC_BRANCHS_NE;
|
||||
case IA_CMPGEU:
|
||||
return BC_JUMPS;
|
||||
case IA_CMPLU:
|
||||
return BC_NOP;
|
||||
}
|
||||
}
|
||||
else if (ins->mSrc[1].IsUByte())
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
|
||||
cins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction bins(BC_LEA_ABS);
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
bins.mLinkerObject = ins->mSrc[0].mLinkerObject;
|
||||
bins.mValue = int(ins->mSrc[0].mIntConst);
|
||||
bins.mRelocate = true;
|
||||
mIns.Push(bins);
|
||||
|
||||
if (csigned)
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPSR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeInstruction cins(BC_BINOP_CMPUR_16);
|
||||
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
cins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||
mIns.Push(cins);
|
||||
}
|
||||
}
|
||||
code = TransposeBranchCondition(code);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1065,7 +1065,10 @@ bool Compiler::GenerateCode(void)
|
|||
for (int i = 0; i < mNativeCodeGenerator->mProcedures.Size(); i++)
|
||||
{
|
||||
if (mCompilerOptions & COPT_VERBOSE2)
|
||||
printf("Assemble native code <%s>\n", mNativeCodeGenerator->mProcedures[i]->mInterProc->mIdent->mString);
|
||||
{
|
||||
if (mNativeCodeGenerator->mProcedures[i]->mInterProc)
|
||||
printf("Assemble native code <%s>\n", mNativeCodeGenerator->mProcedures[i]->mInterProc->mIdent->mString);
|
||||
}
|
||||
mNativeCodeGenerator->mProcedures[i]->Assemble();
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ 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;
|
||||
|
|
|
@ -651,6 +651,7 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
|
|||
{
|
||||
mProcType = exp->mLeft->mDecType;
|
||||
|
||||
Expression* pex = exp->mRight;
|
||||
Declaration* cdec = exp->mLeft->mDecType->mParams;
|
||||
|
||||
int pos = 0;
|
||||
|
@ -659,6 +660,28 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
|
|||
mParams[pos].PutPtr(Value(&mResult));
|
||||
pos = 2;
|
||||
|
||||
if (pex->mType == EX_LIST)
|
||||
pex = pex->mRight;
|
||||
else
|
||||
pex = nullptr;
|
||||
cdec = cdec->mNext;
|
||||
|
||||
while (pex && pex->mType == EX_LIST)
|
||||
{
|
||||
if (!AddParam(pos, pex->mLeft, cdec))
|
||||
return exp;
|
||||
|
||||
pex = pex->mRight;
|
||||
if (cdec)
|
||||
cdec = cdec->mNext;
|
||||
}
|
||||
|
||||
if (pex)
|
||||
{
|
||||
if (!AddParam(pos, pex, cdec))
|
||||
return exp;
|
||||
}
|
||||
|
||||
mHeap = new ExpandingArray<Value*>();
|
||||
|
||||
Execute(exp->mLeft->mDecValue->mValue);
|
||||
|
@ -1174,6 +1197,26 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons
|
|||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::exp(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "sqrt"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::sqrt(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "atan"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::atan(mParams[0].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "atan2"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::atan2(mParams[0].GetFloat(), mParams[1].GetFloat()));
|
||||
}
|
||||
else if (!strcmp(iname->mString, "pow"))
|
||||
{
|
||||
mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
|
||||
mResult.PutFloat(::pow(mParams[0].GetFloat(), mParams[1].GetFloat()));
|
||||
}
|
||||
else
|
||||
mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,17 @@ DeclarationScope::~DeclarationScope(void)
|
|||
delete[] mHash;
|
||||
}
|
||||
|
||||
DeclarationScope* DeclarationScope::Clone(void) const
|
||||
{
|
||||
DeclarationScope* scope = new DeclarationScope(mParent, mLevel, mName);
|
||||
for (int i = 0; i < mHashSize; i++)
|
||||
{
|
||||
if (mHash[i].mIdent)
|
||||
scope->Insert(mHash[i].mIdent, mHash[i].mDec);
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
const Ident* DeclarationScope::Mangle(const Ident* ident) const
|
||||
{
|
||||
if (mName && ident)
|
||||
|
@ -145,7 +156,7 @@ void DeclarationScope::End(const Location& loc)
|
|||
}
|
||||
|
||||
Expression::Expression(const Location& loc, ExpressionType type)
|
||||
: mLocation(loc), mEndLocation(loc), mType(type), mLeft(nullptr), mRight(nullptr), mConst(false), mDecType(nullptr), mDecValue(nullptr), mToken(TK_NONE)
|
||||
: mLocation(loc), mEndLocation(loc), mType(type), mLeft(nullptr), mRight(nullptr), mConst(false), mDecType(nullptr), mDecValue(nullptr), mToken(TK_NONE), mFlags(0)
|
||||
{
|
||||
static uint32 gUID = 0;
|
||||
mUID = gUID++;
|
||||
|
@ -263,6 +274,9 @@ void Expression::Dump(int ident) const
|
|||
case EX_FOR:
|
||||
printf("FOR");
|
||||
break;
|
||||
case EX_FORBODY:
|
||||
printf("FORBODY");
|
||||
break;
|
||||
case EX_DO:
|
||||
printf("DO");
|
||||
break;
|
||||
|
@ -491,6 +505,15 @@ 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;
|
||||
|
@ -1021,6 +1044,20 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
ex->mDecType = dec->mBase;
|
||||
return ex;
|
||||
}
|
||||
else if (mLeft->mDecValue->mType == DT_CONST_ADDRESS && mRight->mDecValue->mType == DT_CONST_ADDRESS && mToken == TK_SUB)
|
||||
{
|
||||
if (mLeft->mDecType->mType == DT_TYPE_POINTER && mRight->mDecType->mType == DT_TYPE_POINTER &&
|
||||
mLeft->mDecType->mBase->IsConstSame(mRight->mDecType->mBase))
|
||||
{
|
||||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
|
||||
dec->mBase = TheSignedIntTypeDeclaration;
|
||||
dec->mInteger = (mLeft->mDecValue->mInteger - mRight->mDecValue->mInteger) / mLeft->mDecType->mBase->mSize;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = dec->mBase;
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if (mLeft->mDecValue->mType == DT_CONST_POINTER && mRight->mDecValue->mType == DT_CONST_INTEGER && (mToken == TK_ADD || mToken == TK_SUB))
|
||||
{
|
||||
|
@ -1156,7 +1193,7 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
return ex;
|
||||
}
|
||||
else if (mType == EX_BINARY && mToken == TK_ADD && mLeft->mType == EX_VARIABLE && mLeft->mDecValue->mType == DT_VARIABLE && (mLeft->mDecValue->mFlags & DTF_CONST) &&
|
||||
mLeft->mDecValue && mRight->mDecValue && mLeft->mDecValue->mValue->mType == EX_CONSTANT &&
|
||||
mLeft->mDecValue && mRight->mDecValue && mLeft->mDecValue->mValue && mLeft->mDecValue->mValue->mType == EX_CONSTANT &&
|
||||
mLeft->mDecType->mType == DT_TYPE_POINTER && mRight->mType == EX_CONSTANT && mRight->mDecValue->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
mLeft = mLeft->mDecValue->mValue;
|
||||
|
@ -1209,19 +1246,23 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
else if (mType == EX_INDEX && mLeft->mType == EX_VARIABLE && mLeft->mDecValue->mType == DT_VARIABLE_REF && (mLeft->mDecValue->mFlags & DTF_GLOBAL) &&
|
||||
mLeft->mDecType->mType == DT_TYPE_ARRAY && mLeft->mDecType->mStride == 0 &&
|
||||
mRight->mType == EX_CONSTANT && mRight->mDecValue->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
int offset = mLeft->mDecValue->mOffset + int(mDecType->mSize * mRight->mDecValue->mInteger);
|
||||
{
|
||||
int offset = mLeft->mDecValue->mOffset + int(mDecType->mSize * mRight->mDecValue->mInteger);
|
||||
|
||||
Expression* ex = new Expression(mLocation, EX_VARIABLE);
|
||||
Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF);
|
||||
dec->mFlags = mLeft->mDecValue->mFlags;
|
||||
dec->mBase = mLeft->mDecValue->mBase;
|
||||
dec->mOffset = offset;
|
||||
dec->mSize = mDecType->mSize;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = mDecType;
|
||||
return ex;
|
||||
}
|
||||
Expression* ex = new Expression(mLocation, EX_VARIABLE);
|
||||
Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF);
|
||||
dec->mFlags = mLeft->mDecValue->mFlags;
|
||||
dec->mBase = mLeft->mDecValue->mBase;
|
||||
dec->mOffset = offset;
|
||||
dec->mSize = mDecType->mSize;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = mDecType;
|
||||
return ex;
|
||||
}
|
||||
else if (mType == EX_VARIABLE && mDecType->IsSimpleType() && (mDecValue->mFlags & DTF_CONST) && mDecValue->mValue && mDecValue->mValue->mType == EX_INITIALIZATION && mDecValue->mValue->mRight->mType == EX_CONSTANT)
|
||||
{
|
||||
return mDecValue->mValue->mRight;
|
||||
}
|
||||
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_INTRINSIC) && mRight && mRight->mType == EX_CONSTANT)
|
||||
{
|
||||
Declaration* decf = mLeft->mDecValue, * decp = mRight->mDecValue;
|
||||
|
@ -1230,6 +1271,7 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
if (decp->mType == DT_CONST_FLOAT || decp->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
double d = decp->mType == DT_CONST_FLOAT ? decp->mNumber : decp->mInteger;
|
||||
double e = 0.0;
|
||||
|
||||
bool check = false;
|
||||
|
||||
|
@ -1249,6 +1291,10 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
d = log(d);
|
||||
else if (!strcmp(iname->mString, "exp"))
|
||||
d = exp(d);
|
||||
else if (!strcmp(iname->mString, "sqrt"))
|
||||
d = sqrt(d);
|
||||
else if (!strcmp(iname->mString, "atan"))
|
||||
d = atan(d);
|
||||
else
|
||||
return this;
|
||||
|
||||
|
@ -1261,6 +1307,36 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
|||
return ex;
|
||||
}
|
||||
}
|
||||
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_INTRINSIC) && mRight &&
|
||||
mRight->mType == EX_LIST && mRight->mLeft->mType == EX_CONSTANT && mRight->mRight->mType == EX_CONSTANT)
|
||||
{
|
||||
Declaration* decf = mLeft->mDecValue, * decp1 = mRight->mLeft->mDecValue, * decp2 = mRight->mRight->mDecValue;
|
||||
const Ident* iname = decf->mQualIdent;
|
||||
|
||||
if ((decp1->mType == DT_CONST_FLOAT || decp1->mType == DT_CONST_INTEGER) &&
|
||||
(decp2->mType == DT_CONST_FLOAT || decp2->mType == DT_CONST_INTEGER))
|
||||
{
|
||||
double d1 = decp1->mType == DT_CONST_FLOAT ? decp1->mNumber : decp1->mInteger;
|
||||
double d2 = decp2->mType == DT_CONST_FLOAT ? decp2->mNumber : decp2->mInteger;
|
||||
|
||||
bool check = false;
|
||||
|
||||
if (!strcmp(iname->mString, "pow"))
|
||||
d1 = pow(d1, d2);
|
||||
else if (!strcmp(iname->mString, "atan2"))
|
||||
d1 = atan2(d1, d2);
|
||||
else
|
||||
return this;
|
||||
|
||||
Expression* ex = new Expression(mLocation, EX_CONSTANT);
|
||||
Declaration* dec = new Declaration(mLocation, DT_CONST_FLOAT);
|
||||
dec->mBase = TheFloatTypeDeclaration;
|
||||
dec->mNumber = d1;
|
||||
ex->mDecValue = dec;
|
||||
ex->mDecType = dec->mBase;
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_CONSTEXPR) && dataSection)
|
||||
{
|
||||
ConstexprInterpreter cinter(mLocation, errors, dataSection);
|
||||
|
@ -1285,6 +1361,7 @@ Declaration::Declaration(const Location& loc, DecType type)
|
|||
mConst(nullptr), mMutable(nullptr), mVolatile(nullptr),
|
||||
mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr), mMoveConstructor(nullptr), mMoveAssignment(nullptr),
|
||||
mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr),
|
||||
mVectorMoveConstructor(nullptr), mVectorMoveAssignment(nullptr),
|
||||
mVTable(nullptr), mTemplate(nullptr), mForwardParam(nullptr), mForwardCall(nullptr),
|
||||
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mFriends(nullptr),
|
||||
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
|
||||
|
@ -1409,6 +1486,51 @@ Declaration* Declaration::ConstCast(Declaration* ntype)
|
|||
pdec->mSize = 2;
|
||||
return pdec;
|
||||
}
|
||||
else if (mType == DT_VARIABLE && mBase->mType == DT_TYPE_ARRAY)
|
||||
{
|
||||
Expression* ex = new Expression(mLocation, EX_VARIABLE);
|
||||
ex->mDecType = mBase;
|
||||
ex->mDecValue = this;
|
||||
|
||||
Declaration* pdec = this->Clone();
|
||||
pdec->mType = DT_CONST_POINTER;
|
||||
pdec->mValue = ex;
|
||||
pdec->mBase = ntype;
|
||||
pdec->mSize = 2;
|
||||
|
||||
return pdec;
|
||||
}
|
||||
else if (mType == DT_VARIABLE_REF)
|
||||
{
|
||||
Declaration* vtype = mBase->mBase;
|
||||
while (vtype && vtype->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
Declaration* dec = vtype->mParams;
|
||||
while (dec && dec->mOffset != mOffset)
|
||||
dec = dec->mNext;
|
||||
if (dec)
|
||||
vtype = dec->mBase;
|
||||
else
|
||||
vtype = nullptr;
|
||||
}
|
||||
|
||||
if (vtype && vtype->mType == DT_TYPE_ARRAY)
|
||||
{
|
||||
Expression* ex = new Expression(mLocation, EX_VARIABLE);
|
||||
ex->mDecType = mBase->mBase;
|
||||
ex->mDecValue = this;
|
||||
|
||||
Declaration* pdec = this->Clone();
|
||||
pdec->mType = DT_CONST_POINTER;
|
||||
pdec->mValue = ex;
|
||||
pdec->mBase = ntype;
|
||||
pdec->mSize = 2;
|
||||
|
||||
return pdec;
|
||||
}
|
||||
else
|
||||
return this;
|
||||
}
|
||||
else
|
||||
return this;
|
||||
}
|
||||
|
@ -1554,8 +1676,9 @@ const Ident* Declaration::FullIdent(void)
|
|||
Declaration* dec = mBase->mParams;
|
||||
while (dec)
|
||||
{
|
||||
if (dec->mBase->mIdent)
|
||||
tident = tident->Mangle(dec->mBase->MangleIdent()->mString);
|
||||
const Ident* mident = dec->mBase->MangleIdent();
|
||||
if (mident)
|
||||
tident = tident->Mangle(mident->mString);
|
||||
dec = dec->mNext;
|
||||
if (dec)
|
||||
tident = tident->Mangle(",");
|
||||
|
@ -1691,7 +1814,7 @@ const Ident* Declaration::MangleIdent(void)
|
|||
}
|
||||
|
||||
dec = dec->mNext;
|
||||
if (dec)
|
||||
if (mMangleIdent && dec)
|
||||
mMangleIdent = mMangleIdent->Mangle(",");
|
||||
}
|
||||
}
|
||||
|
@ -1708,10 +1831,13 @@ const Ident* Declaration::MangleIdent(void)
|
|||
|
||||
}
|
||||
|
||||
if (mFlags & DTF_CONST)
|
||||
mMangleIdent = mMangleIdent->PreMangle("const ");
|
||||
if (mFlags & DTF_VOLATILE)
|
||||
mMangleIdent = mMangleIdent->PreMangle("volatile ");
|
||||
if (mMangleIdent)
|
||||
{
|
||||
if (mFlags & DTF_CONST)
|
||||
mMangleIdent = mMangleIdent->PreMangle("const ");
|
||||
if (mFlags & DTF_VOLATILE)
|
||||
mMangleIdent = mMangleIdent->PreMangle("volatile ");
|
||||
}
|
||||
}
|
||||
|
||||
return mMangleIdent;
|
||||
|
@ -1823,6 +1949,9 @@ 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;
|
||||
|
@ -2055,6 +2184,21 @@ 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)
|
||||
{
|
||||
|
@ -2120,13 +2264,27 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec, bool sam
|
|||
tpdec = tpdec->mNext;
|
||||
}
|
||||
|
||||
return !fpdec && !tpdec;
|
||||
if (fpdec)
|
||||
return false;
|
||||
else if (!tpdec)
|
||||
return true;
|
||||
else if (tpdec->mBase->mType == DT_PACK_TEMPLATE)
|
||||
{
|
||||
Declaration*tppack = new Declaration(tpdec->mLocation, DT_PACK_TYPE);
|
||||
Declaration* pdec = mScope->Insert(tpdec->mBase->mIdent, tppack);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
ftdec = ftdec->mNext;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (!same && tdec->CanAssign(fdec))
|
||||
return true;
|
||||
else
|
||||
return tdec->IsSame(fdec);
|
||||
}
|
||||
|
@ -2258,6 +2416,7 @@ Declaration* Declaration::ToStriped(int stripe)
|
|||
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)
|
||||
{
|
||||
|
@ -2325,6 +2484,7 @@ Declaration* Declaration::ToVolatileType(void)
|
|||
ndec->mVectorConstructor = mVectorConstructor;
|
||||
ndec->mVectorDestructor = mVectorDestructor;
|
||||
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
|
||||
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
|
||||
ndec->mVTable = mVTable;
|
||||
|
||||
mVolatile = ndec;
|
||||
|
@ -2344,7 +2504,10 @@ Declaration* Declaration::ToConstType(void)
|
|||
ndec->mSize = mSize;
|
||||
ndec->mStride = mStride;
|
||||
ndec->mStripe = mStripe;
|
||||
ndec->mBase = mBase;
|
||||
if (mType == DT_TYPE_ARRAY)
|
||||
ndec->mBase = mBase->ToConstType();
|
||||
else
|
||||
ndec->mBase = mBase;
|
||||
ndec->mBits = mBits;
|
||||
ndec->mShift = mShift;
|
||||
ndec->mFlags = mFlags | DTF_CONST;
|
||||
|
@ -2361,6 +2524,7 @@ Declaration* Declaration::ToConstType(void)
|
|||
ndec->mVectorConstructor = mVectorConstructor;
|
||||
ndec->mVectorDestructor = mVectorDestructor;
|
||||
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
|
||||
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
|
||||
ndec->mVTable = mVTable;
|
||||
|
||||
ndec->mMutable = this;
|
||||
|
@ -2413,7 +2577,7 @@ Declaration* Declaration::ToMutableType(void)
|
|||
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;
|
||||
|
@ -2427,6 +2591,7 @@ Declaration* Declaration::ToMutableType(void)
|
|||
ndec->mVectorConstructor = mVectorConstructor;
|
||||
ndec->mVectorDestructor = mVectorDestructor;
|
||||
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
|
||||
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
|
||||
ndec->mVTable = mVTable;
|
||||
|
||||
ndec->mConst = this;
|
||||
|
@ -2756,6 +2921,9 @@ bool Declaration::IsSame(const Declaration* dec) const
|
|||
if (mType != dec->mType)
|
||||
return false;
|
||||
|
||||
if ((mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)) != (dec->mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)))
|
||||
return false;
|
||||
|
||||
if (!(mFlags & dec->mFlags & DTF_DEFINED) && mType == DT_TYPE_STRUCT)
|
||||
return mIdent == dec->mIdent;
|
||||
|
||||
|
@ -2764,9 +2932,6 @@ bool Declaration::IsSame(const Declaration* dec) const
|
|||
if (mStripe != dec->mStripe)
|
||||
return false;
|
||||
|
||||
if ((mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)) != (dec->mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)))
|
||||
return false;
|
||||
|
||||
if (mType == DT_CONST_INTEGER)
|
||||
return mInteger == dec->mInteger;
|
||||
else if (mType == DT_TYPE_INTEGER)
|
||||
|
@ -2813,7 +2978,7 @@ bool Declaration::IsSame(const Declaration* dec) const
|
|||
|
||||
return true;
|
||||
}
|
||||
else if (mType == DT_TYPE_TEMPLATE)
|
||||
else if (mType == DT_TYPE_TEMPLATE || mType == DT_PACK_TEMPLATE)
|
||||
{
|
||||
return mIdent == dec->mIdent;
|
||||
}
|
||||
|
@ -2946,7 +3111,7 @@ bool Declaration::CanAssign(const Declaration* fromType) const
|
|||
if (mScope == fromType->mScope || (mIdent == fromType->mIdent && mSize == fromType->mSize))
|
||||
return true;
|
||||
if (fromType->mBase)
|
||||
return this->CanAssign(fromType->mBase);
|
||||
return this->CanAssign(fromType->mBase->mBase);
|
||||
return false;
|
||||
}
|
||||
else if (mType == DT_TYPE_ARRAY && fromType->mType == DT_TYPE_ARRAY)
|
||||
|
@ -3013,6 +3178,52 @@ bool Declaration::IsIndexed(void) const
|
|||
return mType == DT_TYPE_ARRAY || mType == DT_TYPE_POINTER;
|
||||
}
|
||||
|
||||
bool Declaration::ContainsArray(void) const
|
||||
{
|
||||
if (mType == DT_TYPE_ARRAY)
|
||||
return true;
|
||||
else if (mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
Declaration* p = mParams;
|
||||
while (p)
|
||||
{
|
||||
if (p->mType == DT_ELEMENT && p->mBase->ContainsArray())
|
||||
return true;
|
||||
p = p->mNext;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Declaration::IsShortIntStruct(void) const
|
||||
{
|
||||
if (mType == DT_TYPE_STRUCT && mSize <= 4 && !mDestructor && !mCopyConstructor)
|
||||
{
|
||||
Declaration* em = mParams;
|
||||
while (em)
|
||||
{
|
||||
if (em->mType == DT_ELEMENT && em->mBase->IsIntegerType() && em->mBits == 0)
|
||||
em = em->mNext;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (strcmp(mIdent->mString, "connection")) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Declaration::HasConstructor(void) const
|
||||
{
|
||||
return mType == DT_TYPE_STRUCT && mScope && mScope->Lookup(mIdent->PreMangle("+"));
|
||||
}
|
||||
|
||||
bool Declaration::IsComplexStruct(void) const
|
||||
{
|
||||
return mType == DT_TYPE_STRUCT && !IsShortIntStruct();
|
||||
}
|
||||
|
||||
bool Declaration::IsSimpleType(void) const
|
||||
{
|
||||
|
@ -3032,6 +3243,7 @@ Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
|
|||
Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration;
|
||||
Expression* TheVoidExpression;
|
||||
Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration;
|
||||
Declaration* TheTrueConstDeclaration, * TheFalseConstDeclaration;
|
||||
|
||||
void InitDeclarations(void)
|
||||
{
|
||||
|
@ -3133,4 +3345,13 @@ void InitDeclarations(void)
|
|||
TheZeroFloatConstDeclaration->mBase = TheFloatTypeDeclaration;
|
||||
TheZeroFloatConstDeclaration->mSize = 4;
|
||||
|
||||
TheTrueConstDeclaration = new Declaration(noloc, DT_CONST_INTEGER);
|
||||
TheTrueConstDeclaration->mBase = TheBoolTypeDeclaration;
|
||||
TheTrueConstDeclaration->mSize = 1;
|
||||
TheTrueConstDeclaration->mInteger = 1;
|
||||
|
||||
TheFalseConstDeclaration = new Declaration(noloc, DT_CONST_INTEGER);
|
||||
TheFalseConstDeclaration->mBase = TheBoolTypeDeclaration;
|
||||
TheFalseConstDeclaration->mSize = 1;
|
||||
TheFalseConstDeclaration->mInteger = 0;
|
||||
}
|
||||
|
|
|
@ -127,6 +127,7 @@ 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);
|
||||
|
||||
|
||||
|
||||
|
@ -166,6 +167,8 @@ public:
|
|||
ScopeLevel mLevel;
|
||||
const Ident * mName;
|
||||
|
||||
DeclarationScope* Clone(void) const;
|
||||
|
||||
DeclarationScope* mParent;
|
||||
protected:
|
||||
struct Entry
|
||||
|
@ -215,6 +218,7 @@ enum ExpressionType
|
|||
EX_IF,
|
||||
EX_ELSE,
|
||||
EX_FOR,
|
||||
EX_FORBODY,
|
||||
EX_DO,
|
||||
EX_SCOPE,
|
||||
EX_BREAK,
|
||||
|
@ -242,6 +246,12 @@ 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:
|
||||
|
@ -258,6 +268,7 @@ public:
|
|||
AsmInsType mAsmInsType;
|
||||
AsmInsMode mAsmInsMode;
|
||||
bool mConst;
|
||||
uint32 mFlags;
|
||||
|
||||
Expression* LogicInvertExpression(void);
|
||||
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr);
|
||||
|
@ -266,6 +277,8 @@ public:
|
|||
Expression* ListAppend(Expression* lexp);
|
||||
Expression* ToAlternateThis(Declaration* pthis, Declaration* nthis);
|
||||
|
||||
void ReplaceVariable(Declaration* pvar, Declaration* nvar);
|
||||
|
||||
bool IsSame(const Expression* exp) const;
|
||||
bool IsRValue(void) const;
|
||||
bool IsLValue(void) const;
|
||||
|
@ -289,7 +302,7 @@ public:
|
|||
Token mToken;
|
||||
Declaration * mBase, * mParams, * mParamPack, * mNext, * mPrev, * mConst, * mMutable, * mVolatile;
|
||||
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment;
|
||||
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
|
||||
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment, * mVectorMoveConstructor, * mVectorMoveAssignment;
|
||||
Declaration * mVTable, * mClass, * mTemplate;
|
||||
Declaration * mForwardParam, * mForwardCall;
|
||||
|
||||
|
@ -331,6 +344,10 @@ 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);
|
||||
|
||||
|
@ -381,5 +398,6 @@ extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoid
|
|||
extern Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
|
||||
extern Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration;
|
||||
extern Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration;
|
||||
extern Declaration* TheTrueConstDeclaration, * TheFalseConstDeclaration;
|
||||
extern Expression* TheVoidExpression;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "NumberSet.h"
|
||||
|
||||
|
||||
class Location
|
||||
{
|
||||
public:
|
||||
|
@ -12,7 +13,11 @@ public:
|
|||
Location() : mFileName(nullptr), mLine(0), mColumn(0), mFrom(nullptr) {}
|
||||
Location(const Location& loc, const Location* from)
|
||||
: mFileName(loc.mFileName), mLine(loc.mLine), mColumn(loc.mColumn), mFrom(from)
|
||||
{}
|
||||
{
|
||||
static volatile int k;
|
||||
if (from)
|
||||
k = from->mLine;
|
||||
}
|
||||
};
|
||||
|
||||
class Ident;
|
||||
|
@ -122,6 +127,8 @@ 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,
|
||||
|
|
|
@ -481,7 +481,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
fplimit += 256;
|
||||
}
|
||||
|
||||
if (procDec->mBase->mBase->mType == DT_TYPE_STRUCT)
|
||||
if (procDec->mBase->mBase->IsComplexStruct())
|
||||
{
|
||||
if (nbase < numfpzero && nbase + 2 > numfpzero)
|
||||
nbase = numfpzero;
|
||||
|
@ -665,7 +665,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
|
|||
if (mCompilerOptions & COPT_OPTIMIZE_CONST_EXPRESSIONS)
|
||||
dec->mFlags |= DTF_FUNC_CONSTEXPR;
|
||||
dec->mFlags |= DTF_FUNC_PURE;
|
||||
Analyze(exp, dec, false, false);
|
||||
Analyze(exp, dec, 0);
|
||||
|
||||
Declaration* pdec = dec->mBase->mParams;
|
||||
int vi = 0;
|
||||
|
@ -685,7 +685,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
|
|||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent);
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->FullIdent());
|
||||
if (cexp)
|
||||
mErrors->Error(cexp->mLocation, EINFO_CALLED_FROM, "Called from here");
|
||||
|
||||
|
@ -761,7 +761,7 @@ void GlobalAnalyzer::AnalyzeGlobalVariable(Declaration* dec)
|
|||
|
||||
if (dec->mValue)
|
||||
{
|
||||
Analyze(dec->mValue, dec, false, false);
|
||||
Analyze(dec->mValue, dec, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -771,17 +771,19 @@ void GlobalAnalyzer::AnalyzeInit(Declaration* mdec)
|
|||
while (mdec)
|
||||
{
|
||||
if (mdec->mValue)
|
||||
RegisterProc(Analyze(mdec->mValue, mdec, false, false));
|
||||
RegisterProc(Analyze(mdec->mValue, mdec, 0));
|
||||
else if (mdec->mParams)
|
||||
AnalyzeInit(mdec->mParams);
|
||||
mdec = mdec->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, bool lhs, bool aliasing)
|
||||
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, uint32 flags)
|
||||
{
|
||||
Declaration* ldec, * rdec;
|
||||
|
||||
exp->mFlags = flags;
|
||||
|
||||
switch (exp->mType)
|
||||
{
|
||||
case EX_ERROR:
|
||||
|
@ -799,7 +801,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
}
|
||||
else if (exp->mDecValue->mType == DT_CONST_POINTER)
|
||||
{
|
||||
ldec = Analyze(exp->mDecValue->mValue, procDec, true, true);
|
||||
ldec = Analyze(exp->mDecValue->mValue, procDec, ANAFL_LHS | ANAFL_ALIAS);
|
||||
if (ldec->mType == DT_VARIABLE)
|
||||
ldec->mFlags |= DTF_VAR_ALIASING;
|
||||
RegisterProc(ldec);
|
||||
|
@ -823,7 +825,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (mCompilerOptions & COPT_DEBUGINFO)
|
||||
exp->mDecValue->mReferences.Push(exp);
|
||||
|
||||
if (aliasing)
|
||||
if (flags & ANAFL_ALIAS)
|
||||
{
|
||||
Declaration* dec = exp->mDecValue;
|
||||
while (dec->mType == DT_VARIABLE_REF)
|
||||
|
@ -840,14 +842,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (!(type->mFlags & DTF_CONST))
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
procDec->mFlags &= ~DTF_FUNC_PURE;
|
||||
|
||||
AnalyzeGlobalVariable(exp->mDecValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
exp->mDecValue->mFlags |= DTF_VAR_ADDRESS;
|
||||
|
||||
if (!(exp->mDecValue->mFlags & DTF_ANALYZED))
|
||||
|
@ -861,8 +863,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_ASSIGNMENT:
|
||||
procDec->mComplexity += 5 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, true, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
|
||||
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
|
||||
if (exp->mLeft->mType == EX_VARIABLE && exp->mRight->mType == EX_CALL && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
|
||||
exp->mLeft->mDecValue->mFlags |= DTF_VAR_ALIASING;
|
||||
RegisterProc(rdec);
|
||||
|
@ -871,33 +873,33 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_BINARY:
|
||||
procDec->mComplexity += 10 * exp->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, lhs, false);
|
||||
rdec = Analyze(exp->mRight, procDec, lhs, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
rdec = Analyze(exp->mRight, procDec, flags & ~ANAFL_ALIAS);
|
||||
return ldec;
|
||||
|
||||
case EX_RELATIONAL:
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_RHS);
|
||||
rdec = Analyze(exp->mRight, procDec, ANAFL_RHS);
|
||||
return TheBoolTypeDeclaration;
|
||||
|
||||
case EX_PREINCDEC:
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
return Analyze(exp->mLeft, procDec, true, false);
|
||||
return Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
|
||||
case EX_PREFIX:
|
||||
if (exp->mToken == TK_BINARY_AND)
|
||||
{
|
||||
ldec = Analyze(exp->mLeft, procDec, true, true);
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_ALIAS);
|
||||
if (ldec->mType == DT_VARIABLE)
|
||||
ldec->mFlags |= DTF_VAR_ALIASING;
|
||||
}
|
||||
else if (exp->mToken == TK_MUL)
|
||||
{
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
procDec->mFlags &= ~DTF_FUNC_PURE;
|
||||
|
||||
return exp->mDecType;
|
||||
|
@ -913,7 +915,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
else
|
||||
{
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
return Analyze(exp->mLeft, procDec, false, false);
|
||||
return Analyze(exp->mLeft, procDec, 0);
|
||||
}
|
||||
break;
|
||||
case EX_POSTFIX:
|
||||
|
@ -922,31 +924,31 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_POSTINCDEC:
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
|
||||
return Analyze(exp->mLeft, procDec, true, false);
|
||||
return Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS);
|
||||
case EX_INDEX:
|
||||
procDec->mComplexity += 10 * exp->mRight->mDecType->mSize;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, lhs, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT)
|
||||
{
|
||||
ldec = ldec->mBase;
|
||||
if (ldec->mType == DT_TYPE_POINTER)
|
||||
{
|
||||
if (lhs)
|
||||
if (flags & ANAFL_LHS)
|
||||
procDec->mFlags &= ~DTF_FUNC_PURE;
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
}
|
||||
}
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
if (ldec->mBase)
|
||||
return ldec->mBase;
|
||||
break;
|
||||
case EX_QUALIFY:
|
||||
Analyze(exp->mLeft, procDec, lhs, aliasing);
|
||||
Analyze(exp->mLeft, procDec, flags);
|
||||
return exp->mDecValue->mBase;
|
||||
case EX_DISPATCH:
|
||||
procDec->mFlags |= DTF_PREVENT_INLINE;
|
||||
Analyze(exp->mLeft, procDec, lhs, false);
|
||||
Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
// RegisterCall(procDec, exp->mLeft->mDecType);
|
||||
break;
|
||||
case EX_VCALL:
|
||||
|
@ -957,7 +959,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_INLINE:
|
||||
procDec->mComplexity += 10;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue)
|
||||
{
|
||||
|
||||
|
@ -1044,7 +1046,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (pex->mType == EX_CALL && IsStackParam(pex->mDecType) && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)))
|
||||
ldec->mBase->mFlags |= DTF_STACKCALL;
|
||||
|
||||
RegisterProc(Analyze(pex, procDec, pdec && pdec->mBase->IsReference(), false));
|
||||
RegisterProc(Analyze(pex, procDec, (pdec && pdec->mBase->IsReference()) ? ANAFL_LHS : 0));
|
||||
|
||||
if (pdec)
|
||||
pdec = pdec->mNext;
|
||||
|
@ -1058,12 +1060,12 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
break;
|
||||
case EX_LIST:
|
||||
case EX_COMMA:
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, false, false));
|
||||
return Analyze(exp->mRight, procDec, false, false);
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, 0));
|
||||
return Analyze(exp->mRight, procDec, 0);
|
||||
case EX_RETURN:
|
||||
if (exp->mLeft)
|
||||
{
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference(), false));
|
||||
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference() ? ANAFL_LHS : 0));
|
||||
if (procDec->mBase->mBase && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
|
||||
{
|
||||
if (procDec->mBase->mBase->mMoveConstructor)
|
||||
|
@ -1084,47 +1086,47 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
if (exp->mType == EX_SEQUENCE)
|
||||
{
|
||||
if (exp->mLeft)
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
exp = exp->mRight;
|
||||
}
|
||||
else
|
||||
return Analyze(exp, procDec, false, false);
|
||||
return Analyze(exp, procDec, 0);
|
||||
|
||||
} while (exp);
|
||||
break;
|
||||
|
||||
case EX_SCOPE:
|
||||
Analyze(exp->mLeft, procDec, false, false);
|
||||
Analyze(exp->mLeft, procDec, 0);
|
||||
break;
|
||||
|
||||
case EX_CONSTRUCT:
|
||||
if (exp->mLeft->mLeft)
|
||||
Analyze(exp->mLeft->mLeft, procDec, false, false);
|
||||
Analyze(exp->mLeft->mLeft, procDec, 0);
|
||||
if (exp->mLeft->mRight)
|
||||
Analyze(exp->mLeft->mRight, procDec, false, false);
|
||||
Analyze(exp->mLeft->mRight, procDec, 0);
|
||||
if (exp->mRight)
|
||||
return Analyze(exp->mRight, procDec, false, false);
|
||||
return Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
|
||||
case EX_CLEANUP:
|
||||
Analyze(exp->mRight, procDec, false, false);
|
||||
return Analyze(exp->mLeft, procDec, lhs, false);
|
||||
Analyze(exp->mRight, procDec, 0);
|
||||
return Analyze(exp->mLeft, procDec, flags & ~ANAFL_ALIAS);
|
||||
|
||||
case EX_WHILE:
|
||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||
|
||||
procDec->mComplexity += 20;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_IF:
|
||||
procDec->mComplexity += 20;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight->mLeft, procDec, 0);
|
||||
if (exp->mRight->mRight)
|
||||
rdec = Analyze(exp->mRight->mRight, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_ELSE:
|
||||
break;
|
||||
|
@ -1134,18 +1136,23 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
procDec->mComplexity += 30;
|
||||
|
||||
if (exp->mLeft->mRight)
|
||||
ldec = Analyze(exp->mLeft->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft->mRight, procDec, 0);
|
||||
if (exp->mLeft->mLeft->mLeft)
|
||||
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
if (exp->mLeft->mLeft->mRight)
|
||||
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_FORBODY:
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
if (exp->mRight)
|
||||
Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_DO:
|
||||
procDec->mComplexity += 20;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_BREAK:
|
||||
case EX_CONTINUE:
|
||||
|
@ -1154,18 +1161,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_TYPE:
|
||||
break;
|
||||
case EX_TYPECAST:
|
||||
return Analyze(exp->mLeft, procDec, false, false);
|
||||
return Analyze(exp->mLeft, procDec, 0);
|
||||
break;
|
||||
case EX_LOGICAL_AND:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_LOGICAL_OR:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
rdec = Analyze(exp->mRight, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
rdec = Analyze(exp->mRight, procDec, 0);
|
||||
break;
|
||||
case EX_LOGICAL_NOT:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
break;
|
||||
case EX_ASSEMBLER:
|
||||
procDec->mFlags |= DTF_FUNC_ASSEMBLER;
|
||||
|
@ -1176,14 +1183,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_UNDEFINED:
|
||||
break;
|
||||
case EX_SWITCH:
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
exp = exp->mRight;
|
||||
while (exp)
|
||||
{
|
||||
procDec->mComplexity += 10;
|
||||
|
||||
if (exp->mLeft->mRight)
|
||||
rdec = Analyze(exp->mLeft->mRight, procDec, false, false);
|
||||
rdec = Analyze(exp->mLeft->mRight, procDec, 0);
|
||||
exp = exp->mRight;
|
||||
}
|
||||
break;
|
||||
|
@ -1194,9 +1201,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
case EX_CONDITIONAL:
|
||||
procDec->mComplexity += exp->mDecType->mSize * 10;
|
||||
|
||||
ldec = Analyze(exp->mLeft, procDec, false, false);
|
||||
RegisterProc(Analyze(exp->mRight->mLeft, procDec, lhs, aliasing));
|
||||
RegisterProc(Analyze(exp->mRight->mRight, procDec, lhs, aliasing));
|
||||
ldec = Analyze(exp->mLeft, procDec, 0);
|
||||
RegisterProc(Analyze(exp->mRight->mLeft, procDec, flags));
|
||||
RegisterProc(Analyze(exp->mRight->mRight, procDec, flags));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ protected:
|
|||
int CallerInvokes(Declaration* called);
|
||||
int CallerInvokes(Declaration* caller, Declaration* called);
|
||||
|
||||
Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs, bool aliasing);
|
||||
Declaration* Analyze(Expression* exp, Declaration* procDec, uint32 flags);
|
||||
|
||||
bool IsStackParam(const Declaration* pdec) const;
|
||||
bool MarkCycle(Declaration* rootDec, Declaration* procDec);
|
||||
|
|
|
@ -275,14 +275,22 @@ bool GlobalOptimizer::ReplaceGlobalConst(Expression* exp)
|
|||
{
|
||||
if (exp->mType == EX_VARIABLE && (exp->mDecValue->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(exp->mDecValue->mOptFlags & (OPTF_VAR_MODIFIED | OPTF_VAR_ADDRESS)) && exp->mDecValue->mValue)
|
||||
{
|
||||
|
||||
Expression* cexp = exp->mDecValue->mValue;
|
||||
if (cexp->mType == EX_CONSTANT &&
|
||||
(cexp->mDecValue->mType == DT_CONST_ADDRESS || cexp->mDecValue->mType == DT_CONST_INTEGER ||
|
||||
cexp->mDecValue->mType == DT_CONST_POINTER || cexp->mDecValue->mType == DT_CONST_FLOAT))
|
||||
if (cexp->mType == EX_CONSTANT)
|
||||
{
|
||||
exp->mType = EX_CONSTANT;
|
||||
exp->mDecValue = cexp->mDecValue->ConstCast(exp->mDecType);
|
||||
changed = true;
|
||||
|
||||
if (cexp->mDecValue->mType == DT_CONST_ADDRESS || cexp->mDecValue->mType == DT_CONST_INTEGER ||
|
||||
cexp->mDecValue->mType == DT_CONST_POINTER || cexp->mDecValue->mType == DT_CONST_FLOAT)
|
||||
{
|
||||
exp->mType = EX_CONSTANT;
|
||||
exp->mDecValue = cexp->mDecValue->ConstCast(exp->mDecType);
|
||||
changed = true;
|
||||
}
|
||||
else if (exp->mDecValue->mBase->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
exp->mDecValue->mBase = exp->mDecValue->mBase->ToConstType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,7 +341,7 @@ bool GlobalOptimizer::Optimize(void)
|
|||
|
||||
if (!(func->mOptFlags & OPTF_FUNC_VARIABLE) && !(func->mBase->mFlags & DTF_VIRTUAL))
|
||||
{
|
||||
if (!(func->mOptFlags & OPTF_VAR_USED) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
|
||||
if (!(func->mOptFlags & (OPTF_VAR_USED | OPTF_VAR_ADDRESS)) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
|
||||
{
|
||||
#if DUMP_OPTS
|
||||
printf("Remove return value\n");
|
||||
|
@ -454,7 +462,7 @@ void GlobalOptimizer::AnalyzeProcedure(Expression* exp, Declaration* procDec)
|
|||
Analyze(exp, procDec, false);
|
||||
}
|
||||
else
|
||||
mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->mQualIdent);
|
||||
mErrors->Error(procDec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", procDec->FullIdent());
|
||||
|
||||
procDec->mOptFlags &= ~OPTF_ANALYZING;
|
||||
}
|
||||
|
@ -606,9 +614,6 @@ void GlobalOptimizer::RegisterProc(Declaration* to)
|
|||
}
|
||||
}
|
||||
|
||||
static const uint32 ANAFL_LHS = (1U << 0);
|
||||
static const uint32 ANAFL_RHS = (1U << 1);
|
||||
|
||||
Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uint32 flags)
|
||||
{
|
||||
Declaration* ldec, * rdec;
|
||||
|
@ -654,6 +659,8 @@ 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))
|
||||
{
|
||||
|
@ -665,7 +672,12 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
case EX_INITIALIZATION:
|
||||
case EX_ASSIGNMENT:
|
||||
if (exp->mToken == TK_ASSIGN)
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
|
||||
{
|
||||
if (exp->mType == EX_ASSIGNMENT)
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_ASSIGN | flags);
|
||||
else
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | flags);
|
||||
}
|
||||
else
|
||||
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS | flags);
|
||||
|
||||
|
@ -813,6 +825,22 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
pdec->mOptFlags |= OPTF_VAR_CONST;
|
||||
}
|
||||
}
|
||||
else if (pex->mType == EX_VARIABLE && pdec->mBase->mType == DT_TYPE_POINTER && pex->mDecType->mType == DT_TYPE_ARRAY && (pex->mDecValue->mFlags & (DTF_GLOBAL | DTF_STATIC)) && pdec->mBase->CanAssign(pex->mDecType))
|
||||
{
|
||||
if (pdec->mOptFlags & OPTF_VAR_CONST)
|
||||
{
|
||||
if (pdec->mValue->mType != EX_VARIABLE || pdec->mValue->mDecValue != pex->mDecValue)
|
||||
{
|
||||
pdec->mOptFlags |= OPTF_VAR_NOCONST;
|
||||
pdec->mOptFlags &= ~OPTF_VAR_CONST;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pdec->mValue = pex;
|
||||
pdec->mOptFlags |= OPTF_VAR_CONST;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pdec->mOptFlags |= OPTF_VAR_NOCONST;
|
||||
|
@ -958,6 +986,11 @@ 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);
|
||||
|
|
|
@ -47,7 +47,7 @@ const Ident* Ident::Unique(const char* str)
|
|||
|
||||
const Ident* Ident::PreMangle(const char* str) const
|
||||
{
|
||||
char buffer[200];
|
||||
char buffer[1000];
|
||||
strcpy_s(buffer, str);
|
||||
strcat_s(buffer, mString);
|
||||
return Unique(buffer);
|
||||
|
@ -55,14 +55,14 @@ const Ident* Ident::PreMangle(const char* str) const
|
|||
|
||||
const Ident* Ident::Unique(const char* str, int id)
|
||||
{
|
||||
char buffer[200];
|
||||
char buffer[1000];
|
||||
sprintf_s(buffer, "%s#%d", str, id);
|
||||
return Unique(buffer);
|
||||
}
|
||||
|
||||
const Ident* Ident::Mangle(const char* str) const
|
||||
{
|
||||
char buffer[200];
|
||||
char buffer[1000];
|
||||
strcpy_s(buffer, mString);
|
||||
strcat_s(buffer, str);
|
||||
return Unique(buffer);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -169,6 +169,7 @@ public:
|
|||
} mMinState, mMaxState;
|
||||
|
||||
bool Same(const IntegerValueRange& range) const;
|
||||
bool Weaker(const IntegerValueRange& range) const;
|
||||
bool Merge(const IntegerValueRange& range, bool head, bool initial);
|
||||
void Expand(const IntegerValueRange& range);
|
||||
void Union(const IntegerValueRange& range);
|
||||
|
@ -380,7 +381,7 @@ public:
|
|||
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator;
|
||||
GrowingInstructionArray mInstructions;
|
||||
|
||||
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath, mValueRangeValid;
|
||||
bool mVisited, mInPath, mLoopHead, mChecked, mConditionBlockTrue, mUnreachable, mLoopPath, mValueRangeValid, mPatched, mLoopDebug;
|
||||
mutable int mMark;
|
||||
|
||||
NumberSet mLocalUsedTemps, mLocalModifiedTemps;
|
||||
|
@ -431,6 +432,7 @@ public:
|
|||
void CollectEntryBlocks(InterCodeBasicBlock* from);
|
||||
void GenerateTraces(int expand, bool compact);
|
||||
void BuildDominatorTree(InterCodeBasicBlock * from);
|
||||
bool StripLoopHead(void);
|
||||
|
||||
bool MergeSameConditionTraces(void);
|
||||
|
||||
|
@ -448,6 +450,7 @@ public:
|
|||
void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps);
|
||||
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
|
||||
bool ForwardConstTemps(const GrowingInstructionPtrArray& ctemps);
|
||||
bool PropagateConstCompareResults(void);
|
||||
|
||||
bool EarlyBranchElimination(const GrowingInstructionPtrArray& ctemps);
|
||||
|
||||
|
@ -517,6 +520,8 @@ public:
|
|||
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars, const GrowingInterCodeProcedurePtrArray& staticProcs, FastNumberSet& fsingle);
|
||||
bool EliminateDeadBranches(void);
|
||||
|
||||
bool EliminateIntegerSumAliasTemps(const GrowingInstructionPtrArray& tvalue);
|
||||
|
||||
bool MergeIndexedLoadStore(const GrowingInstructionPtrArray& tvalue);
|
||||
bool SimplifyIntegerNumeric(const GrowingInstructionPtrArray& tvalue, int& spareTemps);
|
||||
bool SimplifyPointerOffsets(void);
|
||||
|
@ -636,14 +641,20 @@ public:
|
|||
void PushMoveOutOfLoop(void);
|
||||
bool MoveConditionOutOfLoop(void);
|
||||
void SingleLoopCountZeroCheck(void);
|
||||
void InnerLoopCountZeroCheck(void);
|
||||
bool PostDecLoopOptimization(void);
|
||||
bool Flatten2DLoop(void);
|
||||
|
||||
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue);
|
||||
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue, bool loops);
|
||||
void RemoveUnusedMallocs(void);
|
||||
|
||||
bool PullStoreUpToConstAddress(void);
|
||||
|
||||
bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray<InterCodeBasicBlock*>& body);
|
||||
bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, ExpandingArray<InterCodeBasicBlock*>& body);
|
||||
|
||||
bool CollectGenericLoop(ExpandingArray<InterCodeBasicBlock*>& lblocks);
|
||||
bool CollectSingleEntryGenericLoop(ExpandingArray<InterCodeBasicBlock*>& lblocks);
|
||||
void CollectReachable(ExpandingArray<InterCodeBasicBlock*>& lblock);
|
||||
|
||||
bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
|
||||
bool MergeLoopTails(void);
|
||||
|
@ -651,6 +662,7 @@ public:
|
|||
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);
|
||||
|
@ -701,6 +713,7 @@ protected:
|
|||
GrowingIntegerValueRangeArray mLocalValueRange, mReverseValueRange;
|
||||
|
||||
void ResetVisited(void);
|
||||
void ResetPatched(void);
|
||||
void ResetEntryBlocks(void);
|
||||
public:
|
||||
InterCodeBasicBlock * mEntryBlock;
|
||||
|
@ -785,6 +798,7 @@ protected:
|
|||
void SingleBlockLoopPointerToByte(FastNumberSet& activeSet);
|
||||
void SingleBlockLoopSinking(FastNumberSet& activeSet);
|
||||
void MergeIndexedLoadStore(void);
|
||||
void EliminateIntegerSumAliasTemps(void);
|
||||
void EliminateAliasValues();
|
||||
void LoadStoreForwarding(InterMemory paramMemory);
|
||||
void ReduceRecursionTempSpilling(InterMemory paramMemory);
|
||||
|
@ -804,7 +818,7 @@ protected:
|
|||
void CheckUsedDefinedTemps(void);
|
||||
void WarnUsedUndefinedVariables(void);
|
||||
void WarnInvalidValueRanges(void);
|
||||
void PropagateMemoryAliasingInfo(void);
|
||||
void PropagateMemoryAliasingInfo(bool loops);
|
||||
void MoveConditionsOutOfLoop(void);
|
||||
void ShortcutConstBranches(void);
|
||||
void ShortcutDuplicateBranches(void);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
InterCodeGenerator::InterCodeGenerator(Errors* errors, Linker* linker)
|
||||
: mErrors(errors), mLinker(linker), mCompilerOptions(COPT_DEFAULT)
|
||||
{
|
||||
|
||||
mMainInitBlock = nullptr;
|
||||
}
|
||||
|
||||
InterCodeGenerator::~InterCodeGenerator(void)
|
||||
|
@ -12,6 +12,16 @@ InterCodeGenerator::~InterCodeGenerator(void)
|
|||
|
||||
}
|
||||
|
||||
static inline InterType InterTypeOfSize(int size)
|
||||
{
|
||||
if (size <= 1)
|
||||
return IT_INT8;
|
||||
else if (size <= 2)
|
||||
return IT_INT16;
|
||||
else
|
||||
return IT_INT32;
|
||||
}
|
||||
|
||||
static inline InterType InterTypeOf(const Declaration* dec)
|
||||
{
|
||||
switch (dec->mType)
|
||||
|
@ -51,7 +61,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::ToValue(InterCodeProcedure* proc
|
|||
return v;
|
||||
}
|
||||
|
||||
InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, int level)
|
||||
InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, int level, int limit)
|
||||
{
|
||||
while (v.mReference > level)
|
||||
{
|
||||
|
@ -72,10 +82,18 @@ InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure*
|
|||
ins->mSrc[0].mStride = v.mReference == 1 ? v.mType->mStripe : 1;
|
||||
|
||||
|
||||
if (v.mReference == 1 && v.mType->mType == DT_TYPE_ENUM && !v.mBits)
|
||||
if (v.mReference == 1)
|
||||
{
|
||||
ins->mDst.mRange.LimitMin(v.mType->mMinValue);
|
||||
ins->mDst.mRange.LimitMax(v.mType->mMaxValue);
|
||||
if (v.mType->mType == DT_TYPE_ENUM && !v.mBits)
|
||||
{
|
||||
ins->mDst.mRange.LimitMin(v.mType->mMinValue);
|
||||
ins->mDst.mRange.LimitMax(v.mType->mMaxValue);
|
||||
}
|
||||
else if (v.mType->mType == DT_TYPE_INTEGER && !v.mBits && limit > 0)
|
||||
{
|
||||
ins->mDst.mRange.LimitMin(0);
|
||||
ins->mDst.mRange.LimitMax(limit - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (v.mType->mFlags & DTF_VOLATILE)
|
||||
|
@ -782,6 +800,16 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
|
|||
var->mLinkerObject->mFlags |= LOBJF_CONST;
|
||||
if (dec->mFlags & DTF_ZEROPAGE)
|
||||
var->mLinkerObject->mFlags |= LOBJF_ZEROPAGE;
|
||||
if (dec->mFlags & DTF_NO_PAGE_CROSS)
|
||||
var->mLinkerObject->mFlags |= LOBJF_NEVER_CROSS | LOBJF_NO_CROSS;
|
||||
if (mCompilerOptions & COPT_OPTIMIZE_PAGE_CROSSING)
|
||||
{
|
||||
if (dec->mSize <= 256 && dec->mSize > 1)
|
||||
{
|
||||
if (dec->mBase->ContainsArray())
|
||||
var->mLinkerObject->mFlags |= LOBJF_NEVER_CROSS | LOBJF_NO_CROSS;
|
||||
}
|
||||
}
|
||||
|
||||
var->mIndex = mod->mGlobalVars.Size();
|
||||
var->mDeclaration = dec;
|
||||
|
@ -875,7 +903,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Declaration *
|
|||
cexp = cexp->mRight;
|
||||
}
|
||||
|
||||
// Check if remapping of lables due to operand address size change
|
||||
// Check if remapping of labels due to operand address size change
|
||||
if (osize != rsize)
|
||||
{
|
||||
adec->mBase->mScope->Iterate([=](const Ident* ident, Declaration* dec) {
|
||||
|
@ -1641,7 +1669,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
|||
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an addressable expression");
|
||||
|
||||
if (vp.mTemp != vr.mTemp)
|
||||
CopyStructSimple(proc, exp, block, inlineMapper, vp, vr);
|
||||
CopyStruct(proc, exp, block, vp, vr, inlineMapper, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1652,12 +1680,15 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
|||
else if (vr.mType->IsReference() && !(pdec && pdec->mBase->IsReference()))
|
||||
{
|
||||
vr.mReference++;
|
||||
vr.mType = vr.mType->mBase;
|
||||
vr = Dereference(proc, texp, block, inlineMapper, vr);
|
||||
}
|
||||
else
|
||||
vr = Dereference(proc, texp, block, inlineMapper, vr);
|
||||
|
||||
if (pdec)
|
||||
if (pdec && (pdec->mFlags & DTF_FPARAM_UNUSED) && vr.mType->mType == DT_TYPE_VOID)
|
||||
;
|
||||
else if (pdec)
|
||||
{
|
||||
if (pdec->mBase->mType == DT_TYPE_POINTER && vr.mType->mType == DT_TYPE_INTEGER)
|
||||
{
|
||||
|
@ -1911,6 +1942,7 @@ void InterCodeGenerator::CopyStruct(InterCodeProcedure* proc, Expression* exp, I
|
|||
nmapper.mReturn = new InterCodeBasicBlock(proc);
|
||||
nmapper.mVarIndex = proc->mNumLocals;
|
||||
nmapper.mConstExpr = false;
|
||||
nmapper.mLocation = new Location(MapLocation(exp, inlineMapper));
|
||||
proc->mNumLocals += ccdec->mNumVars;
|
||||
if (inlineMapper)
|
||||
nmapper.mDepth = inlineMapper->mDepth + 1;
|
||||
|
@ -2199,13 +2231,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (dec->mBase->mFlags & DTF_SIGNED)
|
||||
{
|
||||
if (dec->mInteger < -128 || dec->mInteger > 127)
|
||||
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
|
||||
mErrors->Error(exp->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
|
||||
ins->mConst.mIntConst = int8(dec->mInteger);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dec->mInteger < 0 || dec->mInteger > 255)
|
||||
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated");
|
||||
mErrors->Error(exp->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated");
|
||||
ins->mConst.mIntConst = uint8(dec->mInteger);
|
||||
}
|
||||
}
|
||||
|
@ -2214,13 +2246,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (dec->mBase->mFlags & DTF_SIGNED)
|
||||
{
|
||||
if (dec->mInteger < -32768 || dec->mInteger > 32767)
|
||||
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
|
||||
mErrors->Error(exp->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
|
||||
ins->mConst.mIntConst = int16(dec->mInteger);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dec->mInteger < 0 || dec->mInteger > 65535)
|
||||
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated");
|
||||
mErrors->Error(exp->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated");
|
||||
ins->mConst.mIntConst = uint16(dec->mInteger);
|
||||
}
|
||||
}
|
||||
|
@ -2229,13 +2261,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (dec->mBase->mFlags & DTF_SIGNED)
|
||||
{
|
||||
if (dec->mInteger < -2147483648LL || dec->mInteger > 2147483647LL)
|
||||
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
|
||||
mErrors->Error(exp->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
|
||||
ins->mConst.mIntConst = int32(dec->mInteger);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dec->mInteger < 0 || dec->mInteger > 4294967296LL)
|
||||
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated");
|
||||
mErrors->Error(exp->mLocation, EWARN_CONSTANT_TRUNCATED, "Unsigned integer constant truncated");
|
||||
ins->mConst.mIntConst = uint32(dec->mInteger);
|
||||
}
|
||||
}
|
||||
|
@ -2696,6 +2728,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
else
|
||||
{
|
||||
Declaration * otype = vll.mType;
|
||||
if (vll.mType->mType == DT_TYPE_BOOL && vr.mType->mType == DT_TYPE_BOOL)
|
||||
otype = TheUnsignedCharTypeDeclaration;
|
||||
|
||||
#if 1
|
||||
if ((exp->mRight->mType != EX_CONSTANT || (exp->mToken != TK_ASSIGN_ADD && exp->mToken != TK_ASSIGN_SUB && exp->mToken != TK_ASSIGN_AND && exp->mToken != TK_ASSIGN_OR)) && otype->mSize < 2)
|
||||
#else
|
||||
|
@ -2808,6 +2843,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
|
||||
vl = Dereference(proc, exp, block, inlineMapper, vl, vl.mType->mType == DT_TYPE_POINTER ? 0 : 1);
|
||||
|
||||
vr = Dereference(proc, exp, block, inlineMapper, vr);
|
||||
|
||||
if (vl.mType->mType != DT_TYPE_ARRAY && vl.mType->mType != DT_TYPE_POINTER)
|
||||
|
@ -2842,6 +2878,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ains->mSrc[1].mMemory = IM_INDIRECT;
|
||||
ains->mSrc[0].mType = IT_INT16;
|
||||
ains->mSrc[0].mTemp = mins->mDst.mTemp;
|
||||
if (vl.mType->mType == DT_TYPE_ARRAY && vl.mType->mSize > vl.mType->mBase->mSize && (exp->mFlags & ANAFL_RHS))
|
||||
{
|
||||
ains->mSrc[0].mRange.LimitMin(0);
|
||||
ains->mSrc[0].mRange.LimitMax(vl.mType->mSize);
|
||||
}
|
||||
ains->mSrc[1].mType = IT_POINTER;
|
||||
ains->mSrc[1].mTemp = vl.mTemp;
|
||||
ains->mDst.mType = IT_POINTER;
|
||||
|
@ -2908,7 +2949,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ptype->mSize = 2;
|
||||
ptype->mStride = vl.mType->mStride;
|
||||
vl.mReference = 0;
|
||||
vl.mType = exp->mDecType; // ptype;
|
||||
vl.mType = ptype;
|
||||
}
|
||||
|
||||
if (vr.mType->mType == DT_TYPE_POINTER)
|
||||
|
@ -2970,7 +3011,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
||||
block->Append(ins);
|
||||
}
|
||||
else if (vr.mType->mType == DT_TYPE_POINTER && vr.mType->mBase->IsConstSame(vl.mType->mBase))
|
||||
else if ((vr.mType->mType == DT_TYPE_POINTER || vr.mType->mType == DT_TYPE_ARRAY) && (vl.mType->mType == DT_TYPE_POINTER || vl.mType->mType == DT_TYPE_ARRAY) && vr.mType->mBase->IsConstSame(vl.mType->mBase))
|
||||
{
|
||||
if (exp->mToken == TK_SUB)
|
||||
{
|
||||
|
@ -3033,6 +3074,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
else
|
||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer operation");
|
||||
|
||||
vl.mType = exp->mDecType;
|
||||
}
|
||||
else if (vr.mType->mType == DT_TYPE_POINTER || vr.mType->mType == DT_TYPE_ARRAY)
|
||||
{
|
||||
|
@ -3558,6 +3601,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
else
|
||||
dtype = TheSignedIntTypeDeclaration;
|
||||
}
|
||||
else if (vl.mType->mSize == 1 && vr.mType->mSize == 1 && ((vr.mType->mFlags & DTF_SIGNED) || (vl.mType->mFlags & DTF_SIGNED)))
|
||||
dtype = TheSignedIntTypeDeclaration;
|
||||
else
|
||||
{
|
||||
if (vl.mType->mSize == 4 || vr.mType->mSize == 4)
|
||||
|
@ -3685,6 +3730,18 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
else if (!strcmp(iname->mString, "exp"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(iname->mString, "sqrt"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(iname->mString, "atan"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(iname->mString, "pow"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(iname->mString, "atan2"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(iname->mString, "breakpoint"))
|
||||
{
|
||||
InterInstruction* ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BREAKPOINT);
|
||||
|
@ -3903,6 +3960,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION &&
|
||||
((mCompilerOptions & COPT_OPTIMIZE_INLINE) || (exp->mLeft->mDecValue->mFlags & DTF_FORCE_INLINE)) &&
|
||||
!(inlineMapper && inlineMapper->mDepth > 10) &&
|
||||
!(exp->mLeft->mDecValue->mFlags & DTF_PREVENT_INLINE) &&
|
||||
exp->mType != EX_VCALL;
|
||||
bool doInline = false, inlineConstexpr = false;
|
||||
|
||||
|
@ -3985,7 +4043,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
Declaration * decResult = nullptr;
|
||||
GrowingArray<InterInstruction*> defins(nullptr);
|
||||
|
||||
if (ftype->mBase->mType == DT_TYPE_STRUCT)
|
||||
if (ftype->mBase->IsComplexStruct())
|
||||
{
|
||||
int ttemp;
|
||||
if (lrexp)
|
||||
|
@ -4269,7 +4327,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
cins->mSrc[0].mType = IT_POINTER;
|
||||
cins->mSrc[0].mTemp = vl.mTemp;
|
||||
if (ftype->mBase->mType != DT_TYPE_VOID && ftype->mBase->mType != DT_TYPE_STRUCT)
|
||||
if (ftype->mBase->IsShortIntStruct())
|
||||
{
|
||||
cins->mDst.mType = InterTypeOfSize(ftype->mBase->mSize);
|
||||
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
|
||||
}
|
||||
else if (ftype->mBase->mType != DT_TYPE_VOID && ftype->mBase->mType != DT_TYPE_STRUCT)
|
||||
{
|
||||
cins->mDst.mType = InterTypeOf(ftype->mBase);
|
||||
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
|
||||
|
@ -4292,7 +4355,114 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
block->Append(xins);
|
||||
}
|
||||
|
||||
if (decResult)
|
||||
if (ftype->mBase->IsShortIntStruct())
|
||||
{
|
||||
int ttemp;
|
||||
if (lrexp)
|
||||
{
|
||||
ttemp = lrexp->mTemp;
|
||||
|
||||
decResult = lrexp->mType;
|
||||
}
|
||||
else
|
||||
{
|
||||
int nindex = proc->mNumLocals++;
|
||||
|
||||
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
|
||||
|
||||
vdec->mVarIndex = nindex;
|
||||
vdec->mBase = ftype->mBase;
|
||||
vdec->mSize = ftype->mBase->mSize;
|
||||
|
||||
decResult = vdec;
|
||||
|
||||
InterInstruction* vins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
|
||||
vins->mDst.mType = IT_POINTER;
|
||||
vins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||
vins->mConst.mType = IT_POINTER;
|
||||
vins->mConst.mMemory = IM_LOCAL;
|
||||
vins->mConst.mVarIndex = nindex;
|
||||
vins->mConst.mOperandSize = ftype->mBase->mSize;
|
||||
block->Append(vins);
|
||||
|
||||
ttemp = vins->mDst.mTemp;
|
||||
}
|
||||
// Unmarshall result from return value into struct
|
||||
|
||||
Declaration* dec = ftype->mBase->mParams;
|
||||
while (dec)
|
||||
{
|
||||
if (dec->mType == DT_ELEMENT)
|
||||
{
|
||||
InterInstruction* oins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
|
||||
oins->mDst.mType = IT_INT16;
|
||||
oins->mDst.mTemp = proc->AddTemporary(IT_INT16);
|
||||
oins->mConst.mType = IT_INT16;
|
||||
oins->mConst.mIntConst = dec->mOffset;
|
||||
block->Append(oins);
|
||||
|
||||
InterInstruction* ains = new InterInstruction(MapLocation(exp, inlineMapper), IC_LEA);
|
||||
ains->mSrc[1].mMemory = IM_INDIRECT;
|
||||
ains->mSrc[1].mType = IT_POINTER;
|
||||
ains->mSrc[1].mTemp = ttemp;
|
||||
ains->mSrc[0] = oins->mDst;
|
||||
ains->mDst.mType = IT_POINTER;
|
||||
ains->mDst.mMemory = IM_INDIRECT;
|
||||
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||
ains->mDst.mOperandSize = dec->mSize;
|
||||
ains->mNumOperands = 2;
|
||||
block->Append(ains);
|
||||
|
||||
InterInstruction* csins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
|
||||
csins->mDst.mType = IT_INT8;
|
||||
csins->mDst.mTemp = proc->AddTemporary(csins->mDst.mType);
|
||||
csins->mConst.mType = IT_INT8;
|
||||
csins->mConst.mIntConst = 8 * dec->mOffset;
|
||||
csins->mNumOperands = 0;
|
||||
block->Append(csins);
|
||||
|
||||
InterInstruction* asins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
|
||||
asins->mDst.mType = cins->mDst.mType;
|
||||
asins->mDst.mTemp = proc->AddTemporary(csins->mDst.mType);
|
||||
asins->mConst.mType = cins->mDst.mType;
|
||||
asins->mConst.mIntConst = (1ll << 8 * dec->mSize) - 1;
|
||||
asins->mNumOperands = 0;
|
||||
block->Append(asins);
|
||||
|
||||
InterInstruction* shins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BINARY_OPERATOR);
|
||||
shins->mOperator = IA_SHR;
|
||||
shins->mDst.mType = cins->mDst.mType;
|
||||
shins->mDst.mTemp = proc->AddTemporary(shins->mDst.mType);
|
||||
shins->mSrc[1] = cins->mDst;
|
||||
shins->mSrc[0] = csins->mDst;
|
||||
shins->mNumOperands = 2;
|
||||
block->Append(shins);
|
||||
|
||||
InterInstruction* andins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BINARY_OPERATOR);
|
||||
andins->mOperator = IA_AND;
|
||||
andins->mDst.mType = cins->mDst.mType;
|
||||
andins->mDst.mTemp = proc->AddTemporary(andins->mDst.mType);
|
||||
andins->mSrc[0] = asins->mDst;
|
||||
andins->mSrc[1] = shins->mDst;
|
||||
andins->mNumOperands = 2;
|
||||
block->Append(andins);
|
||||
|
||||
InterInstruction* sins = new InterInstruction(MapLocation(exp, inlineMapper), IC_STORE);
|
||||
sins->mSrc[0].mTemp = andins->mDst.mTemp;
|
||||
sins->mSrc[0].mType = InterTypeOf(dec->mBase);
|
||||
sins->mSrc[1] = ains->mDst;
|
||||
sins->mNumOperands = 2;
|
||||
block->Append(sins);
|
||||
}
|
||||
dec = dec->mNext;
|
||||
}
|
||||
|
||||
if (lrexp)
|
||||
return *lrexp;
|
||||
|
||||
return ExValue(ftype->mBase, ttemp, 1);
|
||||
}
|
||||
else if (decResult)
|
||||
{
|
||||
if (lrexp)
|
||||
return *lrexp;
|
||||
|
@ -4506,9 +4676,130 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mNumOperands = 1;
|
||||
}
|
||||
}
|
||||
else if (!inlineMapper && procType->mBase->IsShortIntStruct())
|
||||
{
|
||||
vr = TranslateExpression(procType, proc, block, exp->mLeft, destack, gotos, breakBlock, continueBlock, inlineMapper);
|
||||
|
||||
if (vr.mType->IsReference())
|
||||
{
|
||||
vr.mReference++;
|
||||
vr.mType = vr.mType->mBase;
|
||||
}
|
||||
|
||||
vr = Dereference(proc, exp, block, inlineMapper, vr, 1);
|
||||
|
||||
if (!procType->mBase || procType->mBase->mType == DT_TYPE_VOID)
|
||||
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Function has void return type");
|
||||
else if (!procType->mBase->CanAssign(vr.mType))
|
||||
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Cannot return incompatible type");
|
||||
else if (vr.mReference != 1)
|
||||
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Non addressable object");
|
||||
|
||||
// Build marshalled struct into single long
|
||||
InterInstruction* pins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
|
||||
pins->mDst.mType = InterTypeOfSize(procType->mBase->mSize);
|
||||
pins->mDst.mTemp = proc->AddTemporary(pins->mDst.mType);
|
||||
pins->mConst.mType = pins->mDst.mType;
|
||||
pins->mConst.mIntConst = 0;
|
||||
block->Append(pins);
|
||||
|
||||
Declaration* dec = procType->mBase->mParams;
|
||||
while (dec)
|
||||
{
|
||||
if (dec->mType == DT_ELEMENT)
|
||||
{
|
||||
InterInstruction * oins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
|
||||
oins->mDst.mType = IT_INT16;
|
||||
oins->mDst.mTemp = proc->AddTemporary(IT_INT16);
|
||||
oins->mConst.mType = IT_INT16;
|
||||
oins->mConst.mIntConst = dec->mOffset;
|
||||
block->Append(oins);
|
||||
|
||||
InterInstruction * ains = new InterInstruction(MapLocation(exp, inlineMapper), IC_LEA);
|
||||
ains->mSrc[1].mMemory = IM_INDIRECT;
|
||||
ains->mSrc[1].mType = IT_POINTER;
|
||||
ains->mSrc[1].mTemp = vr.mTemp;
|
||||
ains->mSrc[0] = oins->mDst;
|
||||
ains->mDst.mType = IT_POINTER;
|
||||
ains->mDst.mMemory = IM_INDIRECT;
|
||||
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||
ains->mDst.mOperandSize = dec->mSize;
|
||||
ains->mNumOperands = 2;
|
||||
block->Append(ains);
|
||||
|
||||
InterInstruction* lins = new InterInstruction(MapLocation(exp, inlineMapper), IC_LOAD);
|
||||
lins->mSrc[0] = ains->mDst;
|
||||
lins->mDst.mType = InterTypeOf(dec->mBase);
|
||||
lins->mDst.mTemp = proc->AddTemporary(lins->mDst.mType);
|
||||
lins->mNumOperands = 1;
|
||||
block->Append(lins);
|
||||
|
||||
if (pins->mDst.mType == IT_INT32)
|
||||
{
|
||||
if (dec->mSize < 4)
|
||||
{
|
||||
InterInstruction* xins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONVERSION_OPERATOR);
|
||||
xins->mOperator = dec->mSize == 1 ? IA_EXT8TO32U : IA_EXT16TO32U;
|
||||
xins->mSrc[0] = lins->mDst;
|
||||
xins->mDst.mType = InterTypeOf(dec->mBase);
|
||||
xins->mDst.mTemp = proc->AddTemporary(pins->mDst.mType);
|
||||
xins->mNumOperands = 1;
|
||||
block->Append(xins);
|
||||
lins = xins;
|
||||
}
|
||||
}
|
||||
else if (pins->mDst.mType == IT_INT16)
|
||||
{
|
||||
if (dec->mSize < 2)
|
||||
{
|
||||
InterInstruction* xins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONVERSION_OPERATOR);
|
||||
xins->mOperator = IA_EXT8TO16U;
|
||||
xins->mSrc[0] = lins->mDst;
|
||||
xins->mDst.mType = InterTypeOf(dec->mBase);
|
||||
xins->mDst.mTemp = proc->AddTemporary(pins->mDst.mType);
|
||||
xins->mNumOperands = 1;
|
||||
block->Append(xins);
|
||||
lins = xins;
|
||||
}
|
||||
}
|
||||
|
||||
InterInstruction* csins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
|
||||
csins->mDst.mType = IT_INT8;
|
||||
csins->mDst.mTemp = proc->AddTemporary(csins->mDst.mType);
|
||||
csins->mConst.mType = IT_INT8;
|
||||
csins->mConst.mIntConst = 8 * dec->mOffset;
|
||||
csins->mNumOperands = 0;
|
||||
block->Append(csins);
|
||||
|
||||
InterInstruction* sins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BINARY_OPERATOR);
|
||||
sins->mOperator = IA_SHL;
|
||||
sins->mDst.mType = pins->mDst.mType;
|
||||
sins->mDst.mTemp = proc->AddTemporary(sins->mDst.mType);
|
||||
sins->mSrc[1] = lins->mDst;
|
||||
sins->mSrc[0] = csins->mDst;
|
||||
sins->mNumOperands = 2;
|
||||
block->Append(sins);
|
||||
|
||||
InterInstruction* orins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BINARY_OPERATOR);
|
||||
orins->mOperator = IA_OR;
|
||||
orins->mDst.mType = pins->mDst.mType;
|
||||
orins->mDst.mTemp = proc->AddTemporary(orins->mDst.mType);
|
||||
orins->mSrc[0] = pins->mDst;
|
||||
orins->mSrc[1] = sins->mDst;
|
||||
orins->mNumOperands = 2;
|
||||
block->Append(orins);
|
||||
|
||||
pins = orins;
|
||||
}
|
||||
dec = dec->mNext;
|
||||
}
|
||||
|
||||
ins->mCode = IC_RETURN_VALUE;
|
||||
ins->mSrc[0] = pins->mDst;
|
||||
ins->mNumOperands = 1;
|
||||
}
|
||||
else if (procType->mBase->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
|
||||
InterInstruction* ains = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
|
||||
|
||||
if (inlineMapper)
|
||||
|
@ -4578,101 +4869,6 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
bool moving = exp->mLeft->IsRValue() || exp->mLeft->mType == EX_VARIABLE && !(exp->mLeft->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL)) && exp->mLeft->mDecType->mType != DT_TYPE_REFERENCE;
|
||||
|
||||
CopyStruct(proc, exp, block, rvr, vr, inlineMapper, moving);
|
||||
#if 0
|
||||
if (procType->mBase->mCopyConstructor)
|
||||
{
|
||||
Declaration* ccdec = procType->mBase->mCopyConstructor;
|
||||
if (ccdec->mBase->mFlags & DTF_FASTCALL)
|
||||
{
|
||||
if (!ccdec->mLinkerObject)
|
||||
this->TranslateProcedure(proc->mModule, ccdec->mValue, ccdec);
|
||||
|
||||
InterInstruction* psins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
|
||||
psins->mDst.mType = IT_POINTER;
|
||||
psins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||
psins->mConst.mVarIndex = 0;
|
||||
psins->mConst.mIntConst = 0;
|
||||
psins->mConst.mOperandSize = 2;
|
||||
if (procType->mFlags & DTF_FASTCALL)
|
||||
{
|
||||
psins->mConst.mMemory = IM_FPARAM;
|
||||
psins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
|
||||
}
|
||||
else
|
||||
psins->mConst.mMemory = IM_PARAM;
|
||||
block->Append(psins);
|
||||
|
||||
InterInstruction* ssins = new InterInstruction(MapLocation(exp, inlineMapper), IC_STORE);
|
||||
ssins->mSrc[0] = ains->mDst;
|
||||
ssins->mSrc[1] = psins->mDst;
|
||||
block->Append(ssins);
|
||||
|
||||
InterInstruction* plins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
|
||||
plins->mDst.mType = IT_POINTER;
|
||||
plins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||
plins->mConst.mVarIndex = 2;
|
||||
plins->mConst.mIntConst = 0;
|
||||
plins->mConst.mOperandSize = 2;
|
||||
if (procType->mFlags & DTF_FASTCALL)
|
||||
{
|
||||
plins->mConst.mMemory = IM_FPARAM;
|
||||
plins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
|
||||
}
|
||||
else
|
||||
plins->mConst.mMemory = IM_PARAM;
|
||||
block->Append(plins);
|
||||
|
||||
InterInstruction* slins = new InterInstruction(MapLocation(exp, inlineMapper), IC_STORE);
|
||||
slins->mSrc[0].mType = IT_POINTER;
|
||||
slins->mSrc[0].mTemp = vr.mTemp;
|
||||
slins->mSrc[0].mMemory = IM_INDIRECT;
|
||||
slins->mSrc[0].mOperandSize = procType->mBase->mSize;
|
||||
slins->mSrc[0].mStride = vr.mType->mStripe;
|
||||
slins->mSrc[1] = plins->mDst;
|
||||
block->Append(slins);
|
||||
|
||||
proc->AddCalledFunction(proc->mModule->mProcedures[ccdec->mVarIndex]);
|
||||
|
||||
InterInstruction* pcins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT);
|
||||
pcins->mDst.mType = IT_POINTER;
|
||||
pcins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||
pcins->mConst.mType = IT_POINTER;
|
||||
pcins->mConst.mVarIndex = ccdec->mVarIndex;
|
||||
pcins->mConst.mIntConst = 0;
|
||||
pcins->mConst.mOperandSize = 2;
|
||||
pcins->mConst.mMemory = IM_GLOBAL;
|
||||
pcins->mConst.mLinkerObject = ccdec->mLinkerObject;
|
||||
block->Append(pcins);
|
||||
|
||||
InterInstruction* cins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CALL);
|
||||
if (ccdec->mFlags & DTF_NATIVE)
|
||||
cins->mCode = IC_CALL_NATIVE;
|
||||
else
|
||||
cins->mCode = IC_CALL;
|
||||
cins->mSrc[0] = pcins->mDst;
|
||||
cins->mNumOperands = 1;
|
||||
|
||||
block->Append(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InterInstruction* cins = new InterInstruction(MapLocation(exp, inlineMapper), IC_COPY);
|
||||
cins->mSrc[0].mType = IT_POINTER;
|
||||
cins->mSrc[0].mTemp = vr.mTemp;
|
||||
cins->mSrc[0].mMemory = IM_INDIRECT;
|
||||
cins->mSrc[0].mOperandSize = procType->mBase->mSize;
|
||||
cins->mSrc[0].mStride = vr.mType->mStripe;
|
||||
|
||||
cins->mSrc[1].mOperandSize = procType->mBase->mSize;
|
||||
cins->mSrc[1].mType = IT_POINTER;
|
||||
cins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||
cins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
|
||||
cins->mConst.mOperandSize = procType->mBase->mSize;
|
||||
block->Append(cins);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4980,64 +5176,92 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
vl = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, destack, gotos, breakBlock, continueBlock, inlineMapper);
|
||||
vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, destack, gotos, breakBlock, continueBlock, inlineMapper);
|
||||
|
||||
int ttemp;
|
||||
InterType ttype, stypel, styper;
|
||||
int ttemp, tref = 0;
|
||||
InterType ttype;
|
||||
|
||||
stypel = InterTypeOf(vl.mType);
|
||||
styper = InterTypeOf(vr.mType);
|
||||
Declaration* dtype = exp->mDecType;
|
||||
|
||||
Declaration* dtype;
|
||||
if (stypel == IT_POINTER || styper == IT_POINTER)
|
||||
if (dtype->IsReference())
|
||||
{
|
||||
if (vl.mType->mType == DT_TYPE_ARRAY)
|
||||
vl = Dereference(proc, exp, tblock, inlineMapper, vl, 1);
|
||||
else
|
||||
vl = Dereference(proc, exp, tblock, inlineMapper, vl);
|
||||
|
||||
if (vr.mType->mType == DT_TYPE_ARRAY)
|
||||
vr = Dereference(proc, exp, fblock, inlineMapper, vr, 1);
|
||||
else
|
||||
vr = Dereference(proc, exp, fblock, inlineMapper, vr);
|
||||
|
||||
if (vl.mType->mBase->IsSubType(vr.mType->mBase))
|
||||
dtype = vr.mType;
|
||||
else if (vr.mType->mBase->IsSubType(vl.mType->mBase))
|
||||
dtype = vl.mType;
|
||||
else
|
||||
{
|
||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible conditional types");
|
||||
dtype = vl.mType;
|
||||
}
|
||||
|
||||
Declaration* ntype = new Declaration(dtype->mLocation, DT_TYPE_POINTER);
|
||||
ntype->mBase = dtype->mBase;
|
||||
dtype = ntype;
|
||||
vl = Dereference(proc, exp, block, inlineMapper, vl, 1);
|
||||
vr = Dereference(proc, exp, block, inlineMapper, vr, 1);
|
||||
tref = 1;
|
||||
|
||||
dtype = dtype->mBase;
|
||||
ttype = IT_POINTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
vl = Dereference(proc, exp, tblock, inlineMapper, vl);
|
||||
vr = Dereference(proc, exp, fblock, inlineMapper, vr);
|
||||
InterType stypel, styper;
|
||||
|
||||
if (stypel == styper)
|
||||
{
|
||||
ttype = stypel;
|
||||
dtype = vl.mType;
|
||||
}
|
||||
else if (stypel > styper)
|
||||
{
|
||||
ttype = stypel;
|
||||
dtype = vl.mType;
|
||||
if (vl.mType->IsReference())
|
||||
vl = ToValue(proc, exp, block, inlineMapper, vl);
|
||||
if (vr.mType->IsReference())
|
||||
vr = ToValue(proc, exp, block, inlineMapper, vr);
|
||||
|
||||
vr = CoerceType(proc, exp, fblock, inlineMapper, vr, dtype);
|
||||
stypel = InterTypeOf(vl.mType);
|
||||
styper = InterTypeOf(vr.mType);
|
||||
|
||||
if (stypel == IT_POINTER || styper == IT_POINTER)
|
||||
{
|
||||
if (vl.mType->mType == DT_TYPE_ARRAY)
|
||||
vl = Dereference(proc, exp, tblock, inlineMapper, vl, 1);
|
||||
else
|
||||
vl = Dereference(proc, exp, tblock, inlineMapper, vl);
|
||||
|
||||
if (vr.mType->mType == DT_TYPE_ARRAY)
|
||||
vr = Dereference(proc, exp, fblock, inlineMapper, vr, 1);
|
||||
else
|
||||
vr = Dereference(proc, exp, fblock, inlineMapper, vr);
|
||||
|
||||
if (vl.mType->mBase && vr.mType->mBase)
|
||||
{
|
||||
if (vl.mType->mBase->IsSubType(vr.mType->mBase))
|
||||
dtype = vr.mType;
|
||||
else if (vr.mType->mBase->IsSubType(vl.mType->mBase))
|
||||
dtype = vl.mType;
|
||||
else
|
||||
{
|
||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible conditional types");
|
||||
dtype = vl.mType;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible conditional types");
|
||||
dtype = vl.mType;
|
||||
}
|
||||
|
||||
Declaration* ntype = new Declaration(dtype->mLocation, DT_TYPE_POINTER);
|
||||
ntype->mBase = dtype->mBase;
|
||||
dtype = ntype;
|
||||
|
||||
ttype = IT_POINTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ttype = styper;
|
||||
dtype = vr.mType;
|
||||
vl = Dereference(proc, exp, tblock, inlineMapper, vl);
|
||||
vr = Dereference(proc, exp, fblock, inlineMapper, vr);
|
||||
|
||||
vl = CoerceType(proc, exp, tblock, inlineMapper, vl, dtype);
|
||||
if (stypel == styper)
|
||||
{
|
||||
ttype = stypel;
|
||||
dtype = vl.mType;
|
||||
}
|
||||
else if (stypel > styper)
|
||||
{
|
||||
ttype = stypel;
|
||||
dtype = vl.mType;
|
||||
|
||||
vr = CoerceType(proc, exp, fblock, inlineMapper, vr, dtype);
|
||||
}
|
||||
else
|
||||
{
|
||||
ttype = styper;
|
||||
dtype = vr.mType;
|
||||
|
||||
vl = CoerceType(proc, exp, tblock, inlineMapper, vl, dtype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5089,7 +5313,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
block = eblock;
|
||||
|
||||
return ExValue(dtype, ttemp);
|
||||
return ExValue(dtype, ttemp, tref);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5107,13 +5331,16 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case EX_TYPECAST:
|
||||
{
|
||||
vr = TranslateExpression(procType, proc, block, exp->mLeft, destack, gotos, breakBlock, continueBlock, inlineMapper);
|
||||
|
||||
InterInstruction * ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONVERSION_OPERATOR);
|
||||
|
||||
if (vr.mType->IsReference() && !exp->mDecType->IsReference())
|
||||
vr = ToValue(proc, exp, block, inlineMapper, vr);
|
||||
|
||||
if (exp->mDecType->mType == DT_TYPE_FLOAT && vr.mType->IsIntegerType())
|
||||
{
|
||||
vr = Dereference(proc, exp, block, inlineMapper, vr);
|
||||
|
@ -5410,6 +5637,37 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
return ExValue(TheVoidTypeDeclaration);
|
||||
}
|
||||
|
||||
case EX_FORBODY:
|
||||
{
|
||||
DestructStack* odestack = destack;
|
||||
|
||||
InterInstruction* jins0 = new InterInstruction(MapLocation(exp, inlineMapper), IC_JUMP);
|
||||
InterInstruction* jins1 = new InterInstruction(MapLocation(exp, inlineMapper), IC_JUMP);
|
||||
|
||||
InterCodeBasicBlock* lblock = new InterCodeBasicBlock(proc);
|
||||
InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc);
|
||||
|
||||
block->Append(jins0);
|
||||
block->Close(lblock, nullptr);
|
||||
|
||||
DestructStack* idestack = destack;
|
||||
|
||||
vr = TranslateExpression(procType, proc, lblock, exp->mLeft, destack, gotos, breakBlock, BranchTarget(cblock, idestack), inlineMapper);
|
||||
|
||||
lblock->Append(jins1);
|
||||
lblock->Close(cblock, nullptr);
|
||||
|
||||
UnwindDestructStack(procType, proc, cblock, destack, idestack, inlineMapper);
|
||||
destack = idestack;
|
||||
|
||||
block = cblock;
|
||||
|
||||
exp = exp->mRight;
|
||||
if (!exp)
|
||||
return ExValue(TheVoidTypeDeclaration);
|
||||
|
||||
} break;
|
||||
|
||||
case EX_FOR:
|
||||
{
|
||||
DestructStack* odestack = destack;
|
||||
|
@ -5529,7 +5787,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
|
||||
case EX_AGGREGATE:
|
||||
mErrors->Error(exp->mLocation, EERR_INVALID_INITIALIZER, "Unexpected aggreate");
|
||||
mErrors->Error(exp->mLocation, EERR_INVALID_INITIALIZER, "Unexpected aggregate");
|
||||
return ExValue(TheVoidTypeDeclaration);
|
||||
|
||||
case EX_SWITCH:
|
||||
|
@ -5978,7 +6236,10 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
|||
proc->mNativeProcedure = true;
|
||||
|
||||
if (dec->mFlags & DTF_INTERRUPT)
|
||||
{
|
||||
proc->mInterrupt = true;
|
||||
proc->mCompilerOptions &= ~COPT_OPTIMIZE_OUTLINE;
|
||||
}
|
||||
|
||||
if (dec->mFlags & DTF_HWINTERRUPT)
|
||||
proc->mHardwareInterrupt = true;
|
||||
|
@ -6051,7 +6312,12 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
|||
else
|
||||
proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
|
||||
|
||||
if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT)
|
||||
if (dec->mBase->mBase->IsShortIntStruct())
|
||||
{
|
||||
proc->mValueReturn = true;
|
||||
proc->mReturnType = IT_INT32;
|
||||
}
|
||||
else if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT)
|
||||
{
|
||||
proc->mValueReturn = true;
|
||||
proc->mReturnType = InterTypeOf(dec->mBase->mBase);
|
||||
|
@ -6127,7 +6393,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
|||
}
|
||||
}
|
||||
else
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent->mString);
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->FullIdent());
|
||||
|
||||
if (strcmp(proc->mIdent->mString, "main"))
|
||||
{
|
||||
|
@ -6152,7 +6418,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
|||
|
||||
void InterCodeGenerator::CompleteMainInit(void)
|
||||
{
|
||||
if (mErrors->mErrorCount == 0)
|
||||
if (mErrors->mErrorCount == 0 && mMainInitBlock)
|
||||
{
|
||||
InterInstruction* ins = new InterInstruction(mMainInitProc->mLocation, IC_JUMP);
|
||||
mMainInitBlock->Append(ins);
|
||||
|
|
|
@ -94,12 +94,12 @@ protected:
|
|||
void BuildSwitchTree(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock* block, InlineMapper * inlineMapper, ExValue v, const SwitchNodeArray& nodes, int left, int right, int vleft, int vright, InterCodeBasicBlock* dblock);
|
||||
|
||||
ExValue ToValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v);
|
||||
ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, int level = 0);
|
||||
ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, int level = 0, int limit = 0);
|
||||
ExValue CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue v, Declaration * type, bool checkTrunc = true);
|
||||
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, GotoNode*& gotos, const BranchTarget & breakBlock, const BranchTarget& continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr);
|
||||
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, DestructStack*& destack, GotoNode*& gotos, InlineMapper* inlineMapper);
|
||||
ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr, ExValue* lrexp);
|
||||
void CopyStruct(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper, bool moving);
|
||||
void CopyStruct (InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper, bool moving);
|
||||
void CopyStructSimple(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock * block, InlineMapper* inlineMapper, ExValue vl, ExValue vr);
|
||||
void StoreValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue vl, ExValue vr);
|
||||
|
||||
|
|
|
@ -650,7 +650,7 @@ bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj, bool merge, boo
|
|||
int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
||||
int end = start + lobj->mSize;
|
||||
|
||||
if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00) && !(lobj->mSection->mFlags & LSECF_PACKED))
|
||||
if (((lobj->mFlags & LOBJF_NEVER_CROSS) || !(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mSection->mFlags & LSECF_PACKED)) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00))
|
||||
;
|
||||
else if (end <= mFreeChunks[i].mEnd)
|
||||
{
|
||||
|
@ -702,7 +702,7 @@ bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj, bool merge, boo
|
|||
int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
||||
int end = start + lobj->mSize;
|
||||
|
||||
if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && !retry && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mFlags & LOBJF_FORCE_ALIGN) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00) && !(lobj->mSection->mFlags & LSECF_PACKED))
|
||||
if (((lobj->mFlags & LOBJF_NEVER_CROSS) || !(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && !retry && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mSection->mFlags & LSECF_PACKED)) && !(lobj->mFlags & LOBJF_FORCE_ALIGN) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00))
|
||||
{
|
||||
start = (start + 0x00ff) & 0xff00;
|
||||
end = start + lobj->mSize;
|
||||
|
@ -1903,6 +1903,8 @@ bool Linker::WriteDbjFile(FILE* file)
|
|||
return true;
|
||||
}
|
||||
|
||||
static const char hexchars[] = "0123456789abcdef";
|
||||
|
||||
bool Linker::WriteLblFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
|
@ -1916,7 +1918,28 @@ bool Linker::WriteLblFile(const char* filename)
|
|||
if (obj->mFlags & LOBJF_REFERENCED)
|
||||
{
|
||||
if (obj->mIdent)
|
||||
fprintf(file, "al %04x .%s\n", obj->mAddress, obj->mIdent->mString);
|
||||
{
|
||||
char buffer[400];
|
||||
char nbuffer[500];
|
||||
|
||||
strcpy_s(buffer, obj->mIdent->mString);
|
||||
int i = 0, j = 0;
|
||||
while (buffer[i])
|
||||
{
|
||||
if (buffer[i] >= '0' && buffer[i] <= '9' || buffer[i] >= 'a' && buffer[i] <= 'z' || buffer[i] >= 'A' && buffer[i] <= 'Z' || buffer[i] == '_' || buffer[i] == ':')
|
||||
nbuffer[j++] = buffer[i];
|
||||
else
|
||||
{
|
||||
nbuffer[j++] = '?';
|
||||
nbuffer[j++] = hexchars[(buffer[i] >> 4) & 0x0f];
|
||||
nbuffer[j++] = hexchars[buffer[i] & 0x0f];
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
nbuffer[j] = 0;
|
||||
fprintf(file, "al %04x .%s\n", obj->mAddress, nbuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -156,6 +156,7 @@ static const uint32 LOBJF_NO_CROSS = 0x00000080;
|
|||
static const uint32 LOBJF_ZEROPAGE = 0x00000100;
|
||||
static const uint32 LOBJF_FORCE_ALIGN = 0x00000200;
|
||||
static const uint32 LOBJF_ZEROPAGESET = 0x00000400;
|
||||
static const uint32 LOBJF_NEVER_CROSS = 0x00000800;
|
||||
|
||||
static const uint32 LOBJF_ARG_REG_A = 0x00001000;
|
||||
static const uint32 LOBJF_ARG_REG_X = 0x00002000;
|
||||
|
@ -163,6 +164,7 @@ static const uint32 LOBJF_ARG_REG_Y = 0x00004000;
|
|||
|
||||
static const uint32 LOBJF_RET_REG_A = 0x00010000;
|
||||
static const uint32 LOBJF_RET_REG_X = 0x00020000;
|
||||
static const uint32 LOBJF_RET_REG_Y = 0x00020000;
|
||||
|
||||
static const uint32 LOBJF_LOCAL_VAR = 0x00100000;
|
||||
static const uint32 LOBJF_LOCAL_USED = 0x00200000;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -135,12 +135,17 @@ 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;
|
||||
|
||||
// use a 32bit zero page register indexed by X for JSR
|
||||
static const uint32 NCIF_USE_ZP_32_X = 0x00010000;
|
||||
static const uint32 NICF_USE_ZP_ADDR = 0x00020000;
|
||||
static const uint32 NICF_USE_WORKREGS = 0x00040000;
|
||||
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;
|
||||
|
||||
static const uint32 NCIF_BREAKPOINT = 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_BREAKPOINT = 0x00800000;
|
||||
|
||||
class NativeCodeInstruction
|
||||
{
|
||||
|
@ -298,6 +303,7 @@ 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);
|
||||
|
||||
|
@ -322,6 +328,8 @@ public:
|
|||
bool UsesZeroPage(int address, int from = 0, int to = 65536) const;
|
||||
bool ReferencesZeroPage(int address, int from = 0, int to = 65536) const;
|
||||
|
||||
bool ChangesMemory(const NativeCodeInstruction& ins, int from = 0, int to = 65536) const;
|
||||
bool ReferencesMemory(const NativeCodeInstruction& ins, int from = 0, int to = 65536) const;
|
||||
|
||||
bool RemoveNops(void);
|
||||
bool PeepHoleOptimizer(int pass);
|
||||
|
@ -340,7 +348,7 @@ public:
|
|||
bool PeepHoleOptimizerIterate(int pass);
|
||||
bool PeepHoleOptimizerExits(int pass);
|
||||
|
||||
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter);
|
||||
void BlockSizeReduction(NativeCodeProcedure* proc, int xenter, int yenter, int center);
|
||||
bool BlockSizeCopyReduction(NativeCodeProcedure* proc, int & si, int & di);
|
||||
|
||||
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, bool full);
|
||||
|
@ -365,9 +373,11 @@ public:
|
|||
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
|
||||
NativeCodeBasicBlock* CollectInnerLoop(NativeCodeBasicBlock* head, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
|
||||
bool OptimizeGenericLoop(NativeCodeProcedure* proc);
|
||||
bool CollectGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
bool CollectSingleEntryGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
int CorrectXOffset(const InterInstruction * ins, int yoffset, int at);
|
||||
int CorrectYOffset(const InterInstruction * ins, int yoffset, int at);
|
||||
bool OptimizeGenericLoop(void);
|
||||
bool CollectGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
bool CollectSingleEntryGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
|
||||
void CollectReachable(ExpandingArray<NativeCodeBasicBlock*>& lblock);
|
||||
|
||||
bool OptimizeFindLoop(NativeCodeProcedure* proc);
|
||||
|
@ -418,6 +428,7 @@ public:
|
|||
|
||||
void LoadByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* rins);
|
||||
void StoreByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* rins);
|
||||
void CopyByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* riins, const InterInstruction* wiins, const InterInstruction* rins, const InterInstruction* wins);
|
||||
|
||||
void CallAssembler(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
void CallFunction(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
|
@ -454,8 +465,6 @@ public:
|
|||
bool MergeBasicBlocks(void);
|
||||
bool RemoveJumpToBranch(void);
|
||||
|
||||
void MarkLoopHead(void);
|
||||
|
||||
struct DominatorStacks
|
||||
{
|
||||
ExpandingArray< NativeCodeBasicBlock* > d1, d2;
|
||||
|
@ -564,6 +573,7 @@ public:
|
|||
bool CombineSameYtoX(int xpos, int ypos, int end);
|
||||
|
||||
bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains);
|
||||
int FindImmediateGlobalStore(int at, const NativeCodeInstruction& ins);
|
||||
|
||||
bool JoinXYCrossBlock(void);
|
||||
bool CanCombineSameXtoYCrossBlock(int from);
|
||||
|
@ -600,6 +610,9 @@ public:
|
|||
bool OffsetValueForwarding(const ValueNumberingDataSet & data);
|
||||
bool AbsoluteValueForwarding(const ExpandingArray<NativeCodeLoadStorePair>& npairs);
|
||||
bool IndexXYValueForwarding(int xreg, int xoffset, int xvalue, int yreg, int yoffset, int yvalue);
|
||||
bool ReduceIndexXYZeroShuffle(NativeCodeBasicBlock* from, int xreg, int yreg);
|
||||
bool CheckLoopIndexXRegisters(NativeCodeBasicBlock* head, int xreg);
|
||||
bool CheckLoopIndexYRegisters(NativeCodeBasicBlock* head, int yreg);
|
||||
|
||||
void MarkLocalUsedLinkerObjects(void);
|
||||
bool RemoveLocalUnusedLinkerObjects(void);
|
||||
|
@ -623,6 +636,8 @@ public:
|
|||
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);
|
||||
|
@ -788,10 +803,20 @@ public:
|
|||
bool CheckPatchFailUse(void);
|
||||
|
||||
bool CheckPatchFailLoop(const NativeCodeBasicBlock* block, const NativeCodeBasicBlock* head, int reg, bool changed);
|
||||
bool CheckPatchFailLoopPair(const NativeCodeBasicBlock* block, const NativeCodeBasicBlock* head, int reg, bool changed);
|
||||
|
||||
bool JoinSameBranch(NativeCodeBasicBlock* block);
|
||||
bool MergeSameBranch(void);
|
||||
|
||||
bool CheckBoolBitPropagation(const NativeCodeBasicBlock* block, int at, int reg);
|
||||
bool PatchBoolBitPropagation(const NativeCodeBasicBlock* block, int at, int reg);
|
||||
|
||||
bool CollectRegBoolInstructionsForward(int reg, ExpandingArray<NativeCodeBasicBlock*>& cblocks, ExpandingArray<NativeCodeInstruction*>& lins);
|
||||
bool CollectRegBoolInstructionsBackward(int reg, ExpandingArray<NativeCodeBasicBlock*>& cblocks, ExpandingArray<NativeCodeInstruction*>& lins);
|
||||
|
||||
bool CollectCheckRegOriginBlocks(int at, int reg, ExpandingArray<NativeCodeBasicBlock*>& lblocks, ExpandingArray<NativeCodeInstruction*>& lins);
|
||||
bool PatchBitBoolConstOrigin(void);
|
||||
|
||||
// reg : base register pair to replace
|
||||
// index: index register
|
||||
// at : start position in block
|
||||
|
|
1626
oscar64/Parser.cpp
1626
oscar64/Parser.cpp
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,7 @@ public:
|
|||
~Parser(void);
|
||||
|
||||
Parser* Clone(void);
|
||||
Parser * mParent;
|
||||
|
||||
DeclarationScope * mGlobals, * mScope, * mTemplateScope, * mCaptureScope;
|
||||
int mLocalIndex;
|
||||
|
@ -24,6 +25,8 @@ public:
|
|||
uint64 mCompilerOptionStack[32];
|
||||
int mCompilerOptionSP;
|
||||
|
||||
Location FullLocation(const Location& loc);
|
||||
|
||||
void Parse(void);
|
||||
protected:
|
||||
bool ExpectToken(Token token);
|
||||
|
@ -77,6 +80,7 @@ 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);
|
||||
|
@ -133,6 +137,8 @@ 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);
|
||||
|
@ -156,6 +162,7 @@ protected:
|
|||
Expression* ParseListExpression(bool lhs, Declaration * params = nullptr);
|
||||
|
||||
Expression* ParseParenthesisExpression(void);
|
||||
void ParseStaticAssert(void);
|
||||
|
||||
Errors* mErrors;
|
||||
Scanner* mScanner;
|
||||
|
|
|
@ -327,6 +327,16 @@ struct CTMHeader9
|
|||
uint8 mColors[7];
|
||||
};
|
||||
|
||||
struct CTTHeader9
|
||||
{
|
||||
uint8 mDispMode;
|
||||
uint8 mColorMethod;
|
||||
uint8 mFlags;
|
||||
uint8 mFgridWidth[2], mFGridHeight[2];
|
||||
char mFGridConfig;
|
||||
uint8 mColors[6];
|
||||
};
|
||||
|
||||
#if 0
|
||||
#pragma pack(push, 1)
|
||||
struct SPDHeader5
|
||||
|
@ -486,6 +496,7 @@ void SourceFile::ReadCharPad(Errors* errors, const Location& location, SourceFil
|
|||
CTMHeader ctmHeader;
|
||||
CTMHeader8 ctmHeader8;
|
||||
CTMHeader9 ctmHeader9;
|
||||
CTTHeader9 cttHeader9;
|
||||
uint16 ctmMarker, numChars, numTiles;
|
||||
char tileWidth, tileHeight;
|
||||
|
||||
|
@ -496,10 +507,20 @@ void SourceFile::ReadCharPad(Errors* errors, const Location& location, SourceFil
|
|||
fread(&ctmHeader8, sizeof(CTMHeader8), 1, mFile);
|
||||
break;
|
||||
case 9:
|
||||
fread(&ctmHeader9, sizeof(CTMHeader9), 1, mFile);
|
||||
ctmHeader8.mDispMode = ctmHeader9.mDispMode;
|
||||
ctmHeader8.mColorMethod = ctmHeader9.mColorMethod;
|
||||
ctmHeader8.mFlags = ctmHeader9.mFlags;
|
||||
if (ctmHeader.mID[2] == 'T')
|
||||
{
|
||||
fread(&cttHeader9, sizeof(CTTHeader9), 1, mFile);
|
||||
ctmHeader8.mDispMode = cttHeader9.mDispMode;
|
||||
ctmHeader8.mColorMethod = cttHeader9.mColorMethod;
|
||||
ctmHeader8.mFlags = cttHeader9.mFlags;
|
||||
}
|
||||
else
|
||||
{
|
||||
fread(&ctmHeader9, sizeof(CTMHeader9), 1, mFile);
|
||||
ctmHeader8.mDispMode = ctmHeader9.mDispMode;
|
||||
ctmHeader8.mColorMethod = ctmHeader9.mColorMethod;
|
||||
ctmHeader8.mFlags = ctmHeader9.mFlags;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ const char* TokenNames[] =
|
|||
"'extern'",
|
||||
"'inline'",
|
||||
"'__assume'",
|
||||
"'static_assert'",
|
||||
|
||||
"__asm",
|
||||
"__interrupt",
|
||||
|
@ -822,28 +823,36 @@ void Scanner::NextPreToken(void)
|
|||
}
|
||||
else if (mToken == TK_PREP_IDENT)
|
||||
{
|
||||
Macro* def = nullptr;
|
||||
if (mDefineArguments)
|
||||
def = mDefineArguments->Lookup(mTokenIdent);
|
||||
if (!def)
|
||||
def = mDefines->Lookup(mTokenIdent);
|
||||
|
||||
if (def)
|
||||
if (mTokenIdent->mString[0])
|
||||
{
|
||||
if (def->mNumArguments == -1)
|
||||
Macro* def = nullptr;
|
||||
if (mDefineArguments)
|
||||
def = mDefineArguments->Lookup(mTokenIdent);
|
||||
if (!def)
|
||||
def = mDefines->Lookup(mTokenIdent);
|
||||
|
||||
if (def)
|
||||
{
|
||||
mToken = TK_STRING;
|
||||
int i = 0;
|
||||
while ((mTokenString[i] = def->mString[i]))
|
||||
i++;
|
||||
mTokenStringSize = i;
|
||||
return;
|
||||
if (def->mNumArguments == -1)
|
||||
{
|
||||
mToken = TK_STRING;
|
||||
int i = 0;
|
||||
while ((mTokenString[i] = def->mString[i]))
|
||||
i++;
|
||||
mTokenStringSize = i;
|
||||
return;
|
||||
}
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
|
||||
}
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
|
||||
}
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
|
||||
{
|
||||
mToken = TK_HASH;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (mToken == TK_PREP_UNDEF)
|
||||
{
|
||||
|
@ -1824,6 +1833,8 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_ASM;
|
||||
else if (!strcmp(tkident, "__assume"))
|
||||
mToken = TK_ASSUME;
|
||||
else if (!strcmp(tkident, "static_assert"))
|
||||
mToken = TK_STATIC_ASSERT;
|
||||
else if (!strcmp(tkident, "__interrupt"))
|
||||
mToken = TK_INTERRUPT;
|
||||
else if (!strcmp(tkident, "__hwinterrupt"))
|
||||
|
@ -2003,7 +2014,7 @@ void Scanner::NextRawToken(void)
|
|||
|
||||
default:
|
||||
// dirty little hack to implement token preview, got to fix
|
||||
// this with an infinit preview sequence at one point
|
||||
// this with an infinite preview sequence at one point
|
||||
mUngetToken = mToken;
|
||||
mToken = TK_OPERATOR;
|
||||
return;
|
||||
|
|
|
@ -49,6 +49,7 @@ enum Token
|
|||
TK_EXTERN,
|
||||
TK_INLINE,
|
||||
TK_ASSUME,
|
||||
TK_STATIC_ASSERT,
|
||||
|
||||
TK_ASM,
|
||||
TK_INTERRUPT,
|
||||
|
|
|
@ -76,7 +76,7 @@ int main2(int argc, const char** argv)
|
|||
|
||||
#else
|
||||
strcpy(strProductName, "oscar64");
|
||||
strcpy(strProductVersion, "1.31.259");
|
||||
strcpy(strProductVersion, "1.31.261");
|
||||
|
||||
#ifdef __APPLE__
|
||||
uint32_t length = sizeof(basePath);
|
||||
|
@ -111,38 +111,12 @@ int main2(int argc, const char** argv)
|
|||
GrowingArray<const char*> dataFiles(nullptr);
|
||||
GrowingArray<bool> dataFileCompressed(false);
|
||||
|
||||
bool emulate = false, profile = false, customCRT = false;
|
||||
int trace = 0;
|
||||
|
||||
compiler->mPreprocessor->AddPath(basePath);
|
||||
strcpy_s(includePath, basePath);
|
||||
{
|
||||
FILE* crtFile;
|
||||
char crtFileNamePath[FILENAME_MAX];
|
||||
crtFileNamePath[FILENAME_MAX - 1] = '\0';
|
||||
strcpy_s(crtFileNamePath, basePath);
|
||||
strcat_s(crtFileNamePath, "include/crt.h");
|
||||
|
||||
if (!fopen_s(&crtFile, crtFileNamePath, "r"))
|
||||
strcat_s(includePath, "include/");
|
||||
else
|
||||
{
|
||||
strcpy_s(crtFileNamePath, basePath);
|
||||
strcat_s(crtFileNamePath, "include/oscar64/crt.h");
|
||||
|
||||
if (!fopen_s(&crtFile, crtFileNamePath, "r"))
|
||||
strcat_s(includePath, "include/oscar64/");
|
||||
else
|
||||
{
|
||||
printf("Could not locate Oscar64 includes under %s\n", basePath);
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
fclose(crtFile);
|
||||
}
|
||||
compiler->mPreprocessor->AddPath(includePath);
|
||||
strcpy_s(crtPath, includePath);
|
||||
strcat_s(crtPath, "crt.c");
|
||||
|
||||
bool emulate = false, profile = false;
|
||||
int trace = 0;
|
||||
strcat_s(includePath, "include");
|
||||
|
||||
targetPath[0] = 0;
|
||||
diskPath[0] = 0;
|
||||
|
@ -185,6 +159,10 @@ int main2(int argc, const char** argv)
|
|||
{
|
||||
compiler->mPreprocessor->AddPath(arg + 3);
|
||||
}
|
||||
else if (arg[1] == 'i' && arg[2] == 'i' && arg[3] == '=')
|
||||
{
|
||||
strcpy_s(includePath, arg + 4);
|
||||
}
|
||||
else if (arg[1] == 'f' && arg[2] == '=')
|
||||
{
|
||||
dataFiles.Push(arg + 3);
|
||||
|
@ -206,6 +184,7 @@ int main2(int argc, const char** argv)
|
|||
else if (arg[1] == 'r' && arg[2] == 't' && arg[3] == '=')
|
||||
{
|
||||
strcpy_s(crtPath, arg + 4);
|
||||
customCRT = true;
|
||||
}
|
||||
else if (arg[1] == 'd' && arg[2] == '6' && arg[3] == '4' && arg[4] == '=')
|
||||
{
|
||||
|
@ -265,6 +244,8 @@ int main2(int argc, const char** argv)
|
|||
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);
|
||||
}
|
||||
|
@ -576,6 +557,35 @@ 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);
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,31,259,0
|
||||
PRODUCTVERSION 1,31,259,0
|
||||
FILEVERSION 1,31,261,0
|
||||
PRODUCTVERSION 1,31,261,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -43,12 +43,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "oscar64"
|
||||
VALUE "FileDescription", "oscar64 compiler"
|
||||
VALUE "FileVersion", "1.31.259.0"
|
||||
VALUE "FileVersion", "1.31.261.0"
|
||||
VALUE "InternalName", "oscar64.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "oscar64.exe"
|
||||
VALUE "ProductName", "oscar64"
|
||||
VALUE "ProductVersion", "1.31.259.0"
|
||||
VALUE "ProductVersion", "1.31.261.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -34,6 +34,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_03D7013B0D39A89CEA9D267005ADCE39"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_04ABABC55200450383686DD782DD1548"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -394,6 +400,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4B482689C546CDFC92F367BA507E7ADE"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4B8FC526E6CC47FC8321D0191BFDBEDC"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -412,6 +424,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4E94486A43C1D1C032A05ED1E6F1FCEF"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_4E9503F4F8F343739E4685C2066B3AD0"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -508,6 +526,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_65687B00DD49EEBBFFECE831614822A9"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_67C8F824E02B4211B315AB32AB7ABBB1"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -736,14 +760,14 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_98B942589E984AAD381F87F18DDB79D3"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmKey" = "8:_9B2E1BB3CD154CEFB214378A64B0B00C"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_9B2E1BB3CD154CEFB214378A64B0B00C"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmKey" = "8:_9CA4DFBA483A862FBF3DAEDE506D7DBD"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
|
@ -772,14 +796,14 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A14BC161099E420286E6A1595596D0F0"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmKey" = "8:_A1455504C259EDA9662CE90C07369CC5"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A16BC2645A14DC0435B7119153B32DE8"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmKey" = "8:_A14BC161099E420286E6A1595596D0F0"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
|
@ -802,6 +826,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A2F68033370E18CD792ECD1F91357C1B"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_A32310DEFD4E41118CD7D36A8614C0D4"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -856,6 +886,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_AD3AED76152E705799261747B7FD2015"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_AE023AEA6C444140B19CD627DDC2CB87"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -904,12 +940,6 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_B61CD152136A6E3CE5FF69D29E7A3F7B"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_B85448D515F0487FB6845119AE346F1D"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -952,6 +982,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_C0E88FBB7B883ED27FFB3C60DBE114B8"
|
||||
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_C239EFB1C3A646809AD2740ABDE747B0"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -1048,6 +1084,18 @@
|
|||
}
|
||||
"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"
|
||||
|
@ -1469,6 +1517,26 @@
|
|||
"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"
|
||||
|
@ -2669,6 +2737,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4B482689C546CDFC92F367BA507E7ADE"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4B8FC526E6CC47FC8321D0191BFDBEDC"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\resources\\scifiglyph.bin"
|
||||
|
@ -2729,6 +2817,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4E94486A43C1D1C032A05ED1E6F1FCEF"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-locale-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-locale-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4E9503F4F8F343739E4685C2066B3AD0"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\plus4\\ted.c"
|
||||
|
@ -3049,6 +3157,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_65687B00DD49EEBBFFECE831614822A9"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_67C8F824E02B4211B315AB32AB7ABBB1"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\games\\breakout.c"
|
||||
|
@ -3809,26 +3937,6 @@
|
|||
"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"
|
||||
|
@ -3849,6 +3957,26 @@
|
|||
"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"
|
||||
|
@ -3929,6 +4057,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A1455504C259EDA9662CE90C07369CC5"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-time-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-time-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A14BC161099E420286E6A1595596D0F0"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\opp\\ofstream.h"
|
||||
|
@ -3949,26 +4097,6 @@
|
|||
"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"
|
||||
|
@ -4029,6 +4157,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A2F68033370E18CD792ECD1F91357C1B"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A32310DEFD4E41118CD7D36A8614C0D4"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\limits.h"
|
||||
|
@ -4209,6 +4357,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AD3AED76152E705799261747B7FD2015"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-math-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-math-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AE023AEA6C444140B19CD627DDC2CB87"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\cx16\\vera.h"
|
||||
|
@ -4369,26 +4537,6 @@
|
|||
"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"
|
||||
|
@ -4529,6 +4677,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C0E88FBB7B883ED27FFB3C60DBE114B8"
|
||||
{
|
||||
"SourcePath" = "8:api-ms-win-crt-string-l1-1-0.dll"
|
||||
"TargetName" = "8:api-ms-win-crt-string-l1-1-0.dll"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C239EFB1C3A646809AD2740ABDE747B0"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\c64\\types.h"
|
||||
|
@ -4849,6 +5017,46 @@
|
|||
"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"
|
||||
|
@ -6102,15 +6310,15 @@
|
|||
{
|
||||
"Name" = "8:Microsoft Visual Studio"
|
||||
"ProductName" = "8:oscar64"
|
||||
"ProductCode" = "8:{26C4BC0B-097A-4E5B-B403-8E947803667A}"
|
||||
"PackageCode" = "8:{0C803CC6-29F2-44B4-91D3-62724E5BC165}"
|
||||
"ProductCode" = "8:{1B9A0E10-DEA6-4276-AC91-17782FE44D94}"
|
||||
"PackageCode" = "8:{51BFE576-50D1-4F8F-AE7A-9FF07396F53D}"
|
||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||
"AspNetVersion" = "8:2.0.50727.0"
|
||||
"RestartWWWService" = "11:FALSE"
|
||||
"RemovePreviousVersions" = "11:TRUE"
|
||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||
"InstallAllUsers" = "11:FALSE"
|
||||
"ProductVersion" = "8:1.31.259"
|
||||
"ProductVersion" = "8:1.31.261"
|
||||
"Manufacturer" = "8:oscar64"
|
||||
"ARPHELPTELEPHONE" = "8:"
|
||||
"ARPHELPLINK" = "8:"
|
||||
|
@ -6624,7 +6832,7 @@
|
|||
{
|
||||
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
{
|
||||
"SourcePath" = "8:..\\Debugx64\\oscar64.exe"
|
||||
"SourcePath" = "8:..\\Releasex64\\oscar64.exe"
|
||||
"TargetName" = "8:"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
|
|
|
@ -29,7 +29,7 @@ const char MissileChars[] = {
|
|||
#define Charset ((char *)0xd800)
|
||||
|
||||
// Joystick and crosshair control
|
||||
int CrossX = 160, CrossY = 100;
|
||||
volatile int CrossX = 160, CrossY = 100;
|
||||
bool CrossP = false;
|
||||
char CrossDelay = 0;
|
||||
|
||||
|
@ -553,20 +553,22 @@ __interrupt void joy_interrupt()
|
|||
joy_poll(0);
|
||||
|
||||
// Move crosshair coordinates
|
||||
CrossX += 2 * joyx[0]; CrossY += 2 * joyy[0];
|
||||
int cx = CrossX + 2 * joyx[0], cy = CrossY + 2 * joyy[0];
|
||||
|
||||
// Stop at edges of screen
|
||||
if (CrossX < 8)
|
||||
CrossX = 8;
|
||||
else if (CrossX > 312)
|
||||
CrossX = 312;
|
||||
if (CrossY < 20)
|
||||
CrossY = 20;
|
||||
else if (CrossY > 172)
|
||||
CrossY = 172;
|
||||
if (cx < 8)
|
||||
cx = 8;
|
||||
else if (cx > 312)
|
||||
cx = 312;
|
||||
if (cy < 20)
|
||||
cy = 20;
|
||||
else if (cy > 172)
|
||||
cy = 172;
|
||||
|
||||
// Move crosshair sprite
|
||||
spr_move(0, CrossX + 14, CrossY + 40);
|
||||
spr_move(0, cx + 14, cy + 40);
|
||||
CrossX = cx;
|
||||
CrossY = cy;
|
||||
|
||||
// Check button
|
||||
if (joyb[0])
|
||||
|
@ -697,15 +699,17 @@ void game_play(void)
|
|||
// Check if fire request
|
||||
if (CrossP)
|
||||
{
|
||||
int cx = CrossX, cy = CrossY;
|
||||
|
||||
// Find launch site
|
||||
int sx = 160;
|
||||
if (CrossX < 120)
|
||||
if (cx < 120)
|
||||
sx = 24;
|
||||
else if (CrossX > 200)
|
||||
else if (cx > 200)
|
||||
sx = 296;
|
||||
|
||||
// Fire missile
|
||||
missile_start(sx, 184, CrossX, CrossY);
|
||||
missile_start(sx, 184, cx, cy);
|
||||
|
||||
// Reset request
|
||||
CrossP = false;
|
||||
|
|
|
@ -22,7 +22,7 @@ __interrupt void doscroll(void)
|
|||
vic.color_border++;
|
||||
|
||||
// Update raster IRQ for scroll line with new horizontal scroll offset
|
||||
rirq_data(&scroll, 0, 7 - (x & 7));
|
||||
rirq_data(&scroll, 1, 7 - (x & 7));
|
||||
// Copy scrolled version of text when switching over char border
|
||||
if ((x & 7) == 0)
|
||||
memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40);
|
||||
|
@ -37,11 +37,13 @@ int main(void)
|
|||
rirq_init(true);
|
||||
|
||||
// Build switch to scroll line IRQ
|
||||
rirq_build(&scroll, 1);
|
||||
rirq_build(&scroll, 2);
|
||||
// Delay for one line to get to right border
|
||||
rirq_delay(&scroll, 11);
|
||||
// Change control register two with this IRQ
|
||||
rirq_write(&scroll, 0, &vic.ctrl2, 0);
|
||||
rirq_write(&scroll, 1, &vic.ctrl2, 0);
|
||||
// Put it onto the scroll line
|
||||
rirq_set(0, 50 + 24 * 8, &scroll);
|
||||
rirq_set(0, 49 + 24 * 8, &scroll);
|
||||
|
||||
// Build the switch to normal IRQ
|
||||
rirq_build(&restore, 2);
|
||||
|
|
|
@ -20,11 +20,13 @@ int main(void)
|
|||
rirq_init(true);
|
||||
|
||||
// Build switch to scroll line IRQ
|
||||
rirq_build(&scroll, 1);
|
||||
rirq_build(&scroll, 2);
|
||||
// Delay for one line to get to right border
|
||||
rirq_delay(&scroll, 11);
|
||||
// Change control register two with this IRQ
|
||||
rirq_write(&scroll, 0, &vic.ctrl2, 0);
|
||||
rirq_write(&scroll, 1, &vic.ctrl2, 0);
|
||||
// Put it onto the scroll line
|
||||
rirq_set(0, 50 + 24 * 8, &scroll);
|
||||
rirq_set(0, 49 + 24 * 8, &scroll);
|
||||
|
||||
// Build the switch to normal IRQ
|
||||
rirq_build(&bottom, 1);
|
||||
|
@ -46,7 +48,7 @@ int main(void)
|
|||
// wait for raster reaching bottom of screen
|
||||
rirq_wait();
|
||||
// Update raster IRQ for scroll line with new horizontal scroll offset
|
||||
rirq_data(&scroll, 0, 7 - (x & 7));
|
||||
rirq_data(&scroll, 1, 7 - (x & 7));
|
||||
// Copy scrolled version of text when switching over char border
|
||||
if ((x & 7) == 0)
|
||||
memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40);
|
||||
|
|
|
@ -27,7 +27,7 @@ ScreenRow * const color = (ScreenRow *)0xd800;
|
|||
// Move the screen one character to the left
|
||||
void scrollLeft(void)
|
||||
{
|
||||
// Loop horizontaly
|
||||
// Loop horizontally
|
||||
for(char x=0; x<39; x++)
|
||||
{
|
||||
// Unroll vertical loop 16 times
|
||||
|
|
|
@ -64,6 +64,7 @@ const char * scrolltext[] = {
|
|||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
};
|
||||
|
||||
|
||||
|
@ -198,7 +199,7 @@ int main(void)
|
|||
// Update interrupt position
|
||||
for(char i=0; i<5; i++)
|
||||
{
|
||||
int ty = 48 * i + 46 + oy;
|
||||
int ty = 48 * i + 45 + oy;
|
||||
|
||||
// No interrupts below screen bottom
|
||||
if (ty < 250)
|
||||
|
@ -246,7 +247,7 @@ int main(void)
|
|||
case 42:
|
||||
readline(line, lpos);
|
||||
lpos++;
|
||||
if (lpos == 28)
|
||||
if (lpos == 27)
|
||||
lpos = 0;
|
||||
break;
|
||||
case 45:
|
||||
|
|
Loading…
Reference in New Issue