Compare commits

...

279 Commits

Author SHA1 Message Date
drmortalwombat 6ed4adb0ed OPtimize signed+unsigned char arithmetic 2025-06-19 21:54:23 +02:00
drmortalwombat f16c24363c Improve pointer compare constant folding 2025-06-19 12:58:40 +02:00
drmortalwombat fd7e68573c Fold CLC into prev block for dual pointer increment 2025-06-19 09:37:03 +02:00
drmortalwombat f1873f0794 Optimize carry flag analysis with indexed tables 2025-06-17 21:51:19 +02:00
drmortalwombat a01d98e584 Propagate closed bool variables to use sign bit instead of zero/one 2025-06-15 18:10:50 +02:00
drmortalwombat c7a53a5be6 Bump version number 2025-06-15 14:27:49 +02:00
drmortalwombat 4633631d7e Fix double condition propagation 2025-06-15 13:56:11 +02:00
drmortalwombat 100608e0ac Fix loop head split for infinite loops 2025-06-14 12:53:55 +02:00
drmortalwombat 35a0b36a0d Make rasterirq handler more resilient for timing glitches 2025-06-11 09:34:21 +02:00
drmortalwombat 5470db3a5f Fix sidfx state machine sequence end 2025-06-10 21:06:28 +02:00
drmortalwombat d6802f3cb9 Make loop head extraction explicit 2025-06-10 17:41:16 +02:00
drmortalwombat 5b4e0c2b55 Sidfx extend gate sprike condition 2025-06-08 18:19:37 +02:00
drmortalwombat 8175fae67a Add complex loop value forwarding, tweak sidfx state machine 2025-06-07 19:35:40 +02:00
drmortalwombat 13c90eb542 Change SIDFX state machine reset 2025-06-06 20:00:38 +02:00
drmortalwombat f98665c577 Fix bool artihmetic assign combos 2025-06-01 18:40:19 +02:00
drmortalwombat 8843f3feba Fix pointer loop reversal counting from one 2025-06-01 11:51:24 +02:00
drmortalwombat 514cf59398 More short loop reversal 2025-05-31 19:44:33 +02:00
drmortalwombat 03c133cd48 Swap shift/add if add fits in byte before but not after 2025-05-30 17:39:40 +02:00
drmortalwombat 880abea32e Shortcut tiny jump detours after placement 2025-05-29 13:38:00 +02:00
drmortalwombat fc9a8f2a89 Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-05-28 20:49:00 +02:00
drmortalwombat 40c467d958 Improve copy elision 2025-05-28 20:48:37 +02:00
drmortalwombat 4bde6385b8
Merge pull request #250 from ilmich/fix-compiler-build
prepare output directory also to build only the compiler
2025-05-28 12:55:39 +02:00
drmortalwombat 688ef958e3 Add default move constructor and assignment operators 2025-05-27 20:47:03 +02:00
ilmich 6da7223472 prepare output directory also to build only the compiler 2025-05-27 16:33:36 +02:00
drmortalwombat a1d4bc8375 Improve const initialized simple type usage for local variables 2025-05-27 14:03:04 +02:00
drmortalwombat 197e2a91be Optimize carry propagation 2025-05-25 17:37:52 +02:00
drmortalwombat 4d9d628b67 Add static_assert 2025-05-25 12:31:15 +02:00
drmortalwombat f720feebbf Fix global register forward mixing up x and y in one case 2025-05-25 10:15:47 +02:00
drmortalwombat 6076808f5e Relax interrupt complexity limits for local variables on stack 2025-05-24 20:48:04 +02:00
drmortalwombat 0af17f0f40 Fix constness of reference parameter of standard copy assignment operator 2025-05-24 17:49:51 +02:00
drmortalwombat 81e5321bfc Return short simple structs in accu 2025-05-23 12:02:12 +02:00
drmortalwombat 27d3666285 Fix pass struct rvalue return to rvalue parameter conflicting zero page registers 2025-05-22 15:28:39 +02:00
drmortalwombat c6b794db3a Fix kernal io return values 2025-05-22 08:11:49 +02:00
drmortalwombat 1fa4c39a20 Add more math intrinsics 2025-05-21 16:59:52 +02:00
drmortalwombat 0ba148b6bb Make raster interrupt start more deterministic 2025-05-20 18:26:42 +02:00
drmortalwombat 65540da3f7 Optimize signed long compare 2025-05-20 16:05:09 +02:00
drmortalwombat e660757824 Some low level shift optimizations 2025-05-20 11:09:20 +02:00
drmortalwombat 05a6d16dde Some cascading store optimization 2025-05-19 17:23:28 +02:00
drmortalwombat 79ec9af3f2 Fix signed unsigned char compare to promote to int 2025-05-19 15:31:30 +02:00
drmortalwombat 8f37df448f Optimize constant array parameters 2025-05-19 10:03:45 +02:00
drmortalwombat d710a71ba0 Fix static const member qualification with dot 2025-05-19 08:16:58 +02:00
drmortalwombat 8dd211b662 Fix crash in peephole optimizer on potential oob static const array access 2025-05-18 19:25:47 +02:00
drmortalwombat 398ed22b09 Fix array member packing strategy 2025-05-18 18:41:37 +02:00
drmortalwombat 6f1da4335b Fix continue/break for unrolled loops 2025-05-18 14:04:14 +02:00
drmortalwombat c86dc364b1 Fixed array size template parameter 2025-05-18 11:35:13 +02:00
drmortalwombat 70eb7a5eab Fix assert with negative array offset in local variable of a recursive function 2025-05-18 11:03:04 +02:00
drmortalwombat c1cd2ba57e Fix crash with partial reference of ternary conditional operator 2025-05-18 09:42:37 +02:00
drmortalwombat 00da0ef87d Add CAPACITYCHECK to static_vector 2025-05-17 09:07:33 +02:00
drmortalwombat be9abbf510 Optimize vector copy 2025-05-16 18:20:23 +02:00
drmortalwombat 0b72e6b2f2 Force nop for breakpoint() to avoid elimination if alone in basic block 2025-05-16 17:25:58 +02:00
drmortalwombat 6ea39d7bfa CTT file import 2025-05-15 17:50:59 +02:00
drmortalwombat c0abe031ee Fix enum base type selection with trailing comma 2025-05-15 08:46:57 +02:00
drmortalwombat fe667863b2 Constant folding of absolute pointer difference 2025-05-15 07:58:58 +02:00
drmortalwombat e514e05dc8 Fix crash constant folding uninitialized constants 2025-05-14 20:22:25 +02:00
drmortalwombat d978d0a483 Fix error message location for integer const truncation 2025-05-14 18:25:20 +02:00
drmortalwombat 37cacdafa7 Improve cross compilation unit template matching 2025-05-14 18:18:13 +02:00
drmortalwombat 78e3696663 Improve nullptr check for addresses of placed linker objects 2025-05-14 17:09:12 +02:00
drmortalwombat a0215a4f21 Add fix for template overload with multiple includes 2025-05-14 15:15:24 +02:00
drmortalwombat 2310416c46 Propagate non aliasing initializers to compile time constants 2025-05-13 20:48:12 +02:00
drmortalwombat 52db653ec1 Optimize shift code generation 2025-05-12 20:09:57 +02:00
drmortalwombat 6fe76e478f Add -ii option to change default include path 2025-05-11 18:29:57 +02:00
drmortalwombat ba05ec743d Fix high byte address forwarding 2025-05-11 17:31:01 +02:00
drmortalwombat 05ef25a61e Add optimization -Ox to simplify pointer arithmetic by non page crossing 2025-05-11 12:41:40 +02:00
drmortalwombat b26cc4ede7 Remove assembly debug output 2025-05-10 20:24:30 +02:00
drmortalwombat 8dc5f703e8 Fix copy indirect lea elimination 2025-05-10 20:23:45 +02:00
drmortalwombat c05d7e47f4 Add assign to vector and static_vector 2025-05-10 18:50:13 +02:00
drmortalwombat 9dc8489693 Fix copy struct to value struct param, add vsprintf 2025-05-10 17:49:34 +02:00
drmortalwombat f443c97f70 Fix for default copy constructor on init calls 2025-05-10 13:40:36 +02:00
drmortalwombat 4837ceb73f Fix inline assembler optimzier for JSR returning result in X and Y 2025-05-10 13:13:27 +02:00
drmortalwombat 42299c9406 Improve const to immediate propagation 2025-05-10 10:50:42 +02:00
drmortalwombat 850bbfc31a Fix alignment increment problem 2025-05-10 09:53:31 +02:00
drmortalwombat 1e95f51469 Fix building object directly on call stack 2025-05-10 08:33:02 +02:00
drmortalwombat e525e5d62e Optimize copy of arrays of ints 2025-05-09 16:52:04 +02:00
drmortalwombat 18deb8846d Add full() to static_vector 2025-05-08 17:31:16 +02:00
drmortalwombat 34ce9afeae Fix memory use after free error in vector 2025-05-08 17:26:10 +02:00
drmortalwombat d0411b7d52 Fix more function overloads with const 2025-05-08 15:21:59 +02:00
drmortalwombat 34fda8c9b5 Fix const struct parameter overload matching 2025-05-08 13:50:51 +02:00
drmortalwombat b4a357e44f Add clear to vector and static_vector 2025-05-08 12:30:50 +02:00
drmortalwombat 2b224f262b Fix use of hash character in preprocessor defines 2025-05-08 08:18:57 +02:00
drmortalwombat 3c306e0899 Fix loss of register dependency chain when splitting 16bit adds into basic blocks 2025-05-07 13:13:33 +02:00
drmortalwombat e82ab0c7ca Improve shift carry combine 2025-05-06 18:38:44 +02:00
drmortalwombat 983064c694 Fix removal of reference returns when struct member used 2025-05-06 17:00:36 +02:00
drmortalwombat 9230d95bad Fix copy constructor selection in placement new 2025-05-06 08:53:57 +02:00
drmortalwombat 8b0790588b Fix integer range when combining same instruction on alternate paths 2025-05-05 16:52:17 +02:00
drmortalwombat 0a9c43757a Fix reference to value cast 2025-05-05 11:44:10 +02:00
drmortalwombat fccfe35c4f Fix 16bit const add propagation 2025-05-05 11:17:00 +02:00
drmortalwombat 064fed63f5 Fix operator() call on reference parameter 2025-05-04 16:18:07 +02:00
drmortalwombat f43f471124 Fix internal const cast 2025-05-04 16:00:08 +02:00
drmortalwombat f99abb32e2 Fix cost method selection for pointers to incomplete types 2025-05-04 15:27:28 +02:00
drmortalwombat 18f044e90c Fix crash in profile generation 2025-05-04 13:12:14 +02:00
drmortalwombat 5b961c031c Fix reference return from inlined function into inline parameter 2025-05-04 11:05:15 +02:00
drmortalwombat 500cce511f Fix removal of function reference result if only used as target 2025-05-03 17:22:18 +02:00
drmortalwombat 885d6ff706 Fix crash in complex select statement 2025-05-03 09:41:15 +02:00
drmortalwombat efc182ce27
Merge pull request #238 from polluks/patch-4
Fixed minor typo
2025-05-02 17:43:29 +02:00
drmortalwombat 06ef87fe63
Merge pull request #237 from polluks/patch-5
Fixed minor typo
2025-05-02 17:43:05 +02:00
drmortalwombat f3d8251072
Merge pull request #236 from polluks/patch-6
Fixed minor typo
2025-05-02 17:42:37 +02:00
drmortalwombat 0d5efc90ed
Merge pull request #235 from polluks/patch-7
Fixed minor typo
2025-05-02 17:42:18 +02:00
drmortalwombat 30b8e4e970
Merge pull request #234 from polluks/patch-8
Fixed minor typo
2025-05-02 17:41:52 +02:00
drmortalwombat 3da1ddf5da
Merge pull request #233 from polluks/patch-9
Fixed typo
2025-05-02 17:41:29 +02:00
drmortalwombat bfdd1b85fb
Merge pull request #239 from polluks/patch-3
Fixed minor typo
2025-05-02 17:40:59 +02:00
drmortalwombat 686d468d32
Merge pull request #240 from polluks/patch-2
Fixed minor typo
2025-05-02 17:40:39 +02:00
drmortalwombat 23b15678cd
Merge pull request #232 from polluks/patch-10
Fixed minor typo
2025-05-02 17:40:13 +02:00
Stefan d1054abd90
Fixed minor typo 2025-05-02 16:50:57 +02:00
Stefan d358c8359b
Fixed typo 2025-05-02 16:48:56 +02:00
Stefan 9e9494ebf9
Fixed minor typo 2025-05-02 16:46:27 +02:00
Stefan 015ada7a33
Fixed minor typo 2025-05-02 16:44:44 +02:00
drmortalwombat 12e832ebd3 Fix static constexpr in class context 2025-05-02 16:44:24 +02:00
Stefan e327d2a148
Fixed minor typo 2025-05-02 16:41:42 +02:00
Stefan 366f9686dd
Fixed minor typo 2025-05-02 16:39:17 +02:00
Stefan a2927401bc
Fixed minor typo 2025-05-02 16:36:01 +02:00
Stefan bbb339d641
Fixed minor typo 2025-05-02 16:33:35 +02:00
Stefan 8e76334c20
Fixed minor typo 2025-05-02 16:30:49 +02:00
drmortalwombat 739f1e2161 Improve conditional branch integer range propagation 2025-05-01 20:23:13 +02:00
drmortalwombat 4ee6ca5b94 Improve function automatic template matching 2025-05-01 16:04:10 +02:00
drmortalwombat 347898ea53 fix mixup of stack and fast call in virtual function parameter offsets 2025-05-01 10:21:35 +02:00
drmortalwombat 6caed58be4 Fix new operator broken with placement new fix 2025-04-30 22:38:43 +02:00
drmortalwombat c4185832ba Fix method invocation on rvalue reference 2025-04-30 17:06:28 +02:00
drmortalwombat 2b0994b086 Fix placement new for vector constructor 2025-04-29 20:12:48 +02:00
drmortalwombat f9acbc152d Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-04-29 14:26:58 +02:00
drmortalwombat 3eed21567e Fix disabled warning bitset size 2025-04-29 14:26:55 +02:00
drmortalwombat f3370cb149
Merge pull request #226 from CTalkobt/main
Update to reflect mega65 in .md
2025-04-27 14:23:54 +02:00
ctalkobt@ctalkobt.net 494fb97e49 Update to reflect mega65 in .md 2025-04-27 07:38:14 -04:00
drmortalwombat bd8786af0b Improve carry propagation to eliminate sec and clc 2025-04-26 21:25:43 +02:00
drmortalwombat f0a7499814 Ignore nullptr access for volatile data 2025-04-24 15:31:39 +02:00
drmortalwombat da4a90b724 Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-04-24 09:05:59 +02:00
drmortalwombat 96a9109915 Add warning pragma, improved token concatenation in preprocessing 2025-04-24 09:05:57 +02:00
drmortalwombat f5a33edcf4
Merge pull request #224 from polluks/patch-1
Changed make target everywhere
2025-04-23 16:58:45 +02:00
Stefan 1bd98bdeb2
Changed make target everywhere
oops
2025-04-23 15:32:26 +02:00
drmortalwombat e4696a6539
Merge pull request #223 from polluks/wildcard
More POSIX, fixed #190
2025-04-23 11:23:21 +02:00
polluks 74350d6133 oops 2025-04-23 10:40:28 +02:00
drmortalwombat cbf86b2e8f
Merge pull request #219 from polluks/patch-3
Changed make target
2025-04-22 08:21:40 +02:00
Stefan cb757dfaf9
Changed make target
https://www.gnu.org/software/make/manual/html_node/Standard-Targets.html
2025-04-21 22:22:40 +02:00
drmortalwombat 5ad94d01d4
Merge pull request #218 from CTalkobt/main
Correct end address for Mega 65
2025-04-21 20:13:40 +02:00
ctalkobt@ctalkobt.net cdba71b353 Correct end address for M65 2025-04-21 13:46:53 -04:00
drmortalwombat 01d187cf83
Merge pull request #217 from CTalkobt/main
Initial patch to add -tm=mega65 support
2025-04-21 18:48:38 +02:00
drmortalwombat ab06ce74c5 More global namespace fixes 2025-04-21 18:29:01 +02:00
Craig Taylor 1e2b227113
Merge branch 'drmortalwombat:main' into main 2025-04-21 11:53:36 -04:00
ctalkobt@ctalkobt.net 9d5dbe67fe Adjust M65 top of memory to $e000 2025-04-21 11:48:12 -04:00
ctalkobt@ctalkobt.net 9a409ca347 Initial patch to add -tm=mega65 support 2025-04-21 11:12:02 -04:00
drmortalwombat 449acece05 Fix global namespace access 2025-04-21 15:58:49 +02:00
drmortalwombat ee3f6fc4a5 Struct value forwarding 2025-04-21 08:18:55 +02:00
drmortalwombat e95b51609c Optimize loop unrolling 2025-04-18 17:16:56 +02:00
drmortalwombat 323589a484 Optimize compilation time 2025-04-18 12:55:10 +02:00
drmortalwombat 33f4b25f28 Fix C64 ascii to petscii output in conio 2025-04-17 22:38:54 +02:00
drmortalwombat 538d965636 Fix 16bit forward for middle 32bit registers 2025-04-17 18:55:53 +02:00
drmortalwombat 4b99110533 Bump version number 2025-04-10 08:47:24 +02:00
drmortalwombat 94f2489083 Fix TAXA range bypass with trailing multi store 2025-04-08 18:22:45 +02:00
drmortalwombat 6de1b1fd96 Code size optimizations 2025-03-31 17:30:57 +02:00
drmortalwombat 80abcdfe95 Optimize local struct variable usage 2025-03-30 20:22:50 +02:00
drmortalwombat 0dc6588a66 Improve double index register single block loops 2025-03-29 13:30:03 +01:00
drmortalwombat 65ad05c608 Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-03-24 08:56:07 +01:00
drmortalwombat 2db8890453 Fix temp spilling in recursive functions 2025-03-24 08:56:03 +01:00
drmortalwombat 3f4268328e
Merge pull request #198 from root42/detect-basic-and-gotoxy-for-pet
Implement gotoxy for PET
2025-03-23 14:54:10 +01:00
Arne Schmitz 33cabb487b pure C implementation 2025-03-23 13:15:09 +01:00
Arne Schmitz ab2ca897ce pure asm implementation of bsplot 2025-03-22 12:31:05 +01:00
Arne Schmitz 2c37e150a9 comment 2025-03-22 12:31:05 +01:00
Arne Schmitz ee68f2575a better implementation, inspired by cc65 2025-03-22 12:31:05 +01:00
Arne Schmitz 4f100266c3 fix ldy 2025-03-22 12:31:05 +01:00
Arne Schmitz c22a67f95f basic version detection and and implement bsplot for PET 2025-03-22 12:31:05 +01:00
drmortalwombat e6bc6371c9 Fix PET target zero page variable range 2025-03-19 17:16:20 +01:00
drmortalwombat 2acca6d7b1 Fix register load/store bypass when register result still needed 2025-03-19 09:38:40 +01:00
drmortalwombat fc2095301d Fix aliasing problem when auto inlining non early embedded assembly stubs 2025-03-16 20:29:03 +01:00
drmortalwombat 32f0b8c6f3 Fix warnings in unreachable code 2025-03-16 15:53:27 +01:00
drmortalwombat 10c9b735e9 Fix short infinite loop code split 2025-03-15 21:17:21 +01:00
drmortalwombat fefb511404 Fix integer range loss in loop index reduction 2025-03-15 17:59:45 +01:00
drmortalwombat bedafe7b6f Fix loss of type reduction in loop causing overflow error 2025-03-15 12:05:34 +01:00
drmortalwombat 242d7f1700 Fix optimizer crash with volatile long ops 2025-03-14 08:10:36 +01:00
drmortalwombat 90e892dfa5
Merge pull request #199 from polluks/patch-2
Fixed install
2025-03-12 08:12:34 +01:00
drmortalwombat c98e0751b0 Fix carry usage check in inline assembler, add optional volatile to __asm 2025-03-12 08:11:23 +01:00
Stefan f3b4a4e5fc
Fixed install
Long options are not POSIX.
2025-03-11 23:01:49 +01:00
drmortalwombat 1c7d71cadb Fix loop unrolling changing boundary constant 2025-03-11 08:19:49 +01:00
drmortalwombat 840050738f Fix compare of enum in striped bitfield 2025-03-09 10:49:23 +01:00
drmortalwombat 2ee5cc7bf4 Fix loss of memory live status when reversing compare 2025-03-07 17:23:50 +01:00
drmortalwombat 490180f9dc Fix compare reversal and reuse if z flag used 2025-03-07 08:17:51 +01:00
drmortalwombat 2582f3076d Fix passing rvalue to non const reference 2025-03-02 15:02:01 +01:00
drmortalwombat 0032d42b2c Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-02-28 16:20:10 +01:00
drmortalwombat 5c70c20c6e Reverse cross block accu to index propagation 2025-02-28 16:20:07 +01:00
drmortalwombat 71236aa405
Merge pull request #193 from polluks/patch-1
Fixed minor typos
2025-02-25 15:50:15 +01:00
Stefan 31a38e2a62
Fixed minor typos 2025-02-25 13:44:32 +01:00
drmortalwombat ee0e4d5428 Fix void pointer arithmetic 2025-02-23 11:04:29 +01:00
drmortalwombat f6296e83e5 Improve outliner for short loops 2025-02-18 14:51:42 +01:00
drmortalwombat 39840b5fb1 Convert add to compare if only flags needed 2025-02-18 11:35:06 +01:00
drmortalwombat fe0bfccfaa Reduce eagerness to join stores with short leas 2025-02-18 09:22:28 +01:00
drmortalwombat 25ee4e9b2b Shortcut known branch cascades 2025-02-17 13:12:28 +01:00
drmortalwombat 9f7d4c0ab0 Improved index register use in short loops 2025-02-16 17:16:27 +01:00
drmortalwombat 038928232c Propagate conditional stores behind blocks 2025-02-15 10:51:55 +01:00
drmortalwombat 100affa083 Reverse zp register alias move across single block loops 2025-02-14 10:40:00 +01:00
drmortalwombat e27075955d Optimize enums in bitfield usage 2025-02-12 15:12:06 +01:00
drmortalwombat 0959a15b10 Fixed striped structs with bitfields 2025-02-09 22:10:39 +01:00
drmortalwombat 4a87e4d97b Fix no inline for overloaded operators 2025-02-08 11:04:19 +01:00
drmortalwombat 9de7caa68d Fix enums in bitfields 2025-02-05 10:57:58 +01:00
drmortalwombat e23d78eb86 Fix move of store abs cross function call 2025-02-01 20:13:18 +01:00
drmortalwombat d0b45fce78 Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2025-01-31 18:43:07 +01:00
drmortalwombat 0126dd53a3 Fix infinite optimizer loop 2025-01-31 18:43:01 +01:00
drmortalwombat 901c8459ec
Merge pull request #186 from seclorum/main
Created a CMakeLists.txt for the project
2025-01-24 20:09:43 +01:00
Jay Vaughan 746fed6704 Get target_sources through glob'ing instead of explicit filenames 2025-01-24 19:07:18 +01:00
Jay Vaughan 54c0f2a670 Created a CMakeLists.txt for the project - oscar64 can now be built on MacOS/Darwin with cmake 2025-01-24 15:17:31 +01:00
drmortalwombat 28ea8ef24f Fix integer value range for ext8to16 unsigned 2025-01-22 21:40:51 +01:00
drmortalwombat 115129e1dd Reorder lda x, cmp y to reuse y 2025-01-21 22:26:57 +01:00
drmortalwombat f41d594015 Fix load/binop/store with different sizes 2025-01-19 21:26:25 +01:00
drmortalwombat c8abb42c3c Optimize outliner compile time performance 2025-01-19 18:10:02 +01:00
drmortalwombat 95732265f6 Add experimental native code outliner 2025-01-19 17:28:20 +01:00
drmortalwombat 9f834c4232 Fix integer type coercion with cast operator 2025-01-18 10:13:29 +01:00
drmortalwombat d10d8bf7ae Optimize index register use for one bit high byte 2025-01-10 21:09:03 +01:00
drmortalwombat f6a2db7866 Reuse index register transfer to avoid compare 2025-01-09 20:12:09 +01:00
drmortalwombat d2fdbd29f5 Add loop sinking optimization 2025-01-09 10:54:45 +01:00
drmortalwombat f5dff9620b Fix degrading merge of stores that prevent absolute addressing 2025-01-07 22:07:36 +01:00
drmortalwombat 28e75a8fa2 Fix invalid double dereference reorder 2025-01-06 22:05:43 +01:00
drmortalwombat 6170c81af3 Improve 8 to 16 bit signed add 2025-01-06 18:54:21 +01:00
drmortalwombat 3d578170db Improve 16bit op pair reordering 2025-01-06 15:58:41 +01:00
drmortalwombat d99499b6e3 Improve double indexed pointer from table 2025-01-04 11:11:37 +01:00
drmortalwombat 950c434157 Improve const range propagation after byte compare 2025-01-04 09:12:56 +01:00
drmortalwombat d6362a305f Improve const bitmask optimization 2025-01-03 14:29:08 +01:00
drmortalwombat 38bb033328 Fix global variable changes bypassing assembly blocks 2024-12-30 18:06:26 +01:00
drmortalwombat 87f1ddd27f Fix usage of assembler labels as pointer initializer 2024-12-29 10:22:01 +01:00
drmortalwombat 9e994560a7 Improve double indexed loop with fixed stride 2024-12-29 09:46:33 +01:00
drmortalwombat e37de95079 Add bounded integer class 2024-12-26 14:57:23 +01:00
drmortalwombat 8e46ae95ec Improve unsigned compare result propagation 2024-12-24 15:23:02 +01:00
drmortalwombat e7cece0f0f Fix debug assert for negative array index intermediate result 2024-12-23 22:31:04 +01:00
drmortalwombat 890a4b996e Merge branch 'main' of https://github.com/drmortalwombat/oscar64 2024-12-22 21:22:08 +01:00
drmortalwombat 5b2ae228cc Improve table pointer forwarding 2024-12-22 21:22:05 +01:00
drmortalwombat 9fc8315f92
Merge pull request #179 from root42/pet-kbhit
kbhit variant for CBM PET
2024-12-18 12:02:31 +01:00
Arne Schmitz 32935cd7a1 use keyboard buffer instead 2024-12-18 11:59:01 +01:00
Arne Schmitz fd02382d38 kbhit variant for CBM PET 2024-12-18 11:47:26 +01:00
drmortalwombat 4fce263228 Optimize hires line draw 2024-12-15 16:34:53 +01:00
drmortalwombat 50c7e10814 Add forward declaration of __asm code 2024-12-08 12:05:02 +01:00
drmortalwombat 7c8ab991be Bump version number 2024-12-07 13:08:37 +01:00
drmortalwombat 067e169803 Fix analysis of register usage of inline assembler 2024-12-06 18:54:55 +01:00
drmortalwombat ccdbbe799a Fix assert in linux autotest 2024-12-05 08:05:43 +01:00
drmortalwombat fac53cfd54 Add "-strict" command line option, to loosen C syntax and allow default arguments when not set 2024-12-03 09:03:43 +01:00
drmortalwombat cfe2c7bed5 Fix infinite loop in parser due to failure to detect label 2024-12-02 16:27:13 +01:00
drmortalwombat f0b9b5cce4 More C++ aggregate initialization 2024-12-02 15:39:14 +01:00
drmortalwombat 803b868356 Improve zero page addressing of global variables in inline assembler 2024-12-01 15:33:51 +01:00
drmortalwombat 907452d918 Fix rirq_sort when called from within interrupt 2024-11-30 13:01:09 +01:00
drmortalwombat c12bca7b4e Fix crash in optimizer due to lack of updated register dependecy set when splitting block in loop 2024-11-30 09:40:26 +01:00
drmortalwombat e1736c8214 Reverse shift with negated distance 2024-11-21 22:02:25 +01:00
drmortalwombat d3e7a991a4 Fix int to bool coercion 2024-11-19 18:42:07 +01:00
drmortalwombat e7b0d17a83 Add some std library functions 2024-11-19 16:22:09 +01:00
drmortalwombat df18dc273e Forward binary op in txax 2024-11-17 21:54:55 +01:00
drmortalwombat b6341e402d Fix const bool to int conversion in loop 2024-11-16 13:48:47 +01:00
drmortalwombat 3f2f703936 Bump version number 2024-11-14 17:37:07 +01:00
drmortalwombat 4acee4531c Remove needless register transfers from inner loops 2024-11-12 13:37:50 +01:00
drmortalwombat 2a476d3372 Fix const void * type propagation 2024-11-07 10:56:21 +01:00
drmortalwombat 0a41cb044c Relax rules for argument forwarding in direct call chains 2024-11-05 17:20:22 +01:00
drmortalwombat 5a0f736d41 Fix in block branch collides with fcall proxy generation 2024-11-05 08:17:18 +01:00
drmortalwombat 020534dbc8 Bump version number 2024-11-03 17:35:19 +01:00
drmortalwombat cee2801847 Fixed negative offset leas 2024-11-03 15:36:53 +01:00
drmortalwombat 51c38a4723 Fix short lea coalescing with negative offsets 2024-11-03 10:14:18 +01:00
drmortalwombat bb01d1024a Fix striped indirect arrays 2024-11-02 14:52:06 +01:00
drmortalwombat 903a5d9b8b
Update README.md 2024-11-02 11:45:31 +01:00
drmortalwombat e360dea558 Fix link text 2024-11-02 11:40:02 +01:00
drmortalwombat 582443ef5c Split readme and reference 2024-11-02 11:36:30 +01:00
drmortalwombat 80a42216c7 Prepare split of readme and manual 2024-11-02 10:30:11 +01:00
drmortalwombat 6576f4d090
Merge pull request #170 from sehugg/main
Fixed stack-use-after-return bug found with -fsanitize=address,undefined
2024-11-01 22:37:25 +01:00
Steven Hugg 55e983e5a1 Fixed stack-use-after-return bug found with -fsanitize 2024-11-01 15:30:17 -05:00
drmortalwombat a6f9c733a1 Fix drop of reading from volatile with discarding result 2024-11-01 20:32:54 +01:00
drmortalwombat 3c129ff4e5 Fix complex diamond pointer forwarding
Forwarding failed when pointer was used and modified in one branch of the diamond
2024-10-31 22:48:34 +01:00
drmortalwombat db386a5958 Fix multi indirection lea propagation 2024-10-31 07:13:30 +01:00
drmortalwombat 179cc694e3 Reduce code size by recycling nearby jmp for far branches 2024-10-27 16:56:35 +01:00
drmortalwombat 887a51b176 Fix array in struct const declaration without braces 2024-10-26 18:35:29 +02:00
drmortalwombat 5b81379dac Fix const structs in arrays without braces 2024-10-26 17:28:13 +02:00
drmortalwombat 4fff9f7060 Add optional static memory profile output file 2024-10-24 13:58:14 +02:00
drmortalwombat 40c407782d Fix uppercase flag in iostream 2024-10-24 07:21:39 +02:00
drmortalwombat 5946f17632 Detangle XY abs load/store pairs 2024-10-22 17:17:29 +02:00
drmortalwombat 7e0ff7449c Fix address/register mismatch in 16bit sum forwarding 2024-10-22 13:21:16 +02:00
drmortalwombat d597219aea Fix loss of memory live status when shortcuting zp shift add 2024-10-21 21:36:18 +02:00
drmortalwombat a311396cf8 Loop optimization for x and y used in simple loop 2024-10-20 18:09:50 +02:00
drmortalwombat 94607cab7f Fix extern const struct merging 2024-10-20 11:11:43 +02:00
drmortalwombat 4d193a30b0 Fix cia init code 2024-10-19 09:19:07 +02:00
drmortalwombat c1ad265f47 Fix memory type propagation in loop strength reduction 2024-10-18 15:24:08 +02:00
drmortalwombat 4e2a2c99ba Fix x reg zp dependency during peephole shuffle 2024-10-17 18:12:08 +02:00
drmortalwombat ea33f253d4 Reduce branches in short basic block sequences 2024-10-15 07:37:35 +02:00
drmortalwombat ebc41560d9 Fix value forwarding register forgetting memory reference 2024-10-13 19:52:52 +02:00
drmortalwombat 2d2c696aa4 Add sprite pad tile import 2024-10-10 16:12:35 +02:00
drmortalwombat b622c25a56 FIx previous case for TYA as well 2024-10-06 22:31:22 +02:00
drmortalwombat 439cf499ed Fix peephole opt for while (x--) 2024-10-06 22:17:29 +02:00
drmortalwombat cd5f1daaba Fixing O3 cases for gcc tests 2024-10-06 16:44:22 +02:00
drmortalwombat ec95f6dc98 Fix dynamic variable initalizer 2024-10-06 13:59:06 +02:00
drmortalwombat 66dfe5df46 Fixed constant array bounds check regression 2024-10-06 12:47:53 +02:00
87 changed files with 16292 additions and 4375 deletions

67
CMakeLists.txt Normal file
View File

@ -0,0 +1,67 @@
cmake_minimum_required(VERSION 3.15)
# Project name and version
project(oscar64 VERSION 1.0 LANGUAGES CXX)
# Define the executable
add_executable(oscar64)
# Glob all source files in the oscar64/ directory
file(GLOB OSCAR64_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/oscar64/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/oscar64/*.h")
# Add the sources to the target
target_sources(${PROJECT_NAME} PRIVATE ${OSCAR64_SOURCES})
# Add header files
target_include_directories(oscar64 PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
# Compiler settings based on configuration
set_target_properties(oscar64 PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED YES
CXX_EXTENSIONS NO
)
# Set debug and release configurations
target_compile_definitions(oscar64 PRIVATE $<$<CONFIG:Debug>:_DEBUG;_CONSOLE> $<$<CONFIG:Release>:NDEBUG;_CONSOLE>)
target_compile_options(oscar64 PRIVATE $<$<CONFIG:Debug>:/W3 /WX> $<$<CONFIG:Release>:/O2 /W3>)
# Post-build steps (only for Release builds)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
add_custom_command(TARGET oscar64 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:oscar64> ${CMAKE_BINARY_DIR}/bin
)
endif()
if (WIN32)
target_link_libraries(oscar64 PRIVATE kernel32 user32 gdi32 winspool comdlg32 advapi32 shell32 ole32 oleaut32 uuid odbc32 odbccp32 version)
elseif (APPLE)
# Add macOS-specific frameworks to replace Windows libraries
target_link_libraries(${PROJECT_NAME}
"-framework Cocoa" # For GUI and application support
"-framework CoreFoundation" # For Core Foundation utilities (similar to advapi32 or shell32)
"-framework CoreGraphics" # For graphics and rendering (similar to gdi32)
"-framework IOKit" # For hardware interaction
"-framework AppKit" # For GUI (equivalent to user32)
)
elseif (UNIX)
# Add Linux-specific libraries for equivalent functionality
target_link_libraries(${PROJECT_NAME}
pthread # For threading (similar to kernel32)
dl # For dynamic library loading (similar to LoadLibrary)
m # For math library (optional but common on Linux)
X11 # For X Window System (similar to user32 for GUI support)
)
endif()
# Output directories
set_target_properties(oscar64 PROPERTIES
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Debug
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Release
)

1522
README.md

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,8 @@
rem @echo off rem @echo off
@call :test rolrortest.cpp
@if %errorlevel% neq 0 goto :error
@call :test bitfields.cpp @call :test bitfields.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@ -15,6 +18,9 @@ rem @echo off
@call :testh opp_vector.cpp @call :testh opp_vector.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :testh opp_static_vector.cpp
@if %errorlevel% neq 0 goto :error
@call :testh opp_vector_string.cpp @call :testh opp_vector_string.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@ -33,7 +39,7 @@ rem @echo off
@call :testh opp_list.cpp @call :testh opp_list.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :testh opp_functional.cpp @call :testn opp_functional.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :testh operatoroverload.cpp @call :testh operatoroverload.cpp
@ -51,7 +57,7 @@ rem @echo off
@call :testh constructortest.cpp @call :testh constructortest.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :testh copyconstructor.cpp @call :testn copyconstructor.cpp
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :testh copyassign.cpp @call :testh copyassign.cpp
@ -274,6 +280,15 @@ exit /b %errorlevel%
..\bin\oscar64 -e -O2 -n -dHEAPCHECK %~1 ..\bin\oscar64 -e -O2 -n -dHEAPCHECK %~1
@if %errorlevel% neq 0 goto :error @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 ..\bin\oscar64 -e -O0 -bc %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@ -331,6 +346,12 @@ exit /b %errorlevel%
..\bin\oscar64 -e -O2 -xz -Oz -n %~1 ..\bin\oscar64 -e -O2 -xz -Oz -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Oo -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Ox -n %~1
@if %errorlevel% neq 0 goto :error
@exit /b 0 @exit /b 0
:testb :testb
@ -370,4 +391,10 @@ exit /b %errorlevel%
..\bin\oscar64 -e -O2 -xz -Oz -n %~1 ..\bin\oscar64 -e -O2 -xz -Oz -n %~1
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Oo -n %~1
@if %errorlevel% neq 0 goto :error
..\bin\oscar64 -e -O2 -Ox -n %~1
@if %errorlevel% neq 0 goto :error
@exit /b 0 @exit /b 0

View File

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

View File

@ -50,5 +50,11 @@ autorefreturn: autorefreturn.cpp
$(OSCAR64_CC) -e -Os -n $< $(OSCAR64_CC) -e -Os -n $<
$(OSCAR64_CC) -e -O3 -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: clean:
@$(RM) *.asm *.bcs *.int *.lbl *.map *.prg @$(RM) *.asm *.bcs *.int *.lbl *.map *.prg

View File

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

View File

@ -64,5 +64,15 @@ int main(void)
opp::cout << i << ", "; opp::cout << i << ", ";
opp::cout << "\n"; 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; return 0;
} }

76
autotest/rolrortest.cpp Normal file
View File

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

View File

@ -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) bool beqz(long a)
{ {
return a == 0; 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 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); 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); 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) void cmpz(long a)
{ {
bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(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); 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) int main(void)
{ {
cmp( 0, 1); cmp( 0, 1);
@ -327,6 +454,10 @@ int main(void)
cmp1(256); cmp1(256);
cmp1(10000); cmp1(10000);
cmp1(20000); cmp1(20000);
cmp1(1000000l);
cmp1(2000000l);
cmp1(100000000l);
cmp1(200000000l);
cmp1(-1); cmp1(-1);
cmp1(-2); cmp1(-2);
cmp1(-3); cmp1(-3);
@ -334,6 +465,34 @@ int main(void)
cmp1(-256); cmp1(-256);
cmp1(-10000); cmp1(-10000);
cmp1(-20000); 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; return 0;

View File

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

View File

@ -20,6 +20,8 @@ inline void sidfx_play(byte chn, const SIDFX * fx, byte cnt);
void sidfx_stop(byte chn); void sidfx_stop(byte chn);
char sidfx_cnt(byte chn);
void sidfx_loop(void); void sidfx_loop(void);
void sidfx_loop_2(void); void sidfx_loop_2(void);

View File

@ -16,7 +16,7 @@ void cia_init(void)
cia2.ddrb = 0x00; cia2.ddrb = 0x00;
cia1.ddra = 0xff; cia1.ddra = 0xff;
cia2.prb = 0x07; cia2.pra = 0x07;
cia2.ddra = 0x3f; cia2.ddra = 0x3f;
char i0 = cia1.icr; char i0 = cia1.icr;

View File

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

View File

@ -5,16 +5,16 @@
#include <c64/asm6502.h> #include <c64/asm6502.h>
#include <stdlib.h> #include <stdlib.h>
volatile char npos = 1, tpos = 0;
volatile byte rirq_count; volatile byte rirq_count;
static byte rirq_pcount;
byte rasterIRQRows[NUM_IRQS + 1]; byte rasterIRQRows[NUM_IRQS + 1];
byte rasterIRQIndex[NUM_IRQS + 1]; byte rasterIRQIndex[NUM_IRQS + 1]; // Sort order of interrupt index, offset by one
#ifdef ZPAGE_IRQS #ifdef ZPAGE_IRQS
__zeropage __zeropage
#endif #endif
byte rasterIRQNext[NUM_IRQS + 1]; byte rasterIRQNext[NUM_IRQS + 1]; // Rasterline of interrupt, terminated by 0xff
byte rasterIRQLow[NUM_IRQS]; byte rasterIRQLow[NUM_IRQS]; // Address of interrupt code
byte rasterIRQHigh[NUM_IRQS]; byte rasterIRQHigh[NUM_IRQS];
#ifdef ZPAGE_IRQS #ifdef ZPAGE_IRQS
@ -22,28 +22,25 @@ __zeropage
#endif #endif
byte nextIRQ; byte nextIRQ;
__asm irq0 // nextIRQ is the index of the next expected IRQ, or $ff if no IRQ is scheduled
__asm rirq_isr_ram_io
{ {
pha stx plrx + 1
txa
pha
tya
pha
kentry:
asl $d019
ldx nextIRQ ldx nextIRQ
bmi exi
sta plra + 1
sty plry + 1
l1: l1:
lda rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x ldy rasterIRQIndex + 1, x
tax ldx rasterIRQLow, y
lda rasterIRQLow, y stx ji + 1
sta ji + 1 ldx rasterIRQHigh, y
lda rasterIRQHigh, y stx ji + 2
sta ji + 2
ji: ji:
jsr $0000 jsr $0000
@ -51,21 +48,82 @@ ji:
inc nextIRQ inc nextIRQ
ldx nextIRQ ldx nextIRQ
lda rasterIRQNext, x ldy rasterIRQNext, x
cmp #$ff
beq e2
// carry is cleared at this point
tay asl $d019
sbc #2
cmp $d012 cpy #$ff
bcc l1 beq e2
dey
sty $d012
dey
cpy $d012
bcc l1
plry:
ldy #0
plra:
lda #0
plrx:
ldx #0
rti
exi:
asl $d019
jmp plrx
// No more interrupts to service
e2:
inc rirq_count
ldy rasterIRQNext
dey
sty $d012
ldx #0
stx nextIRQ
beq plry
}
__asm rirq_isr_io
{
pha
txa
pha
tya
pha
kentry:
ldx nextIRQ
bmi exi
l1:
lda rasterIRQNext, x
ldy rasterIRQIndex + 1, x
ldx rasterIRQLow, y
stx ji + 1
ldx rasterIRQHigh, y
stx ji + 2
ji:
jsr $0000
inc nextIRQ
ldx nextIRQ
ldy rasterIRQNext, x
asl $d019
cpy #$ff
beq e2
dey
sty $d012
dey
cpy $d012
bcc l1
exd: exd:
dey
ex:
sty $d012
pla pla
tay tay
pla pla
@ -73,25 +131,22 @@ ex:
pla pla
rti rti
exi:
asl $d019
jmp exd
e2: e2:
ldx npos
stx tpos
inc rirq_count inc rirq_count
tay
bit $d011 ldy rasterIRQNext
bpl ex dey
sty $d012
e1:
ldx #0 ldx #0
stx nextIRQ stx nextIRQ
ldy rasterIRQNext beq exd
jmp exd
} }
__asm irq2 __asm rirq_isr_noio
{ {
pha pha
txa txa
@ -105,20 +160,15 @@ kentry:
lda #$35 lda #$35
sta $01 sta $01
asl $d019
ldx nextIRQ ldx nextIRQ
bmi exi
l1: l1:
lda rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x ldy rasterIRQIndex + 1, x
tax ldx rasterIRQLow, y
lda rasterIRQLow, y stx ji + 1
sta ji + 1 ldx rasterIRQHigh, y
lda rasterIRQHigh, y stx ji + 2
sta ji + 2
ji: ji:
jsr $0000 jsr $0000
@ -126,21 +176,20 @@ ji:
inc nextIRQ inc nextIRQ
ldx nextIRQ ldx nextIRQ
lda rasterIRQNext, x ldy rasterIRQNext, x
cmp #$ff
asl $d019
cpy #$ff
beq e2 beq e2
// carry is cleared at this point
tay
dey dey
sbc #2
cmp $d012
bcc l1
sty $d012 sty $d012
dey
cpy $d012
bcc l1
ex: exd:
pla pla
sta $01 sta $01
@ -151,45 +200,35 @@ ex:
pla pla
rti rti
e2: exi:
asl $d019
jmp exd
ldx npos e2:
stx tpos
inc rirq_count inc rirq_count
bit $d011
bmi e1
sta $d012
jmp ex
e1:
ldx #0
stx nextIRQ
ldy rasterIRQNext ldy rasterIRQNext
dey dey
sty $d012 sty $d012
jmp ex ldx #0
stx nextIRQ
beq exd
} }
__asm irq1 __asm rirq_isr_kernal_io
{ {
lda $d019 lda $d019
bpl ex2 bpl ex2
ldx nextIRQ ldx nextIRQ
bmi exi
l1: l1:
lda rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x ldy rasterIRQIndex + 1, x
tax ldx rasterIRQLow, y
lda rasterIRQLow, y stx ji + 1
sta ji + 1 ldx rasterIRQHigh, y
lda rasterIRQHigh, y stx ji + 2
sta ji + 2
ji: ji:
jsr $0000 jsr $0000
@ -198,45 +237,36 @@ jx:
inc nextIRQ inc nextIRQ
ldx nextIRQ ldx nextIRQ
lda rasterIRQNext, x ldy rasterIRQNext, x
cmp #$ff
beq e2
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 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 jmp $ea81
ex2: ex2:
@ -245,7 +275,7 @@ ex2:
jmp $ea31 jmp $ea31
} }
__asm irq3 __asm rirq_isr_kernal_noio
{ {
lda $01 lda $01
pha pha
@ -256,17 +286,14 @@ __asm irq3
bpl ex2 bpl ex2
ldx nextIRQ ldx nextIRQ
bmi exi
l1: l1:
lda rasterIRQNext, x lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex + 1, x ldy rasterIRQIndex + 1, x
tax ldx rasterIRQLow, y
lda rasterIRQLow, y stx ji + 1
sta ji + 1 ldx rasterIRQHigh, y
lda rasterIRQHigh, y stx ji + 2
sta ji + 2
ji: ji:
jsr $0000 jsr $0000
@ -275,49 +302,40 @@ jx:
inc nextIRQ inc nextIRQ
ldx nextIRQ ldx nextIRQ
lda rasterIRQNext, x ldy rasterIRQNext, x
cmp #$ff
asl $d019
cpy #$ff
beq e2 beq e2
tay dey
sec
sbc #4
cmp $d012
bcc l1
dey dey
sty $d012 sty $d012
w1: dey
jmp ex cpy $d012
bcc l1
e2: exd:
ldx npos
stx tpos
inc rirq_count
bit $d011
bmi e1
sta $d012
jmp ex
e1:
ldx #0
stx nextIRQ
lda rasterIRQNext, x
sec
sbc #1
sta $d012
ex:
asl $d019
pla pla
sta $01 sta $01
jmp $ea81 jmp $ea81
exi:
asl $d019
jmp exd
e2:
inc rirq_count
ldy rasterIRQNext
dey
dey
sty $d012
ldx #0
stx nextIRQ
beq exd
ex2: ex2:
LDA $DC0D LDA $DC0D
cli cli
@ -347,8 +365,8 @@ void rirq_build(RIRQCode * ic, byte size)
ic->size = size; ic->size = size;
asm_im(ic->code + 0, ASM_LDY, 0); asm_im(ic->code + 0, ASM_LDY, 0);
asm_im(ic->code + 2, ASM_LDA, 0); asm_im(ic->code + 2, ASM_LDX, 0);
asm_ab(ic->code + 4, ASM_CPX, 0xd012); asm_ab(ic->code + 4, ASM_CMP, 0xd012);
asm_rl(ic->code + 7, ASM_BCS, -5); asm_rl(ic->code + 7, ASM_BCS, -5);
asm_ab(ic->code + 9, ASM_STY, 0x0000); asm_ab(ic->code + 9, ASM_STY, 0x0000);
@ -362,7 +380,7 @@ void rirq_build(RIRQCode * ic, byte size)
} }
else else
{ {
asm_ab(ic->code + 12, ASM_STA, 0x0000); asm_ab(ic->code + 12, ASM_STX, 0x0000);
byte p = 15; byte p = 15;
for(byte i=2; i<size; i++) for(byte i=2; i<size; i++)
@ -421,7 +439,8 @@ void rirq_addrhi(RIRQCode * ic, byte n, byte hi)
void rirq_data(RIRQCode * ic, byte n, byte data) void rirq_data(RIRQCode * ic, byte n, byte data)
{ {
byte p = irqdi[n]; byte p = irqdi[n];
ic->code[p] = data; // ic->code[p] = data;
(volatile char *)(ic->code)[p] = data;
} }
void rirq_write(RIRQCode * ic, byte n, void * addr, byte data) void rirq_write(RIRQCode * ic, byte n, void * addr, byte data)
@ -481,7 +500,7 @@ void rirq_init_kernal(void)
sei sei
} }
*(void **)0x0314 = irq1; *(void **)0x0314 = rirq_isr_kernal_io;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; 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(); rirq_init_tables();
@ -498,7 +517,7 @@ void rirq_init_kernal_io(void)
sei sei
} }
*(void **)0x0314 = irq3; *(void **)0x0314 = rirq_isr_kernal_noio;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; vic.ctrl1 &= 0x7f;
@ -515,8 +534,8 @@ void rirq_init_crt(void)
sei sei
} }
*(void **)0x0314 = irq0.kentry; *(void **)0x0314 = rirq_isr_io.kentry;
*(void **)0xfffe = irq0; *(void **)0xfffe = rirq_isr_io;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; 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(); rirq_init_tables();
@ -533,8 +552,8 @@ void rirq_init_crt_io(void)
sei sei
} }
*(void **)0x0314 = irq2.kentry; *(void **)0x0314 = rirq_isr_noio.kentry;
*(void **)0xfffe = irq2; *(void **)0xfffe = rirq_isr_noio;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; vic.ctrl1 &= 0x7f;
@ -551,7 +570,7 @@ void rirq_init_io(void)
sei sei
} }
*(void **)0xfffe = irq0; *(void **)0xfffe = rirq_isr_ram_io;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; vic.ctrl1 &= 0x7f;
@ -568,7 +587,7 @@ void rirq_init_memmap(void)
sei sei
} }
*(void **)0xfffe = irq2; *(void **)0xfffe = rirq_isr_noio;
vic.intr_enable = 1; vic.intr_enable = 1;
vic.ctrl1 &= 0x7f; vic.ctrl1 &= 0x7f;
@ -586,12 +605,18 @@ void rirq_init(bool kernalIRQ)
void rirq_wait(void) void rirq_wait(void)
{ {
while (tpos != npos) ; char i0 = rirq_pcount;
npos++; char i1;
do {
i1 = rirq_count;
} while (i0 == i1);
rirq_pcount = i1;
} }
void rirq_sort(void) void rirq_sort(bool inirq)
{ {
// disable raster interrupts while sorting
nextIRQ = 0xff;
#if 1 #if 1
byte maxr = rasterIRQRows[rasterIRQIndex[1]]; byte maxr = rasterIRQRows[rasterIRQIndex[1]];
for(byte i = 2; i<NUM_IRQS + 1; i++) for(byte i = 2; i<NUM_IRQS + 1; i++)
@ -639,10 +664,18 @@ void rirq_sort(void)
} }
#endif #endif
npos++; rirq_pcount = rirq_count;
byte yp = rasterIRQNext[nextIRQ]; if (inirq)
if (yp != 0xff) nextIRQ = NUM_IRQS - 1;
vic.raster = yp - 1; else
{
byte yp = rasterIRQNext[0];
if (yp != 0xff)
{
vic.raster = yp - 1;
nextIRQ = 0;
}
}
} }
void rirq_start(void) void rirq_start(void)
@ -656,6 +689,7 @@ void rirq_start(void)
lda #100 lda #100
sta $d012 sta $d012
asl $d019
cli cli
} }
} }

View File

@ -154,7 +154,7 @@ void rirq_init_kernal(void);
// Raster IRQ through kernal, with IO range not always enabled // Raster IRQ through kernal, with IO range not always enabled
// calls kernal continuation // 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 // Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range always enabled
// does not call kernal continuation // 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 // Raster IRQ through RAM and ROM vector, with ROM disabled or not and IO range not always enabled
// does not call kernal continuation // 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 // Raster IRQ through RAM vector, with ROM disabled and IO range always enabled
// does not call kernal continuation // does not call kernal continuation
@ -179,8 +179,9 @@ void rirq_start(void);
void rirq_stop(void); void rirq_stop(void);
// Sort the raster IRQ, must be performed at the end of the frame after changing // 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.
void rirq_sort(void); // Set the inirq flag to true when calling this from an interrupt
void rirq_sort(bool inirq = false);
// Wait for the last raster IRQ op to have completed. Must be called before a // Wait for the last raster IRQ op to have completed. Must be called before a
// sort if the raster IRQ system is active // sort if the raster IRQ system is active

View File

@ -171,6 +171,12 @@ void vspr_init(char * screen)
} }
} }
void vspr_shutdown(void)
{
for(int i=0; i<VSPRITES_MAX - 7; i++)
rirq_clear(i);
}
void vspr_screen(char * screen) void vspr_screen(char * screen)
{ {
vspriteScreen = screen + 0x3f8; vspriteScreen = screen + 0x3f8;
@ -309,6 +315,8 @@ void vspr_update(void)
if (!done && spriteYPos[ti + 9] < 250) if (!done && spriteYPos[ti + 9] < 250)
{ {
byte ri = spriteOrder[ti + 8]; byte ri = spriteOrder[ti + 8];
rirq_move(ti, spriteYPos[ti + 1] + 23);
#ifdef VSPRITE_REVERSE #ifdef VSPRITE_REVERSE
char m = 0x80 >> (ti & 7); char m = 0x80 >> (ti & 7);
#else #else
@ -325,7 +333,6 @@ void vspr_update(void)
rirq_data(spirq + ti, 3, vspriteImage[ri]); rirq_data(spirq + ti, 3, vspriteImage[ri]);
rirq_data(spirq + ti, 4, xymask); rirq_data(spirq + ti, 4, xymask);
rirq_move(ti, spriteYPos[ti + 1] + 23);
// spriteYPos[ti + 9] = vspriteYLow[ri]; // spriteYPos[ti + 9] = vspriteYLow[ri];
} }
else else

View File

@ -68,6 +68,8 @@ inline void spr_expand(char sp, bool xexpand, bool yexpand);
void vspr_init(char * screen); void vspr_init(char * screen);
void vspr_shutdown(void);
void vspr_screen(char * screen); void vspr_screen(char * screen);
// set one sprite with the given attribute // set one sprite with the given attribute

View File

@ -114,4 +114,21 @@ void vic_waitBelow(int line)
} }
} }
void vic_waitRange(char below, char above)
{
while (vic.ctrl1 & VIC_CTRL1_RST8)
;
if (vic.raster >= above)
{
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
;
while (vic.ctrl1 & VIC_CTRL1_RST8)
;
}
while (vic.raster < below)
;
}
#pragma native(vic_waitLine) #pragma native(vic_waitLine)

View File

@ -118,6 +118,9 @@ void vic_waitLine(int line);
// wait for beam to be below a line // wait for beam to be below a line
void vic_waitBelow(int line); void vic_waitBelow(int line);
// wait for beam to be in a given range on screen
void vic_waitRange(char below, char above);
// reference to the VIC chip // reference to the VIC chip
#define vic (*((struct VIC *)0xd000)) #define vic (*((struct VIC *)0xd000))

View File

@ -131,6 +131,18 @@ __asm bsinit
lda #147 lda #147
jmp $ffd2 jmp $ffd2
} }
#elif defined(__CBMPET__)
#define bsout 0xffd2
#define bsin 0xffe4
__asm bsplot
{
/* no equivalent on PET */
}
__asm bsinit
{
/* no equivalent on PET */
}
#define bsget 0xffcf
#else #else
#define bsout 0xffd2 #define bsout 0xffd2
#define bsin 0xffe4 #define bsin 0xffe4
@ -212,11 +224,10 @@ void putpch(char c)
c ^= 0xa0; c ^= 0xa0;
c ^= 0x20; c ^= 0x20;
#else #else
if (c >= 97) c ^= 0x20;
c ^= 0x20;
#endif #endif
if (giocharmap == IOCHM_PETSCII_2) if (giocharmap == IOCHM_PETSCII_1)
c &= 0xdf; c &= 0xdf;
} }
} }
@ -268,11 +279,19 @@ char getpch(void)
char kbhit(void) char kbhit(void)
{ {
#if defined(__CBMPET__)
return __asm
{
lda $9e
sta accu
};
#else
return __asm return __asm
{ {
lda $c6 lda $c6
sta accu sta accu
}; };
#endif
} }
char getche(void) char getche(void)
@ -323,10 +342,7 @@ void putch(char c)
void clrscr(void) void clrscr(void)
{ {
__asm putrch(147);
{
jsr bsinit
}
} }
void textcursor(bool show) void textcursor(bool show)
@ -336,6 +352,24 @@ void textcursor(bool show)
void gotoxy(char cx, char cy) void gotoxy(char cx, char cy)
{ {
#if defined(__CBMPET__)
#define CURS_X 0xc6
#define CURS_Y 0xd8
#define SCREEN_PTR 0xc4
#define SCR_LINELEN 0xd5
__assume(cy < 25);
*(volatile char *)CURS_X = cx;
*(volatile char *)CURS_Y = cy;
if (*(volatile char *)SCR_LINELEN > 40)
cy <<= 1;
const unsigned off = cy * 40;
* (volatile unsigned *)SCREEN_PTR = off + 0x8000;
#else
__asm __asm
{ {
ldx cy ldx cy
@ -343,6 +377,7 @@ void gotoxy(char cx, char cy)
clc clc
jsr bsplot jsr bsplot
} }
#endif
} }
void textcolor(char c) void textcolor(char c)
@ -350,6 +385,24 @@ void textcolor(char c)
*(volatile char *)0x0286 = c; *(volatile char *)0x0286 = c;
} }
void bgcolor(char c)
{
*(volatile char *)0xd021 = c;
}
void bordercolor(char c)
{
*(volatile char *)0xd020 = c;
}
void revers(char r)
{
if (r)
putrch(18);
else
putrch(18 + 128);
}
char wherex(void) char wherex(void)
{ {
#if defined(__C128__) || defined(__C128B__) || defined(__C128E__) #if defined(__C128__) || defined(__C128B__) || defined(__C128E__)

View File

@ -43,6 +43,26 @@ void dispmode80col(void);
#define PETSCII_F7 0x88 #define PETSCII_F7 0x88
#define PETSCII_F8 0x8c #define PETSCII_F8 0x8c
enum ConioColors
{
COLOR_BLACK,
COLOR_WHITE,
COLOR_RED,
COLOR_CYAN,
COLOR_PURPLE,
COLOR_GREEN,
COLOR_BLUE,
COLOR_YELLOW,
COLOR_ORANGE,
COLOR_BROWN,
COLOR_LT_RED,
COLOR_DARK_GREY,
COLOR_MED_GREY,
COLOR_LT_GREEN,
COLOR_LT_BLUE,
COLOR_LT_GREY
};
// Lowlevel console in/out // Lowlevel console in/out
// using petscii translation // using petscii translation
@ -74,6 +94,12 @@ void gotoxy(char x, char y);
inline void textcolor(char c); inline void textcolor(char c);
inline void bgcolor(char c);
inline void bordercolor(char c);
inline void revers(char r);
inline char wherex(void); inline char wherex(void);
inline char wherey(void); inline char wherey(void);

View File

@ -236,46 +236,40 @@ w0:
// Clear BSS Segment // Clear BSS Segment
#ifndef NOBSSCLEAR #ifndef NOBSSCLEAR
lda #<BSSStart ldx #>BSSStart
sta ip ldy #<BSSStart
lda #>BSSStart
sta ip + 1
sec
lda #>BSSEnd
sbc #>BSSStart
beq w1
tax
lda #0 lda #0
ldy #0 sta ip
l1: sta (ip), y l3:
stx ip + 1
cpx #>BSSEnd
beq w2
l1:
sta (ip), y
iny iny
bne l1 bne l1
inc ip + 1
dex
bne l1
w1:
sec
lda #<BSSEnd
sbc #<BSSStart
beq w2
tay
lda #0
l2: dey
sta (ip), y
bne l2
w2:
#endif
#ifndef NOZPCLEAR
ldx #<ZeroStart
cpx #<ZeroEnd
beq w3
l3: sta $00, x
inx inx
cpx #<ZeroEnd bne l3
bne l3 l2:
w3: sta (ip), y
iny
w2:
cpy #<BSSEnd
bne l2
#endif #endif
#ifndef NOZPCLEAR
lda #0
ldx #<ZeroStart
bne w3
l4: sta $00, x
inx
w3:
cpx #<ZeroEnd
bne l4
#endif
lda #<StackEnd - 2 lda #<StackEnd - 2
sta sp sta sp
lda #>StackEnd - 2 lda #>StackEnd - 2
@ -673,21 +667,19 @@ L1: rol accu
sbc tmp + 1 sbc tmp + 1
lda tmp + 6 lda tmp + 6
sbc tmp + 2 sbc tmp + 2
tax
lda tmp + 7 lda tmp + 7
sbc tmp + 3 sbc tmp + 3
bcc W1 bcc W1
stx tmp + 6
sta tmp + 7
lda tmp + 4 lda tmp + 4
sbc tmp + 0 sbc tmp + 0
sta tmp + 4 sta tmp + 4
lda tmp + 5 lda tmp + 5
sbc tmp + 1 sbc tmp + 1
sta tmp + 5 sta tmp + 5
lda tmp + 6 sec
sbc tmp + 2
sta tmp + 6
lda tmp + 7
sbc tmp + 3
sta tmp + 7
W1: dey W1: dey
bne L1 bne L1
rol accu rol accu
@ -764,6 +756,11 @@ __asm mul32
sta tmp + 6 sta tmp + 6
sta tmp + 7 sta tmp + 7
lda tmp + 3
ora tmp + 2
ora tmp + 1
beq WB
lda tmp + 0 lda tmp + 0
jsr WM jsr WM
lda tmp + 1 lda tmp + 1
@ -781,6 +778,7 @@ WM:
stx accu + 1 stx accu + 1
sta accu sta accu
rts rts
WB: lda tmp + 0
W0: W0:
sec sec
ror ror
@ -3078,7 +3076,7 @@ __asm inp_binop_sub_f32
#pragma bytecode(BC_BINOP_SUB_F32, inp_binop_sub_f32) #pragma bytecode(BC_BINOP_SUB_F32, inp_binop_sub_f32)
__asm fmul8 __asm crt_fmul8
{ {
sec sec
ror ror
@ -3112,7 +3110,7 @@ W1:
rts rts
} }
__asm fmul __asm crt_fmul
{ {
lda accu lda accu
ora accu + 1 ora accu + 1
@ -3153,13 +3151,13 @@ W2:
beq W5 beq W5
bne W6 bne W6
W4: W4:
jsr fmul8 jsr crt_fmul8
lda tmp + 1 lda tmp + 1
W6: W6:
jsr fmul8 jsr crt_fmul8
W5: W5:
lda tmp + 2 lda tmp + 2
jsr fmul8 jsr crt_fmul8
sec sec
lda tmp + 8 lda tmp + 8
@ -3216,12 +3214,12 @@ __asm inp_binop_mul_f32
{ {
jsr freg.split_exp jsr freg.split_exp
sty tmpy sty tmpy
jsr fmul jsr crt_fmul
ldy tmpy ldy tmpy
jmp startup.exec jmp startup.exec
} }
__asm fdiv __asm crt_fdiv
{ {
lda accu lda accu
ora accu + 1 ora accu + 1
@ -3343,13 +3341,13 @@ ZERO:
__asm inp_binop_div_f32 __asm inp_binop_div_f32
{ {
jsr freg.split_exp jsr freg.split_exp
jsr fdiv jsr crt_fdiv
jmp startup.exec jmp startup.exec
} }
#pragma bytecode(BC_BINOP_DIV_F32, inp_binop_div_f32) #pragma bytecode(BC_BINOP_DIV_F32, inp_binop_div_f32)
__asm fcmp __asm crt_fcmp
{ {
lda accu + 3 lda accu + 3
eor tmp + 3 eor tmp + 3
@ -4064,9 +4062,9 @@ __asm load32
#pragma runtime(fmergea, freg.merge_aexp) #pragma runtime(fmergea, freg.merge_aexp)
#pragma runtime(fadd, faddsub.fadd) #pragma runtime(fadd, faddsub.fadd)
#pragma runtime(fsub, faddsub.fsub) #pragma runtime(fsub, faddsub.fsub)
#pragma runtime(fmul, fmul) #pragma runtime(fmul, crt_fmul)
#pragma runtime(fdiv, fdiv) #pragma runtime(fdiv, crt_fdiv)
#pragma runtime(fcmp, fcmp) #pragma runtime(fcmp, crt_fcmp)
#pragma runtime(ffromi, sint16_to_float) #pragma runtime(ffromi, sint16_to_float)
#pragma runtime(ffromu, uint16_to_float) #pragma runtime(ffromu, uint16_to_float)
#pragma runtime(ftoi, f32_to_i16) #pragma runtime(ftoi, f32_to_i16)
@ -4564,7 +4562,7 @@ struct Heap {
#pragma section(heap, 0x0000, HeapStart, HeapEnd) #pragma section(heap, 0x0000, HeapStart, HeapEnd)
__asm malloc __asm crt_malloc
{ {
// make room for two additional bytes // make room for two additional bytes
// to store pointer to end of used memory // to store pointer to end of used memory
@ -4791,14 +4789,14 @@ hc2:
__asm inp_malloc __asm inp_malloc
{ {
sty tmpy sty tmpy
jsr malloc jsr crt_malloc
ldy tmpy ldy tmpy
jmp startup.exec jmp startup.exec
} }
#pragma bytecode(BC_MALLOC, inp_malloc) #pragma bytecode(BC_MALLOC, inp_malloc)
__asm free __asm crt_free
{ {
// check nullptr free // check nullptr free
@ -5015,21 +5013,21 @@ nostart:
__asm inp_free __asm inp_free
{ {
sty tmpy sty tmpy
jsr free jsr crt_free
ldy tmpy ldy tmpy
jmp startup.exec jmp startup.exec
} }
#pragma bytecode(BC_FREE, inp_free) #pragma bytecode(BC_FREE, inp_free)
__asm breakpoint __asm crt_breakpoint
{ {
rts rts
} }
#pragma runtime(malloc, malloc) #pragma runtime(malloc, crt_malloc)
#pragma runtime(free, free) #pragma runtime(free, crt_free)
#pragma runtime(breakpoint, breakpoint) #pragma runtime(breakpoint, crt_breakpoint)
#if 0 #if 0

View File

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

View File

@ -525,7 +525,7 @@ void bm_polygon_nc_fill(const Bitmap * bm, const ClipRect * clip, int * px, int
static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up, char pattern, LineOp op) static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up, char pattern, LineOp op)
{ {
char ip = 0; char ip = 0;
bool delta16 = ((dx | dy) & 0xff80) != 0; bool delta16 =((dx | dy) & 0xff80) != 0;
// ylow // ylow
ip += asm_im(BLIT_CODE + ip, ASM_LDY, ly); ip += asm_im(BLIT_CODE + ip, ASM_LDY, ly);
@ -579,82 +579,105 @@ static inline void buildline(char ly, char lx, int dx, int dy, int stride, bool
break; break;
} }
if (dx && dy)
{
// m >= 0
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + delta16);
ip += asm_rl(BLIT_CODE + ip, ASM_BMI, delta16 ? 5 + 15 + 13 + 2 : 5 + 15 + 7 + 2);
}
if (dy) if (dy)
{ {
ip += asm_np(BLIT_CODE + ip, up ? ASM_DEY : ASM_INY); bool delta8 = false;
ip += asm_im(BLIT_CODE + ip, ASM_CPY, up ? 0xff : 0x08);
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, 15);
ip += asm_np(BLIT_CODE + ip, ASM_CLC); if (dx)
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_LDY, up ? 0x07 : 0x00);
}
if (dx && dy)
{
ip += asm_np(BLIT_CODE + ip, ASM_SEC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
if (delta16)
{ {
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1); // m >= 0
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8); ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + delta16);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1); char n = delta16 ? 18 + 13 + 2 : 18 + 7 + 2;
if (!up) n++;
ip += asm_rl(BLIT_CODE + ip, ASM_BMI, n);
delta8 = !delta16;
}
if (up)
{
ip += asm_np(BLIT_CODE + ip, ASM_DEY);
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta8 ? 17 : 15);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x07);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
}
else
{
ip += asm_np(BLIT_CODE + ip, ASM_INY);
ip += asm_im(BLIT_CODE + ip, ASM_CPY, 0x08);
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, delta8 ? 16 : 14);
ip += asm_im(BLIT_CODE + ip, ASM_LDY, 0x00);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, (stride - 1) >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1);
}
if (dx)
{
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_np(BLIT_CODE + ip, ASM_SEC);
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
if (delta16)
{
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 13 + 4 + 12);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
}
else
{
// We know regdp to be in the accu at this point
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 5 + 4 + 12);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
}
} }
// m < 0 // m < 0
ip += asm_rl(BLIT_CODE + ip, ASM_BPL, delta16 ? 4 + 13 + 13 : 4 + 13 + 7);
} }
if (dx) if (dx)
{ {
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ASL : ASM_LSR, REG_D0); ip += asm_zp(BLIT_CODE + ip, left ? ASM_ASL : ASM_LSR, REG_D0);
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 13); ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 12);
ip += asm_zp(BLIT_CODE + ip, left ? ASM_ROL : ASM_ROR, REG_D0); ip += asm_zp(BLIT_CODE + ip, left ? ASM_ROL : ASM_ROR, REG_D0);
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP); ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, left ? 0xf8 : 0x08);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
if (left) if (left)
{ {
ip += asm_im(BLIT_CODE + ip, ASM_ADC, 0xf8);
ip += asm_rl(BLIT_CODE + ip, ASM_BCS, 2); ip += asm_rl(BLIT_CODE + ip, ASM_BCS, 2);
ip += asm_zp(BLIT_CODE + ip, ASM_DEC, REG_SP + 1); ip += asm_zp(BLIT_CODE + ip, ASM_DEC, REG_SP + 1);
} }
else else
{ {
ip += asm_im(BLIT_CODE + ip, ASM_ADC, 0x08);
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 2); ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 2);
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_SP + 1); ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_SP + 1);
} }
}
if (dx && dy) ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP);
{
ip += asm_np(BLIT_CODE + ip, ASM_CLC);
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP);
if (delta16)
{
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8);
ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1);
}
} }
// l -- // l --

View File

@ -110,12 +110,12 @@ float atan2(float p, float q)
return s; return s;
} }
#define F_EXP_0 1.0000003 #define F_EXP_0 1.0
#define F_EXP_1 0.693147059 #define F_EXP_1 0.69315668
#define F_EXP_2 0.240173099 #define F_EXP_2 0.240132068
#define F_EXP_3 0.055816392 #define F_EXP_3 0.055876024
#define F_EXP_4 0.008965036 #define F_EXP_4 0.008940801
#define F_EXP_5 0.001898429 #define F_EXP_5 0.001894414
float exp(float f) float exp(float f)
{ {
@ -143,12 +143,12 @@ float exp(float f)
return s * x.f; return s * x.f;
} }
#define F_LOG_0 -3.78712618 #define F_LOG_0 -3.78717706
#define F_LOG_1 10.0957081 #define F_LOG_1 10.0960498
#define F_LOG_2 -13.9747486 #define F_LOG_2 -13.975654
#define F_LOG_3 12.7568806 #define F_LOG_3 12.7580616
#define F_LOG_4 -6.48114552 #define F_LOG_4 -6.48190725
#define F_LOG_5 1.39045416 #define F_LOG_5 1.39064767
float log(float f) float log(float f)
{ {

View File

@ -33,10 +33,15 @@ bool isfinite(float f);
#pragma intrinsic(sin) #pragma intrinsic(sin)
#pragma intrinsic(cos) #pragma intrinsic(cos)
#pragma intrinsic(tan) #pragma intrinsic(tan)
#pragma intrinsic(atan)
#pragma intrinsic(atan2)
#pragma intrinsic(log) #pragma intrinsic(log)
#pragma intrinsic(exp) #pragma intrinsic(exp)
#pragma intrinsic(pow)
#pragma intrinsic(sqrt)
#pragma compile("math.c") #pragma compile("math.c")

59
include/opp/boundint.h Normal file
View File

@ -0,0 +1,59 @@
#ifndef OPP_BOUNDINT_H
#define OPP_BOUNDINT_H
namespace opp {
template<int tmin, int tmax>
constexpr auto boundinttype(void)
{
if constexpr (tmin >= 0 && tmax <= 255)
return (char)0;
else if constexpr (tmin >= -128 && tmax <= 127)
return (signed char)0;
else
return (int)0;
}
template<int tmin, int tmax>
class boundint
{
protected:
decltype(boundinttype<tmin, tmax>()) v;
public:
boundint(int i)
: v(i)
{
}
void operator=(int k)
{
__assume(k >= tmin && k <= tmax);
v = k;
}
void operator+=(int k)
{
k += v;
__assume(k >= tmin && k <= tmax);
v = k;
}
void operator-=(int k)
{
k = v - k;
__assume(k >= tmin && k <= tmax);
v = k;
}
operator int() const
{
int k = v;
__assume(k >= tmin && k <= tmax);
return k;
}
};
}
#endif

View File

@ -37,7 +37,7 @@ public:
showpos = 0x0800, showpos = 0x0800,
skipws = 0x1000, skipws = 0x1000,
unitbuf = 0x2000, unitbuf = 0x2000,
uppercase = 0x3000, uppercase = 0x4000,
adjustfield = 0x00b0, adjustfield = 0x00b0,
basefield = 0x004a, basefield = 0x004a,

View File

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

View File

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

View File

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

View File

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

View File

@ -417,7 +417,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
si.precision = i; si.precision = i;
} }
if (c == 'd' || c == p'd') if (c == 'd' || c == p'd' || c == 'i' || c == p'i')
{ {
bi = nformi(&si, bp, *fps++, true); bi = nformi(&si, bp, *fps++, true);
} }
@ -556,6 +556,17 @@ int sprintf(char * str, const char * fmt, ...)
return d - str; 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) static inline bool isspace(char c)
{ {

View File

@ -3,6 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stddef.h> #include <stddef.h>
#include <stdarg.h>
void putchar(char c); void putchar(char c);
@ -18,6 +19,10 @@ void printf(const char * fmt, ...);
int sprintf(char * str, 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 scanf(const char * fmt, ...);
int sscanf(const char * str, const char * fmt, ...); int sscanf(const char * str, const char * fmt, ...);

View File

@ -544,7 +544,7 @@ unsigned heapfree(void)
} }
#if 0 #if 0
struct Heap { struct Heap {q
unsigned int size; unsigned int size;
Heap * next; Heap * next;
} * freeHeap; } * freeHeap;
@ -667,6 +667,97 @@ void * calloc(int num, int size)
return p; 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; static unsigned seed = 31232;
unsigned int rand(void) unsigned int rand(void)

View File

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

View File

@ -138,6 +138,20 @@ char * cpycat(char * dst, const char * src)
#pragma native(cpycat) #pragma native(cpycat)
char* strchr( const char* str, int ch )
{
char * p = (char *)str;
while (*p != (char)ch)
{
if (!*p)
return nullptr;
p++;
}
return p;
}
void * memset(void * dst, int value, int size) void * memset(void * dst, int value, int size)
{ {
__asm __asm

View File

@ -21,6 +21,8 @@ int memcmp(const void * ptr1, const void * ptr2, int size);
void * memmove(void * dst, const void * src, int size); void * memmove(void * dst, const void * src, int size);
char* strchr( const char* str, int ch );
#pragma intrinsic(strcpy) #pragma intrinsic(strcpy)
#pragma intrinsic(memcpy) #pragma intrinsic(memcpy)

View File

@ -12,8 +12,8 @@ export OSCAR64_CFLAGS =
export OSCAR64_CXX = $(project_dir)/bin/oscar64 export OSCAR64_CXX = $(project_dir)/bin/oscar64
MKDIR_PARENT = /bin/mkdir -p -m 755 MKDIR_PARENT = /bin/mkdir -p -m 755
INSTALL = /usr/bin/install INSTALL = /usr/bin/install
INSTALL_PROGRAM = $(INSTALL) --mode=755 INSTALL_PROGRAM = $(INSTALL) -m 755
INSTALL_DATA = $(INSTALL) --mode=644 INSTALL_DATA = $(INSTALL) -m 644
DESTDIR = DESTDIR =
prefix = /usr/local prefix = /usr/local
exec_prefix = $(prefix) exec_prefix = $(prefix)
@ -38,7 +38,7 @@ else
endif endif
all: --prep-build-dir compiler samples tests all: compiler samples check
$(srcdir)/%.o: $(project_dir)/oscar64/%.cpp $(srcdir)/%.o: $(project_dir)/oscar64/%.cpp
@ -56,7 +56,7 @@ $(srcdir)/%.d: $(project_dir)/oscar64/%.cpp
$(RM) $@.$$$$ $(RM) $@.$$$$
compiler: $(objects) compiler: --prep-build-dir $(objects)
@$(MKDIR_PARENT) $(srcdir) @$(MKDIR_PARENT) $(srcdir)
@echo "Linking compiler..." @echo "Linking compiler..."
$(CXX) $(CPPFLAGS) $(objects) $(linklibs) -o $(project_dir)/bin/oscar64 $(CXX) $(CPPFLAGS) $(objects) $(linklibs) -o $(project_dir)/bin/oscar64
@ -85,7 +85,7 @@ samples: compiler
@$(MAKE) -C $(project_dir)/samples all @$(MAKE) -C $(project_dir)/samples all
tests: compiler check: compiler
@$(MAKE) -C $(project_dir)/autotest all @$(MAKE) -C $(project_dir)/autotest all
install: compiler install: compiler
@ -93,16 +93,16 @@ install: compiler
@$(MKDIR_PARENT) $(DESTDIR)$(bindir) @$(MKDIR_PARENT) $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) $(project_dir)/bin/oscar64 $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) $(project_dir)/bin/oscar64 $(DESTDIR)$(bindir)
@$(MKDIR_PARENT) $(DESTDIR)$(includedir)/oscar64/{audio,c64,c128,cx16,gfx,nes,opp,plus4,vic20} @$(MKDIR_PARENT) $(DESTDIR)$(includedir)/oscar64/{audio,c64,c128,cx16,gfx,nes,opp,plus4,vic20}
$(INSTALL_DATA) $(project_dir)/include/*.{h,c} $(DESTDIR)$(includedir)/oscar64 $(INSTALL_DATA) $(wildcard $(project_dir)/include/*.h $(project_dir)/include/*.c) $(DESTDIR)$(includedir)/oscar64
$(INSTALL_DATA) $(project_dir)/include/audio/*.{h,c} $(DESTDIR)$(includedir)/oscar64/audio $(INSTALL_DATA) $(wildcard $(project_dir)/include/audio/*.h $(project_dir)/include/audio/*.c) $(DESTDIR)$(includedir)/oscar64/audio
$(INSTALL_DATA) $(project_dir)/include/c64/*.{h,c} $(DESTDIR)$(includedir)/oscar64/c64 $(INSTALL_DATA) $(wildcard $(project_dir)/include/c64/*.h $(project_dir)/include/c64/*.c) $(DESTDIR)$(includedir)/oscar64/c64
$(INSTALL_DATA) $(project_dir)/include/c128/*.{h,c} $(DESTDIR)$(includedir)/oscar64/c128 $(INSTALL_DATA) $(wildcard $(project_dir)/include/c128/*.h $(project_dir)/include/c128/*.c) $(DESTDIR)$(includedir)/oscar64/c128
$(INSTALL_DATA) $(project_dir)/include/cx16/*.{h,c} $(DESTDIR)$(includedir)/oscar64/cx16 $(INSTALL_DATA) $(wildcard $(project_dir)/include/cx16/*.h $(project_dir)/include/cx16/*.c) $(DESTDIR)$(includedir)/oscar64/cx16
$(INSTALL_DATA) $(project_dir)/include/gfx/*.{h,c} $(DESTDIR)$(includedir)/oscar64/gfx $(INSTALL_DATA) $(wildcard $(project_dir)/include/gfx/*.h $(project_dir)/include/gfx/*.c) $(DESTDIR)$(includedir)/oscar64/gfx
$(INSTALL_DATA) $(project_dir)/include/nes/*.{h,c} $(DESTDIR)$(includedir)/oscar64/nes $(INSTALL_DATA) $(wildcard $(project_dir)/include/nes/*.h $(project_dir)/include/nes/*.c) $(DESTDIR)$(includedir)/oscar64/nes
$(INSTALL_DATA) $(project_dir)/include/opp/*.{h,cpp} $(DESTDIR)$(includedir)/oscar64/opp $(INSTALL_DATA) $(wildcard $(project_dir)/include/opp/*.h $(project_dir)/include/opp/*.cpp) $(DESTDIR)$(includedir)/oscar64/opp
$(INSTALL_DATA) $(project_dir)/include/plus4/*.{h,c} $(DESTDIR)$(includedir)/oscar64/plus4 $(INSTALL_DATA) $(wildcard $(project_dir)/include/plus4/*.h $(project_dir)/include/plus4/*.c) $(DESTDIR)$(includedir)/oscar64/plus4
$(INSTALL_DATA) $(project_dir)/include/vic20/*.{h,c} $(DESTDIR)$(includedir)/oscar64/vic20 $(INSTALL_DATA) $(wildcard $(project_dir)/include/vic20/*.h $(project_dir)/include/vic20/*.c) $(DESTDIR)$(includedir)/oscar64/vic20
uninstall: uninstall:

1630
oscar64.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 17
VisualStudioVersion = 16.0.31624.102 VisualStudioVersion = 17.13.35931.197
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oscar64", "oscar64\oscar64.vcxproj", "{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oscar64", "oscar64\oscar64.vcxproj", "{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}"
EndProject EndProject
@ -23,10 +23,14 @@ Global
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x64.Build.0 = Release|x64 {1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x64.Build.0 = Release|x64
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.ActiveCfg = Release|Win32 {1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.ActiveCfg = Release|Win32
{1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.Build.0 = Release|Win32 {1DBC623E-6109-41FE-B1BB-9B43FC984F7D}.Release|x86.Build.0 = Release|Win32
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.ActiveCfg = Debug {567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.ActiveCfg = Debug|x64
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug {567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x64.Build.0 = Debug|x64
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.ActiveCfg = Release {567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.ActiveCfg = Debug|x86
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.ActiveCfg = Release {567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Debug|x86.Build.0 = Debug|x86
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.ActiveCfg = Release|x64
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x64.Build.0 = Release|x64
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.ActiveCfg = Release|x86
{567F9C0F-5888-442A-BC9A-D7F9591E5AB4}.Release|x86.Build.0 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -421,9 +421,33 @@ protected:
array = a2; array = a2;
} }
for (int i = size; i < to; i++) array[i] = T{};
size = to; size = to;
} }
template<typename F>
void Partition(const F & f, int l, int r)
{
if (r > l + 1)
{
int pi = l;
T p(array[pi]);
for (int i = l + 1; i < r; i++)
{
if (f(array[i], p))
{
array[pi++] = array[i];
array[i] = array[pi];
}
}
array[pi] = p;
Partition(f, l, pi);
Partition(f, pi + 1, r);
}
}
public: public:
ExpandingArray(void) ExpandingArray(void)
{ {
@ -596,6 +620,24 @@ public:
return false; return false;
} }
void Fill(const T& t)
{
for (int i = 0; i < size; i++)
array[i] = t;
}
void Clear(void)
{
for (int i = 0; i < size; i++)
array[i] = T{};
}
template<typename F>
void Sort(const F & f)
{
Partition(f, 0, size);
}
__forceinline T& operator[](int n) __forceinline T& operator[](int n)
{ {
assert(n >= 0 && n < size); assert(n >= 0 && n < size);

View File

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

View File

@ -31,7 +31,9 @@ enum AsmInsMode
NUM_ASM_INS_MODES, NUM_ASM_INS_MODES,
ASMIM_IMMEDIATE_ADDRESS ASMIM_IMMEDIATE_ADDRESS,
NUM_ASM_INS_MODES_X,
}; };
struct AsmInsData struct AsmInsData
@ -45,6 +47,8 @@ extern AsmInsData DecInsData[256];
extern short AsmInsOpcodes[NUM_ASM_INS_TYPES][NUM_ASM_INS_MODES]; extern short AsmInsOpcodes[NUM_ASM_INS_TYPES][NUM_ASM_INS_MODES];
extern int AsmInsModeSize[NUM_ASM_INS_MODES_X];
extern const char* AsmInstructionNames[NUM_ASM_INS_TYPES]; extern const char* AsmInstructionNames[NUM_ASM_INS_TYPES];
AsmInsType FindAsmInstruction(const char * ins); AsmInsType FindAsmInstruction(const char * ins);

View File

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

View File

@ -3462,94 +3462,151 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
{ {
if (ins->mSrc[1].mTemp < 0) if (ins->mSrc[1].mTemp < 0)
{ {
ByteCodeInstruction lins(BC_LOAD_REG_16); if (ins->mSrc[1].mType == IT_INT16 || ins->mSrc[1].mMemory == IM_ABSOLUTE)
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); ByteCodeInstruction lins(BC_LOAD_REG_16);
cins.mValue = int(ins->mSrc[1].mIntConst); lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
mIns.Push(cins); lins.mRegisterFinal = ins->mSrc[0].mFinal;
} mIns.Push(lins);
else
{ if (csigned)
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
cins.mValue = int(ins->mSrc[1].mIntConst);
mIns.Push(cins);
}
}
else if (ins->mSrc[0].mTemp < 0)
{
ByteCodeInstruction lins(BC_LOAD_REG_16);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
lins.mRegisterFinal = ins->mSrc[1].mFinal;
mIns.Push(lins);
if (csigned)
{
if (optzero && ins->mSrc[0].mIntConst == 0)
{
switch (ins->mOperator)
{
case IA_CMPEQ:
return BC_BRANCHS_EQ;
case IA_CMPNE:
return BC_BRANCHS_NE;
case IA_CMPLES:
return BC_BRANCHS_LE;
case IA_CMPGS:
return BC_BRANCHS_GT;
case IA_CMPGES:
return BC_BRANCHS_GE;
case IA_CMPLS:
return BC_BRANCHS_LT;
}
}
else if (ins->mSrc[1].IsUByte())
{
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
cins.mValue = int(ins->mSrc[0].mIntConst);
mIns.Push(cins);
}
else
{ {
ByteCodeInstruction cins(BC_BINOP_CMPSI_16); ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
cins.mValue = int(ins->mSrc[0].mIntConst); cins.mValue = int(ins->mSrc[1].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); mIns.Push(cins);
} }
else else
{ {
ByteCodeInstruction cins(BC_BINOP_CMPUI_16); 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); mIns.Push(cins);
} }
} }
code = TransposeBranchCondition(code);
} }
else else
{ {

View File

@ -174,13 +174,13 @@ void Compiler::RegisterRuntime(const Location & loc, const Ident* ident)
if (bcdec->mType == DT_CONST_ASSEMBLER) if (bcdec->mType == DT_CONST_ASSEMBLER)
{ {
if (!bcdec->mLinkerObject) if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
linkerObject = bcdec->mLinkerObject; linkerObject = bcdec->mLinkerObject;
} }
else if (bcdec->mType == DT_LABEL) else if (bcdec->mType == DT_LABEL)
{ {
if (!bcdec->mBase->mLinkerObject) if (!bcdec->mBase->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr);
linkerObject = bcdec->mBase->mLinkerObject; linkerObject = bcdec->mBase->mLinkerObject;
offset = int(bcdec->mInteger); offset = int(bcdec->mInteger);
@ -466,7 +466,7 @@ void Compiler::CompileProcedure(InterCodeProcedure* proc)
printf("Generate native code <%s>\n", proc->mIdent->mString); printf("Generate native code <%s>\n", proc->mIdent->mString);
ncproc->Compile(proc); ncproc->Compile(proc);
mNativeProcedures.Push(ncproc); mNativeCodeGenerator->mProcedures.Push(ncproc);
} }
else else
{ {
@ -508,6 +508,8 @@ bool Compiler::GenerateCode(void)
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00e0, 0x00ff); regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00e0, 0x00ff);
else if (mCompilerOptions & (COPT_EXTENDED_ZERO_PAGE | COPT_TARGET_NES)) else if (mCompilerOptions & (COPT_EXTENDED_ZERO_PAGE | COPT_TARGET_NES))
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff); regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff);
else if (mTargetMachine == TMACH_PET_8K || mTargetMachine == TMACH_PET_16K || mTargetMachine == TMACH_PET_32K)
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00ed, 0x00f7);
else else
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00f7, 0x00ff); regionZeroPage = mLinker->AddRegion(identZeroPage, 0x00f7, 0x00ff);
} }
@ -521,6 +523,12 @@ bool Compiler::GenerateCode(void)
{ {
switch (mTargetMachine) switch (mTargetMachine)
{ {
case TMACH_MEGA65:
if (mCompilerOptions & COPT_NATIVE)
regionStartup = mLinker->AddRegion(identStartup, 0x2001, 0x2080);
else
regionStartup = mLinker->AddRegion(identStartup, 0x2001, 0x2100);
break;
case TMACH_C64: case TMACH_C64:
case TMACH_X16: case TMACH_X16:
if (mCompilerOptions & COPT_NATIVE) if (mCompilerOptions & COPT_NATIVE)
@ -623,6 +631,9 @@ bool Compiler::GenerateCode(void)
{ {
switch (mTargetMachine) switch (mTargetMachine)
{ {
case TMACH_MEGA65:
regionBytecode = mLinker->AddRegion(identBytecode, 0x2100, 0x2200);
break;
case TMACH_C64: case TMACH_C64:
case TMACH_X16: case TMACH_X16:
regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00); regionBytecode = mLinker->AddRegion(identBytecode, 0x0900, 0x0a00);
@ -684,6 +695,9 @@ bool Compiler::GenerateCode(void)
{ {
switch (mTargetMachine) switch (mTargetMachine)
{ {
case TMACH_MEGA65:
regionMain = mLinker->AddRegion(identMain, 0x2300, 0xc000);
break;
case TMACH_C64: case TMACH_C64:
regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000); regionMain = mLinker->AddRegion(identMain, 0x0a00, 0xa000);
break; break;
@ -735,6 +749,14 @@ bool Compiler::GenerateCode(void)
{ {
switch (mTargetMachine) switch (mTargetMachine)
{ {
case TMACH_MEGA65:
// TODO: Disable M65 cartridges for now.
//
// if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16))
// regionMain = mLinker->AddRegion(identMain, 0x2666, 0xff00);
// else
regionMain = mLinker->AddRegion(identMain, 0x2080, 0xc000);
break;
case TMACH_C64: case TMACH_C64:
if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16)) if (mCompilerOptions & (COPT_TARGET_CRT8 | COPT_TARGET_CRT16))
@ -910,7 +932,7 @@ bool Compiler::GenerateCode(void)
if (mCompilerOptions & COPT_VERBOSE) if (mCompilerOptions & COPT_VERBOSE)
printf("Generate intermediate code\n"); printf("Generate intermediate code\n");
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart, nullptr);
for (int i = 0; i < mCompilationUnits->mReferenced.Size(); i++) for (int i = 0; i < mCompilationUnits->mReferenced.Size(); i++)
{ {
Declaration* dec = mCompilationUnits->mReferenced[i]; Declaration* dec = mCompilationUnits->mReferenced[i];
@ -993,7 +1015,7 @@ bool Compiler::GenerateCode(void)
if (bcdec->mType == DT_CONST_ASSEMBLER) if (bcdec->mType == DT_CONST_ASSEMBLER)
{ {
if (!bcdec->mLinkerObject) if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject; mByteCodeGenerator->mExtByteCodes[i] = bcdec->mLinkerObject;
} }
} }
@ -1036,13 +1058,18 @@ bool Compiler::GenerateCode(void)
mCompilationUnits->mSectionStack->mSections.Push(proc->mLinkerObject->mStackSection); mCompilationUnits->mSectionStack->mSections.Push(proc->mLinkerObject->mStackSection);
} }
mNativeCodeGenerator->OutlineFunctions();
mNativeCodeGenerator->BuildFunctionProxies(); mNativeCodeGenerator->BuildFunctionProxies();
for (int i = 0; i < mNativeProcedures.Size(); i++) for (int i = 0; i < mNativeCodeGenerator->mProcedures.Size(); i++)
{ {
if (mCompilerOptions & COPT_VERBOSE2) if (mCompilerOptions & COPT_VERBOSE2)
printf("Assemble native code <%s>\n", mNativeProcedures[i]->mInterProc->mIdent->mString); {
mNativeProcedures[i]->Assemble(); if (mNativeCodeGenerator->mProcedures[i]->mInterProc)
printf("Assemble native code <%s>\n", mNativeCodeGenerator->mProcedures[i]->mInterProc->mIdent->mString);
}
mNativeCodeGenerator->mProcedures[i]->Assemble();
} }
LinkerObject* byteCodeObject = nullptr; LinkerObject* byteCodeObject = nullptr;
@ -1068,13 +1095,13 @@ bool Compiler::GenerateCode(void)
if (bcdec->mType == DT_CONST_ASSEMBLER) if (bcdec->mType == DT_CONST_ASSEMBLER)
{ {
if (!bcdec->mLinkerObject) if (!bcdec->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec, nullptr);
linkerObject = bcdec->mLinkerObject; linkerObject = bcdec->mLinkerObject;
} }
else if (bcdec->mType == DT_LABEL) else if (bcdec->mType == DT_LABEL)
{ {
if (!bcdec->mBase->mLinkerObject) if (!bcdec->mBase->mLinkerObject)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue, nullptr); mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase, nullptr);
linkerObject = bcdec->mBase->mLinkerObject; linkerObject = bcdec->mBase->mLinkerObject;
offset = int(bcdec->mInteger); offset = int(bcdec->mInteger);
} }
@ -1270,7 +1297,7 @@ bool Compiler::WriteErrorFile(const char* targetPath)
bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64) bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
{ {
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200], dbjPath[200]; char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200], dbjPath[200], cszPath[200];
char basePath[200]; char basePath[200];
strcpy_s(basePath, targetPath); strcpy_s(basePath, targetPath);
@ -1293,6 +1320,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
strcpy_s(intPath, prgPath); strcpy_s(intPath, prgPath);
strcpy_s(bcsPath, prgPath); strcpy_s(bcsPath, prgPath);
strcpy_s(dbjPath, prgPath); strcpy_s(dbjPath, prgPath);
strcpy_s(cszPath, prgPath);
strcat_s(mapPath, "map"); strcat_s(mapPath, "map");
strcat_s(asmPath, "asm"); strcat_s(asmPath, "asm");
@ -1300,6 +1328,7 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
strcat_s(intPath, "int"); strcat_s(intPath, "int");
strcat_s(bcsPath, "bcs"); strcat_s(bcsPath, "bcs");
strcat_s(dbjPath, "dbj"); strcat_s(dbjPath, "dbj");
strcat_s(cszPath, "csz");
if (mCompilerOptions & COPT_TARGET_PRG) if (mCompilerOptions & COPT_TARGET_PRG)
{ {
@ -1382,6 +1411,9 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
if (mCompilerOptions & COPT_DEBUGINFO) if (mCompilerOptions & COPT_DEBUGINFO)
WriteDbjFile(dbjPath); WriteDbjFile(dbjPath);
if (mCompilerOptions & COPT_PROFILEINFO)
WriteCszFile(cszPath);
if (!(mCompilerOptions & COPT_NATIVE)) if (!(mCompilerOptions & COPT_NATIVE))
{ {
if (mCompilerOptions & COPT_VERBOSE) if (mCompilerOptions & COPT_VERBOSE)
@ -1448,6 +1480,111 @@ static void DumpReferences(FILE* file, Declaration* dec)
} }
bool Compiler::WriteCszFile(const char* filename)
{
FILE* file;
fopen_s(&file, filename, "wb");
if (file)
{
for (int i = 0; i < mInterCodeModule->mProcedures.Size(); i++)
{
InterCodeProcedure* p(mInterCodeModule->mProcedures[i]);
if (p->mLinkerObject && p->mIdent && p->mDeclaration)
{
LinkerObject* lo = p->mLinkerObject;
struct SourceCount
{
const char* mFileName;
int mLine, mAddress;
int mBytes;
};
ExpandingArray<SourceCount> ea;
for (int j = 0; j < lo->mCodeLocations.Size(); j++)
{
const CodeLocation& co(lo->mCodeLocations[j]);
const Location* ls = &(co.mLocation);
while (ls->mFrom)
ls = ls->mFrom;
int k = 0;
while (k < ea.Size() && (ea[k].mFileName != ls->mFileName || ea[k].mLine != ls->mLine))
k++;
if (k == ea.Size())
{
SourceCount sc;
sc.mFileName = ls->mFileName;
sc.mLine = ls->mLine;
sc.mBytes = 0;
sc.mAddress = co.mStart + lo->mAddress;
ea.Push(sc);
}
ea[k].mBytes += co.mEnd - co.mStart;
}
if (ea.Size())
{
ea.Sort([](const SourceCount& l, const SourceCount& r)->bool {
return l.mFileName == r.mFileName ? l.mLine < r.mLine : l.mAddress < r.mAddress;
});
FILE* fsrc;
fopen_s(&fsrc, ea[0].mFileName, "r");
if (fsrc)
{
fprintf(file, "<%s, %s>\n", p->mDeclaration->mQualIdent->mString, ea[0].mFileName);
#if 0
for (int i = 0; i < ea.Size(); i++)
{
fprintf(file, "%s:%d : %d\n", ea[i].mFileName, ea[i].mLine, ea[i].mBytes);
}
#endif
int k = 0, l = 1;
char line[1024];
while (k < ea.Size() && fgets(line, 1024, fsrc))
{
size_t ll = strlen(line);
while (ll > 0 && (line[ll - 1] == '\r' || line[ll - 1] == '\n'))
ll--;
line[ll] = 0;
if (l < ea[k].mLine)
{
if (k > 0)
fprintf(file, "%5d,---- ( ) : %s\n", l, line);
}
else
{
int ks = k, sum = 0;
do {
sum += ea[ks].mBytes;
ks++;
} while (ks < ea.Size() && ea[ks].mFileName != ea[0].mFileName);
fprintf(file, "%5d,%04x (%3d) : %s\n", l, ea[k].mAddress, ea[k].mBytes, line);
k = ks;
}
l++;
}
fclose(fsrc);
fprintf(file, "\n");
}
}
}
}
fclose(file);
return true;
}
else
return false;
}
bool Compiler::WriteDbjFile(const char* filename) bool Compiler::WriteDbjFile(const char* filename)
{ {
FILE* file; FILE* file;

View File

@ -29,7 +29,6 @@ public:
GlobalOptimizer* mGlobalOptimizer; GlobalOptimizer* mGlobalOptimizer;
GrowingArray<ByteCodeProcedure*> mByteCodeFunctions; GrowingArray<ByteCodeProcedure*> mByteCodeFunctions;
ExpandingArray<NativeCodeProcedure*> mNativeProcedures;
TargetMachine mTargetMachine; TargetMachine mTargetMachine;
uint64 mCompilerOptions; uint64 mCompilerOptions;
@ -61,4 +60,5 @@ public:
void CompleteTemplateExpansion(void); void CompleteTemplateExpansion(void);
bool WriteDbjFile(const char* filename); bool WriteDbjFile(const char* filename);
bool WriteCszFile(const char* filename);
}; };

View File

@ -14,6 +14,8 @@ static const uint64 COPT_OPTIMIZE_AUTO_ZEROPAGE = 1ULL << 8;
static const uint64 COPT_OPTIMIZE_CONST_PARAMS = 1ULL << 9; static const uint64 COPT_OPTIMIZE_CONST_PARAMS = 1ULL << 9;
static const uint64 COPT_OPTIMIZE_MERGE_CALLS = 1ULL << 10; static const uint64 COPT_OPTIMIZE_MERGE_CALLS = 1ULL << 10;
static const uint64 COPT_OPTIMIZE_GLOBAL = 1ULL << 11; 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_OPTIMIZE_CODE_SIZE = 1ULL << 16;
static const uint64 COPT_NATIVE = 1ULL << 17; static const uint64 COPT_NATIVE = 1ULL << 17;
@ -41,13 +43,16 @@ static const uint64 COPT_CPLUSPLUS = 1ULL << 52;
static const uint64 COPT_PETSCII = 1ULL << 53; static const uint64 COPT_PETSCII = 1ULL << 53;
static const uint64 COPT_ERROR_FILES = 1ULL << 54; static const uint64 COPT_ERROR_FILES = 1ULL << 54;
static const uint64 COPT_PROFILEINFO = 1ULL << 55;
static const uint64 COPT_STRICT = 1ULL << 56;
static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS; static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;
static const uint64 COPT_OPTIMIZE_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS; static const uint64 COPT_OPTIMIZE_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;
static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_CODE_SIZE | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL; static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_CODE_SIZE | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;// | COPT_OPTIMIZE_OUTLINE;
static const uint64 COPT_OPTIMIZE_SPEED = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_UNROLL | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_ASSEMBLER | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL; static const uint64 COPT_OPTIMIZE_SPEED = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_UNROLL | COPT_OPTIMIZE_CONST_EXPRESSIONS | COPT_OPTIMIZE_ASSEMBLER | COPT_OPTIMIZE_CONST_PARAMS | COPT_OPTIMIZE_MERGE_CALLS | COPT_OPTIMIZE_GLOBAL;
@ -74,7 +79,8 @@ enum TargetMachine
TMACH_NES_MMC1, TMACH_NES_MMC1,
TMACH_NES_MMC3, TMACH_NES_MMC3,
TMACH_ATARI, TMACH_ATARI,
TMACH_X16 TMACH_X16,
TMACH_MEGA65
}; };

View File

@ -11,7 +11,7 @@ int CompressLZO(uint8* dst, const uint8* source, int size)
while (pi < 127 && pos < size) while (pi < 127 && pos < size)
{ {
int bi = pi, bj = 0; int bi = pi, bj = 0;
for (int i = 1; i < (pos < 255 ? pos : 255); i++) for (int i = 1; i <= (pos < 255 ? pos : 255); i++)
{ {
int j = 0; int j = 0;
while (j < 127 && pos + j < size && source[pos - i + j] == source[pos + j]) while (j < 127 && pos + j < size && source[pos - i + j] == source[pos + j])

View File

@ -651,6 +651,7 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
{ {
mProcType = exp->mLeft->mDecType; mProcType = exp->mLeft->mDecType;
Expression* pex = exp->mRight;
Declaration* cdec = exp->mLeft->mDecType->mParams; Declaration* cdec = exp->mLeft->mDecType->mParams;
int pos = 0; int pos = 0;
@ -659,6 +660,28 @@ Expression* ConstexprInterpreter::EvalConstructor(Expression* exp)
mParams[pos].PutPtr(Value(&mResult)); mParams[pos].PutPtr(Value(&mResult));
pos = 2; 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*>(); mHeap = new ExpandingArray<Value*>();
Execute(exp->mLeft->mDecValue->mValue); Execute(exp->mLeft->mDecValue->mValue);
@ -754,6 +777,9 @@ bool ConstexprInterpreter::AddParam(int& pos, Expression* pex, Declaration* dec)
Expression* ConstexprInterpreter::EvalCall(Expression* exp) Expression* ConstexprInterpreter::EvalCall(Expression* exp)
{ {
if (!exp->mLeft->mDecValue || !exp->mLeft->mDecValue->mValue)
return exp;
mProcType = exp->mLeft->mDecType; mProcType = exp->mLeft->mDecType;
Expression* pex = exp->mRight; Expression* pex = exp->mRight;
@ -1020,6 +1046,9 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalUnary(Expression* exp, con
break; break;
case TK_MUL: case TK_MUL:
return vl.GetPtr(); return vl.GetPtr();
case TK_SIZEOF:
v.PutInt(vl.mDecType->mSize);
break;
default: default:
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible operator", TokenNames[exp->mToken]); mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible operator", TokenNames[exp->mToken]);
} }
@ -1168,6 +1197,26 @@ ConstexprInterpreter::Value ConstexprInterpreter::EvalCall(Expression* exp, Cons
mResult = Value(exp->mLocation, TheFloatTypeDeclaration); mResult = Value(exp->mLocation, TheFloatTypeDeclaration);
mResult.PutFloat(::exp(mParams[0].GetFloat())); 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 else
mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname); mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname);
} }

View File

@ -31,6 +31,17 @@ DeclarationScope::~DeclarationScope(void)
delete[] mHash; 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 const Ident* DeclarationScope::Mangle(const Ident* ident) const
{ {
if (mName && ident) if (mName && ident)
@ -145,7 +156,7 @@ void DeclarationScope::End(const Location& loc)
} }
Expression::Expression(const Location& loc, ExpressionType type) 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; static uint32 gUID = 0;
mUID = gUID++; mUID = gUID++;
@ -263,6 +274,9 @@ void Expression::Dump(int ident) const
case EX_FOR: case EX_FOR:
printf("FOR"); printf("FOR");
break; break;
case EX_FORBODY:
printf("FORBODY");
break;
case EX_DO: case EX_DO:
printf("DO"); printf("DO");
break; break;
@ -335,6 +349,9 @@ void Expression::Dump(int ident) const
case EX_LABEL: case EX_LABEL:
printf("LABEL %s", mDecValue->mIdent->mString); printf("LABEL %s", mDecValue->mIdent->mString);
break; break;
case EX_AGGREGATE:
printf("AGGREGATE");
break;
} }
printf("\n"); printf("\n");
@ -387,6 +404,17 @@ bool Expression::IsRValue(void) const
return true; return true;
} }
bool Expression::IsVolatile(void) const
{
if (mDecType->mFlags & DTF_VOLATILE)
return true;
if (mLeft && mLeft->IsVolatile())
return true;
if (mRight && mRight->IsVolatile())
return true;
return false;
}
bool Expression::IsConstRef(void) const bool Expression::IsConstRef(void) const
{ {
if (mDecType->mType == DT_TYPE_RVALUEREF || mDecType->mType == DT_TYPE_REFERENCE) if (mDecType->mType == DT_TYPE_RVALUEREF || mDecType->mType == DT_TYPE_REFERENCE)
@ -477,6 +505,63 @@ Expression* Expression::LogicInvertExpression(void)
} }
} }
void Expression::ReplaceVariable(Declaration* pvar, Declaration* nvar)
{
if (mLeft) mLeft->ReplaceVariable(pvar, nvar);
if (mRight) mRight->ReplaceVariable(pvar, nvar);
if (mType == EX_VARIABLE && mDecValue == pvar)
mDecValue = nvar;
}
Expression* Expression::ToAlternateThis(Declaration* pthis, Declaration* nthis)
{
Expression* left = mLeft ? mLeft->ToAlternateThis(pthis, nthis) : nullptr;
Expression* right = mRight ? mRight->ToAlternateThis(pthis, nthis) : nullptr;
Declaration* decType = mDecType, * decValue = mDecValue;
Declaration* lp = pthis, * np = nthis;
while (lp)
{
if (decType == lp->mBase)
decType = np->mBase;
else if (decType == lp->mBase->mBase)
decType = np->mBase->mBase;
if (decValue == lp)
decValue = np;
lp = lp->mNext;
np = np->mNext;
}
if (mType == EX_QUALIFY && mLeft->mDecType != left->mDecType)
{
Declaration* pe = mLeft->mDecType->mParams, * ne = left->mDecType->mParams;
while (pe && ne && pe != mDecValue)
{
pe = pe->mNext;
ne = ne->mNext;
}
decValue = ne;
decType = ne->mBase;
}
if (left == mLeft && right == mRight && decType == mDecType && decValue == mDecValue)
return this;
else
{
Expression* nexp = new Expression(mLocation, mType);
nexp->mLeft = left;
nexp->mRight = right;
nexp->mDecType = decType;
nexp->mDecValue = decValue;
nexp->mToken = mToken;
nexp->mConst = mConst;
return nexp;
}
}
Expression* Expression::ConstantDereference(Errors* errors, LinkerSection* dataSection) Expression* Expression::ConstantDereference(Errors* errors, LinkerSection* dataSection)
{ {
if (mType == EX_VARIABLE) if (mType == EX_VARIABLE)
@ -594,6 +679,19 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
return this; return this;
} }
else if (mType == EX_PREFIX && mToken == TK_SIZEOF)
{
if (mLeft->mDecType->mFlags & DTF_DEFINED)
{
Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
dec->mBase = TheSignedIntTypeDeclaration;
dec->mInteger = mLeft->mDecType->mSize;
ex->mDecValue = dec;
ex->mDecType = dec->mBase;
return ex;
}
}
else if (mType == EX_PREFIX && mLeft->mType == EX_CONSTANT) else if (mType == EX_PREFIX && mLeft->mType == EX_CONSTANT)
{ {
@ -677,14 +775,29 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
ex->mDecType = mDecType; ex->mDecType = mDecType;
return ex; return ex;
} }
else if (mType == EX_PREFIX && mToken == TK_BINARY_AND && mLeft->mType == EX_INDEX && mLeft->mLeft->mType == EX_VARIABLE && (mLeft->mLeft->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL)) && mLeft->mRight->mType == EX_CONSTANT) else if (mType == EX_PREFIX && mToken == TK_BINARY_AND && mLeft->mType == EX_INDEX &&
mLeft->mLeft->mType == EX_VARIABLE && mLeft->mLeft->mDecType->mType == DT_TYPE_ARRAY &&
(mLeft->mLeft->mDecValue->mFlags & (DTF_STATIC | DTF_GLOBAL)) && mLeft->mRight->mType == EX_CONSTANT)
{ {
Declaration* vdec = mLeft->mLeft->mDecValue;
Expression* ex = new Expression(mLocation, EX_VARIABLE); Expression* ex = new Expression(mLocation, EX_VARIABLE);
Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF); Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF);
dec->mFlags = mLeft->mLeft->mDecValue->mFlags;
dec->mBase = mLeft->mLeft->mDecValue; if (vdec->mType == DT_VARIABLE_REF)
dec->mSize = mLeft->mLeft->mDecType->mBase->mSize - int(mLeft->mRight->mDecValue->mInteger) * dec->mSize; {
dec->mOffset = int(mLeft->mRight->mDecValue->mInteger) * dec->mSize; dec->mFlags = vdec->mFlags;
dec->mBase = vdec->mBase;
dec->mSize = mLeft->mLeft->mDecType->mBase->mSize - int(mLeft->mRight->mDecValue->mInteger) * dec->mSize;
dec->mOffset = int(mLeft->mRight->mDecValue->mInteger) * dec->mSize + vdec->mOffset;
}
else
{
dec->mFlags = vdec->mFlags;
dec->mBase = vdec;
dec->mSize = mLeft->mLeft->mDecType->mBase->mSize - int(mLeft->mRight->mDecValue->mInteger) * dec->mSize;
dec->mOffset = int(mLeft->mRight->mDecValue->mInteger) * dec->mSize;
}
ex->mDecValue = dec; ex->mDecValue = dec;
ex->mDecType = mLeft->mLeft->mDecType; ex->mDecType = mLeft->mLeft->mDecType;
return ex; return ex;
@ -808,11 +921,19 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
{ {
int64 ival = 0, ileft = mLeft->mDecValue->mInteger, iright = mRight->mDecValue->mInteger; int64 ival = 0, ileft = mLeft->mDecValue->mInteger, iright = mRight->mDecValue->mInteger;
bool signop = Declaration* dtype = TheSignedIntTypeDeclaration;
(mLeft->mDecValue->mBase->mSize < 2 || (mLeft->mDecValue->mBase->mFlags & DTF_SIGNED)) && if (mLeft->mDecValue->mBase->mSize > mRight->mDecValue->mBase->mSize)
(mRight->mDecValue->mBase->mSize < 2 || (mRight->mDecValue->mBase->mFlags & DTF_SIGNED)); dtype = mLeft->mDecValue->mBase;
else if (mLeft->mDecValue->mBase->mSize < mRight->mDecValue->mBase->mSize)
dtype = mRight->mDecValue->mBase;
else if (mLeft->mDecValue->mBase->mSize > 1)
{
if ((mLeft->mDecValue->mBase->mFlags & DTF_SIGNED) && !(mRight->mDecValue->mBase->mFlags & DTF_SIGNED))
dtype = mRight->mDecValue->mBase;
else
dtype = mLeft->mDecValue->mBase;
}
bool promote = true;
switch (mToken) switch (mToken)
{ {
case TK_ADD: case TK_ADD:
@ -826,27 +947,25 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
break; break;
case TK_DIV: case TK_DIV:
if (iright == 0) if (iright == 0)
errors->Error(mLocation, EERR_INVALID_VALUE, "Constant division by zero"); return this;
else if (signop) else if (dtype->mFlags & DTF_SIGNED)
ival = ileft / iright; ival = ileft / iright;
else else
ival = (uint64)ileft / (uint64)iright; ival = (uint64)ileft / (uint64)iright;
break; break;
case TK_MOD: case TK_MOD:
if (iright == 0) if (iright == 0)
errors->Error(mLocation, EERR_INVALID_VALUE, "Constant division by zero"); return this;
else if (signop) else if (dtype->mFlags & DTF_SIGNED)
ival = ileft % iright; ival = ileft % iright;
else else
ival = (uint64)ileft % (uint64)iright; ival = (uint64)ileft % (uint64)iright;
break; break;
case TK_LEFT_SHIFT: case TK_LEFT_SHIFT:
ival = ileft << iright; ival = ileft << iright;
promote = false;
break; break;
case TK_RIGHT_SHIFT: case TK_RIGHT_SHIFT:
ival = ileft >> iright; ival = ileft >> iright;
promote = false;
break; break;
case TK_BINARY_AND: case TK_BINARY_AND:
ival = ileft & iright; ival = ileft & iright;
@ -863,29 +982,14 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
Expression* ex = new Expression(mLocation, EX_CONSTANT); Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER); Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
if (promote) dec->mBase = dtype;
{ dec->mInteger = signextend(ival, dec->mBase);
if (mLeft->mDecValue->mBase->mSize <= 2 && mRight->mDecValue->mBase->mSize <= 2)
dec->mBase = ival < 32768 ? TheSignedIntTypeDeclaration : TheUnsignedIntTypeDeclaration;
else
dec->mBase = ival < 2147483648 ? TheSignedLongTypeDeclaration : TheUnsignedLongTypeDeclaration;
}
else
{
if (mLeft->mDecValue->mBase->mSize < 2)
dec->mBase = TheSignedIntTypeDeclaration;
else
dec->mBase = mLeft->mDecValue->mBase;
}
dec->mInteger = ival;
ex->mDecValue = dec; ex->mDecValue = dec;
ex->mDecType = dec->mBase; ex->mDecType = dec->mBase;
return ex; return ex;
} }
else if ((mLeft->mDecValue->mType == DT_CONST_INTEGER || mLeft->mDecValue->mType == DT_CONST_FLOAT) && (mRight->mDecValue->mType == DT_CONST_INTEGER || mRight->mDecValue->mType == DT_CONST_FLOAT)) else if ((mLeft->mDecValue->mType == DT_CONST_INTEGER || mLeft->mDecValue->mType == DT_CONST_FLOAT) && (mRight->mDecValue->mType == DT_CONST_INTEGER || mRight->mDecValue->mType == DT_CONST_FLOAT))
{ {
double dval; double dval;
double dleft = mLeft->mDecValue->mType == DT_CONST_INTEGER ? mLeft->mDecValue->mInteger : mLeft->mDecValue->mNumber; double dleft = mLeft->mDecValue->mType == DT_CONST_INTEGER ? mLeft->mDecValue->mInteger : mLeft->mDecValue->mNumber;
double dright = mRight->mDecValue->mType == DT_CONST_INTEGER ? mRight->mDecValue->mInteger : mRight->mDecValue->mNumber; double dright = mRight->mDecValue->mType == DT_CONST_INTEGER ? mRight->mDecValue->mInteger : mRight->mDecValue->mNumber;
@ -940,6 +1044,20 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
ex->mDecType = dec->mBase; ex->mDecType = dec->mBase;
return ex; 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 #if 0
else if (mLeft->mDecValue->mType == DT_CONST_POINTER && mRight->mDecValue->mType == DT_CONST_INTEGER && (mToken == TK_ADD || mToken == TK_SUB)) else if (mLeft->mDecValue->mType == DT_CONST_POINTER && mRight->mDecValue->mType == DT_CONST_INTEGER && (mToken == TK_ADD || mToken == TK_SUB))
{ {
@ -1020,6 +1138,26 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
} }
} }
else if (mType == EX_LOGICAL_AND && mLeft->mType == EX_CONSTANT)
{
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
{
if (mLeft->mDecValue->mInteger == 0)
return mLeft;
else
return mRight->ConstantFold(errors, dataSection);
}
}
else if (mType == EX_LOGICAL_OR && mLeft->mType == EX_CONSTANT)
{
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
{
if (mLeft->mDecValue->mInteger != 0)
return mLeft;
else
return mRight->ConstantFold(errors, dataSection);
}
}
else if (mType == EX_CONDITIONAL && mLeft->mType == EX_CONSTANT) else if (mType == EX_CONDITIONAL && mLeft->mType == EX_CONSTANT)
{ {
if (mLeft->mDecValue->mType == DT_CONST_INTEGER) if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
@ -1055,7 +1193,7 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
return ex; return ex;
} }
else if (mType == EX_BINARY && mToken == TK_ADD && mLeft->mType == EX_VARIABLE && mLeft->mDecValue->mType == DT_VARIABLE && (mLeft->mDecValue->mFlags & DTF_CONST) && 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->mDecType->mType == DT_TYPE_POINTER && mRight->mType == EX_CONSTANT && mRight->mDecValue->mType == DT_CONST_INTEGER)
{ {
mLeft = mLeft->mDecValue->mValue; mLeft = mLeft->mDecValue->mValue;
@ -1108,19 +1246,23 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
else if (mType == EX_INDEX && mLeft->mType == EX_VARIABLE && mLeft->mDecValue->mType == DT_VARIABLE_REF && (mLeft->mDecValue->mFlags & DTF_GLOBAL) && 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 && mLeft->mDecType->mType == DT_TYPE_ARRAY && mLeft->mDecType->mStride == 0 &&
mRight->mType == EX_CONSTANT && mRight->mDecValue->mType == DT_CONST_INTEGER) 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); Expression* ex = new Expression(mLocation, EX_VARIABLE);
Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF); Declaration* dec = new Declaration(mLocation, DT_VARIABLE_REF);
dec->mFlags = mLeft->mDecValue->mFlags; dec->mFlags = mLeft->mDecValue->mFlags;
dec->mBase = mLeft->mDecValue->mBase; dec->mBase = mLeft->mDecValue->mBase;
dec->mOffset = offset; dec->mOffset = offset;
dec->mSize = mDecType->mSize; dec->mSize = mDecType->mSize;
ex->mDecValue = dec; ex->mDecValue = dec;
ex->mDecType = mDecType; ex->mDecType = mDecType;
return ex; 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) 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; Declaration* decf = mLeft->mDecValue, * decp = mRight->mDecValue;
@ -1129,6 +1271,7 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
if (decp->mType == DT_CONST_FLOAT || decp->mType == DT_CONST_INTEGER) if (decp->mType == DT_CONST_FLOAT || decp->mType == DT_CONST_INTEGER)
{ {
double d = decp->mType == DT_CONST_FLOAT ? decp->mNumber : decp->mInteger; double d = decp->mType == DT_CONST_FLOAT ? decp->mNumber : decp->mInteger;
double e = 0.0;
bool check = false; bool check = false;
@ -1148,6 +1291,10 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
d = log(d); d = log(d);
else if (!strcmp(iname->mString, "exp")) else if (!strcmp(iname->mString, "exp"))
d = exp(d); d = exp(d);
else if (!strcmp(iname->mString, "sqrt"))
d = sqrt(d);
else if (!strcmp(iname->mString, "atan"))
d = atan(d);
else else
return this; return this;
@ -1160,6 +1307,36 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
return ex; 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) else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_CONSTEXPR) && dataSection)
{ {
ConstexprInterpreter cinter(mLocation, errors, dataSection); ConstexprInterpreter cinter(mLocation, errors, dataSection);
@ -1184,6 +1361,7 @@ Declaration::Declaration(const Location& loc, DecType type)
mConst(nullptr), mMutable(nullptr), mVolatile(nullptr), mConst(nullptr), mMutable(nullptr), mVolatile(nullptr),
mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr), mMoveConstructor(nullptr), mMoveAssignment(nullptr), mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr), mMoveConstructor(nullptr), mMoveAssignment(nullptr),
mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr), mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr),
mVectorMoveConstructor(nullptr), mVectorMoveAssignment(nullptr),
mVTable(nullptr), mTemplate(nullptr), mForwardParam(nullptr), mForwardCall(nullptr), mVTable(nullptr), mTemplate(nullptr), mForwardParam(nullptr), mForwardCall(nullptr),
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mFriends(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), mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
@ -1205,7 +1383,7 @@ int Declaration::Stride(void) const
{ {
if (mStride > 0) if (mStride > 0)
return mStride; return mStride;
else if (mBase) else if (mBase && mBase->mType != DT_TYPE_VOID)
return mBase->mSize; return mBase->mSize;
else else
return 1; return 1;
@ -1308,6 +1486,51 @@ Declaration* Declaration::ConstCast(Declaration* ntype)
pdec->mSize = 2; pdec->mSize = 2;
return pdec; 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 else
return this; return this;
} }
@ -1453,7 +1676,9 @@ const Ident* Declaration::FullIdent(void)
Declaration* dec = mBase->mParams; Declaration* dec = mBase->mParams;
while (dec) while (dec)
{ {
tident = tident->Mangle(dec->mBase->MangleIdent()->mString); const Ident* mident = dec->mBase->MangleIdent();
if (mident)
tident = tident->Mangle(mident->mString);
dec = dec->mNext; dec = dec->mNext;
if (dec) if (dec)
tident = tident->Mangle(","); tident = tident->Mangle(",");
@ -1589,25 +1814,30 @@ const Ident* Declaration::MangleIdent(void)
} }
dec = dec->mNext; dec = dec->mNext;
if (dec) if (mMangleIdent && dec)
mMangleIdent = mMangleIdent->Mangle(","); mMangleIdent = mMangleIdent->Mangle(",");
} }
} }
else else
mMangleIdent = Ident::Unique("void"); mMangleIdent = Ident::Unique("void");
} }
else else if (mQualIdent)
mMangleIdent = mQualIdent; mMangleIdent = mQualIdent;
else
mMangleIdent = mIdent;
if (mTemplate) if (mTemplate)
{ {
} }
if (mFlags & DTF_CONST) if (mMangleIdent)
mMangleIdent = mMangleIdent->PreMangle("const "); {
if (mFlags & DTF_VOLATILE) if (mFlags & DTF_CONST)
mMangleIdent = mMangleIdent->PreMangle("volatile "); mMangleIdent = mMangleIdent->PreMangle("const ");
if (mFlags & DTF_VOLATILE)
mMangleIdent = mMangleIdent->PreMangle("volatile ");
}
} }
return mMangleIdent; return mMangleIdent;
@ -1668,19 +1898,8 @@ Declaration* Declaration::ExpandTemplate(DeclarationScope* scope)
return this; return this;
} }
bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec) bool Declaration::ResolveTemplateParameterList(Expression* pexp, Declaration* pdec, bool preliminary)
{ {
Declaration* pdec = tdec->mBase->mParams;
// Insert partially resolved templates
Declaration* ptdec = tdec->mTemplate->mParams;
while (ptdec)
{
if (ptdec->mBase)
mScope->Insert(ptdec->mIdent, ptdec->mBase);
ptdec = ptdec->mNext;
}
Declaration* phead = nullptr, * ptail = nullptr; Declaration* phead = nullptr, * ptail = nullptr;
int pcnt = 0; int pcnt = 0;
@ -1716,7 +1935,7 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
} }
else else
{ {
if (!ResolveTemplate(ex->mDecType, pdec->mBase)) if (!ResolveTemplate(ex->mDecType, pdec->mBase, false, preliminary))
return false; return false;
pdec = pdec->mNext; pdec = pdec->mNext;
@ -1730,6 +1949,9 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
{ {
if (pdec->mType == DT_PACK_ARGUMENT) if (pdec->mType == DT_PACK_ARGUMENT)
{ {
if (preliminary)
return true;
Declaration* tpdec = new Declaration(pdec->mLocation, DT_PACK_TYPE); Declaration* tpdec = new Declaration(pdec->mLocation, DT_PACK_TYPE);
if (pdec->mBase->mType == DT_TYPE_REFERENCE) if (pdec->mBase->mType == DT_TYPE_REFERENCE)
tpdec->mIdent = pdec->mBase->mBase->mIdent; tpdec->mIdent = pdec->mBase->mBase->mIdent;
@ -1743,6 +1965,25 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
return false; return false;
} }
return true;
}
bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
{
Declaration* pdec = tdec->mBase->mParams;
// Insert partially resolved templates
Declaration* ptdec = tdec->mTemplate->mParams;
while (ptdec)
{
if (ptdec->mBase)
mScope->Insert(ptdec->mIdent, ptdec->mBase);
ptdec = ptdec->mNext;
}
if (!ResolveTemplateParameterList(pexp, pdec, true) || !ResolveTemplateParameterList(pexp, pdec, false))
return false;
Declaration* ppdec = nullptr; Declaration* ppdec = nullptr;
ptdec = tdec->mTemplate->mParams; ptdec = tdec->mTemplate->mParams;
while (ptdec) while (ptdec)
@ -1785,7 +2026,7 @@ bool Declaration::CanResolveTemplate(Expression* pexp, Declaration* tdec)
if (pdec) if (pdec)
{ {
if (!ResolveTemplate(ex->mDecType, pdec->mBase)) if (!ResolveTemplate(ex->mDecType, pdec->mBase, false, false))
return false; return false;
if (pdec->mType != DT_PACK_ARGUMENT) if (pdec->mType != DT_PACK_ARGUMENT)
@ -1801,19 +2042,19 @@ bool Declaration::CanResolveTemplate(Expression* pexp, Declaration* tdec)
return true; return true;
} }
bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec) bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec, bool same, bool preliminary)
{ {
if (tdec->IsSame(fdec)) if (tdec->IsSame(fdec))
return true; return true;
else if (fdec->IsReference()) else if (fdec->IsReference())
return ResolveTemplate(fdec->mBase, tdec); return ResolveTemplate(fdec->mBase, tdec, same, preliminary);
else if (tdec->mType == DT_TYPE_FUNCTION) else if (tdec->mType == DT_TYPE_FUNCTION)
{ {
if (fdec->mType == DT_TYPE_FUNCTION) if (fdec->mType == DT_TYPE_FUNCTION)
{ {
if (fdec->mBase) if (fdec->mBase)
{ {
if (!tdec->mBase || !ResolveTemplate(fdec->mBase, tdec->mBase)) if (!tdec->mBase || !ResolveTemplate(fdec->mBase, tdec->mBase, true, preliminary))
return false; return false;
} }
else if (tdec->mBase) else if (tdec->mBase)
@ -1852,7 +2093,7 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
if (!fpdec) if (!fpdec)
return false; return false;
if (!ResolveTemplate(fpdec->mBase, tpdec->mBase)) if (!ResolveTemplate(fpdec->mBase, tpdec->mBase, true, preliminary))
return false; return false;
fpdec = fpdec->mNext; fpdec = fpdec->mNext;
@ -1868,16 +2109,16 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
} }
else if (tdec->mType == DT_TYPE_REFERENCE) else if (tdec->mType == DT_TYPE_REFERENCE)
{ {
return ResolveTemplate(fdec, tdec->mBase); return ResolveTemplate(fdec, tdec->mBase, true, preliminary);
} }
else if (tdec->mType == DT_TYPE_RVALUEREF) else if (tdec->mType == DT_TYPE_RVALUEREF)
{ {
return ResolveTemplate(fdec, tdec->mBase); return ResolveTemplate(fdec, tdec->mBase, true, preliminary);
} }
else if (tdec->mType == DT_TYPE_POINTER) else if (tdec->mType == DT_TYPE_POINTER)
{ {
if (fdec->mType == DT_TYPE_POINTER || fdec->mType == DT_TYPE_ARRAY) if (fdec->mType == DT_TYPE_POINTER || fdec->mType == DT_TYPE_ARRAY)
return ResolveTemplate(fdec->mBase, tdec->mBase); return ResolveTemplate(fdec->mBase, tdec->mBase, true, preliminary);
else else
return false; return false;
} }
@ -1897,10 +2138,12 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
if (pdec->mType == DT_TYPE_STRUCT) if (pdec->mType == DT_TYPE_STRUCT)
pdec = pdec->mScope->Lookup(tdec->mIdent); pdec = pdec->mScope->Lookup(tdec->mIdent);
} }
else if (preliminary && !same)
return true;
else else
pdec = mScope->Insert(tdec->mIdent, fdec); pdec = mScope->Insert(tdec->mIdent, fdec);
if (pdec && !pdec->IsSame(fdec)) if (pdec && !(same ? pdec->IsSame(fdec) : pdec->CanAssign(fdec)))
return false; return false;
return true; return true;
@ -1941,6 +2184,21 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
} }
return true; 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) else if (tdec->mType == DT_TYPE_STRUCT && fdec->mType == DT_TYPE_STRUCT && tdec->mTemplate)
{ {
@ -2006,13 +2264,27 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
tpdec = tpdec->mNext; 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; ftdec = ftdec->mNext;
} }
return false; return false;
} }
else if (!same && tdec->CanAssign(fdec))
return true;
else else
return tdec->IsSame(fdec); return tdec->IsSame(fdec);
} }
@ -2025,6 +2297,8 @@ Declaration* Declaration::Clone(void)
ndec->mOffset = mOffset; ndec->mOffset = mOffset;
ndec->mStride = mStride; ndec->mStride = mStride;
ndec->mStripe = mStripe; ndec->mStripe = mStripe;
ndec->mBits = mBits;
ndec->mShift = mShift;
ndec->mBase = mBase; ndec->mBase = mBase;
ndec->mFlags = mFlags; ndec->mFlags = mFlags;
ndec->mScope = mScope; ndec->mScope = mScope;
@ -2044,6 +2318,7 @@ Declaration* Declaration::Clone(void)
ndec->mMaxValue = mMaxValue; ndec->mMaxValue = mMaxValue;
ndec->mCompilerOptions = mCompilerOptions; ndec->mCompilerOptions = mCompilerOptions;
ndec->mParser = mParser; ndec->mParser = mParser;
ndec->mNumVars = mNumVars;
return ndec; return ndec;
} }
@ -2095,6 +2370,8 @@ Declaration* Declaration::ToStriped(int stripe)
ndec->mOffset = mOffset * stripe; ndec->mOffset = mOffset * stripe;
ndec->mStride = mStride; ndec->mStride = mStride;
ndec->mStripe = stripe; ndec->mStripe = stripe;
ndec->mBits = mBits;
ndec->mShift = mShift;
ndec->mFlags = mFlags; ndec->mFlags = mFlags;
ndec->mIdent = mIdent; ndec->mIdent = mIdent;
ndec->mQualIdent = mQualIdent; ndec->mQualIdent = mQualIdent;
@ -2122,6 +2399,24 @@ Declaration* Declaration::ToStriped(int stripe)
prev = pnec; prev = pnec;
p = p->mNext; p = p->mNext;
} }
Declaration* pndec = ndec->BuildPointer(mLocation);
mScope->Iterate([=](const Ident* ident, Declaration* vdec) {
if (vdec->mType == DT_CONST_FUNCTION)
{
ndec->mScope->Insert(ident, vdec->ToAlternateThis(pndec));
}
});
ndec->mDestructor = mDestructor ? mDestructor->ToAlternateThis(pndec) : nullptr;
ndec->mDefaultConstructor = mDefaultConstructor ? mDefaultConstructor->ToAlternateThis(pndec) : nullptr;
ndec->mCopyConstructor = mCopyConstructor ? mCopyConstructor->ToAlternateThis(pndec) : nullptr;
ndec->mMoveConstructor = mMoveConstructor ? mMoveConstructor->ToAlternateThis(pndec) : nullptr;
ndec->mVectorConstructor = mVectorConstructor ? mVectorConstructor->ToAlternateThis(pndec, 2) : nullptr;
ndec->mVectorDestructor = mVectorDestructor ? mVectorDestructor->ToAlternateThis(pndec, 2) : nullptr;
ndec->mVectorCopyConstructor = mVectorCopyConstructor ? mVectorCopyConstructor->ToAlternateThis(pndec, 2) : nullptr;
ndec->mVectorMoveConstructor = mVectorMoveConstructor ? mVectorMoveConstructor->ToAlternateThis(pndec, 2) : nullptr;
} }
else if (mType == DT_TYPE_FUNCTION) else if (mType == DT_TYPE_FUNCTION)
{ {
@ -2152,6 +2447,8 @@ Declaration* Declaration::ToVolatileType(void)
ndec->mSize = mSize; ndec->mSize = mSize;
ndec->mStride = mStride; ndec->mStride = mStride;
ndec->mBase = mBase; ndec->mBase = mBase;
ndec->mBits = mBits;
ndec->mShift = mShift;
ndec->mFlags = mFlags | DTF_VOLATILE; ndec->mFlags = mFlags | DTF_VOLATILE;
ndec->mScope = mScope; ndec->mScope = mScope;
ndec->mParams = mParams; ndec->mParams = mParams;
@ -2187,6 +2484,7 @@ Declaration* Declaration::ToVolatileType(void)
ndec->mVectorConstructor = mVectorConstructor; ndec->mVectorConstructor = mVectorConstructor;
ndec->mVectorDestructor = mVectorDestructor; ndec->mVectorDestructor = mVectorDestructor;
ndec->mVectorCopyConstructor = mVectorCopyConstructor; ndec->mVectorCopyConstructor = mVectorCopyConstructor;
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
ndec->mVTable = mVTable; ndec->mVTable = mVTable;
mVolatile = ndec; mVolatile = ndec;
@ -2205,7 +2503,13 @@ Declaration* Declaration::ToConstType(void)
Declaration* ndec = new Declaration(mLocation, mType); Declaration* ndec = new Declaration(mLocation, mType);
ndec->mSize = mSize; ndec->mSize = mSize;
ndec->mStride = mStride; ndec->mStride = mStride;
ndec->mBase = mBase; ndec->mStripe = mStripe;
if (mType == DT_TYPE_ARRAY)
ndec->mBase = mBase->ToConstType();
else
ndec->mBase = mBase;
ndec->mBits = mBits;
ndec->mShift = mShift;
ndec->mFlags = mFlags | DTF_CONST; ndec->mFlags = mFlags | DTF_CONST;
ndec->mScope = mScope; ndec->mScope = mScope;
ndec->mParams = mParams; ndec->mParams = mParams;
@ -2220,6 +2524,7 @@ Declaration* Declaration::ToConstType(void)
ndec->mVectorConstructor = mVectorConstructor; ndec->mVectorConstructor = mVectorConstructor;
ndec->mVectorDestructor = mVectorDestructor; ndec->mVectorDestructor = mVectorDestructor;
ndec->mVectorCopyConstructor = mVectorCopyConstructor; ndec->mVectorCopyConstructor = mVectorCopyConstructor;
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
ndec->mVTable = mVTable; ndec->mVTable = mVTable;
ndec->mMutable = this; ndec->mMutable = this;
@ -2229,6 +2534,35 @@ Declaration* Declaration::ToConstType(void)
return mConst; return mConst;
} }
Declaration* Declaration::ToAlternateThis(Declaration* pthis, int nthis)
{
Declaration* ndec = this->Clone();
if (mType == DT_CONST_FUNCTION)
{
ndec->mBase = mBase->ToAlternateThis(pthis, nthis);
if (mValue)
ndec->mValue = mValue->ToAlternateThis(mBase->mParams, ndec->mBase->mParams);
}
else
{
Declaration* nparam = ndec->mParams->Clone();
Declaration* npp = nparam;
Declaration* kpp = ndec->mParams->mNext;
while (kpp)
{
npp->mNext = kpp->Clone();
npp = npp->mNext;
kpp = npp->mNext;
}
nparam->mBase = pthis;
if (nthis == 2)
nparam->mNext->mBase = pthis;
ndec->mParams = nparam;
}
return ndec;
}
Declaration* Declaration::ToMutableType(void) Declaration* Declaration::ToMutableType(void)
{ {
if (!(mFlags & DTF_CONST)) if (!(mFlags & DTF_CONST))
@ -2239,8 +2573,11 @@ Declaration* Declaration::ToMutableType(void)
Declaration* ndec = new Declaration(mLocation, mType); Declaration* ndec = new Declaration(mLocation, mType);
ndec->mSize = mSize; ndec->mSize = mSize;
ndec->mStride = mStride; ndec->mStride = mStride;
ndec->mStripe = mStripe;
ndec->mBase = mBase; ndec->mBase = mBase;
ndec->mFlags = mFlags | DTF_CONST; ndec->mBits = mBits;
ndec->mShift = mShift;
ndec->mFlags = mFlags & ~DTF_CONST;
ndec->mScope = mScope; ndec->mScope = mScope;
ndec->mParams = mParams; ndec->mParams = mParams;
ndec->mIdent = mIdent; ndec->mIdent = mIdent;
@ -2254,6 +2591,7 @@ Declaration* Declaration::ToMutableType(void)
ndec->mVectorConstructor = mVectorConstructor; ndec->mVectorConstructor = mVectorConstructor;
ndec->mVectorDestructor = mVectorDestructor; ndec->mVectorDestructor = mVectorDestructor;
ndec->mVectorCopyConstructor = mVectorCopyConstructor; ndec->mVectorCopyConstructor = mVectorCopyConstructor;
ndec->mVectorMoveConstructor = mVectorMoveConstructor;
ndec->mVTable = mVTable; ndec->mVTable = mVTable;
ndec->mConst = this; ndec->mConst = this;
@ -2583,6 +2921,9 @@ bool Declaration::IsSame(const Declaration* dec) const
if (mType != dec->mType) if (mType != dec->mType)
return false; 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) if (!(mFlags & dec->mFlags & DTF_DEFINED) && mType == DT_TYPE_STRUCT)
return mIdent == dec->mIdent; return mIdent == dec->mIdent;
@ -2591,9 +2932,6 @@ bool Declaration::IsSame(const Declaration* dec) const
if (mStripe != dec->mStripe) if (mStripe != dec->mStripe)
return false; 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) if (mType == DT_CONST_INTEGER)
return mInteger == dec->mInteger; return mInteger == dec->mInteger;
else if (mType == DT_TYPE_INTEGER) else if (mType == DT_TYPE_INTEGER)
@ -2640,7 +2978,7 @@ bool Declaration::IsSame(const Declaration* dec) const
return true; return true;
} }
else if (mType == DT_TYPE_TEMPLATE) else if (mType == DT_TYPE_TEMPLATE || mType == DT_PACK_TEMPLATE)
{ {
return mIdent == dec->mIdent; return mIdent == dec->mIdent;
} }
@ -2773,7 +3111,7 @@ bool Declaration::CanAssign(const Declaration* fromType) const
if (mScope == fromType->mScope || (mIdent == fromType->mIdent && mSize == fromType->mSize)) if (mScope == fromType->mScope || (mIdent == fromType->mIdent && mSize == fromType->mSize))
return true; return true;
if (fromType->mBase) if (fromType->mBase)
return this->CanAssign(fromType->mBase); return this->CanAssign(fromType->mBase->mBase);
return false; return false;
} }
else if (mType == DT_TYPE_ARRAY && fromType->mType == DT_TYPE_ARRAY) else if (mType == DT_TYPE_ARRAY && fromType->mType == DT_TYPE_ARRAY)
@ -2810,6 +3148,10 @@ bool Declaration::CanAssign(const Declaration* fromType) const
{ {
return true; return true;
} }
else if (mBase->mType == DT_TYPE_FUNCTION && fromType->mType == DT_TYPE_ASSEMBLER)
{
return (mBase->mBase->mType == DT_TYPE_VOID && !mBase->mBase->mParams);
}
} }
return false; return false;
@ -2836,6 +3178,52 @@ bool Declaration::IsIndexed(void) const
return mType == DT_TYPE_ARRAY || mType == DT_TYPE_POINTER; 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 bool Declaration::IsSimpleType(void) const
{ {
@ -2855,14 +3243,17 @@ Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration; Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration;
Expression* TheVoidExpression; Expression* TheVoidExpression;
Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration; Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration;
Declaration* TheTrueConstDeclaration, * TheFalseConstDeclaration;
void InitDeclarations(void) void InitDeclarations(void)
{ {
static Location noloc; static Location noloc;
TheVoidTypeDeclaration = new Declaration(noloc, DT_TYPE_VOID); TheVoidTypeDeclaration = new Declaration(noloc, DT_TYPE_VOID);
TheVoidTypeDeclaration->mSize = 0;
TheVoidTypeDeclaration->mFlags = DTF_DEFINED; TheVoidTypeDeclaration->mFlags = DTF_DEFINED;
TheConstVoidTypeDeclaration = new Declaration(noloc, DT_TYPE_VOID); TheConstVoidTypeDeclaration = new Declaration(noloc, DT_TYPE_VOID);
TheConstVoidTypeDeclaration->mSize = 0;
TheConstVoidTypeDeclaration->mFlags = DTF_DEFINED | DTF_CONST; TheConstVoidTypeDeclaration->mFlags = DTF_DEFINED | DTF_CONST;
TheVoidPointerTypeDeclaration = new Declaration(noloc, DT_TYPE_POINTER); TheVoidPointerTypeDeclaration = new Declaration(noloc, DT_TYPE_POINTER);
@ -2954,4 +3345,13 @@ void InitDeclarations(void)
TheZeroFloatConstDeclaration->mBase = TheFloatTypeDeclaration; TheZeroFloatConstDeclaration->mBase = TheFloatTypeDeclaration;
TheZeroFloatConstDeclaration->mSize = 4; TheZeroFloatConstDeclaration->mSize = 4;
TheTrueConstDeclaration = new Declaration(noloc, DT_CONST_INTEGER);
TheTrueConstDeclaration->mBase = TheBoolTypeDeclaration;
TheTrueConstDeclaration->mSize = 1;
TheTrueConstDeclaration->mInteger = 1;
TheFalseConstDeclaration = new Declaration(noloc, DT_CONST_INTEGER);
TheFalseConstDeclaration->mBase = TheBoolTypeDeclaration;
TheFalseConstDeclaration->mSize = 1;
TheFalseConstDeclaration->mInteger = 0;
} }

View File

@ -126,6 +126,8 @@ static const uint64 DTF_VAR_ALIASING = (1ULL << 48);
static const uint64 DTF_FPARAM_UNUSED = (1ULL << 49); static const uint64 DTF_FPARAM_UNUSED = (1ULL << 49);
static const uint64 DTF_DEPRECATED = (1ULL << 50); static const uint64 DTF_DEPRECATED = (1ULL << 50);
static const uint64 DTF_FUNC_NO_RETURN = (1ULL << 51); static const uint64 DTF_FUNC_NO_RETURN = (1ULL << 51);
static const uint64 DTF_PLACED = (1ULL << 52);
static const uint64 DTF_NO_PAGE_CROSS = (1ULL << 53);
@ -165,6 +167,8 @@ public:
ScopeLevel mLevel; ScopeLevel mLevel;
const Ident * mName; const Ident * mName;
DeclarationScope* Clone(void) const;
DeclarationScope* mParent; DeclarationScope* mParent;
protected: protected:
struct Entry struct Entry
@ -214,6 +218,7 @@ enum ExpressionType
EX_IF, EX_IF,
EX_ELSE, EX_ELSE,
EX_FOR, EX_FOR,
EX_FORBODY,
EX_DO, EX_DO,
EX_SCOPE, EX_SCOPE,
EX_BREAK, EX_BREAK,
@ -237,9 +242,16 @@ enum ExpressionType
EX_PACK, EX_PACK,
EX_PACK_TYPE, EX_PACK_TYPE,
EX_LABEL, EX_LABEL,
EX_GOTO EX_GOTO,
EX_AGGREGATE
}; };
static const uint32 ANAFL_LHS = (1U << 0);
static const uint32 ANAFL_RHS = (1U << 1);
static const uint32 ANAFL_ASSIGN = (1U << 2);
static const uint32 ANAFL_ALIAS = (1U << 3);
class Expression class Expression
{ {
public: public:
@ -256,17 +268,23 @@ public:
AsmInsType mAsmInsType; AsmInsType mAsmInsType;
AsmInsMode mAsmInsMode; AsmInsMode mAsmInsMode;
bool mConst; bool mConst;
uint32 mFlags;
Expression* LogicInvertExpression(void); Expression* LogicInvertExpression(void);
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr); Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr);
Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection); Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection);
bool HasSideEffects(void) const; bool HasSideEffects(void) const;
Expression* ListAppend(Expression* lexp); Expression* ListAppend(Expression* lexp);
Expression* ToAlternateThis(Declaration* pthis, Declaration* nthis);
void ReplaceVariable(Declaration* pvar, Declaration* nvar);
bool IsSame(const Expression* exp) const; bool IsSame(const Expression* exp) const;
bool IsRValue(void) const; bool IsRValue(void) const;
bool IsLValue(void) const; bool IsLValue(void) const;
bool IsConstRef(void) const; bool IsConstRef(void) const;
bool IsVolatile(void) const;
void Dump(int ident) const; void Dump(int ident) const;
}; };
@ -284,7 +302,7 @@ public:
Token mToken; Token mToken;
Declaration * mBase, * mParams, * mParamPack, * mNext, * mPrev, * mConst, * mMutable, * mVolatile; Declaration * mBase, * mParams, * mParamPack, * mNext, * mPrev, * mConst, * mMutable, * mVolatile;
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment; Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment;
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment; Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment, * mVectorMoveConstructor, * mVectorMoveAssignment;
Declaration * mVTable, * mClass, * mTemplate; Declaration * mVTable, * mClass, * mTemplate;
Declaration * mForwardParam, * mForwardCall; Declaration * mForwardParam, * mForwardCall;
@ -326,12 +344,17 @@ public:
bool IsSimpleType(void) const; bool IsSimpleType(void) const;
bool IsReference(void) const; bool IsReference(void) const;
bool IsIndexed(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); void SetDefined(void);
Declaration* ToConstType(void); Declaration* ToConstType(void);
Declaration* ToMutableType(void); Declaration* ToMutableType(void);
Declaration* ToVolatileType(void); Declaration* ToVolatileType(void);
Declaration* ToAlternateThis(Declaration* pthis, int nthis = 1);
Declaration* ToStriped(int stripe); Declaration* ToStriped(int stripe);
Declaration* ToStriped(Errors* errors); Declaration* ToStriped(Errors* errors);
@ -355,8 +378,9 @@ public:
DecType ValueType(void) const; DecType ValueType(void) const;
bool CanResolveTemplate(Expression* pexp, Declaration* tdec); bool CanResolveTemplate(Expression* pexp, Declaration* tdec);
bool ResolveTemplate(Declaration* fdec, Declaration * tdec); bool ResolveTemplate(Declaration* fdec, Declaration * tdec, bool same, bool preliminary);
bool ResolveTemplate(Expression* pexp, Declaration* tdec); bool ResolveTemplate(Expression* pexp, Declaration* tdec);
bool ResolveTemplateParameterList(Expression* pexp, Declaration* pdec, bool preliminary);
Declaration* ExpandTemplate(DeclarationScope* scope); Declaration* ExpandTemplate(DeclarationScope* scope);
@ -374,5 +398,6 @@ extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoid
extern Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration; extern Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration;
extern Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration; extern Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration;
extern Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration; extern Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration;
extern Declaration* TheTrueConstDeclaration, * TheFalseConstDeclaration;
extern Expression* TheVoidExpression; extern Expression* TheVoidExpression;

View File

@ -4,11 +4,18 @@
#include <stdlib.h> #include <stdlib.h>
Errors::Errors(void) Errors::Errors(void)
: mErrorCount(0) : mErrorCount(0), mMinLevel(EINFO_GENERIC), mDisabled(EERR_GENERIC)
{ {
} }
ErrorID Errors::SetMinLevel(ErrorID id)
{
ErrorID pid = mMinLevel;
mMinLevel = id;
return pid;
}
void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2) void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2)
{ {
if (!info1) if (!info1)
@ -22,41 +29,44 @@ void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const Iden
void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const char* info1, const char * info2) void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const char* info1, const char * info2)
{ {
const char* level = "info"; if (eid >= mMinLevel && !(eid < EERR_GENERIC && mDisabled[eid]))
if (eid >= EERR_GENERIC)
{ {
level = "error"; const char* level = "info";
mErrorCount++; if (eid >= EERR_GENERIC)
} {
else if (eid >= EWARN_GENERIC) level = "error";
{ mErrorCount++;
level = "warning"; }
} else if (eid >= EWARN_GENERIC)
{
level = "warning";
}
if (loc.mFileName) if (loc.mFileName)
{ {
if (!info1) if (!info1)
fprintf(stderr, "%s(%d, %d) : %s %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg); fprintf(stderr, "%s(%d, %d) : %s %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg);
else if (!info2) else if (!info2)
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1); fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1);
else
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s' != '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1, info2);
if (loc.mFrom)
Error(*(loc.mFrom), EINFO_EXPANDED, "While expanding here");
}
else else
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s' != '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1, info2); {
if (!info1)
fprintf(stderr, "oscar64: %s %d: %s\n", level, eid, msg);
else if (!info2)
fprintf(stderr, "oscar64: %s %d: %s '%s'\n", level, eid, msg, info1);
else
fprintf(stderr, "oscar64: %s %d: %s '%s' != '%s'\n", level, eid, msg, info1, info2);
}
if (loc.mFrom) if (mErrorCount > 10 || eid >= EFATAL_GENERIC)
Error(*(loc.mFrom), EINFO_EXPANDED, "While expanding here"); exit(20);
} }
else
{
if (!info1)
fprintf(stderr, "oscar64: %s %d: %s\n", level, eid, msg);
else if (!info2)
fprintf(stderr, "oscar64: %s %d: %s '%s'\n", level, eid, msg, info1);
else
fprintf(stderr, "oscar64: %s %d: %s '%s' != '%s'\n", level, eid, msg, info1, info2);
}
if (mErrorCount > 10 || eid >= EFATAL_GENERIC)
exit(20);
} }

View File

@ -1,5 +1,8 @@
#pragma once #pragma once
#include "NumberSet.h"
class Location class Location
{ {
public: public:
@ -10,7 +13,11 @@ public:
Location() : mFileName(nullptr), mLine(0), mColumn(0), mFrom(nullptr) {} Location() : mFileName(nullptr), mLine(0), mColumn(0), mFrom(nullptr) {}
Location(const Location& loc, const Location* from) Location(const Location& loc, const Location* from)
: mFileName(loc.mFileName), mLine(loc.mLine), mColumn(loc.mColumn), mFrom(from) : mFileName(loc.mFileName), mLine(loc.mLine), mColumn(loc.mColumn), mFrom(from)
{} {
static volatile int k;
if (from)
k = from->mLine;
}
}; };
class Ident; class Ident;
@ -44,6 +51,8 @@ enum ErrorID
EWARN_DEFAULT_COPY_DEPRECATED, EWARN_DEFAULT_COPY_DEPRECATED,
EWARN_INSUFFICIENT_MEMORY, EWARN_INSUFFICIENT_MEMORY,
EWARN_FUNCTION_NOT_INLINED, EWARN_FUNCTION_NOT_INLINED,
EWARN_INVALID_VOID_POINTER_ARITHMETIC,
EWARN_DIVISION_BY_ZERO,
EERR_GENERIC = 3000, EERR_GENERIC = 3000,
EERR_FILE_NOT_FOUND, EERR_FILE_NOT_FOUND,
@ -103,7 +112,7 @@ enum ErrorID
ERRR_INSTANTIATE_ABSTRACT_CLASS, ERRR_INSTANTIATE_ABSTRACT_CLASS,
ERRR_INVALID_GOTO, ERRR_INVALID_GOTO,
EERR_INVALID_INITIALIZER, EERR_INVALID_INITIALIZER,
ERRR_INVALID_VOID_POINTER_ARITHMETIC,
EERR_INVALID_CONSTEXPR, EERR_INVALID_CONSTEXPR,
EERR_DOUBLE_FREE, EERR_DOUBLE_FREE,
@ -118,9 +127,13 @@ enum ErrorID
EERR_INVALID_CLASS_INITIALIZER, EERR_INVALID_CLASS_INITIALIZER,
EERR_CALL_OF_DELETED_FUNCTION, EERR_CALL_OF_DELETED_FUNCTION,
EERR_STATIC_ASSERT,
EFATAL_GENERIC = 4000, EFATAL_GENERIC = 4000,
EFATAL_OUT_OF_MEMORY, EFATAL_OUT_OF_MEMORY,
EFATAL_MACRO_EXPANSION_DEPTH, EFATAL_MACRO_EXPANSION_DEPTH,
ERROR_MAX = 5000
}; };
class Errors class Errors
@ -128,7 +141,12 @@ class Errors
public: public:
Errors(void); Errors(void);
ErrorID SetMinLevel(ErrorID id);
int mErrorCount; int mErrorCount;
ErrorID mMinLevel;
NumberSet mDisabled;
void Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2 = nullptr); void Error(const Location& loc, ErrorID eid, const char* msg, const Ident* info1, const Ident* info2 = nullptr);
void Error(const Location& loc, ErrorID eid, const char* msg, const char* info1 = nullptr, const char* info2 = nullptr); void Error(const Location& loc, ErrorID eid, const char* msg, const char* info1 = nullptr, const char* info2 = nullptr);

View File

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

View File

@ -35,7 +35,7 @@ protected:
int CallerInvokes(Declaration* called); int CallerInvokes(Declaration* called);
int CallerInvokes(Declaration* caller, 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 IsStackParam(const Declaration* pdec) const;
bool MarkCycle(Declaration* rootDec, Declaration* procDec); bool MarkCycle(Declaration* rootDec, Declaration* procDec);

View File

@ -60,7 +60,7 @@ void GlobalOptimizer::Reset(void)
mFunctions.SetSize(0); mFunctions.SetSize(0);
mGlobalVariables.SetSize(0); mGlobalVariables.SetSize(0);
mCalledFunctions.SetSize(0); mCalledFunctions.SetSize(0);
mCalledFunctions.SetSize(0); mCallingFunctions.SetSize(0);
} }
void GlobalOptimizer::PropagateParamCommas(Expression*& fexp, Expression*& exp) void GlobalOptimizer::PropagateParamCommas(Expression*& fexp, Expression*& exp)
@ -189,7 +189,7 @@ bool GlobalOptimizer::CheckUnusedLocals(Expression*& exp)
if (vexp->mType == EX_VARIABLE) if (vexp->mType == EX_VARIABLE)
{ {
Declaration* vdec = vexp->mDecValue; Declaration* vdec = vexp->mDecValue;
if (vdec->mType == DT_VARIABLE && !(vdec->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(vdec->mOptFlags & OPTF_VAR_USED)) if (vdec->mType == DT_VARIABLE && !(vdec->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(vdec->mOptFlags & OPTF_VAR_USED) && !exp->mRight->IsVolatile())
{ {
exp = exp->mRight; exp = exp->mRight;
return true; return true;
@ -243,6 +243,19 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
bool changed = false; bool changed = false;
if (exp) if (exp)
{ {
if (ReplaceParamConst(exp->mLeft, param))
changed = true;
if (ReplaceParamConst(exp->mRight, param))
changed = true;
if (changed)
{
if (exp->mLeft)
exp->mLeft = exp->mLeft->ConstantFold(mErrors, nullptr);
if (exp->mRight)
exp->mRight = exp->mRight->ConstantFold(mErrors, nullptr);
}
if (exp->mType == EX_VARIABLE && exp->mDecValue == param) if (exp->mType == EX_VARIABLE && exp->mDecValue == param)
{ {
exp->mType = EX_CONSTANT; exp->mType = EX_CONSTANT;
@ -251,10 +264,6 @@ bool GlobalOptimizer::ReplaceParamConst(Expression* exp, Declaration* param)
changed = true; changed = true;
} }
if (ReplaceParamConst(exp->mLeft, param))
changed = true;
if (ReplaceParamConst(exp->mRight, param))
changed = true;
} }
return changed; return changed;
} }
@ -266,14 +275,22 @@ bool GlobalOptimizer::ReplaceGlobalConst(Expression* exp)
{ {
if (exp->mType == EX_VARIABLE && (exp->mDecValue->mFlags & (DTF_GLOBAL | DTF_STATIC)) && !(exp->mDecValue->mOptFlags & (OPTF_VAR_MODIFIED | OPTF_VAR_ADDRESS)) && exp->mDecValue->mValue) 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; Expression* cexp = exp->mDecValue->mValue;
if (cexp->mType == EX_CONSTANT && if (cexp->mType == EX_CONSTANT)
(cexp->mDecValue->mType == DT_CONST_ADDRESS || cexp->mDecValue->mType == DT_CONST_INTEGER ||
cexp->mDecValue->mType == DT_CONST_POINTER || cexp->mDecValue->mType == DT_CONST_FLOAT))
{ {
exp->mType = EX_CONSTANT;
exp->mDecValue = cexp->mDecValue; if (cexp->mDecValue->mType == DT_CONST_ADDRESS || cexp->mDecValue->mType == DT_CONST_INTEGER ||
changed = true; cexp->mDecValue->mType == DT_CONST_POINTER || cexp->mDecValue->mType == DT_CONST_FLOAT)
{
exp->mType = EX_CONSTANT;
exp->mDecValue = cexp->mDecValue->ConstCast(exp->mDecType);
changed = true;
}
else if (exp->mDecValue->mBase->mType == DT_TYPE_STRUCT)
{
exp->mDecValue->mBase = exp->mDecValue->mBase->ToConstType();
}
} }
} }
@ -324,7 +341,7 @@ bool GlobalOptimizer::Optimize(void)
if (!(func->mOptFlags & OPTF_FUNC_VARIABLE) && !(func->mBase->mFlags & DTF_VIRTUAL)) if (!(func->mOptFlags & OPTF_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 #if DUMP_OPTS
printf("Remove return value\n"); printf("Remove return value\n");
@ -382,6 +399,7 @@ bool GlobalOptimizer::Optimize(void)
{ {
if (ReplaceParamConst(func->mValue, pdec)) if (ReplaceParamConst(func->mValue, pdec))
{ {
func->mValue = func->mValue->ConstantFold(mErrors, nullptr);
#if DUMP_OPTS #if DUMP_OPTS
printf("Const parameter %s\n", pdec->mIdent ? pdec->mIdent->mString : "_"); printf("Const parameter %s\n", pdec->mIdent ? pdec->mIdent->mString : "_");
#endif #endif
@ -444,7 +462,7 @@ void GlobalOptimizer::AnalyzeProcedure(Expression* exp, Declaration* procDec)
Analyze(exp, procDec, false); Analyze(exp, procDec, false);
} }
else 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; procDec->mOptFlags &= ~OPTF_ANALYZING;
} }
@ -596,9 +614,6 @@ void GlobalOptimizer::RegisterProc(Declaration* to)
} }
} }
static const uint32 ANAFL_LHS = (1U << 0);
static const uint32 ANAFL_RHS = (1U << 1);
Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uint32 flags) Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uint32 flags)
{ {
Declaration* ldec, * rdec; Declaration* ldec, * rdec;
@ -644,8 +659,10 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
exp->mDecValue->mOptFlags |= OPTF_VAR_USED; exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
if (flags & ANAFL_LHS) if (flags & ANAFL_LHS)
exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS; exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS;
if (exp->mDecValue->mBase->IsReference() && (flags & ANAFL_ASSIGN))
exp->mDecValue->mOptFlags |= OPTF_VAR_USED;
if (exp->mDecValue->mType == DT_ARGUMENT) if (exp->mDecValue->mType == DT_ARGUMENT && (flags & ANAFL_LHS))
{ {
exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD; exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD;
exp->mDecValue->mForwardParam = nullptr; exp->mDecValue->mForwardParam = nullptr;
@ -655,7 +672,12 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
case EX_INITIALIZATION: case EX_INITIALIZATION:
case EX_ASSIGNMENT: case EX_ASSIGNMENT:
if (exp->mToken == TK_ASSIGN) 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 else
ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS | flags); ldec = Analyze(exp->mLeft, procDec, ANAFL_LHS | ANAFL_RHS | flags);
@ -803,6 +825,22 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
pdec->mOptFlags |= OPTF_VAR_CONST; 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 else
{ {
pdec->mOptFlags |= OPTF_VAR_NOCONST; pdec->mOptFlags |= OPTF_VAR_NOCONST;
@ -948,13 +986,20 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
if (exp->mLeft->mLeft->mRight) if (exp->mLeft->mLeft->mRight)
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0); ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0);
break; break;
case EX_FORBODY:
ldec = Analyze(exp->mLeft, procDec, 0);
if (exp->mRight)
rdec = Analyze(exp->mRight, procDec, 0);
break;
case EX_DO: case EX_DO:
ldec = Analyze(exp->mRight, procDec, 0); ldec = Analyze(exp->mRight, procDec, 0);
rdec = Analyze(exp->mLeft, procDec, ANAFL_RHS); rdec = Analyze(exp->mLeft, procDec, ANAFL_RHS);
break; break;
case EX_BREAK: case EX_BREAK:
case EX_CONTINUE: case EX_CONTINUE:
break;
case EX_ASSUME: case EX_ASSUME:
return Analyze(exp->mLeft, procDec, ANAFL_RHS);
break; break;
case EX_TYPE: case EX_TYPE:
break; break;

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -169,6 +169,7 @@ public:
} mMinState, mMaxState; } mMinState, mMaxState;
bool Same(const IntegerValueRange& range) const; bool Same(const IntegerValueRange& range) const;
bool Weaker(const IntegerValueRange& range) const;
bool Merge(const IntegerValueRange& range, bool head, bool initial); bool Merge(const IntegerValueRange& range, bool head, bool initial);
void Expand(const IntegerValueRange& range); void Expand(const IntegerValueRange& range);
void Union(const IntegerValueRange& range); void Union(const IntegerValueRange& range);
@ -198,7 +199,7 @@ public:
typedef GrowingArray<IntegerValueRange> GrowingIntegerValueRangeArray; typedef ExpandingArray<IntegerValueRange> GrowingIntegerValueRangeArray;
class ValueSet class ValueSet
{ {
@ -380,7 +381,7 @@ public:
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator; InterCodeBasicBlock * mTrueJump, * mFalseJump, * mLoopPrefix, * mDominator;
GrowingInstructionArray mInstructions; 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; mutable int mMark;
NumberSet mLocalUsedTemps, mLocalModifiedTemps; NumberSet mLocalUsedTemps, mLocalModifiedTemps;
@ -423,14 +424,15 @@ public:
InterCodeBasicBlock* Clone(void); InterCodeBasicBlock* Clone(void);
void Append(InterInstruction * code); void Append(InterInstruction * code);
void AppendBeforeBranch(InterInstruction* code); void AppendBeforeBranch(InterInstruction* code, bool loopindex = false);
const InterInstruction* FindByDst(int dst) const; const InterInstruction* FindByDst(int dst) const;
void Close(InterCodeBasicBlock* trueJump, InterCodeBasicBlock* falseJump); void Close(InterCodeBasicBlock* trueJump, InterCodeBasicBlock* falseJump);
void CollectEntries(void); void CollectEntries(void);
void CollectEntryBlocks(InterCodeBasicBlock* from); void CollectEntryBlocks(InterCodeBasicBlock* from);
void GenerateTraces(bool expand, bool compact); void GenerateTraces(int expand, bool compact);
void BuildDominatorTree(InterCodeBasicBlock * from); void BuildDominatorTree(InterCodeBasicBlock * from);
bool StripLoopHead(void);
bool MergeSameConditionTraces(void); bool MergeSameConditionTraces(void);
@ -448,6 +450,7 @@ public:
void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps); void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps);
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps); bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
bool ForwardConstTemps(const GrowingInstructionPtrArray& ctemps); bool ForwardConstTemps(const GrowingInstructionPtrArray& ctemps);
bool PropagateConstCompareResults(void);
bool EarlyBranchElimination(const GrowingInstructionPtrArray& ctemps); bool EarlyBranchElimination(const GrowingInstructionPtrArray& ctemps);
@ -480,6 +483,8 @@ public:
bool CheckSingleBlockLimitedLoop(InterCodeBasicBlock*& pblock, int64 & nloop); bool CheckSingleBlockLimitedLoop(InterCodeBasicBlock*& pblock, int64 & nloop);
bool TempIsUnsigned(int temp);
void RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); void RestartLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
void BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); void BuildLocalIntegerRangeSets(int num, const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
void UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars); void UpdateLocalIntegerRangeSets(const GrowingVariableArray& localVars, const GrowingVariableArray& paramVars);
@ -515,6 +520,8 @@ public:
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars, const GrowingInterCodeProcedurePtrArray& staticProcs, FastNumberSet& fsingle); void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars, const GrowingInterCodeProcedurePtrArray& staticProcs, FastNumberSet& fsingle);
bool EliminateDeadBranches(void); bool EliminateDeadBranches(void);
bool EliminateIntegerSumAliasTemps(const GrowingInstructionPtrArray& tvalue);
bool MergeIndexedLoadStore(const GrowingInstructionPtrArray& tvalue); bool MergeIndexedLoadStore(const GrowingInstructionPtrArray& tvalue);
bool SimplifyIntegerNumeric(const GrowingInstructionPtrArray& tvalue, int& spareTemps); bool SimplifyIntegerNumeric(const GrowingInstructionPtrArray& tvalue, int& spareTemps);
bool SimplifyPointerOffsets(void); bool SimplifyPointerOffsets(void);
@ -623,29 +630,42 @@ public:
void SingleBlockLoopUnrolling(void); void SingleBlockLoopUnrolling(void);
bool SingleBlockLoopPointerSplit(int& spareTemps); bool SingleBlockLoopPointerSplit(int& spareTemps);
bool SingleBlockLoopPointerToByte(int& spareTemps); bool SingleBlockLoopPointerToByte(int& spareTemps);
bool SingleBlockLoopSinking(int& spareTemps);
bool CollectLoopBody(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*> & body); bool CollectLoopBody(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*> & body);
bool CollectLoopBodyRecursive(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*>& body); bool CollectLoopBodyRecursive(InterCodeBasicBlock* head, ExpandingArray<InterCodeBasicBlock*>& body);
void CollectLoopPath(const ExpandingArray<InterCodeBasicBlock*>& body, ExpandingArray<InterCodeBasicBlock*>& path); void CollectLoopPath(const ExpandingArray<InterCodeBasicBlock*>& body, ExpandingArray<InterCodeBasicBlock*>& path);
void InnerLoopOptimization(const NumberSet& aliasedParams); void InnerLoopOptimization(const NumberSet& aliasedParams);
void ConstLoopOptimization(void); void ConstLoopOptimization(void);
bool EmptyLoopOptimization(void);
void EliminateDoubleLoopCounter(void); void EliminateDoubleLoopCounter(void);
void PushMoveOutOfLoop(void); void PushMoveOutOfLoop(void);
bool MoveConditionOutOfLoop(void); bool MoveConditionOutOfLoop(void);
void SingleLoopCountZeroCheck(void); void SingleLoopCountZeroCheck(void);
void InnerLoopCountZeroCheck(void);
bool PostDecLoopOptimization(void); bool PostDecLoopOptimization(void);
bool Flatten2DLoop(void);
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue); void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue, bool loops);
void RemoveUnusedMallocs(void); void RemoveUnusedMallocs(void);
bool PullStoreUpToConstAddress(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 SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
bool MergeLoopTails(void); bool MergeLoopTails(void);
bool ChangeTrueJump(InterCodeBasicBlock* block);
bool ChangeFalseJump(InterCodeBasicBlock* block);
InterCodeBasicBlock* CheckIsSimpleIntRangeBranch(const GrowingIntegerValueRangeArray & irange);
InterCodeBasicBlock* CheckIsConstBranch(const GrowingInstructionPtrArray& cins); InterCodeBasicBlock* CheckIsConstBranch(const GrowingInstructionPtrArray& cins);
bool ShortcutConstBranches(const GrowingInstructionPtrArray& cins); bool ShortcutConstBranches(const GrowingInstructionPtrArray& cins);
bool ShortcutDuplicateBranches(void);
InterCodeBasicBlock* BuildLoopPrefix(void); InterCodeBasicBlock* BuildLoopPrefix(void);
void BuildLoopSuffix(void); void BuildLoopSuffix(void);
@ -656,6 +676,7 @@ public:
void FollowJumps(void); void FollowJumps(void);
bool ShortLeaMerge(int& spareTemps); bool ShortLeaMerge(int& spareTemps);
bool ShortLeaCleanup(void);
bool IsEqual(const InterCodeBasicBlock* block) const; bool IsEqual(const InterCodeBasicBlock* block) const;
@ -692,6 +713,7 @@ protected:
GrowingIntegerValueRangeArray mLocalValueRange, mReverseValueRange; GrowingIntegerValueRangeArray mLocalValueRange, mReverseValueRange;
void ResetVisited(void); void ResetVisited(void);
void ResetPatched(void);
void ResetEntryBlocks(void); void ResetEntryBlocks(void);
public: public:
InterCodeBasicBlock * mEntryBlock; InterCodeBasicBlock * mEntryBlock;
@ -753,7 +775,7 @@ public:
void Disassemble(const char* name, bool dumpSets = false); void Disassemble(const char* name, bool dumpSets = false);
protected: protected:
void BuildLocalAliasTable(void); void BuildLocalAliasTable(void);
void BuildTraces(bool expand, bool dominators = true, bool compact = false); void BuildTraces(int expand, bool dominators = true, bool compact = false);
void TrimBlocks(void); void TrimBlocks(void);
void EarlyBranchElimination(void); void EarlyBranchElimination(void);
void BuildDataFlowSets(void); void BuildDataFlowSets(void);
@ -774,7 +796,9 @@ protected:
void SimplifyIntegerNumeric(FastNumberSet& activeSet); void SimplifyIntegerNumeric(FastNumberSet& activeSet);
void SingleBlockLoopPointerSplit(FastNumberSet& activeSet); void SingleBlockLoopPointerSplit(FastNumberSet& activeSet);
void SingleBlockLoopPointerToByte(FastNumberSet& activeSet); void SingleBlockLoopPointerToByte(FastNumberSet& activeSet);
void SingleBlockLoopSinking(FastNumberSet& activeSet);
void MergeIndexedLoadStore(void); void MergeIndexedLoadStore(void);
void EliminateIntegerSumAliasTemps(void);
void EliminateAliasValues(); void EliminateAliasValues();
void LoadStoreForwarding(InterMemory paramMemory); void LoadStoreForwarding(InterMemory paramMemory);
void ReduceRecursionTempSpilling(InterMemory paramMemory); void ReduceRecursionTempSpilling(InterMemory paramMemory);
@ -794,9 +818,10 @@ protected:
void CheckUsedDefinedTemps(void); void CheckUsedDefinedTemps(void);
void WarnUsedUndefinedVariables(void); void WarnUsedUndefinedVariables(void);
void WarnInvalidValueRanges(void); void WarnInvalidValueRanges(void);
void PropagateMemoryAliasingInfo(void); void PropagateMemoryAliasingInfo(bool loops);
void MoveConditionsOutOfLoop(void); void MoveConditionsOutOfLoop(void);
void ShortcutConstBranches(void); void ShortcutConstBranches(void);
void ShortcutDuplicateBranches(void);
void EliminateDoubleLoopCounter(void); void EliminateDoubleLoopCounter(void);
void StructReturnPropagation(void); void StructReturnPropagation(void);

File diff suppressed because it is too large Load Diff

View File

@ -45,7 +45,7 @@ public:
uint64 mCompilerOptions; uint64 mCompilerOptions;
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec); InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
void TranslateAssembler(InterCodeModule* mod, Expression * exp, GrowingArray<Declaration *> * refvars); void TranslateAssembler(InterCodeModule* mod, Declaration* adec,GrowingArray<Declaration *> * refvars);
void InitGlobalVariable(InterCodeModule* mod, Declaration* dec); void InitGlobalVariable(InterCodeModule* mod, Declaration* dec);
void InitLocalVariable(InterCodeProcedure* proc, Declaration* dec, int index); void InitLocalVariable(InterCodeProcedure* proc, Declaration* dec, int index);
void InitParameter(InterCodeProcedure* proc, Declaration* dec, int index); void InitParameter(InterCodeProcedure* proc, Declaration* dec, int index);
@ -94,12 +94,12 @@ protected:
void BuildSwitchTree(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock* block, InlineMapper * inlineMapper, ExValue v, const SwitchNodeArray& nodes, int left, int right, int vleft, int vright, InterCodeBasicBlock* dblock); 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 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 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); 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); 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); 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 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); void StoreValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, InlineMapper* inlineMapper, ExValue vl, ExValue vr);

View File

@ -45,7 +45,7 @@ bool LinkerReference::operator!=(const LinkerReference& ref)
} }
LinkerObject::LinkerObject(void) LinkerObject::LinkerObject(void)
: mReferences(nullptr), mNumTemporaries(0), mSize(0), mAlignment(1), mStackSection(nullptr), mIdent(nullptr), mFullIdent(nullptr), mStartUsed(0x10000), mEndUsed(0x00000), mMemory(nullptr) : mReferences(nullptr), mNumTemporaries(0), mSize(0), mStripe(0), mAlignment(1), mStackSection(nullptr), mIdent(nullptr), mFullIdent(nullptr), mStartUsed(0x10000), mEndUsed(0x00000), mMemory(nullptr)
, mPrefix(nullptr), mSuffix(nullptr), mProc(nullptr), mNativeProc(nullptr) , mPrefix(nullptr), mSuffix(nullptr), mProc(nullptr), mNativeProc(nullptr)
{} {}
@ -54,6 +54,23 @@ LinkerObject::~LinkerObject(void)
} }
LinkerObject* LinkerObject::CloneAssembler(Linker* linker) const
{
LinkerObject* lo = linker->AddObject(mLocation, mIdent, mSection, mType, mAlignment);
lo->AddData(mData, mSize);
lo->mFlags = mFlags;
for (int i = 0; i < mReferences.Size(); i++)
{
LinkerReference ref = *(mReferences[i]);
if (ref.mObject == this) ref.mObject = lo;
if (ref.mRefObject == this) ref.mRefObject = lo;
lo->AddReference(ref);
}
return lo;
}
void LinkerObject::AddReference(const LinkerReference& ref) void LinkerObject::AddReference(const LinkerReference& ref)
{ {
LinkerReference* nref = new LinkerReference(ref); LinkerReference* nref = new LinkerReference(ref);
@ -633,7 +650,7 @@ bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj, bool merge, boo
int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1); int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
int end = start + lobj->mSize; 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) else if (end <= mFreeChunks[i].mEnd)
{ {
@ -685,7 +702,7 @@ bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj, bool merge, boo
int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1); int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
int end = start + lobj->mSize; 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; start = (start + 0x00ff) & 0xff00;
end = start + lobj->mSize; end = start + lobj->mSize;
@ -1886,6 +1903,8 @@ bool Linker::WriteDbjFile(FILE* file)
return true; return true;
} }
static const char hexchars[] = "0123456789abcdef";
bool Linker::WriteLblFile(const char* filename) bool Linker::WriteLblFile(const char* filename)
{ {
FILE* file; FILE* file;
@ -1899,7 +1918,28 @@ bool Linker::WriteLblFile(const char* filename)
if (obj->mFlags & LOBJF_REFERENCED) if (obj->mFlags & LOBJF_REFERENCED)
{ {
if (obj->mIdent) 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);
}
} }
} }

View File

@ -156,6 +156,7 @@ static const uint32 LOBJF_NO_CROSS = 0x00000080;
static const uint32 LOBJF_ZEROPAGE = 0x00000100; static const uint32 LOBJF_ZEROPAGE = 0x00000100;
static const uint32 LOBJF_FORCE_ALIGN = 0x00000200; static const uint32 LOBJF_FORCE_ALIGN = 0x00000200;
static const uint32 LOBJF_ZEROPAGESET = 0x00000400; 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_A = 0x00001000;
static const uint32 LOBJF_ARG_REG_X = 0x00002000; 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_A = 0x00010000;
static const uint32 LOBJF_RET_REG_X = 0x00020000; 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_VAR = 0x00100000;
static const uint32 LOBJF_LOCAL_USED = 0x00200000; static const uint32 LOBJF_LOCAL_USED = 0x00200000;
@ -190,7 +192,7 @@ public:
LinkerObjectType mType; LinkerObjectType mType;
int mID, mMapID; int mID, mMapID;
int mAddress, mRefAddress; int mAddress, mRefAddress;
int mSize, mAlignment, mStartUsed, mEndUsed; int mSize, mAlignment, mStripe, mStartUsed, mEndUsed;
LinkerSection * mSection; LinkerSection * mSection;
LinkerRegion * mRegion; LinkerRegion * mRegion;
uint8 * mData, * mMemory; uint8 * mData, * mMemory;
@ -212,6 +214,8 @@ public:
LinkerObject(void); LinkerObject(void);
~LinkerObject(void); ~LinkerObject(void);
LinkerObject* CloneAssembler(Linker * linker) const;
void AddData(const uint8* data, int size); void AddData(const uint8* data, int size);
void AddLocations(const ExpandingArray<CodeLocation>& locations); void AddLocations(const ExpandingArray<CodeLocation>& locations);
uint8* AddSpace(int size); uint8* AddSpace(int size);

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,9 @@ class NativeCodeBasicBlock;
class NativeCodeGenerator; class NativeCodeGenerator;
class NativeCodeInstruction; class NativeCodeInstruction;
class NativeCodeMapper;
class SuffixTree;
enum NativeRegisterDataMode enum NativeRegisterDataMode
{ {
NRDM_UNKNOWN, NRDM_UNKNOWN,
@ -130,31 +133,42 @@ static const uint32 NCIF_ALIASING = 0x00000800;
static const uint32 NCIF_USE_CPU_REG_A = 0x00001000; static const uint32 NCIF_USE_CPU_REG_A = 0x00001000;
static const uint32 NCIF_USE_CPU_REG_X = 0x00002000; 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_Y = 0x00004000;
static const uint32 NCIF_USE_CPU_REG_C = 0x00008000;
static const uint32 NCIF_PROVIDE_CPU_REG_A = 0x00010000;
static const uint32 NCIF_PROVIDE_CPU_REG_X = 0x00020000;
static const uint32 NCIF_PROVIDE_CPU_REG_Y = 0x00040000;
static const uint32 NCIF_PROVIDE_CPU_REG_C = 0x00080000;
// use a 32bit zero page register indexed by X for JSR // use a 32bit zero page register indexed by X for JSR
static const uint32 NCIF_USE_ZP_32_X = 0x00008000; static const uint32 NCIF_USE_ZP_32_X = 0x00100000;
static const uint32 NICF_USE_ZP_ADDR = 0x00010000; static const uint32 NICF_USE_ZP_ADDR = 0x00200000;
static const uint32 NICF_USE_WORKREGS = 0x00020000; static const uint32 NICF_USE_WORKREGS = 0x00400000;
static const uint32 NCIF_BREAKPOINT = 0x00040000; static const uint32 NCIF_BREAKPOINT = 0x00800000;
class NativeCodeInstruction class NativeCodeInstruction
{ {
public: public:
NativeCodeInstruction(void); NativeCodeInstruction(void);
NativeCodeInstruction(const InterInstruction * ins, AsmInsType type, AsmInsMode mode = ASMIM_IMPLIED, int64 address = 0, LinkerObject * linkerObject = nullptr, uint32 flags = NCIF_LOWER | NCIF_UPPER, int param = 0); NativeCodeInstruction(const InterInstruction * ins, AsmInsType type, AsmInsMode mode = ASMIM_IMPLIED, int64 address = 0, LinkerObject * linkerObject = nullptr, uint32 flags = NCIF_LOWER | NCIF_UPPER, int param = 0, int minv = 0, int maxv = 255);
NativeCodeInstruction(const InterInstruction* ins, AsmInsType type, const NativeCodeInstruction & addr); NativeCodeInstruction(const InterInstruction* ins, AsmInsType type, const NativeCodeInstruction & addr);
AsmInsType mType; AsmInsType mType;
AsmInsMode mMode; AsmInsMode mMode;
int mAddress, mParam; int mAddress, mParam;
uint32 mFlags; uint32 mFlags;
uint32 mLive; uint32 mLive;
LinkerObject * mLinkerObject; LinkerObject * mLinkerObject;
const InterInstruction * mIns; const InterInstruction * mIns;
uint8 mMinVal, mMaxVal;
void Disassemble(FILE* file) const;
void DisassembleAddress(FILE* file) const;
void CopyMode(const NativeCodeInstruction& ins); void CopyMode(const NativeCodeInstruction& ins);
void CopyModeAndRange(const NativeCodeInstruction& ins);
void Assemble(NativeCodeBasicBlock* block); void Assemble(NativeCodeBasicBlock* block);
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps); void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
@ -191,6 +205,7 @@ public:
bool UsesZeroPage(int address) const; bool UsesZeroPage(int address) const;
bool ReferencesZeroPage(int address) const; bool ReferencesZeroPage(int address) const;
bool SameLinkerObjectVariableRange(const NativeCodeInstruction& ins, bool sameXY = false) const;
bool ChangesGlobalMemory(void) const; bool ChangesGlobalMemory(void) const;
bool UsesMemoryOf(const NativeCodeInstruction& ins) const; bool UsesMemoryOf(const NativeCodeInstruction& ins) const;
@ -205,7 +220,7 @@ public:
bool IsShift(void) const; bool IsShift(void) const;
bool IsShiftOrInc(void) const; bool IsShiftOrInc(void) const;
bool IsSimpleJSR(void) const; bool IsSimpleJSR(void) const;
bool MayBeMovedBefore(const NativeCodeInstruction& ins); bool MayBeMovedBefore(const NativeCodeInstruction& ins) const;
bool ReplaceYRegWithXReg(void); bool ReplaceYRegWithXReg(void);
bool ReplaceXRegWithYReg(void); bool ReplaceXRegWithYReg(void);
@ -216,6 +231,12 @@ public:
void BuildCollisionTable(NumberSet& liveTemps, NumberSet* collisionSets); void BuildCollisionTable(NumberSet& liveTemps, NumberSet* collisionSets);
uint32 NeedsLive(void) const; uint32 NeedsLive(void) const;
uint32 CodeHash(void) const;
bool CodeSame(const NativeCodeInstruction& ins);
protected:
const char* AddrName(char* buffer) const;
}; };
struct NativeCodeLoadStorePair struct NativeCodeLoadStorePair
@ -246,10 +267,12 @@ public:
ExpandingArray<NativeCodeBasicBlock*> mEntryBlocks; ExpandingArray<NativeCodeBasicBlock*> mEntryBlocks;
int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset, mTemp; int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset, mTemp;
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit; bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchUsed, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit;
bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX, mChecked; bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX, mChecked;
NativeCodeBasicBlock * mDominator, * mSameBlock; NativeCodeBasicBlock * mDominator, * mSameBlock;
int mAsmFromJump;
NativeCodeBasicBlock* mLoopHeadBlock, * mLoopTailBlock; NativeCodeBasicBlock* mLoopHeadBlock, * mLoopTailBlock;
NativeRegisterDataSet mDataSet, mNDataSet, mFDataSet; NativeRegisterDataSet mDataSet, mNDataSet, mFDataSet;
@ -262,21 +285,27 @@ public:
NativeCodeInstruction mALSIns, mXLSIns, mYLSIns; NativeCodeInstruction mALSIns, mXLSIns, mYLSIns;
void Disassemble(FILE* file);
void DisassembleBody(FILE* file);
NativeCodeInstruction DecodeNative(const InterInstruction* ins, LinkerObject * lobj, int& offset) const; NativeCodeInstruction DecodeNative(const InterInstruction* ins, LinkerObject * lobj, int& offset) const;
int PutBranch(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, AsmInsType code, int offset); int PutBranch(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, AsmInsType code, int from, int to);
int PutJump(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, int offset, AsmInsType code = ASMIT_INV); int PutJump(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, int from, int to, AsmInsType code = ASMIT_INV);
int JumpByteSize(NativeCodeBasicBlock * target, int offset, bool second); int JumpByteSize(NativeCodeBasicBlock * target, int from, int to, bool second, bool final);
int BranchByteSize(NativeCodeBasicBlock* target, int from, int to); int CheckFinalBranchByteSize(NativeCodeBasicBlock* target, int from, int to) const;
int BranchByteSize(NativeCodeBasicBlock* target, int from, int to, bool final) const;
NativeCodeBasicBlock* SplitAt(int at); NativeCodeBasicBlock* SplitAt(int at);
NativeCodeBasicBlock* BypassEmptyBlocks(void); NativeCodeBasicBlock* BypassEmptyBlocks(void);
int LeadsInto(NativeCodeBasicBlock* block, int dist); int LeadsInto(NativeCodeBasicBlock* block, int dist);
NativeCodeBasicBlock* PlaceSequence(ExpandingArray<NativeCodeBasicBlock*>& placement, NativeCodeBasicBlock* block);
void BuildPlacement(ExpandingArray<NativeCodeBasicBlock*>& placement); void BuildPlacement(ExpandingArray<NativeCodeBasicBlock*>& placement);
void OptimizePlacement(void);
void InitialOffset(int& total); void InitialOffset(int& total);
bool CalculateOffset(int& total); bool CalculateOffset(int& total, bool final);
void CopyCode(NativeCodeProcedure* proc, uint8* target); void CopyCode(NativeCodeProcedure* proc, uint8* target);
void Assemble(void); void Assemble(void);
@ -299,6 +328,8 @@ public:
bool UsesZeroPage(int address, int from = 0, int to = 65536) const; bool UsesZeroPage(int address, int from = 0, int to = 65536) const;
bool ReferencesZeroPage(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 RemoveNops(void);
bool PeepHoleOptimizer(int pass); bool PeepHoleOptimizer(int pass);
@ -317,18 +348,20 @@ public:
bool PeepHoleOptimizerIterate(int pass); bool PeepHoleOptimizerIterate(int pass);
bool PeepHoleOptimizerExits(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 BlockSizeCopyReduction(NativeCodeProcedure* proc, int & si, int & di);
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, bool full); bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, bool full);
bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock * prevBlock, NativeCodeBasicBlock* exitBlock, bool full); bool OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock * prevBlock, NativeCodeBasicBlock* exitBlock, bool full);
bool RemoveSimpleLoopUnusedIndex(void); bool RemoveSimpleLoopUnusedIndex(void);
bool OptimizeLoopCarryOver(void); bool OptimizeLoopCarryOver(void);
bool OptimizeLoopRegisterWrapAround(void);
bool OptimizeSingleEntryLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prev, NativeCodeBasicBlock* tail, ExpandingArray<NativeCodeBasicBlock*>& blocks); bool OptimizeSingleEntryLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* prev, NativeCodeBasicBlock* tail, ExpandingArray<NativeCodeBasicBlock*>& blocks);
bool OptimizeSingleEntryLoop(NativeCodeProcedure* proc); bool OptimizeSingleEntryLoop(NativeCodeProcedure* proc);
bool OptimizeSimpleLoop(NativeCodeProcedure* proc, bool full); bool OptimizeSimpleLoop(NativeCodeProcedure* proc, bool full);
bool OptimizeSimpleForLoop(void);
bool SimpleLoopReversal(NativeCodeProcedure* proc); bool SimpleLoopReversal(NativeCodeProcedure* proc);
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, ExpandingArray<NativeCodeBasicBlock*>& blocks); bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, ExpandingArray<NativeCodeBasicBlock*>& blocks);
bool OptimizeXYSimpleLoop(void); bool OptimizeXYSimpleLoop(void);
@ -340,9 +373,11 @@ public:
bool OptimizeInnerLoops(NativeCodeProcedure* proc); bool OptimizeInnerLoops(NativeCodeProcedure* proc);
NativeCodeBasicBlock* CollectInnerLoop(NativeCodeBasicBlock* head, ExpandingArray<NativeCodeBasicBlock*>& lblocks); NativeCodeBasicBlock* CollectInnerLoop(NativeCodeBasicBlock* head, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
bool OptimizeGenericLoop(NativeCodeProcedure* proc); int CorrectXOffset(const InterInstruction * ins, int yoffset, int at);
bool CollectGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks); int CorrectYOffset(const InterInstruction * ins, int yoffset, int at);
bool CollectSingleEntryGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks); bool OptimizeGenericLoop(void);
bool CollectGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
bool CollectSingleEntryGenericLoop(ExpandingArray<NativeCodeBasicBlock*>& lblocks);
void CollectReachable(ExpandingArray<NativeCodeBasicBlock*>& lblock); void CollectReachable(ExpandingArray<NativeCodeBasicBlock*>& lblock);
bool OptimizeFindLoop(NativeCodeProcedure* proc); bool OptimizeFindLoop(NativeCodeProcedure* proc);
@ -358,7 +393,7 @@ public:
void CheckFrameIndex(const InterInstruction * ins, int & reg, int & index, int size, int treg = 0); void CheckFrameIndex(const InterInstruction * ins, int & reg, int & index, int size, int treg = 0);
void LoadValueToReg(InterCodeProcedure* proc, const InterInstruction * ins, int reg, const NativeCodeInstruction * ainsl, const NativeCodeInstruction* ainsh); void LoadValueToReg(InterCodeProcedure* proc, const InterInstruction * ins, int reg, const NativeCodeInstruction * ainsl, const NativeCodeInstruction* ainsh);
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction* ins, InterType type, int reg); void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction* ins, InterType type, int reg);
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction* ins, const InterOperand & op, InterType type, int reg); void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction* ins, const InterOperand & op, InterType type, int reg, bool checkRange = true);
void LoadConstant(InterCodeProcedure* proc, const InterInstruction * ins); void LoadConstant(InterCodeProcedure* proc, const InterInstruction * ins);
void StoreValue(InterCodeProcedure* proc, const InterInstruction * ins); void StoreValue(InterCodeProcedure* proc, const InterInstruction * ins);
@ -376,7 +411,7 @@ public:
NativeCodeBasicBlock* BinaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0); NativeCodeBasicBlock* BinaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
void UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins); void UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump); void RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0, bool addrvalid); void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0, bool addrvalid, bool addrused = false);
void LoadStoreOpAbsolute2D(InterCodeProcedure* proc, const InterInstruction* lins1, const InterInstruction* lins2, const InterInstruction* mins); void LoadStoreOpAbsolute2D(InterCodeProcedure* proc, const InterInstruction* lins1, const InterInstruction* lins2, const InterInstruction* mins);
void SignExtendAddImmediate(InterCodeProcedure* proc, const InterInstruction* xins, const InterInstruction* ains); void SignExtendAddImmediate(InterCodeProcedure* proc, const InterInstruction* xins, const InterInstruction* ains);
void BinaryDivModPair(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins1, const InterInstruction* ins2); void BinaryDivModPair(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins1, const InterInstruction* ins2);
@ -393,6 +428,7 @@ public:
void LoadByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* rins); void LoadByteIndexedValue(InterCodeProcedure* proc, const InterInstruction* iins, const InterInstruction* rins);
void StoreByteIndexedValue(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 CallAssembler(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
void CallFunction(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins); void CallFunction(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
@ -405,6 +441,7 @@ public:
int ShortSignedDivide(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins, const InterInstruction* sins, int mul); int ShortSignedDivide(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins, const InterInstruction* sins, int mul);
bool CheckPredAccuStore(int reg); bool CheckPredAccuStore(int reg);
bool CheckIsInAccu(int reg);
NumberSet mLocalRequiredRegs, mLocalProvidedRegs; NumberSet mLocalRequiredRegs, mLocalProvidedRegs;
NumberSet mEntryRequiredRegs, mEntryProvidedRegs; NumberSet mEntryRequiredRegs, mEntryProvidedRegs;
@ -426,9 +463,7 @@ public:
void CountEntries(NativeCodeBasicBlock* fromJump); void CountEntries(NativeCodeBasicBlock* fromJump);
NativeCodeBasicBlock * ForwardAccuBranch(bool eq, bool ne, bool pl, bool mi, int limit); NativeCodeBasicBlock * ForwardAccuBranch(bool eq, bool ne, bool pl, bool mi, int limit);
bool MergeBasicBlocks(void); bool MergeBasicBlocks(void);
void RemoveJumpToBranch(void); bool RemoveJumpToBranch(void);
void MarkLoopHead(void);
struct DominatorStacks struct DominatorStacks
{ {
@ -502,7 +537,9 @@ public:
bool CombineImmediateADCUp(int at); bool CombineImmediateADCUp(int at);
bool CombineImmediateADCUpX(int at); bool CombineImmediateADCUpX(int at);
bool MoveTXADCDown(int at); bool MoveTXADCDown(int at);
bool MoveTXALogicTAXDown(int at);
bool FoldShiftORAIntoLoadImmUp(int at); bool FoldShiftORAIntoLoadImmUp(int at);
bool ReverseShiftByteOrder(int at);
bool FindAccuExitValue(int& at); bool FindAccuExitValue(int& at);
bool MoveLoadXAbsUpCrossBlock(int at); bool MoveLoadXAbsUpCrossBlock(int at);
@ -536,6 +573,7 @@ public:
bool CombineSameYtoX(int xpos, int ypos, int end); bool CombineSameYtoX(int xpos, int ypos, int end);
bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains); bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains);
int FindImmediateGlobalStore(int at, const NativeCodeInstruction& ins);
bool JoinXYCrossBlock(void); bool JoinXYCrossBlock(void);
bool CanCombineSameXtoYCrossBlock(int from); bool CanCombineSameXtoYCrossBlock(int from);
@ -556,6 +594,13 @@ public:
bool ReverseReplaceTAX(int at); bool ReverseReplaceTAX(int at);
bool CanReplaceExitAccuWithX(NativeCodeBasicBlock * target);
bool CanReplaceExitAccuWithY(NativeCodeBasicBlock* target);
void ReplaceExitAccuWithX(NativeCodeBasicBlock* target);
void ReplaceExitAccuWithY(NativeCodeBasicBlock* target);
bool ReverseLoadAccuToRegXY(void);
void ResetModifiedDataSet(NativeRegisterDataSet& data); void ResetModifiedDataSet(NativeRegisterDataSet& data);
bool ValueForwarding(NativeCodeProcedure* proc, const NativeRegisterDataSet& data, bool global, bool final); bool ValueForwarding(NativeCodeProcedure* proc, const NativeRegisterDataSet& data, bool global, bool final);
@ -565,6 +610,9 @@ public:
bool OffsetValueForwarding(const ValueNumberingDataSet & data); bool OffsetValueForwarding(const ValueNumberingDataSet & data);
bool AbsoluteValueForwarding(const ExpandingArray<NativeCodeLoadStorePair>& npairs); bool AbsoluteValueForwarding(const ExpandingArray<NativeCodeLoadStorePair>& npairs);
bool IndexXYValueForwarding(int xreg, int xoffset, int xvalue, int yreg, int yoffset, int yvalue); 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); void MarkLocalUsedLinkerObjects(void);
bool RemoveLocalUnusedLinkerObjects(void); bool RemoveLocalUnusedLinkerObjects(void);
@ -584,7 +632,14 @@ public:
bool HasTailSTY(int& addr, int& index) const; bool HasTailSTY(int& addr, int& index) const;
bool HasTailSTAX16(int& addr, int& index0) const; bool HasTailSTAX16(int& addr, int& index0) const;
bool HasTailSTAInto(int& addr, int& index, NativeCodeBasicBlock* tblock) const;
bool HasTailSTXInto(int& addr, int& index, NativeCodeBasicBlock* tblock) const;
bool HasTailSTYInto(int& addr, int& index, NativeCodeBasicBlock* tblock) const;
bool HasTailSTAGlobal(NativeCodeInstruction & ins, int& index) const;
bool MayBeMovedBeforeBlock(int at); bool MayBeMovedBeforeBlock(int at);
bool MayBeMovedBeforeBlock(int at, const NativeCodeInstruction & ins);
bool MayBeMovedBeforeBlock(int start, int end); bool MayBeMovedBeforeBlock(int start, int end);
bool SafeInjectSequenceFromBack(NativeCodeBasicBlock* block, int start, int end); bool SafeInjectSequenceFromBack(NativeCodeBasicBlock* block, int start, int end);
bool JoinCommonBranchCodeSequences(void); bool JoinCommonBranchCodeSequences(void);
@ -688,6 +743,8 @@ public:
bool EliminateDeadLoops(void); bool EliminateDeadLoops(void);
bool LoopRegisterWrapAround(void); bool LoopRegisterWrapAround(void);
bool CrossBlockFlagsForwarding(void); bool CrossBlockFlagsForwarding(void);
bool MoveStoresBeforeDiamond(void);
bool MoveStoresBehindCondition(void);
bool SinglePathRegisterForwardY(NativeCodeBasicBlock* path, int yreg); bool SinglePathRegisterForwardY(NativeCodeBasicBlock* path, int yreg);
bool SinglePathRegisterForward(void); bool SinglePathRegisterForward(void);
@ -720,8 +777,9 @@ public:
bool CanGlobalSwapXY(void); bool CanGlobalSwapXY(void);
bool GlobalSwapXY(void); bool GlobalSwapXY(void);
bool LocalSwapXY(void); bool LocalSwapXY(void);
bool UntangleXYUsage(void); bool UntangleXYUsage(bool final);
bool AlternateXXUsage(void); bool AlternateXXUsage(void);
bool ShortSwapXY(void);
bool IsSimpleSubExpression(int at, NativeSimpleSubExpression & ex); bool IsSimpleSubExpression(int at, NativeSimpleSubExpression & ex);
bool PropagateCommonSubExpression(void); bool PropagateCommonSubExpression(void);
@ -745,10 +803,20 @@ public:
bool CheckPatchFailUse(void); bool CheckPatchFailUse(void);
bool CheckPatchFailLoop(const NativeCodeBasicBlock* block, const NativeCodeBasicBlock* head, int reg, bool changed); 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 JoinSameBranch(NativeCodeBasicBlock* block);
bool MergeSameBranch(void); 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 // reg : base register pair to replace
// index: index register // index: index register
// at : start position in block // at : start position in block
@ -758,9 +826,20 @@ public:
bool CheckGlobalAddressSumYPointer(const NativeCodeBasicBlock * block, int reg, int index, int at, int yval); bool CheckGlobalAddressSumYPointer(const NativeCodeBasicBlock * block, int reg, int index, int at, int yval);
bool PatchGlobalAddressSumYPointer(const NativeCodeBasicBlock* block, int reg, int index, int at, int yval, LinkerObject * lobj, int address, uint32 flags = NCIF_LOWER | NCIF_UPPER); bool PatchGlobalAddressSumYPointer(const NativeCodeBasicBlock* block, int reg, int index, int at, int yval, LinkerObject * lobj, int address, uint32 flags = NCIF_LOWER | NCIF_UPPER);
// reg : register to replace
// at : start position in block
// ains : instruction loading original data
// cycles : max number of cycles saving
bool CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains, int cycles); bool CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains, int cycles);
bool PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains); bool PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains);
// rins : instruction storing the data
// at : start position in block
// ains : instruction loading original data
// cycles : max number of cycles saving
bool CheckSingleUseGlobalLoadStruct(const NativeCodeBasicBlock* block, const NativeCodeInstruction& rins, int at, const NativeCodeInstruction& ains, bool cleared, bool poisoned);
bool PatchSingleUseGlobalLoadStruct(const NativeCodeBasicBlock* block, const NativeCodeInstruction& rins, int at, const NativeCodeInstruction& ains);
// reg : base register pair to replace // reg : base register pair to replace
// base: new base register // base: new base register
// iins : indexing instruction // iins : indexing instruction
@ -804,6 +883,10 @@ public:
void PropagateAddGlobalCarry(void); void PropagateAddGlobalCarry(void);
bool EliminateNonAliasedLocalStores(void);
bool CheckNonAliasedLocalStore(int at, const NativeCodeInstruction& sins);
void RegisterFunctionCalls(void); void RegisterFunctionCalls(void);
bool MergeFunctionCalls(void); bool MergeFunctionCalls(void);
@ -813,6 +896,9 @@ public:
void CheckBlocks(bool sequence = false); void CheckBlocks(bool sequence = false);
void CheckAsmCode(void); void CheckAsmCode(void);
void CheckVisited(void); void CheckVisited(void);
int* mSuffixString;
void AddToSuffixTree(NativeCodeMapper& mapper, SuffixTree * tree);
}; };
class NativeCodeProcedure class NativeCodeProcedure
@ -827,6 +913,10 @@ class NativeCodeProcedure
NativeCodeGenerator* mGenerator; NativeCodeGenerator* mGenerator;
InterCodeProcedure* mInterProc; InterCodeProcedure* mInterProc;
LinkerObject* mLinkerObject;
const Ident* mIdent;
Location mLocation;
uint64 mCompilerOptions;
int mProgStart, mProgSize, mIndex, mFrameOffset, mStackExpand; int mProgStart, mProgSize, mIndex, mFrameOffset, mStackExpand;
int mFastCallBase; int mFastCallBase;
@ -838,10 +928,15 @@ class NativeCodeProcedure
ExpandingArray<CodeLocation> mCodeLocations; ExpandingArray<CodeLocation> mCodeLocations;
void DisassembleDebug(const char* name);
void Disassemble(FILE* file);
void Compile(InterCodeProcedure* proc); void Compile(InterCodeProcedure* proc);
void Optimize(void); void Optimize(void);
void Assemble(void); void Assemble(void);
void AddToSuffixTree(NativeCodeMapper& mapper, SuffixTree* tree);
NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block); NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
NativeCodeBasicBlock* AllocateBlock(void); NativeCodeBasicBlock* AllocateBlock(void);
@ -907,6 +1002,8 @@ public:
Linker* mLinker; Linker* mLinker;
LinkerSection* mRuntimeSection; LinkerSection* mRuntimeSection;
ExpandingArray<NativeCodeProcedure*> mProcedures;
ExpandingArray<Runtime> mRuntime; ExpandingArray<Runtime> mRuntime;
ExpandingArray<MulTable> mMulTables; ExpandingArray<MulTable> mMulTables;
ExpandingArray<FloatTable> mFloatTables; ExpandingArray<FloatTable> mFloatTables;
@ -925,6 +1022,8 @@ public:
FunctionCall* mFunctionCalls; FunctionCall* mFunctionCalls;
void OutlineFunctions(void);
void RegisterFunctionCall(NativeCodeBasicBlock* block, int at); void RegisterFunctionCall(NativeCodeBasicBlock* block, int at);
void BuildFunctionProxies(void); void BuildFunctionProxies(void);
bool MergeFunctionCall(NativeCodeBasicBlock* block, int at); bool MergeFunctionCall(NativeCodeBasicBlock* block, int at);

View File

@ -0,0 +1,379 @@
#include "NativeCodeOutliner.h"
NativeCodeMapper::NativeCodeMapper(void)
{
for (int i = 0; i < HashSize; i++)
mHash[i] = nullptr;
}
NativeCodeMapper::~NativeCodeMapper(void)
{
for (int i = 0; i < HashSize; i++)
{
InsNode* n = mHash[i];
while (n)
{
InsNode* m = n;
n = n->mNext;
delete m;
}
mHash[i] = nullptr;
}
}
void NativeCodeMapper::Reset(void)
{
mBlocks.SetSize(0);
}
int NativeCodeMapper::MapBasicBlock(NativeCodeBasicBlock* block)
{
mBlocks.Push(block);
return -mBlocks.Size();
}
int NativeCodeMapper::MapInstruction(const NativeCodeInstruction& ins, LinkerSection* ls)
{
int hash = ins.CodeHash() % HashSize;
InsNode* n = mHash[hash];
while (n)
{
if (mIns[n->mIndex].CodeSame(ins) && n->mSection == ls)
return n->mIndex;
n = n->mNext;
}
n = new InsNode();
n->mIndex = mIns.Size();
n->mSection = ls;
mIns.Push(ins);
n->mNext = mHash[hash];
mHash[hash] = n;
return n->mIndex;
}
SuffixTree::SuffixTree(const int* str, int s, SuffixTree* n)
{
mSeg = str;
mSize = s;
mNext = n;
mParent = nullptr;
mFirst = nullptr;
}
SuffixTree::~SuffixTree(void)
{
delete[] mFirst;
}
void SuffixTree::AddParents(SuffixTree* parent)
{
mParent = parent;
if (mFirst)
{
for (int i = 0; i < HashSize; i++)
{
SuffixTree* n = mFirst[i];
while (n)
{
n->AddParents(this);
n = n->mNext;
}
}
}
}
void SuffixTree::AddSuffix(const int* str, int s)
{
int hi = str[0] & (HashSize - 1);
SuffixTree* c = mFirst ? mFirst[hi] : nullptr;
while (c && c->mSeg[0] != str[0])
c = c->mNext;
if (c)
{
int k = 1;
while (k < c->mSize && str[k] == c->mSeg[k])
k++;
if (k == c->mSize)
c->AddSuffix(str + k, s - k);
else
{
SuffixTree * n = new SuffixTree(c->mSeg + k, c->mSize - k, nullptr);
if (c->mFirst)
{
n->mFirst = new SuffixTree * [HashSize];
for (int i = 0; i < HashSize; i++)
{
n->mFirst[i] = c->mFirst[i];
c->mFirst[i] = nullptr;
}
}
else
{
c->mFirst = new SuffixTree * [HashSize];
for (int i = 0; i < HashSize; i++)
c->mFirst[i] = nullptr;
}
c->mFirst[c->mSeg[k] & (HashSize - 1)] = n;
int hk = str[k] & (HashSize - 1);
c->mFirst[hk] = new SuffixTree(str + k, s - k, c->mFirst[hk]);
c->mSize = k;
}
}
else
{
if (!mFirst)
{
mFirst = new SuffixTree * [HashSize];
for (int i = 0; i < HashSize; i++)
mFirst[i] = nullptr;
}
mFirst[hi] = new SuffixTree(str, s, mFirst[hi]);
}
}
void SuffixTree::AddString(const int* str)
{
int s = 0;
while(str[s] >= 0)
s++;
s++;
int i = 0;
while (str[i] >= 0)
{
AddSuffix(str + i, s - i);
i++;
}
AddSuffix(str + i, 1);
}
void SuffixTree::CollectSuffix(NativeCodeMapper& map, int offset, ExpandingArray<SuffixSegment>& segs)
{
offset += mSize;
if (mFirst)
{
for (int i = 0; i < HashSize; i++)
{
SuffixTree* t = mFirst[i];
while (t)
{
t->CollectSuffix(map, offset, segs);
t = t->mNext;
}
}
}
else
{
NativeCodeBasicBlock* block = map.mBlocks[-(mSeg[mSize - 1] + 1)];
SuffixSegment seg;
seg.mBlock = block;
seg.mStart = offset;
seg.mEnd = block->mIns.Size() + 1;
segs.Push(seg);
}
}
int SuffixTree::LongestMatch(NativeCodeMapper& map, int size, int isize, int& msize, SuffixTree*& mtree)
{
if (mFirst)
{
isize += mSize;
for (int i = 0; i < mSize; i++)
{
if (mSeg[i] >= 0)
size += AsmInsModeSize[map.mIns[mSeg[i]].mMode];
}
assert(size < 10000);
int cnt = 0;
for (int i = 0; i < HashSize; i++)
{
SuffixTree* t = mFirst[i];
while (t)
{
cnt += t->LongestMatch(map, size, isize, msize, mtree);
t = t->mNext;
}
}
if (size >= 6 && (size - 3) * (cnt - 1) > msize)
{
// Second run to cross check for overlaps
ExpandingArray<SuffixSegment> segs;
for (int i = 0; i < HashSize; i++)
{
SuffixTree* t = mFirst[i];
while (t)
{
t->CollectSuffix(map, 0, segs);
t = t->mNext;
}
}
segs.Sort([](const SuffixSegment& l, const SuffixSegment& r)->bool {
return l.mBlock == r.mBlock ? l.mStart < r.mStart : ptrdiff_t(l.mBlock) < ptrdiff_t(r.mBlock);
});
for (int i = 0; i + 1 < segs.Size(); i++)
{
if (segs[i].mBlock == segs[i + 1].mBlock && segs[i].mStart + isize > segs[i + 1].mStart)
cnt--;
}
if (cnt > 1 && (size - 3) * (cnt - 1) > msize)
{
msize = (size - 3) * (cnt - 1);
mtree = this;
}
}
return cnt;
}
else
return 1;
}
void SuffixTree::Print(FILE * file, NativeCodeMapper& map, int depth)
{
for (int i = 0; i < depth; i++)
fprintf(file, ".");
for (int i = 0; i < mSize; i++)
{
fprintf(file, "[");
if (mSeg[i] >= 0)
map.mIns[mSeg[i]].Disassemble(file);
else
{
NativeCodeBasicBlock* block = map.mBlocks[- (mSeg[i] + 1)];
fprintf(file, "%s,%d", block->mProc->mInterProc->mIdent->mString, block->mIndex);
}
fprintf(file, "]");
}
fprintf(file, "\n");
if (mFirst)
{
for (int i = 0; i < HashSize; i++)
{
SuffixTree* n = mFirst[i];
while (n)
{
n->Print(file, map, depth + 1);
n = n->mNext;
}
}
}
}
void SuffixTree::ParentPrint(FILE* file, NativeCodeMapper& map)
{
if (mParent)
mParent->ParentPrint(file, map);
for (int i = 0; i < mSize; i++)
{
if (mSeg[i] >= 0)
map.mIns[mSeg[i]].Disassemble(file);
else
{
NativeCodeBasicBlock* block = map.mBlocks[-(mSeg[i] + 1)];
fprintf(file, "%s,%d", block->mProc->mInterProc->mIdent->mString, block->mIndex);
}
fprintf(file, "\n");
}
}
int SuffixTree::ParentCodeSize(NativeCodeMapper& map) const
{
int size = 0;
for (int i = 0; i < mSize; i++)
{
if (mSeg[i] >= 0)
size += AsmInsModeSize[map.mIns[mSeg[i]].mMode];
}
if (mParent)
size += mParent->ParentCodeSize(map);
return size;
}
void SuffixTree::ParentCollect(NativeCodeMapper& map, NativeCodeBasicBlock* block)
{
if (mParent)
mParent->ParentCollect(map, block);
for (int i = 0; i < mSize; i++)
block->mIns.Push(map.mIns[mSeg[i]]);
}
void SuffixTree::ReplaceCalls(NativeCodeMapper& map, ExpandingArray<SuffixSegment>& segs)
{
if (mFirst)
{
for (int i = 0; i < HashSize; i++)
{
SuffixTree* n = mFirst[i];
while (n)
{
n->ChildReplaceCalls(map, this, 0, segs);
n = n->mNext;
}
}
}
}
void SuffixTree::ChildReplaceCalls(NativeCodeMapper& map, SuffixTree* tree, int offset, ExpandingArray<SuffixSegment>& segs)
{
for (int i = 0; i < mSize; i++)
{
if (mSeg[i] >= 0)
offset ++;
}
if (mFirst)
{
for (int i = 0; i < HashSize; i++)
{
SuffixTree* n = mFirst[i];
while (n)
{
n->ChildReplaceCalls(map, tree, offset, segs);
n = n->mNext;
}
}
}
else
{
NativeCodeBasicBlock* block = map.mBlocks[-(mSeg[mSize - 1] + 1)];
tree->ParentReplaceCalls(map, block, offset, 0, segs);
}
}
void SuffixTree::ParentReplaceCalls(NativeCodeMapper& map, NativeCodeBasicBlock* block, int offset, int size, ExpandingArray<SuffixSegment>& segs)
{
for (int i = 0; i < mSize; i++)
{
if (mSeg[i] >= 0)
size ++;
}
if (mParent)
mParent->ParentReplaceCalls(map, block, offset, size, segs);
else
{
int at = block->mIns.Size() - offset - size;
SuffixSegment seg;
seg.mBlock = block;
seg.mStart = at;
seg.mEnd = at + size;
segs.Push(seg);
}
}

View File

@ -0,0 +1,66 @@
#pragma once
#include "NativeCodeGenerator.h"
#include "Array.h"
class NativeCodeMapper
{
public:
NativeCodeMapper(void);
~NativeCodeMapper(void);
void Reset(void);
int MapInstruction(const NativeCodeInstruction& ins, LinkerSection * ls);
int MapBasicBlock(NativeCodeBasicBlock* block);
ExpandingArray<NativeCodeInstruction> mIns;
ExpandingArray<NativeCodeBasicBlock*> mBlocks;
protected:
static const int HashSize = 256;
struct InsNode
{
int mIndex;
LinkerSection * mSection;
InsNode* mNext;
};
InsNode * mHash[HashSize];
};
struct SuffixSegment
{
NativeCodeBasicBlock * mBlock;
int mStart, mEnd;
};
class SuffixTree
{
public:
const int * mSeg;
int mSize;
static const int HashSize = 32;
SuffixTree* mNext, * mParent, ** mFirst;
SuffixTree(const int* str, int s, SuffixTree* n);
~SuffixTree(void);
void AddParents(SuffixTree* parent);
void AddSuffix(const int* str, int s);
void AddString(const int* str);
void Print(FILE* file, NativeCodeMapper & map, int depth);
void ParentPrint(FILE* file, NativeCodeMapper& map);
int LongestMatch(NativeCodeMapper& map, int size, int isize, int & msize, SuffixTree *& mtree);
void CollectSuffix(NativeCodeMapper& map, int offset, ExpandingArray<SuffixSegment>& segs);
int ParentCodeSize(NativeCodeMapper& map) const;
void ParentCollect(NativeCodeMapper& map, NativeCodeBasicBlock * block);
void ReplaceCalls(NativeCodeMapper& map, ExpandingArray<SuffixSegment> & segs);
void ChildReplaceCalls(NativeCodeMapper& map, SuffixTree * tree, int offset, ExpandingArray<SuffixSegment>& segs);
void ParentReplaceCalls(NativeCodeMapper& map, NativeCodeBasicBlock* block, int offset, int size, ExpandingArray<SuffixSegment>& segs);
};

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@ public:
~Parser(void); ~Parser(void);
Parser* Clone(void); Parser* Clone(void);
Parser * mParent;
DeclarationScope * mGlobals, * mScope, * mTemplateScope, * mCaptureScope; DeclarationScope * mGlobals, * mScope, * mTemplateScope, * mCaptureScope;
int mLocalIndex; int mLocalIndex;
@ -24,6 +25,8 @@ public:
uint64 mCompilerOptionStack[32]; uint64 mCompilerOptionStack[32];
int mCompilerOptionSP; int mCompilerOptionSP;
Location FullLocation(const Location& loc);
void Parse(void); void Parse(void);
protected: protected:
bool ExpectToken(Token token); bool ExpectToken(Token token);
@ -77,12 +80,13 @@ protected:
Expression* DefaultInitExpression(Expression* vexp); Expression* DefaultInitExpression(Expression* vexp);
Expression* ParseVarInitExpression(Expression* lexp, bool inner = false); Expression* ParseVarInitExpression(Expression* lexp, bool inner = false);
Expression* CloneVarInitExpression(Expression* vexp, Expression* iexp, Expression * qexp); Expression* CloneVarInitExpression(Expression* vexp, Expression* iexp, Expression * qexp);
Expression* CopyElision(Expression* vexp, Expression* rexp);
Declaration* ParsePostfixDeclaration(void); Declaration* ParsePostfixDeclaration(void);
Declaration* ReverseDeclaration(Declaration* odec, Declaration* bdec); Declaration* ReverseDeclaration(Declaration* odec, Declaration* bdec);
Expression* ParseFunction(Declaration* dec); Expression* ParseFunction(Declaration* dec);
Expression* ParseAssembler(void); Expression* ParseAssembler(Declaration * vdassm = nullptr);
Expression* ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset); Expression* ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset);
Expression* ParseAssemblerMulOperand(Declaration* pcasm, int pcoffset); Expression* ParseAssemblerMulOperand(Declaration* pcasm, int pcoffset);
@ -133,7 +137,10 @@ protected:
Declaration* ParseTypeID(bool tid, Declaration * bdec = nullptr); Declaration* ParseTypeID(bool tid, Declaration * bdec = nullptr);
Expression* ParseConstruction(Declaration* type);
Expression* ParseCastExpression(Expression* exp); Expression* ParseCastExpression(Expression* exp);
Expression* ParseIdentExpression(const Location & eloc, Declaration* dec, bool lhs, bool tid = false);
Expression* ParseSimpleExpression(bool lhs, bool tid = false); Expression* ParseSimpleExpression(bool lhs, bool tid = false);
Expression* ParsePrefixExpression(bool lhs); Expression* ParsePrefixExpression(bool lhs);
Expression* ParsePostfixExpression(bool lhs); Expression* ParsePostfixExpression(bool lhs);
@ -152,9 +159,10 @@ protected:
Expression* ParseRExpression(void); Expression* ParseRExpression(void);
Expression* ExpandArgumentPack(Expression * exp, Declaration* dec); Expression* ExpandArgumentPack(Expression * exp, Declaration* dec);
Expression* ParseListExpression(bool lhs); Expression* ParseListExpression(bool lhs, Declaration * params = nullptr);
Expression* ParseParenthesisExpression(void); Expression* ParseParenthesisExpression(void);
void ParseStaticAssert(void);
Errors* mErrors; Errors* mErrors;
Scanner* mScanner; Scanner* mScanner;

View File

@ -44,7 +44,7 @@ bool SourceFile::ReadLineLZO(char* line, ptrdiff_t limit)
while (pi < 127 && mPos < mFill) while (pi < 127 && mPos < mFill)
{ {
int bi = pi, bj = 0; int bi = pi, bj = 0;
for (int i = 1; i < mPos; i++) for (int i = 1; i <= (mPos < 255 ? mPos : 255); i++)
{ {
int j = 0; int j = 0;
while (j < 127 && mPos + j < mFill && mBuffer[mPos - i + j] == mBuffer[mPos + j]) while (j < 127 && mPos + j < mFill && mBuffer[mPos - i + j] == mBuffer[mPos + j])
@ -327,6 +327,16 @@ struct CTMHeader9
uint8 mColors[7]; uint8 mColors[7];
}; };
struct CTTHeader9
{
uint8 mDispMode;
uint8 mColorMethod;
uint8 mFlags;
uint8 mFgridWidth[2], mFGridHeight[2];
char mFGridConfig;
uint8 mColors[6];
};
#if 0 #if 0
#pragma pack(push, 1) #pragma pack(push, 1)
struct SPDHeader5 struct SPDHeader5
@ -420,6 +430,7 @@ void SourceFile::ReadSpritePad(Errors* errors, const Location& location, SourceF
if (spdHeader.mID[0] == 'S' && spdHeader.mID[1] == 'P' && spdHeader.mID[2] == 'D') if (spdHeader.mID[0] == 'S' && spdHeader.mID[1] == 'P' && spdHeader.mID[2] == 'D')
{ {
int numSprites = 0; int numSprites = 0;
int numTiles = 0, tileSize = 0;
switch (spdHeader.mVersion[0]) switch (spdHeader.mVersion[0])
{ {
@ -428,6 +439,8 @@ void SourceFile::ReadSpritePad(Errors* errors, const Location& location, SourceF
SPDHeader5 spdHeader5; SPDHeader5 spdHeader5;
fread(&spdHeader5, sizeof(SPDHeader5), 1, mFile); fread(&spdHeader5, sizeof(SPDHeader5), 1, mFile);
numSprites = spdHeader5.mNumSprites; numSprites = spdHeader5.mNumSprites;
numTiles = spdHeader5.mNumTiles;
tileSize = spdHeader5.mTileHeight * spdHeader5.mTileWidth;
break; break;
} }
case 3: case 3:
@ -435,6 +448,8 @@ void SourceFile::ReadSpritePad(Errors* errors, const Location& location, SourceF
SPDHeader3 spdHeader3; SPDHeader3 spdHeader3;
fread(&spdHeader3, sizeof(SPDHeader3), 1, mFile); fread(&spdHeader3, sizeof(SPDHeader3), 1, mFile);
numSprites = spdHeader3.mNumSprites; numSprites = spdHeader3.mNumSprites;
numTiles = spdHeader3.mNumTiles;
tileSize = spdHeader3.mTileHeight * spdHeader3.mTileWidth;
break; break;
} }
case 1: case 1:
@ -454,6 +469,21 @@ void SourceFile::ReadSpritePad(Errors* errors, const Location& location, SourceF
mLimit = 64 * numSprites; mLimit = 64 * numSprites;
return; return;
} }
else if (decoder == SFD_SPD_TILES)
{
fseek(mFile, 64 * numSprites, SEEK_CUR);
mMemSize = numTiles * tileSize;
mLimit = mMemSize;
mMemPos = 0;
mMemData = new uint8[mMemSize];
for (int i = 0; i < mMemSize; i++)
{
int16 d;
fread(&d, 2, 1, mFile);
mMemData[i] = uint8(d);
}
return;
}
} }
else else
errors->Error(location, EERR_UNIMPLEMENTED, "SPD file format not recognized"); errors->Error(location, EERR_UNIMPLEMENTED, "SPD file format not recognized");
@ -466,6 +496,7 @@ void SourceFile::ReadCharPad(Errors* errors, const Location& location, SourceFil
CTMHeader ctmHeader; CTMHeader ctmHeader;
CTMHeader8 ctmHeader8; CTMHeader8 ctmHeader8;
CTMHeader9 ctmHeader9; CTMHeader9 ctmHeader9;
CTTHeader9 cttHeader9;
uint16 ctmMarker, numChars, numTiles; uint16 ctmMarker, numChars, numTiles;
char tileWidth, tileHeight; char tileWidth, tileHeight;
@ -476,10 +507,20 @@ void SourceFile::ReadCharPad(Errors* errors, const Location& location, SourceFil
fread(&ctmHeader8, sizeof(CTMHeader8), 1, mFile); fread(&ctmHeader8, sizeof(CTMHeader8), 1, mFile);
break; break;
case 9: case 9:
fread(&ctmHeader9, sizeof(CTMHeader9), 1, mFile); if (ctmHeader.mID[2] == 'T')
ctmHeader8.mDispMode = ctmHeader9.mDispMode; {
ctmHeader8.mColorMethod = ctmHeader9.mColorMethod; fread(&cttHeader9, sizeof(CTTHeader9), 1, mFile);
ctmHeader8.mFlags = ctmHeader9.mFlags; 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; break;
} }
@ -725,6 +766,7 @@ void SourceFile::Limit(Errors* errors, const Location& location, SourceFileDecod
break; break;
case SFD_SPD_SPRITES: case SFD_SPD_SPRITES:
case SFD_SPD_TILES:
ReadSpritePad(errors, location, decoder); ReadSpritePad(errors, location, decoder);
break; break;

View File

@ -34,7 +34,8 @@ enum SourceFileDecoder
SFD_CTM_TILES_16, SFD_CTM_TILES_16,
SFD_CTM_MAP_8, SFD_CTM_MAP_8,
SFD_CTM_MAP_16, SFD_CTM_MAP_16,
SFD_SPD_SPRITES SFD_SPD_SPRITES,
SFD_SPD_TILES,
}; };
class SourceFile class SourceFile

View File

@ -51,6 +51,7 @@ const char* TokenNames[] =
"'extern'", "'extern'",
"'inline'", "'inline'",
"'__assume'", "'__assume'",
"'static_assert'",
"__asm", "__asm",
"__interrupt", "__interrupt",
@ -173,6 +174,7 @@ const char* TokenNames[] =
"'friend'", "'friend'",
"'constexpr'", "'constexpr'",
"'typename'", "'typename'",
"'decltype'",
}; };
@ -355,7 +357,7 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
mToken = TK_NONE; mToken = TK_NONE;
mUngetToken = TK_NONE; mUngetToken = TK_NONE;
mReplay = nullptr; mReplay = nullptr;
mRecord = mRecordLast = nullptr; mRecord = mRecordLast = mRecordPrev = nullptr;
mOnceDict = new MacroDict(); mOnceDict = new MacroDict();
@ -372,13 +374,13 @@ Scanner::~Scanner(void)
void Scanner::BeginRecord(void) void Scanner::BeginRecord(void)
{ {
mRecord = mRecordLast = new TokenSequence(this); mRecord = mRecordLast = mRecordPrev = new TokenSequence(this);
} }
TokenSequence* Scanner::CompleteRecord(void) TokenSequence* Scanner::CompleteRecord(void)
{ {
TokenSequence* seq = mRecord; TokenSequence* seq = mRecord;
mRecord = mRecordLast = nullptr; mRecord = mRecordLast = mRecordPrev = nullptr;
return seq; return seq;
} }
@ -483,6 +485,8 @@ void Scanner::UngetToken(Token token)
{ {
mUngetToken = mToken; mUngetToken = mToken;
mToken = token; mToken = token;
if (mRecord)
mRecordLast = mRecordPrev;
} }
void Scanner::NextToken(void) void Scanner::NextToken(void)
@ -491,10 +495,8 @@ void Scanner::NextToken(void)
{ {
mToken = mUngetToken; mToken = mUngetToken;
mUngetToken = TK_NONE; mUngetToken = TK_NONE;
return;
} }
else if (mReplay)
if (mReplay)
{ {
mLocation = mReplay->mLocation; mLocation = mReplay->mLocation;
mToken = mReplay->mToken; mToken = mReplay->mToken;
@ -515,6 +517,7 @@ void Scanner::NextToken(void)
if (mRecord) if (mRecord)
{ {
mRecordPrev = mRecordLast;
mRecordLast->mNext = new TokenSequence(this); mRecordLast->mNext = new TokenSequence(this);
mRecordLast = mRecordLast->mNext; mRecordLast = mRecordLast->mNext;
} }
@ -820,28 +823,36 @@ void Scanner::NextPreToken(void)
} }
else if (mToken == TK_PREP_IDENT) else if (mToken == TK_PREP_IDENT)
{ {
Macro* def = nullptr; if (mTokenIdent->mString[0])
if (mDefineArguments)
def = mDefineArguments->Lookup(mTokenIdent);
if (!def)
def = mDefines->Lookup(mTokenIdent);
if (def)
{ {
if (def->mNumArguments == -1) Macro* def = nullptr;
if (mDefineArguments)
def = mDefineArguments->Lookup(mTokenIdent);
if (!def)
def = mDefines->Lookup(mTokenIdent);
if (def)
{ {
mToken = TK_STRING; if (def->mNumArguments == -1)
int i = 0; {
while ((mTokenString[i] = def->mString[i])) mToken = TK_STRING;
i++; int i = 0;
mTokenStringSize = i; while ((mTokenString[i] = def->mString[i]))
return; i++;
mTokenStringSize = i;
return;
}
else
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
} }
else else
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent); mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent);
} }
else else
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", mTokenIdent); {
mToken = TK_HASH;
return;
}
} }
else if (mToken == TK_PREP_UNDEF) else if (mToken == TK_PREP_UNDEF)
{ {
@ -986,6 +997,8 @@ void Scanner::NextPreToken(void)
decoder = SFD_CTM_MAP_16; decoder = SFD_CTM_MAP_16;
else if (!strcmp(mTokenIdent->mString, "spd_sprites")) else if (!strcmp(mTokenIdent->mString, "spd_sprites"))
decoder = SFD_SPD_SPRITES; decoder = SFD_SPD_SPRITES;
else if (!strcmp(mTokenIdent->mString, "spd_tiles"))
decoder = SFD_SPD_TILES;
else else
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Invalid embed compression mode", mTokenIdent); mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Invalid embed compression mode", mTokenIdent);
@ -1112,46 +1125,70 @@ void Scanner::NextPreToken(void)
while (mTokenChar == ' ') while (mTokenChar == ' ')
NextChar(); NextChar();
while (mTokenChar == '#' && mLine[mOffset] == '#') if (mTokenChar == '#' && mLine[mOffset] == '#')
{ {
mOffset++;
NextChar();
char tkbase[256]; char tkbase[256];
strcpy_s(tkbase, mTokenIdent->mString); strcpy_s(tkbase, mTokenIdent->mString);
ptrdiff_t n = 0; do {
char tkident[256]; mOffset++;
while (IsIdentChar(mTokenChar))
{
if (n < 255)
tkident[n++] = mTokenChar;
NextChar(); NextChar();
}
tkident[n] = 0;
const Ident* ntkident = Ident::Unique(tkident); ptrdiff_t n = 0;
char tkident[256];
while (IsIdentChar(mTokenChar))
{
if (n < 255)
tkident[n++] = mTokenChar;
NextChar();
}
tkident[n] = 0;
Macro* def = nullptr; const Ident* ntkident = Ident::Unique(tkident);
if (mDefineArguments)
def = mDefineArguments->Lookup(ntkident);
if (!def)
def = mDefines->Lookup(ntkident);
if (def) Macro* def = nullptr;
strcat_s(tkbase, def->mString); if (mDefineArguments)
else def = mDefineArguments->Lookup(ntkident);
strcat_s(tkbase, tkident); if (!def)
def = mDefines->Lookup(ntkident);
n = strlen(tkbase); if (def)
while (n > 0 && tkbase[n - 1] == ' ') strcat_s(tkbase, def->mString);
n--; else
tkbase[n] = 0; strcat_s(tkbase, tkident);
mTokenIdent = Ident::Unique(tkbase); n = strlen(tkbase);
while (n > 0 && tkbase[n - 1] == ' ')
n--;
tkbase[n] = 0;
while (mTokenChar == ' ')
NextChar();
} while (mTokenChar == '#' && mLine[mOffset] == '#');
ptrdiff_t n = strlen(tkbase);
char* str = new char[n + 1];
strcpy_s(str, n + 1, tkbase);
MacroExpansion* ex = new MacroExpansion();
ex->mDefinedArguments = mDefineArguments;
ex->mLine = mLine;
ex->mOffset = mOffset;
ex->mLink = mMacroExpansion;
ex->mChar = mTokenChar;
mMacroExpansion = ex;
mMacroExpansionDepth++;
if (mMacroExpansionDepth > 1024)
mErrors->Error(mLocation, EFATAL_MACRO_EXPANSION_DEPTH, "Maximum macro expansion depth exceeded", mTokenIdent);
mLine = str;
mOffset = 0;
NextChar();
} }
else
return; return;
} }
} }
else else
@ -1796,6 +1833,8 @@ void Scanner::NextRawToken(void)
mToken = TK_ASM; mToken = TK_ASM;
else if (!strcmp(tkident, "__assume")) else if (!strcmp(tkident, "__assume"))
mToken = TK_ASSUME; mToken = TK_ASSUME;
else if (!strcmp(tkident, "static_assert"))
mToken = TK_STATIC_ASSERT;
else if (!strcmp(tkident, "__interrupt")) else if (!strcmp(tkident, "__interrupt"))
mToken = TK_INTERRUPT; mToken = TK_INTERRUPT;
else if (!strcmp(tkident, "__hwinterrupt")) else if (!strcmp(tkident, "__hwinterrupt"))
@ -1844,6 +1883,8 @@ void Scanner::NextRawToken(void)
mToken = TK_CONSTEXPR; mToken = TK_CONSTEXPR;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "typename")) else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "typename"))
mToken = TK_TYPENAME; mToken = TK_TYPENAME;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "decltype"))
mToken = TK_DECLTYPE;
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator")) else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
{ {
NextRawToken(); NextRawToken();
@ -1973,7 +2014,7 @@ void Scanner::NextRawToken(void)
default: default:
// dirty little hack to implement token preview, got to fix // 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; mUngetToken = mToken;
mToken = TK_OPERATOR; mToken = TK_OPERATOR;
return; return;

View File

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

View File

@ -76,7 +76,7 @@ int main2(int argc, const char** argv)
#else #else
strcpy(strProductName, "oscar64"); strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.31.255"); strcpy(strProductVersion, "1.31.261");
#ifdef __APPLE__ #ifdef __APPLE__
uint32_t length = sizeof(basePath); uint32_t length = sizeof(basePath);
@ -111,38 +111,12 @@ int main2(int argc, const char** argv)
GrowingArray<const char*> dataFiles(nullptr); GrowingArray<const char*> dataFiles(nullptr);
GrowingArray<bool> dataFileCompressed(false); GrowingArray<bool> dataFileCompressed(false);
bool emulate = false, profile = false, customCRT = false;
int trace = 0;
compiler->mPreprocessor->AddPath(basePath); compiler->mPreprocessor->AddPath(basePath);
strcpy_s(includePath, basePath); strcpy_s(includePath, basePath);
{ strcat_s(includePath, "include");
FILE* crtFile;
char crtFileNamePath[FILENAME_MAX];
crtFileNamePath[FILENAME_MAX - 1] = '\0';
strcpy_s(crtFileNamePath, basePath);
strcat_s(crtFileNamePath, "include/crt.h");
if (!fopen_s(&crtFile, crtFileNamePath, "r"))
strcat_s(includePath, "include/");
else
{
strcpy_s(crtFileNamePath, basePath);
strcat_s(crtFileNamePath, "include/oscar64/crt.h");
if (!fopen_s(&crtFile, crtFileNamePath, "r"))
strcat_s(includePath, "include/oscar64/");
else
{
printf("Could not locate Oscar64 includes under %s\n", basePath);
return 20;
}
}
fclose(crtFile);
}
compiler->mPreprocessor->AddPath(includePath);
strcpy_s(crtPath, includePath);
strcat_s(crtPath, "crt.c");
bool emulate = false, profile = false;
int trace = 0;
targetPath[0] = 0; targetPath[0] = 0;
diskPath[0] = 0; diskPath[0] = 0;
@ -185,6 +159,10 @@ int main2(int argc, const char** argv)
{ {
compiler->mPreprocessor->AddPath(arg + 3); 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] == '=') else if (arg[1] == 'f' && arg[2] == '=')
{ {
dataFiles.Push(arg + 3); 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] == '=') else if (arg[1] == 'r' && arg[2] == 't' && arg[3] == '=')
{ {
strcpy_s(crtPath, arg + 4); strcpy_s(crtPath, arg + 4);
customCRT = true;
} }
else if (arg[1] == 'd' && arg[2] == '6' && arg[3] == '4' && arg[4] == '=') else if (arg[1] == 'd' && arg[2] == '6' && arg[3] == '4' && arg[4] == '=')
{ {
@ -253,6 +232,8 @@ int main2(int argc, const char** argv)
compiler->mCompilerOptions |= COPT_OPTIMIZE_ASSEMBLER; compiler->mCompilerOptions |= COPT_OPTIMIZE_ASSEMBLER;
else if (arg[2] == 'i' && !arg[3]) else if (arg[2] == 'i' && !arg[3])
compiler->mCompilerOptions |= COPT_OPTIMIZE_AUTO_INLINE; compiler->mCompilerOptions |= COPT_OPTIMIZE_AUTO_INLINE;
else if (arg[2] == 'i' && arg[3] == 'i' && !arg[4])
compiler->mCompilerOptions |= COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_INLINE_ALL;
else if (arg[2] == 'z' && !arg[3]) else if (arg[2] == 'z' && !arg[3])
compiler->mCompilerOptions |= COPT_OPTIMIZE_AUTO_ZEROPAGE; compiler->mCompilerOptions |= COPT_OPTIMIZE_AUTO_ZEROPAGE;
else if (arg[2] == 'p' && !arg[3]) else if (arg[2] == 'p' && !arg[3])
@ -261,6 +242,10 @@ int main2(int argc, const char** argv)
compiler->mCompilerOptions |= COPT_OPTIMIZE_GLOBAL; compiler->mCompilerOptions |= COPT_OPTIMIZE_GLOBAL;
else if (arg[2] == 'm' && !arg[3]) else if (arg[2] == 'm' && !arg[3])
compiler->mCompilerOptions |= COPT_OPTIMIZE_MERGE_CALLS; 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 else
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid command line argument", arg); compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid command line argument", arg);
} }
@ -297,6 +282,10 @@ int main2(int argc, const char** argv)
{ {
compiler->mCompilerOptions |= COPT_DEBUGINFO; compiler->mCompilerOptions |= COPT_DEBUGINFO;
} }
else if (arg[1] == 'g' && arg[2] == 'p' && !arg[3])
{
compiler->mCompilerOptions |= COPT_DEBUGINFO | COPT_PROFILEINFO;
}
else if (arg[1] == 'v') else if (arg[1] == 'v')
{ {
compiler->mCompilerOptions |= COPT_VERBOSE; compiler->mCompilerOptions |= COPT_VERBOSE;
@ -317,7 +306,13 @@ int main2(int argc, const char** argv)
{ {
compiler->mCompilerOptions |= COPT_CPLUSPLUS; compiler->mCompilerOptions |= COPT_CPLUSPLUS;
compiler->AddDefine(Ident::Unique("__cplusplus"), "1"); compiler->AddDefine(Ident::Unique("__cplusplus"), "1");
compiler->AddDefine(Ident::Unique("__cplusplus__"), "1");
} }
else if (arg[1] == 's' && arg[2] == 't' && arg[3] == 'r' && arg[4] == 'i' && arg[5] == 'c' && arg[6] == 't' && !arg[7])
{
compiler->mCompilerOptions |= COPT_STRICT;
compiler->AddDefine(Ident::Unique("__strict__"), "1");
}
else if (arg[1] == 'r' && arg[2] == 'm' && arg[3] == 'p' && !arg[4]) else if (arg[1] == 'r' && arg[2] == 'm' && arg[3] == 'p' && !arg[4])
{ {
compiler->mCompilerOptions |= COPT_ERROR_FILES; compiler->mCompilerOptions |= COPT_ERROR_FILES;
@ -335,6 +330,7 @@ int main2(int argc, const char** argv)
{ {
compiler->mCompilerOptions |= COPT_CPLUSPLUS; compiler->mCompilerOptions |= COPT_CPLUSPLUS;
compiler->AddDefine(Ident::Unique("__cplusplus"), "1"); compiler->AddDefine(Ident::Unique("__cplusplus"), "1");
compiler->AddDefine(Ident::Unique("__cplusplus__"), "1");
} }
compiler->mCompilationUnits->AddUnit(loc, argv[i], nullptr); compiler->mCompilationUnits->AddUnit(loc, argv[i], nullptr);
@ -431,6 +427,12 @@ int main2(int argc, const char** argv)
compiler->mTargetMachine = TMACH_PLUS4; compiler->mTargetMachine = TMACH_PLUS4;
compiler->AddDefine(Ident::Unique("__PLUS4__"), "1"); compiler->AddDefine(Ident::Unique("__PLUS4__"), "1");
} }
else if (!strcmp(targetMachine, "mega65"))
{
strcpy_s(basicStart, "0x2001");
compiler->mTargetMachine = TMACH_MEGA65;
compiler->AddDefine(Ident::Unique("__MEGA65__"), "1");
}
else if (!strcmp(targetMachine, "x16")) else if (!strcmp(targetMachine, "x16"))
{ {
strcpy_s(basicStart, "0x0801"); strcpy_s(basicStart, "0x0801");
@ -549,12 +551,41 @@ int main2(int argc, const char** argv)
strftime(dstring, sizeof(tstring) - 1, "\"%b %d %Y\"", &t); strftime(dstring, sizeof(tstring) - 1, "\"%b %d %Y\"", &t);
strftime(tstring, sizeof(dstring) - 1, "\"%H:%M:%S\"", &t); strftime(tstring, sizeof(dstring) - 1, "\"%H:%M:%S\"", &t);
compiler->AddDefine(Ident::Unique("__DATE__"), dstring); compiler->AddDefine(Ident::Unique("__DATE__"), _strdup(dstring));
compiler->AddDefine(Ident::Unique("__TIME__"), tstring); compiler->AddDefine(Ident::Unique("__TIME__"), _strdup(tstring));
} }
// Add runtime module // 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]) if (crtPath[0])
compiler->mCompilationUnits->AddUnit(loc, crtPath, nullptr); compiler->mCompilationUnits->AddUnit(loc, crtPath, nullptr);

View File

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

View File

@ -189,6 +189,7 @@
<ClCompile Include="Linker.cpp" /> <ClCompile Include="Linker.cpp" />
<ClCompile Include="MachineTypes.cpp" /> <ClCompile Include="MachineTypes.cpp" />
<ClCompile Include="NativeCodeGenerator.cpp" /> <ClCompile Include="NativeCodeGenerator.cpp" />
<ClCompile Include="NativeCodeOutliner.cpp" />
<ClCompile Include="NumberSet.cpp" /> <ClCompile Include="NumberSet.cpp" />
<ClCompile Include="oscar64.cpp" /> <ClCompile Include="oscar64.cpp" />
<ClCompile Include="Parser.cpp" /> <ClCompile Include="Parser.cpp" />
@ -218,6 +219,7 @@
<ClInclude Include="Linker.h" /> <ClInclude Include="Linker.h" />
<ClInclude Include="MachineTypes.h" /> <ClInclude Include="MachineTypes.h" />
<ClInclude Include="NativeCodeGenerator.h" /> <ClInclude Include="NativeCodeGenerator.h" />
<ClInclude Include="NativeCodeOutliner.h" />
<ClInclude Include="NumberSet.h" /> <ClInclude Include="NumberSet.h" />
<ClInclude Include="Parser.h" /> <ClInclude Include="Parser.h" />
<ClInclude Include="Preprocessor.h" /> <ClInclude Include="Preprocessor.h" />

View File

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

View File

@ -220,12 +220,6 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_23B2892D4F99800BBD8DB9210ECF6B0F"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_24F2466589154E2DAA108C2EDB3BB432" "MsmKey" = "8:_24F2466589154E2DAA108C2EDB3BB432"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -286,12 +280,6 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_31D185B4E4448BB9122BE23BE0C259A8"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_3277DE1463544F67B7E7390175F8A9CF" "MsmKey" = "8:_3277DE1463544F67B7E7390175F8A9CF"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -412,6 +400,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_4B482689C546CDFC92F367BA507E7ADE"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_4B8FC526E6CC47FC8321D0191BFDBEDC" "MsmKey" = "8:_4B8FC526E6CC47FC8321D0191BFDBEDC"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -430,6 +424,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_4E94486A43C1D1C032A05ED1E6F1FCEF"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_4E9503F4F8F343739E4685C2066B3AD0" "MsmKey" = "8:_4E9503F4F8F343739E4685C2066B3AD0"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -454,12 +454,6 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_55D2A0DA296A07FFD056F9B0C3671317"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_5832EB4DC2134FF0BB7872666547CA0B" "MsmKey" = "8:_5832EB4DC2134FF0BB7872666547CA0B"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -532,6 +526,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_65687B00DD49EEBBFFECE831614822A9"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_67C8F824E02B4211B315AB32AB7ABBB1" "MsmKey" = "8:_67C8F824E02B4211B315AB32AB7ABBB1"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -634,12 +634,6 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_7E4677138841AB7F15DEADCDE137C3A1"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_7E6F12A2B7A647199FCBA7CBDF4E94D2" "MsmKey" = "8:_7E6F12A2B7A647199FCBA7CBDF4E94D2"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -724,12 +718,6 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_8F9D1B22CCDDE3C1C2E92F178E8AD418"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_90171C7FE48D426E8664B043F5E75D6B" "MsmKey" = "8:_90171C7FE48D426E8664B043F5E75D6B"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -808,6 +796,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_A1455504C259EDA9662CE90C07369CC5"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_A14BC161099E420286E6A1595596D0F0" "MsmKey" = "8:_A14BC161099E420286E6A1595596D0F0"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -832,6 +826,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_A2F68033370E18CD792ECD1F91357C1B"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_A32310DEFD4E41118CD7D36A8614C0D4" "MsmKey" = "8:_A32310DEFD4E41118CD7D36A8614C0D4"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -844,12 +844,6 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_A3FC19061EE356D91CA54089DF69D2ED"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_A566398810C1458E8E063A81FA88D46F" "MsmKey" = "8:_A566398810C1458E8E063A81FA88D46F"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -892,6 +886,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_AD3AED76152E705799261747B7FD2015"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_AE023AEA6C444140B19CD627DDC2CB87" "MsmKey" = "8:_AE023AEA6C444140B19CD627DDC2CB87"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -958,12 +958,6 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_BB6C841EC4662FACDA8C15CBE509E50F"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_BBECB7DB41D84A34B2837C5E7EC7FAD4" "MsmKey" = "8:_BBECB7DB41D84A34B2837C5E7EC7FAD4"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -988,6 +982,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_C0E88FBB7B883ED27FFB3C60DBE114B8"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_C239EFB1C3A646809AD2740ABDE747B0" "MsmKey" = "8:_C239EFB1C3A646809AD2740ABDE747B0"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -1084,7 +1084,13 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_CF200F5BD2D7FF90606D390FBF182D8D" "MsmKey" = "8:_D04F8D80984DFA3EA342FE8FA1B7CC91"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_D057B4CD935875ECE7F0A91620660D07"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" "OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
} }
@ -1342,12 +1348,6 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_FA51546D227188A30196C2FBB877CF97"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6" "MsmKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -2137,26 +2137,6 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_23B2892D4F99800BBD8DB9210ECF6B0F"
{
"SourcePath" = "8:api-ms-win-crt-locale-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-locale-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_24F2466589154E2DAA108C2EDB3BB432" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_24F2466589154E2DAA108C2EDB3BB432"
{ {
"SourcePath" = "8:..\\include\\oscar.c" "SourcePath" = "8:..\\include\\oscar.c"
@ -2357,26 +2337,6 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_31D185B4E4448BB9122BE23BE0C259A8"
{
"SourcePath" = "8:api-ms-win-crt-math-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-math-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3277DE1463544F67B7E7390175F8A9CF" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3277DE1463544F67B7E7390175F8A9CF"
{ {
"SourcePath" = "8:..\\samples\\rasterirq\\autocrawler.c" "SourcePath" = "8:..\\samples\\rasterirq\\autocrawler.c"
@ -2777,6 +2737,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4B8FC526E6CC47FC8321D0191BFDBEDC"
{ {
"SourcePath" = "8:..\\samples\\resources\\scifiglyph.bin" "SourcePath" = "8:..\\samples\\resources\\scifiglyph.bin"
@ -2837,6 +2817,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4E9503F4F8F343739E4685C2066B3AD0"
{ {
"SourcePath" = "8:..\\include\\plus4\\ted.c" "SourcePath" = "8:..\\include\\plus4\\ted.c"
@ -2917,26 +2917,6 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_55D2A0DA296A07FFD056F9B0C3671317"
{
"SourcePath" = "8:api-ms-win-crt-heap-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-heap-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5832EB4DC2134FF0BB7872666547CA0B" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5832EB4DC2134FF0BB7872666547CA0B"
{ {
"SourcePath" = "8:..\\samples\\sprites\\make.bat" "SourcePath" = "8:..\\samples\\sprites\\make.bat"
@ -3177,6 +3157,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_67C8F824E02B4211B315AB32AB7ABBB1"
{ {
"SourcePath" = "8:..\\samples\\games\\breakout.c" "SourcePath" = "8:..\\samples\\games\\breakout.c"
@ -3517,26 +3517,6 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7E4677138841AB7F15DEADCDE137C3A1"
{
"SourcePath" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7E6F12A2B7A647199FCBA7CBDF4E94D2" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7E6F12A2B7A647199FCBA7CBDF4E94D2"
{ {
"SourcePath" = "8:..\\samples\\kernalio\\filewrite.c" "SourcePath" = "8:..\\samples\\kernalio\\filewrite.c"
@ -3817,26 +3797,6 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8F9D1B22CCDDE3C1C2E92F178E8AD418"
{
"SourcePath" = "8:api-ms-win-crt-convert-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-convert-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_90171C7FE48D426E8664B043F5E75D6B" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_90171C7FE48D426E8664B043F5E75D6B"
{ {
"SourcePath" = "8:..\\include\\c128\\mmu.c" "SourcePath" = "8:..\\include\\c128\\mmu.c"
@ -4097,6 +4057,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A14BC161099E420286E6A1595596D0F0"
{ {
"SourcePath" = "8:..\\include\\opp\\ofstream.h" "SourcePath" = "8:..\\include\\opp\\ofstream.h"
@ -4177,6 +4157,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A32310DEFD4E41118CD7D36A8614C0D4"
{ {
"SourcePath" = "8:..\\include\\limits.h" "SourcePath" = "8:..\\include\\limits.h"
@ -4217,26 +4217,6 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A3FC19061EE356D91CA54089DF69D2ED"
{
"SourcePath" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A566398810C1458E8E063A81FA88D46F" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A566398810C1458E8E063A81FA88D46F"
{ {
"SourcePath" = "8:..\\include\\stddef.h" "SourcePath" = "8:..\\include\\stddef.h"
@ -4377,6 +4357,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_AE023AEA6C444140B19CD627DDC2CB87"
{ {
"SourcePath" = "8:..\\include\\cx16\\vera.h" "SourcePath" = "8:..\\include\\cx16\\vera.h"
@ -4597,26 +4597,6 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BB6C841EC4662FACDA8C15CBE509E50F"
{
"SourcePath" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BBECB7DB41D84A34B2837C5E7EC7FAD4" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BBECB7DB41D84A34B2837C5E7EC7FAD4"
{ {
"SourcePath" = "8:..\\samples\\hires\\make.bat" "SourcePath" = "8:..\\samples\\hires\\make.bat"
@ -4697,6 +4677,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C239EFB1C3A646809AD2740ABDE747B0"
{ {
"SourcePath" = "8:..\\include\\c64\\types.h" "SourcePath" = "8:..\\include\\c64\\types.h"
@ -5017,10 +5017,30 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CF200F5BD2D7FF90606D390FBF182D8D" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D04F8D80984DFA3EA342FE8FA1B7CC91"
{ {
"SourcePath" = "8:api-ms-win-crt-time-l1-1-0.dll" "SourcePath" = "8:api-ms-win-crt-heap-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-time-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:" "Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4" "Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:" "Condition" = "8:"
@ -5877,26 +5897,6 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FA51546D227188A30196C2FBB877CF97"
{
"SourcePath" = "8:api-ms-win-crt-string-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-string-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FCF3696486DC430EA7BFACA8BE9731E7" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FCF3696486DC430EA7BFACA8BE9731E7"
{ {
"SourcePath" = "8:..\\include\\ctype.c" "SourcePath" = "8:..\\include\\ctype.c"
@ -6310,15 +6310,15 @@
{ {
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64" "ProductName" = "8:oscar64"
"ProductCode" = "8:{DF8EA500-AEE0-466B-A4A7-4AF4F3DFDA84}" "ProductCode" = "8:{1B9A0E10-DEA6-4276-AC91-17782FE44D94}"
"PackageCode" = "8:{70789022-7FA0-4A4F-B592-F9074ACA6673}" "PackageCode" = "8:{51BFE576-50D1-4F8F-AE7A-9FF07396F53D}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0" "AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE" "RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE" "RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE" "InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.31.255" "ProductVersion" = "8:1.31.261"
"Manufacturer" = "8:oscar64" "Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:" "ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:" "ARPHELPLINK" = "8:"

View File

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

View File

@ -48,7 +48,7 @@ struct Point
}; };
Point tcorners[8], pcorners[8]; __striped Point tcorners[8], pcorners[8];
void drawCube(void) void drawCube(void)
{ {
@ -77,6 +77,45 @@ void hideCube(void)
} }
} }
void xorCube(void)
{
for(char i=0; i<8; i++)
{
if (!(i & 1))
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 1].x, tcorners[i | 1].y, 0xff, LINOP_XOR);
if (!(i & 2))
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 2].x, tcorners[i | 2].y, 0xff, LINOP_XOR);
if (!(i & 4))
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 4].x, tcorners[i | 4].y, 0xff, LINOP_XOR);
pcorners[i] = tcorners[i];
}
}
void xor2Cube(void)
{
for(char i=0; i<8; i++)
{
if (!(i & 1))
{
bm_line(&Screen, &cr, pcorners[i].x, pcorners[i].y, pcorners[i | 1].x, pcorners[i | 1].y, 0xff, LINOP_XOR);
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 1].x, tcorners[i | 1].y, 0xff, LINOP_XOR);
}
if (!(i & 2))
{
bm_line(&Screen, &cr, pcorners[i].x, pcorners[i].y, pcorners[i | 2].x, pcorners[i | 2].y, 0xff, LINOP_XOR);
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 2].x, tcorners[i | 2].y, 0xff, LINOP_XOR);
}
if (!(i & 4))
{
bm_line(&Screen, &cr, pcorners[i].x, pcorners[i].y, pcorners[i | 4].x, pcorners[i | 4].y, 0xff, LINOP_XOR);
bm_line(&Screen, &cr, tcorners[i].x, tcorners[i].y, tcorners[i | 4].x, tcorners[i | 4].y, 0xff, LINOP_XOR);
}
}
for(char i=0; i<8; i++)
pcorners[i] = tcorners[i];
}
#if 1 #if 1
F12Vector3 corners[8]; F12Vector3 corners[8];
@ -112,8 +151,15 @@ int main(void)
tcorners[i].y = lmuldiv16s(vd.v[1], 140, vd.v[2] + 4 * FIX12_ONE) + 100; tcorners[i].y = lmuldiv16s(vd.v[1], 140, vd.v[2] + 4 * FIX12_ONE) + 100;
} }
#if 1
if (k)
xor2Cube();
else
xorCube();
#else
hideCube(); hideCube();
drawCube(); drawCube();
#endif
} }

View File

@ -28,6 +28,8 @@ void init(void)
// Install IRQ trampoline // Install IRQ trampoline
mmap_trampoline(); mmap_trampoline();
cia_init();
// All RAM // All RAM
mmap_set(MMAP_RAM); mmap_set(MMAP_RAM);
@ -60,7 +62,6 @@ void init(void)
spr_move(1, 24, 50); spr_move(1, 24, 50);
// Disable system interrupt and init mouse // Disable system interrupt and init mouse
cia_init();
mouse_init(); mouse_init();
bm_init(&sbm, Hires, 40, 25); bm_init(&sbm, Hires, 40, 25);

View File

@ -22,7 +22,7 @@ __interrupt void doscroll(void)
vic.color_border++; vic.color_border++;
// Update raster IRQ for scroll line with new horizontal scroll offset // 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 // Copy scrolled version of text when switching over char border
if ((x & 7) == 0) if ((x & 7) == 0)
memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40); memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40);
@ -37,11 +37,13 @@ int main(void)
rirq_init(true); rirq_init(true);
// Build switch to scroll line IRQ // 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 // 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 // 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 // Build the switch to normal IRQ
rirq_build(&restore, 2); rirq_build(&restore, 2);

View File

@ -20,11 +20,13 @@ int main(void)
rirq_init(true); rirq_init(true);
// Build switch to scroll line IRQ // 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 // 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 // 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 // Build the switch to normal IRQ
rirq_build(&bottom, 1); rirq_build(&bottom, 1);
@ -46,7 +48,7 @@ int main(void)
// wait for raster reaching bottom of screen // wait for raster reaching bottom of screen
rirq_wait(); rirq_wait();
// Update raster IRQ for scroll line with new horizontal scroll offset // 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 // Copy scrolled version of text when switching over char border
if ((x & 7) == 0) if ((x & 7) == 0)
memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40); memcpy((char *)0x0400 + 40 * 24, Text + ((x >> 3) & 255), 40);

View File

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

View File

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