├── .github └── workflows │ └── main.yml ├── LICENSE ├── README.md ├── baseline_runall_linux_test.txt ├── baseline_runall_windows_test.txt ├── c_tests ├── an.c ├── ba.c ├── djlclib.c ├── djlprt.c ├── e.c ├── fileops.c ├── glob.c ├── lenum.c ├── mall.sh ├── mallx.sh ├── mm.c ├── mone.sh ├── monex.sh ├── nantst.c ├── pis.c ├── printint.c ├── rvosbug.c ├── sieve.c ├── simple.c ├── sleeptm.c ├── t.c ├── t_setjmp.c ├── tao.c ├── tap.c ├── tarray.c ├── tatomic.c ├── tbits.c ├── tcalloc.c ├── tcmp.c ├── td.c ├── terrno.c ├── tex.c ├── tf.c ├── tflags.c ├── tlead.c ├── tm.c ├── tmmap.c ├── tmuldiv.c ├── tp.bas ├── tparity.c ├── tphi.c ├── tpi.c ├── tprintf.c ├── tregex.c ├── trw.c ├── ts.c ├── tsimplef.c ├── tstga.c ├── tstr.c ├── tstrlen.c ├── ttime.c ├── ttt.c ├── ttypes.c └── words.txt ├── djl_128.hxx ├── djl_con.hxx ├── djl_mmap.hxx ├── djl_os.hxx ├── djltrace.hxx ├── kendryte.ld ├── linuxem.h ├── m.bat ├── m.sh ├── make_s.bat ├── mariscv.bat ├── marm64.bat ├── marm64r.bat ├── mg.bat ├── mgr.bat ├── minimal.ino ├── mmac.sh ├── mr.bat ├── mr.sh ├── mrcl.bat ├── mrmac.sh ├── mrvos.bat ├── mrvoself.sh ├── mrvoselfr.sh ├── mrvosr.bat ├── riscv.cxx ├── riscv.hxx ├── runall.bat ├── runall.sh ├── rust_tests ├── acos.rs ├── ato.rs ├── e.rs ├── fileops.dat ├── fileops.rs ├── m.bat ├── m.sh ├── mall.sh ├── mysort.rs ├── real.rs ├── rvfeat.rs ├── sorted.txt ├── tap.rs ├── td.rs ├── tmm.rs ├── tphi.rs ├── ttt.rs └── words.txt ├── rvctable.txt ├── rvos.cxx ├── rvos.ld ├── ttt_riscv.s └── words.txt /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the main branch 8 | push: 9 | branches: [ main ] 10 | pull_request: 11 | branches: [ main ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: windows-2022 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v3 27 | 28 | # Runs a single command using the runners shell 29 | - name: build the app 30 | run: | 31 | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" 32 | .\mr.bat 33 | shell: cmd 34 | 35 | - name: archive the binary 36 | uses: actions/upload-artifact@v4 37 | with: 38 | name: application 39 | path: rvos.exe 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /c_tests/e.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | //#pragma GCC optimize ("O0") 6 | 7 | extern int main() { 8 | const int DIGITS_TO_FIND = 200; //9009; 9 | 10 | int N = DIGITS_TO_FIND; 11 | char buf[ 128 ]; 12 | int x = 0; 13 | int a[ DIGITS_TO_FIND ]; 14 | 15 | for (int n = N - 1; n > 0; --n) { 16 | a[n] = 1; 17 | } 18 | 19 | a[1] = 2, a[0] = 0; 20 | while (N > 9) { 21 | int n = N--; 22 | while (--n) { 23 | a[n] = x % n; 24 | 25 | x = 10 * a[n-1] + x/n; 26 | } 27 | printf("%d", x); 28 | fflush(stdout); 29 | } 30 | 31 | printf( "\ndone\n" ); 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /c_tests/fileops.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | char acbuf[ 128 ]; 7 | char acbuf512[ 512 ]; 8 | 9 | /* this does not work on Aztec -- fseek to SEEK_END closes the file and doesn't re-open it! */ 10 | 11 | long portable_filelen( FILE * fp ) 12 | { 13 | int result; 14 | long len; 15 | long offset; 16 | long current = ftell( fp ); 17 | printf( "current offset: %ld\n", current ); 18 | offset = 0; 19 | result = fseek( fp, offset, SEEK_END ); 20 | printf( "result of fseek: %d\n", result ); 21 | len = ftell( fp ); 22 | printf( "file length from ftell: %ld\n", len ); 23 | fseek( fp, current, SEEK_SET ); 24 | return len; 25 | } 26 | 27 | void read_and_validate( long offset, int chunkLen, FILE * fp ) 28 | { 29 | int result; 30 | 31 | result = fread( acbuf512, 1, chunkLen, fp ); 32 | printf( "result of read at offset %ld: %d\n", offset, result ); 33 | if ( 0 == result ) 34 | printf( " errno (0 if at eof): %d\n", errno ); 35 | else 36 | { 37 | if ( 512 == offset ) 38 | { 39 | if ( acbuf512[ 0 ] != 'k' ) 40 | printf( "data at fixed offset 512 isn't a k\n" ); 41 | if ( acbuf512[ 127 ] != 'k' ) 42 | printf( "data at fixed offset 512 + 127 isn't a k\n" ); 43 | if ( acbuf512[ 128 ] != 0 ) 44 | printf( "data at fixed offset 512 + 128 isn't a 0\n" ); 45 | } 46 | else if ( 8192 == offset ) 47 | { 48 | if ( acbuf512[ 0 ] != 'j' ) 49 | printf( "data at fixed offset 8192 isn't a j\n" ); 50 | if ( acbuf512[ 127 ] != 0x1a ) 51 | printf( "didn't find a ^z at the end of the file\n" ); 52 | } 53 | else 54 | { 55 | if ( 0 != acbuf512[ 0 ] ) 56 | printf( "data at offset %d isn't a 0\n", offset ); 57 | if ( 0 != acbuf512[ 511 ] ) 58 | printf( "data at offset %d isn't a 0\n", offset + 511 ); 59 | } 60 | } 61 | } /*read_and_validate*/ 62 | 63 | int main( int argc, char * argv[] ) 64 | { 65 | char * pcFile = (char *) "fileops.dat"; 66 | FILE * fp; 67 | long len, offset; 68 | int chunkLen; 69 | int result; 70 | 71 | remove( pcFile ); 72 | 73 | fp = fopen( pcFile, "wb+" ); 74 | //printf( "fp: %d\n", fp ); 75 | if ( 0 == fp ) 76 | { 77 | printf( "unable to open file, errno %d\n", errno ); 78 | exit( 1 ); 79 | } 80 | 81 | len = portable_filelen( fp ); 82 | printf( "empty file length: %ld\n", len ); 83 | 84 | offset = 8192; 85 | result = fseek( fp, offset, SEEK_SET ); 86 | printf( "result of fseek: %d\n", result ); 87 | if ( -1 == result ) 88 | printf( "errno after fseek: %d\n", errno ); 89 | 90 | memset( acbuf, 'j', sizeof( acbuf ) ); 91 | acbuf[ sizeof( acbuf ) - 1 ] = 0x1a; /* ^z end of file */ 92 | 93 | result = fwrite( acbuf, sizeof( acbuf ), 1, fp ); 94 | printf( "result of fwrite (should be 1): %d\n", result ); 95 | if ( 1 != result ) 96 | printf( "errno after fwrite: %d\n", errno ); 97 | 98 | len = portable_filelen( fp ); 99 | printf( "8192 + 128 = 8320 file length from portable_filelen: %ld\n", len ); 100 | 101 | offset = 512; 102 | result = fseek( fp, offset, SEEK_SET ); 103 | printf( "result of fseek to middle of file: %d\n", result ); 104 | if ( -1 == result ) 105 | printf( "errno after fseek to middle of file: %d\n", errno ); 106 | 107 | memset( acbuf, 'k', sizeof( acbuf ) ); 108 | result = fwrite( acbuf, sizeof( acbuf), 1, fp ); 109 | printf( "result of fwrite to middle of file (should be 1): %d\n", result ); 110 | if ( 1 != result ) 111 | printf( "errno after fwrite middle of file: %d\n", errno ); 112 | 113 | fflush( fp ); 114 | fclose( fp ); 115 | 116 | fp = fopen( pcFile, "rb+" ); 117 | //printf( "fp: %d\n", fp ); 118 | if ( 0 == fp ) 119 | { 120 | printf( "unable to open file a second time, errno %d\n", errno ); 121 | exit( 1 ); 122 | } 123 | 124 | len = portable_filelen( fp ); 125 | printf( "8192 + 128 = 8320 file length: %ld\n", len ); 126 | 127 | memset( acbuf512, 'd', sizeof( acbuf512 ) ); 128 | chunkLen = 512; 129 | for ( offset = 0; offset < 8320; offset += chunkLen ) 130 | read_and_validate( offset, chunkLen, fp ); 131 | 132 | /* now read in blocks from the end of the file to the start using fseek() */ 133 | 134 | printf( "testing backwards read\n" ); 135 | 136 | memset( acbuf512, 'e', sizeof( acbuf512 ) ); 137 | for ( offset = 8192; offset >= 0; offset -= chunkLen ) 138 | { 139 | result = fseek( fp, offset, SEEK_SET ); 140 | read_and_validate( offset, chunkLen, fp ); 141 | } 142 | 143 | fclose( fp ); 144 | printf( "fileops has completed with great success\n" ); 145 | return 0; 146 | } /*main*/ 147 | -------------------------------------------------------------------------------- /c_tests/glob.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class CTest 4 | { 5 | private: 6 | int foo; 7 | public: 8 | CTest() : foo( 666 ) 9 | { 10 | printf( "in CTest constructor\n" ); 11 | } 12 | 13 | ~CTest() 14 | { 15 | printf( "in ~CTest destructor\n" ); 16 | } 17 | 18 | int get_foo() { return foo; } 19 | }; 20 | 21 | CTest ctest; 22 | 23 | int main( int argc, char * argv[], char * envp[] ) 24 | { 25 | printf( "top main\n" ); 26 | 27 | printf( "value of ctest::foo: %d\n", ctest.get_foo() ); 28 | 29 | printf( "end of main\n" ); 30 | } //main 31 | 32 | -------------------------------------------------------------------------------- /c_tests/lenum.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main( int argc, char * argv[] ) 10 | { 11 | DIR * dir = opendir( "." ); 12 | if ( 0 == dir ) 13 | { 14 | printf( "can't open current folder, error %d\n", errno ); 15 | return -1; 16 | } 17 | 18 | int count = 0; 19 | bool parent_found = false; 20 | 21 | do 22 | { 23 | struct dirent * entry = readdir( dir ); 24 | if ( !entry ) 25 | break; 26 | if ( !strcmp( "..", entry->d_name ) ) 27 | parent_found = true; 28 | 29 | count++; 30 | } while( true ); 31 | 32 | if ( !parent_found ) 33 | { 34 | printf( "error: parent folder not found in enumeration out of %d files returned\n", count ); 35 | return 1; 36 | } 37 | 38 | int ret = closedir( dir ); 39 | if ( 0 != ret ) 40 | { 41 | printf( "error: closedir after enumeration failed, errno: %d\n", errno ); 42 | return 1; 43 | } 44 | 45 | printf( "linux file system enumeration completed with great success\n" ); 46 | return 0; 47 | } // main 48 | -------------------------------------------------------------------------------- /c_tests/mall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for arg in tcmp t e printint sieve simple tmuldiv tpi ts tarray tbits trw tmmap tstr \ 4 | fileops ttime tm glob tap tsimplef tphi tf ttt td terrno t_setjmp tex \ 5 | pis mm tao ttypes nantst sleeptm tatomic lenum tregex an ba; 6 | do 7 | echo $arg 8 | for optflag in 0 1 2 3 fast; 9 | do 10 | mkdir bin"$optflag" 2>/dev/null 11 | _gnubuild="g++ "$arg".c -o bin"$optflag"/"$arg" -O"$optflag" -static -fsigned-char -Wno-format -Wno-format-security" 12 | 13 | if [ "$optflag" != "fast" ]; then 14 | $_gnubuild & 15 | else 16 | $_gnubuild 17 | fi 18 | done 19 | done 20 | 21 | echo "Waiting for all processes to complete..." 22 | wait 23 | 24 | -------------------------------------------------------------------------------- /c_tests/mallx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for arg in tcmp t e printint sieve simple tmuldiv tpi ts tarray tbits trw tmmap tstr \ 4 | fileops ttime tm glob tap tsimplef tphi tf ttt td terrno t_setjmp tex \ 5 | pis mm tao ttypes nantst sleeptm tatomic lenum tregex an ba; 6 | do 7 | echo $arg 8 | for optflag in 0 1 2 3 fast; 9 | do 10 | mkdir bin"$optflag" 2>/dev/null 11 | _gnubuild="riscv64-unknown-linux-gnu-c++ "$arg".c -o bin"$optflag"/"$arg" -O"$optflag" -mcmodel=medany -mabi=lp64d -march=rv64imadc -latomic -static -fsigned-char -Wno-format -Wno-format-security" 12 | 13 | if [ "$optflag" != "fast" ]; then 14 | $_gnubuild & 15 | else 16 | $_gnubuild 17 | fi 18 | done 19 | done 20 | 21 | -------------------------------------------------------------------------------- /c_tests/mone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for optflag in 0 1 2 3 fast; 4 | do 5 | mkdir bin"$optflag" 2>/dev/null 6 | _gnubuild="g++ $1.c -o bin"$optflag"/$1 -O"$optflag" -static -fsigned-char -Wno-format -Wno-format-security" 7 | 8 | if [ "$optflag" != "fast" ]; then 9 | $_gnubuild & 10 | else 11 | $_gnubuild 12 | fi 13 | done 14 | 15 | echo "Waiting for all processes to complete..." 16 | wait 17 | 18 | -------------------------------------------------------------------------------- /c_tests/monex.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for optflag in 0 1 2 3 fast; 4 | do 5 | mkdir bin"$optflag" 2>/dev/null 6 | _gnubuild="riscv64-unknown-linux-gnu-c++ $1.c -o bin"$optflag"/$1 -O"$optflag" -mcmodel=medany -mabi=lp64d -march=rv64imadcv -latomic -static -fsigned-char -Wno-format -Wno-format-security" 7 | 8 | if [ "$optflag" != "fast" ]; then 9 | $_gnubuild & 10 | else 11 | $_gnubuild 12 | fi 13 | done 14 | 15 | echo "Waiting for all processes to complete..." 16 | wait 17 | -------------------------------------------------------------------------------- /c_tests/nantst.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define _perhaps_inline __attribute__((noinline)) 12 | 13 | // -Ofast doesn't understand infinity so the compiler would emit this warning 14 | // v14 of clang doesn't understand this 15 | #pragma clang diagnostic ignored "-Wnan-infinity-disabled" 16 | 17 | template inline T get_max( T a, T b ) 18 | { 19 | if ( a > b ) 20 | return a; 21 | return b; 22 | } //get_max 23 | 24 | template inline T get_min( T a, T b ) 25 | { 26 | if ( a < b ) 27 | return a; 28 | return b; 29 | } //get_min 30 | 31 | double set_double_sign( double d, bool sign ) 32 | { 33 | uint64_t val = sign ? ( ( * (uint64_t *) &d ) | 0x8000000000000000 ) : ( ( * (uint64_t *) &d ) & 0x7fffffffffffffff ); 34 | return * (double *) &val; 35 | } //set_double_sign 36 | 37 | const char * tf( bool f ) 38 | { 39 | return f ? "true" : "false"; 40 | } 41 | 42 | void _perhaps_inline show_num( double d ) 43 | { 44 | printf( " %lf = %#llx, isnan %s, isinf %s, iszero %s, signbit %s\n", * (uint64_t *) &d, 45 | (double) d, tf( isnan( d ) ), tf( isinf( d ) ), 46 | tf( 0.0 == d ), tf( signbit( d ) ) ); 47 | } //show_num 48 | 49 | template void _perhaps_inline cmp( T a, T b ) 50 | { 51 | bool gt = ( a > b ); 52 | bool lt = ( a < b ); 53 | bool eq = ( a == b ); 54 | bool le = ( a <= b ); 55 | bool ge = ( a >= b ); 56 | printf( " lt %d le %d eq %d ge %d gt %d\n", lt, le, eq, ge, gt ); 57 | } //cmp 58 | 59 | template void _perhaps_inline minmax( T a, T b ) 60 | { 61 | T min = get_min( a, b ); 62 | T max = get_max( a, b ); 63 | printf( " min %lf, max %lf\n", (double) min, (double) max ); 64 | } //minmax 65 | 66 | double _perhaps_inline do_math( double a, double b ) 67 | { 68 | double r = 0.0; 69 | 70 | printf( " in do_math()\n" ); 71 | printf( " a:" ); 72 | show_num( a ); 73 | printf( " b:" ); 74 | show_num( b ); 75 | 76 | r = a * b; 77 | printf( " *:" ); 78 | show_num( r ); 79 | 80 | r = a / b; 81 | printf( " /:" ); 82 | show_num( r ); 83 | 84 | r = a + b; 85 | printf( " +:" ); 86 | show_num( r ); 87 | 88 | r = a - b; 89 | printf( " -:" ); 90 | show_num( r ); 91 | 92 | printf( " cmp:" ); 93 | cmp( a, b ); 94 | 95 | printf( " minmax:" ); 96 | minmax( a, b ); 97 | 98 | return r; 99 | } 100 | 101 | double zero = 0.0; 102 | double neg_zero = set_double_sign( 0.0, true ); 103 | double infinity = INFINITY; 104 | double neg_infinity = set_double_sign( INFINITY, true ); 105 | double not_a_number = NAN; 106 | double neg_not_a_number = set_double_sign( NAN, true ); 107 | double quiet_nan = std::numeric_limits::quiet_NaN(); 108 | double signaling_nan = std::numeric_limits::signaling_NaN(); 109 | 110 | double test_case( double d ) 111 | { 112 | double r = 0.0; 113 | r += do_math( d, 0.0 ); 114 | r += do_math( 0.0, d ); 115 | r += do_math( d, neg_zero ); 116 | r += do_math( neg_zero, d ); 117 | r += do_math( 3.0, d ); 118 | r += do_math( d, 3.0 ); 119 | r += do_math( -3.0, d ); 120 | r += do_math( d, -3.0 ); 121 | r += do_math( d, not_a_number ); 122 | r += do_math( not_a_number, d ); 123 | r += do_math( d, neg_not_a_number ); 124 | r += do_math( neg_not_a_number, d ); 125 | r += do_math( d, infinity ); 126 | r += do_math( infinity, d ); 127 | r += do_math( d, neg_infinity ); 128 | r += do_math( neg_infinity, d ); 129 | r += do_math( d, d ); 130 | return r; 131 | } //test_case 132 | 133 | int main( int argc, char * argv[] ) 134 | { 135 | double d; 136 | 137 | printf( "NAN: %#llx\n", * (uint64_t *) & not_a_number ); 138 | printf( "-NAN: %#llx\n", * (uint64_t *) & neg_not_a_number ); 139 | printf( "quiet NAN: %#llx\n", * (uint64_t *) & quiet_nan ); 140 | printf( "signaling NAN: %#llx\n", * (uint64_t *) & signaling_nan ); 141 | printf( "INFINITY: %#llx\n", * (uint64_t *) & infinity ); 142 | printf( "-INFINITY: %#llx\n", * (uint64_t *) & neg_infinity ); 143 | printf( "0.0: %#llx\n", * (uint64_t *) & zero ); 144 | printf( "-0.0: %#llx\n", * (uint64_t *) & neg_zero ); 145 | 146 | printf( "testing with NAN:\n" ); 147 | test_case( not_a_number ); 148 | 149 | printf( "testing with -NAN:\n" ); 150 | test_case( neg_not_a_number ); 151 | 152 | printf( "testing with INFINITY:\n" ); 153 | test_case( infinity ); 154 | 155 | printf( "testing with -INFINITY:\n" ); 156 | test_case( neg_infinity ); 157 | 158 | printf( "testing with 69:\n" ); 159 | test_case( 69.0 ); 160 | 161 | printf( "testing with -69:\n" ); 162 | test_case( -69.0 ); 163 | 164 | printf( "testing with 0.0:\n" ); 165 | test_case( zero ); 166 | 167 | printf( "testing with -0.0:\n" ); 168 | test_case( neg_zero ); 169 | 170 | printf( "nan test completed with great success\n" ); 171 | return 0; 172 | } 173 | -------------------------------------------------------------------------------- /c_tests/pis.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | double fpart_nomod( double x ) 11 | { 12 | //printf( "finding fpart_nomod of %lf\n", x ); 13 | assert( x < 2.0 ); 14 | assert( x >= 0.0 ); 15 | 16 | double d; 17 | 18 | if ( x >= 1.0 ) 19 | d = x - 1.0; 20 | else 21 | d = x; 22 | 23 | //printf( "fpart of x %.*lf is %.*lf\n", 20, x, 20, d ); 24 | return d; 25 | } //fpart_nomod 26 | 27 | double fpart( double x ) 28 | { 29 | double d = fmod( x, 1.0 ); 30 | 31 | if ( d < 0.0 ) 32 | d = 1.0 + d; 33 | 34 | //printf( "fpart of x %.*lf is %.*lf\n", 20, x, 20, d ); 35 | return d; 36 | } //fpart 37 | 38 | double eps( double d ) 39 | { 40 | double n = std::nextafter( d, DBL_MAX ); 41 | double r = n - d; 42 | 43 | //printf( " n %.*lf eps of %.*lf is %.*lf\n", 20, n, 20, d, 20, r ); 44 | return r; 45 | } //eps 46 | 47 | size_t powermod16_faster( size_t e, size_t m ) 48 | { 49 | // https://en.wikipedia.org/wiki/Modular_exponentiation 50 | // faster way to calculate b^e % m 51 | 52 | if ( 1 == m ) 53 | return 0; 54 | 55 | if ( 0 == e ) 56 | return 1; 57 | 58 | size_t result = 1; 59 | size_t b = 16 % m; 60 | 61 | do 62 | { 63 | if ( e & 1 ) 64 | result = ( result * b ) % m; 65 | 66 | e >>= 1; 67 | 68 | if ( 0 == e ) 69 | return result; 70 | 71 | b = ( b * b ) % m; 72 | } while ( true ); 73 | } //powermod16_faster 74 | 75 | double fun( size_t n, size_t j ) 76 | { 77 | //printf( "fun call n %zd, j %zd\n", n, j ); 78 | double s = 0.0; 79 | size_t denom = j; 80 | 81 | for ( size_t k = 0; k <= n; k++ ) 82 | { 83 | size_t p = powermod16_faster( n - k, denom ); 84 | //printf( "in kloop, s %lf p %zd, denom %zd\n", s, p, denom ); 85 | s = fpart_nomod( s + ( (double) p / (double) denom ) ); 86 | //printf( " in kloop: k %zd, p %zd, denom %lf incremental s %lf\n", k, p, denom, s ); 87 | denom += 8; 88 | } 89 | 90 | //printf( "after kloop: n %zd, j %zd, s %lf\n", n, j, s ); 91 | 92 | double num = 1.0 / 16.0; 93 | double fdenom = (double) denom; 94 | double frac; 95 | 96 | while ( ( frac = ( num / fdenom ) ) > eps( s ) ) 97 | { 98 | //printf( " frac: %.*lf, would-be result %.*lf\n", 20, frac, 20, fpart_nomod( s ) ); 99 | s += frac; 100 | num /= 16.0; 101 | fdenom += 8.0; 102 | } 103 | 104 | //printf( "final frac %.*lf and s prior to fpart %.*lf fpart_nomod(s) %.*lf\n", 20, frac, 20, s, 20, fpart( s ) ); 105 | return fpart_nomod( s ); 106 | } //fun 107 | 108 | int pi_digit( size_t n ) 109 | { 110 | double sum = ( 4.0 * fun( n, 1 ) ) - ( 2.0 * fun( n, 4 ) ) - fun( n, 5 ) - fun( n, 6 ); 111 | double f = fpart( sum ); 112 | double r = 16.0 * f; 113 | int x = (int) r; 114 | 115 | //printf( "resulting sum %lf, f %lf, r %lf, x: %d\n", sum, f, r, x ); 116 | assert( x >= 0 && x <= 15 ); 117 | return x; 118 | } //pi_digit 119 | 120 | void Usage() 121 | { 122 | printf( "Usage: pis [offset] [count]\n" ); 123 | printf( " PI source. Generates hexadecimal digits of PI.\n" ); 124 | printf( " arguments: [offset] Offset in 128 where generation starts. Default is 0.\n" ); 125 | printf( " [count] Count in 128 of digits to generate. Default is 1.\n" ); 126 | exit( 1 ); 127 | } //Usage 128 | 129 | int main( int argc, char * argv[] ) 130 | { 131 | // These are in units of 128 132 | 133 | size_t startingOffset = 0; 134 | size_t startingOffset128 = 0; 135 | size_t countGenerated128 = 1; 136 | size_t countGenerated = countGenerated128 * 128; 137 | 138 | if ( argc > 3 ) 139 | Usage(); 140 | 141 | if ( argc >= 2 ) 142 | { 143 | startingOffset128 = atoll( argv[ 1 ] ); 144 | startingOffset = startingOffset128 * 128; 145 | } 146 | 147 | if ( 3 == argc ) 148 | { 149 | countGenerated128 = atoll( argv[ 2 ] ); 150 | countGenerated = 128 * countGenerated128; 151 | } 152 | 153 | printf( "startingOffset128: %lld, startingOffset: %lld, countGenerated128 %lld, countGenerated %lld\n", 154 | startingOffset128, startingOffset, countGenerated128, countGenerated ); 155 | 156 | size_t bufsize = 1 + countGenerated; 157 | char* ac = new char[ bufsize ]; 158 | memset( ac, 0, bufsize ); 159 | 160 | const size_t chunkSize = 32; // rely on fact that 32*3 = 128 161 | size_t startInChunks = ( startingOffset128 * 128 ) / chunkSize; 162 | size_t limitInChunks = ( startInChunks + ( countGenerated128 * 128 ) ) / chunkSize; 163 | 164 | printf( "startInChunks: %lld, limitInChunks %lld\n", startInChunks, limitInChunks ); 165 | 166 | size_t complete = 0; 167 | size_t generatedChunks = countGenerated128 * 129 / chunkSize; 168 | 169 | for ( size_t i = startInChunks; i < limitInChunks; i++ ) 170 | { 171 | size_t start = i * chunkSize; 172 | 173 | for ( size_t d = start; d < start + chunkSize; d++ ) 174 | { 175 | int x = pi_digit( d ); 176 | char c = x <= 9 ? '0' + x : 'a' + x - 10; 177 | ac[ d - startingOffset ] = c; 178 | } 179 | 180 | complete++; 181 | printf( "percent complete: %lf\n", 100.0 * (double) complete / (double) generatedChunks ); 182 | }; 183 | 184 | if ( 0 == startingOffset && countGenerated128 >= 1 ) 185 | { 186 | const char* Julia1k = 187 | "243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89452821e638d01377be54" 188 | "66cf34e90c6cc0ac29b7c97c50dd3f84d5b5b54709179216d5d98979fb1bd1310ba698dfb5ac2ffd72db" 189 | "d01adfb7b8e1afed6a267e96ba7c9045f12c7f9924a19947b3916cf70801f2e2858efc16636920d87157" 190 | "4e69a458fea3f4933d7e0d95748f728eb658718bcd5882154aee7b54a41dc25a59b59c30d5392af26013" 191 | "c5d1b023286085f0ca417918b8db38ef8e79dcb0603a180e6c9e0e8bb01e8a3ed71577c1bd314b2778af" 192 | "2fda55605c60e65525f3aa55ab945748986263e8144055ca396a2aab10b6b4cc5c341141e8cea15486af" 193 | "7c72e993b3ee1411636fbc2a2ba9c55d741831f6ce5c3e169b87931eafd6ba336c24cf5c7a3253812895" 194 | "86773b8f48986b4bb9afc4bfe81b6628219361d809ccfb21a991487cac605dec8032ef845d5de98575b1" 195 | "dc262302eb651b8823893e81d396acc50f6d6ff383f442392e0b4482a484200469c8f04a9e1f9b5e21c6" 196 | "6842f6e96c9a670c9c61abd388f06a51a0d2d8542f68960fa728ab5133a36eef0b6c137a3be4ba3bf050" 197 | "7efb2a98a1f1651d39af017666ca593e82430e888cee8619456f9fb47d84a5c33b8b5ebee06f75d885c1" 198 | "2073401a449f56c16aa64ed3aa62363f77061bfedf72429b023d37d0d724d00a1248db0fead349f1c09b" 199 | "075372c980991b7b"; 200 | 201 | if ( countGenerated128 >= 8 && strncmp( ac, Julia1k, 1024 ) ) 202 | printf( "results 1k don't match Julia!\n" ); 203 | else if ( strncmp( ac, Julia1k, 128 ) ) 204 | printf( "results 128 don't match Julia!\n" ); 205 | else 206 | printf( "results are valid\n" ); 207 | } 208 | 209 | printf( "final: %s\n", ac ); 210 | return 0; 211 | } //main 212 | 213 | -------------------------------------------------------------------------------- /c_tests/printint.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main( int argc, char * argv[] ) 4 | { 5 | //printf( "p %d\n", 13 ); 6 | printf( "n %d\n", -13 ); 7 | return 0; 8 | } -------------------------------------------------------------------------------- /c_tests/rvosbug.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #pragma GCC optimize ("O2") 5 | //#pragma GCC optimize ("no-inline") 6 | 7 | static int64_t sign_extend( uint64_t x, uint64_t bits ) 8 | { 9 | const int64_t m = ( (uint64_t) 1 ) << bits; 10 | return ( x ^ m ) - m; 11 | } //sign_extend 12 | 13 | void runtest( uint32_t t, uint32_t shift ) 14 | { 15 | uint64_t result = sign_extend( t >> shift, 31 - shift ); 16 | printf( "result (0xfffffffffffffff0 expected): %#llx\n", result ); 17 | } 18 | 19 | int main( int argc, char * argv[] ) 20 | { 21 | uint64_t rv = 0xfffffffff0000000ull; 22 | runtest( rv & 0xffffffff, 24 ); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /c_tests/sieve.c: -------------------------------------------------------------------------------- 1 | /* sieve.c */ 2 | 3 | /* Eratosthenes Sieve Prime Number Program in C from Byte Jan 1983 4 | to compare the speed. */ 5 | 6 | #include 7 | 8 | #define TRUE 1 9 | #define FALSE 0 10 | #define SIZE 8190 11 | 12 | char flags[SIZE+1]; 13 | 14 | int main() 15 | { 16 | int i,k; 17 | int prime,count,iter; 18 | 19 | for (iter = 1; iter <= 10; iter++) { /* do program 10 times */ 20 | count = 0; /* initialize prime counter */ 21 | for (i = 0; i <= SIZE; i++) /* set all flags TRUE */ 22 | flags[i] = TRUE; 23 | for (i = 0; i <= SIZE; i++) { 24 | if (flags[i]) { /* found a prime */ 25 | prime = i + i + 3; /* twice index + 3 */ 26 | for (k = i + prime; k <= SIZE; k += prime) 27 | flags[k] = FALSE; /* kill all multiples */ 28 | count++; /* primes found */ 29 | } 30 | } 31 | } 32 | printf("%d primes.\n",count); /*primes found in 10th pass */ 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /c_tests/simple.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main( int argc, char * argv[], char * env[] ) 4 | { 5 | for ( int i = 0; i < argc; i++ ) 6 | printf( "argument %d: %s\n", i, argv[ i ] ); 7 | 8 | for ( int i = 0; ( 0 != env[ i ]); i++ ) 9 | printf( "environment variable %d: %s\n", i, env[ i ] ); 10 | return argc; 11 | } -------------------------------------------------------------------------------- /c_tests/sleeptm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std::chrono; 12 | 13 | int main( int argc, char * argv[] ) 14 | { 15 | high_resolution_clock::time_point tStart = high_resolution_clock::now(); 16 | 17 | //printf( "this test should take about 2.5 seconds to complete\n" ); 18 | uint64_t clk_tck = sysconf( _SC_CLK_TCK ); 19 | printf( "clk_tck / number of linux ticks per second: %llu\n", clk_tck ); 20 | 21 | struct tms tstart; 22 | clock_t cstart = times( &tstart ); 23 | struct timespec request = { 1, 500000000 }; // 1.5 seconds 24 | int result = nanosleep( &request, 0 ); 25 | if ( -1 == result ) 26 | { 27 | printf( "nanosleep failed with error %d\n", errno ); 28 | exit( 1 ); 29 | } 30 | 31 | high_resolution_clock::time_point tAfterSleep = high_resolution_clock::now(); 32 | 33 | struct tms tend_sleep; 34 | clock_t cend_sleep = times( &tend_sleep ); 35 | clock_t cduration = cend_sleep - cstart; 36 | //printf( "sleep duration %#llx = end %#llx - start %#llx\n", cduration, cend_sleep, cstart ); 37 | //printf( "sleep duration %#llx\n", cduration ); 38 | //printf( " sleep duration in milliseconds: %llu\n", ( cduration * 1000 ) / clk_tck ); 39 | //printf( " user time: %llu, kernel time: %llu\n", tend_sleep.tms_utime, tend_sleep.tms_stime ); 40 | 41 | uint64_t busy_work = 0; 42 | do 43 | { 44 | clock_t cbusy_loop = times( 0 ); 45 | clock_t busy_time = ( ( cbusy_loop - cend_sleep ) * 1000 ) / clk_tck; 46 | if ( busy_time >= 1000 ) 47 | break; 48 | busy_work *= busy_time; 49 | busy_work -= 33; 50 | busy_work *= 14; 51 | } while( true ); 52 | 53 | struct tms tend; 54 | clock_t cend = times( &tend ); 55 | cduration = cend - cend_sleep; 56 | //printf( "busy_work value (this will be somewhat random): %#llx\n", busy_work ); 57 | //printf( " busy duration %#llx = end %#llx - start %#llx\n", cduration, cend, cend_sleep ); 58 | //printf( " busy duration %#llx\n", cduration ); 59 | //printf( " busy duration in milliseconds: %llu\n", ( cduration * 1000 ) / clk_tck ); 60 | uint64_t user_ms = ( tend.tms_utime * 1000 ) / clk_tck; 61 | uint64_t system_ms = ( tend.tms_stime * 1000 ) / clk_tck; 62 | //printf( " user time in ms: %llu, kernel time: %llu\n", user_ms, system_ms ); 63 | 64 | struct rusage usage; 65 | result = getrusage( RUSAGE_SELF, &usage ); 66 | if ( -1 == result ) 67 | { 68 | printf( "getrusage failed with error %d\n", errno ); 69 | exit( 1 ); 70 | } 71 | 72 | user_ms = ( usage.ru_utime.tv_sec * 1000 ) + ( usage.ru_utime.tv_usec / 1000 ); 73 | system_ms = ( usage.ru_stime.tv_sec * 1000 ) + ( usage.ru_stime.tv_usec / 1000 ); 74 | 75 | // surely some time was consumed by the busy loop 76 | if ( 0 == user_ms || 0 == system_ms ) 77 | printf( "getrusage user time in ms: %llu, system time %llu\n", user_ms, system_ms ); 78 | 79 | high_resolution_clock::time_point tEnd = high_resolution_clock::now(); 80 | int64_t sleepMS = duration_cast( tAfterSleep - tStart ).count(); 81 | int64_t totalMS = duration_cast( tEnd - tStart ).count(); 82 | 83 | // cut precision some slack 84 | 85 | if ( sleepMS < 1480 || sleepMS > 1520 || totalMS < 2480 || totalMS > 2520 ) 86 | printf( "milliseconds sleeping (should be ~1500) %llu, milliseconds total (should be ~2500): %llu\n", sleepMS, totalMS ); 87 | 88 | printf( "sleepy time ended with great success\n" ); 89 | return 0; 90 | } //main 91 | -------------------------------------------------------------------------------- /c_tests/t.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void swap( char & a, char & b ) 7 | { 8 | char c = a; 9 | a = b; 10 | b = c; 11 | } //swap 12 | 13 | void reverse( char str[], int length ) 14 | { 15 | int start = 0; 16 | int end = length - 1; 17 | while ( start < end ) 18 | { 19 | swap( * ( str + start ), * ( str + end ) ); 20 | start++; 21 | end--; 22 | } 23 | } //reverse 24 | 25 | char * i64toa( int64_t num, char * str, int base ) 26 | { 27 | int i = 0; 28 | bool isNegative = false; 29 | 30 | if ( 0 == num ) 31 | { 32 | str[i++] = '0'; 33 | str[i] = '\0'; 34 | return str; 35 | } 36 | 37 | if ( num < 0 && 10 == base ) 38 | { 39 | isNegative = true; 40 | num = -num; 41 | } 42 | 43 | while ( 0 != num ) 44 | { 45 | int rem = num % base; 46 | str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0'; 47 | num = num/base; 48 | } 49 | 50 | if (isNegative) 51 | str[i++] = '-'; 52 | 53 | str[i] = '\0'; 54 | 55 | reverse( str, i ); 56 | 57 | return str; 58 | } //i64toa 59 | 60 | template T myabs( T x ) 61 | { 62 | if ( x < 0 ) 63 | return -x; 64 | return x; 65 | } //myabs 66 | 67 | // g++ has an internal compiler error with optimization levels 2, 3, and fast for this template 68 | 69 | #pragma GCC push_options 70 | #pragma GCC optimize("O0") 71 | 72 | template T test( T & min, T & max ) 73 | { 74 | T a[ 340 ]; 75 | 76 | for ( uint64_t i = 0; i < sizeof( a ) / sizeof( a[0] ); i++ ) 77 | a[ i ] = i; 78 | 79 | for ( size_t zz = 0; zz < 10; zz++ ) 80 | { 81 | for ( T i = min; i < max; i++ ) 82 | { 83 | T j = 13 - i; 84 | int x = (int) j; 85 | int y = x * 2; 86 | a[ myabs( i ) ] = (T) y; 87 | a[ myabs( i + 1 ) ] = a[ myabs( i ) + 2 ] | a[ myabs( i ) + 3 ]; 88 | a[ myabs( i + 2 ) ] = a[ myabs( i ) + 3 ] & a[ myabs( i ) + 4 ]; 89 | a[ myabs( i + 3 ) ] = a[ myabs( i ) + 4 ] + a[ myabs( i ) + 5 ]; 90 | a[ myabs( i + 4 ) ] = a[ myabs( i ) + 5 ] - a[ myabs( i ) + 6 ]; 91 | a[ myabs( i + 5 ) ] = a[ myabs( i ) + 6 ] * a[ myabs( i ) + 7 ]; 92 | if ( 0 != a[ myabs( i ) + 8 ] ) 93 | a[ myabs( i + 6 ) ] = a[ myabs( i ) + 7 ] / a[ myabs( i ) + 8 ]; 94 | a[ myabs( i + 7 ) ] = a[ myabs( i ) + 8 ] ^ a[ myabs( i ) + 9 ]; 95 | if ( 0 != a[ myabs( i ) + 10 ] ) 96 | a[ myabs( i + 8 ) ] = a[ myabs( i ) + 9 ] % a[ myabs( i ) + 10 ]; 97 | a[ myabs( i + 9 ) ] = a[ myabs( i ) + 8 ] << a[ myabs( i ) + 11 ]; 98 | a[ myabs( i + 10 ) ] = a[ myabs( i ) + 8 ] >> a[ myabs( i ) + 12 ]; 99 | a[ myabs( i + 11 ) ] = ( a[ myabs( i ) + 8 ] << 3 ); 100 | a[ myabs( i + 12 ) ] = ( a[ myabs( i ) + 8 ] >> 4 ); 101 | 102 | if ( a[ myabs( i + 12 ) ] > a[ myabs( i + 13 ) ] ) 103 | a[ myabs( i + 14 ) ] += 3; 104 | 105 | if ( a[ myabs( i + 12 ) ] < a[ myabs( i + 13 ) ] ) 106 | a[ myabs( i + 14 ) ] += 7; 107 | 108 | if ( a[ myabs( i + 12 ) ] >= a[ myabs( i + 13 ) ] ) 109 | a[ myabs( i + 14 ) ] += 3; 110 | 111 | if ( a[ myabs( i + 12 ) ] <= a[ myabs( i + 13 ) ] ) 112 | a[ myabs( i + 14 ) ] += 7; 113 | 114 | if ( a[ myabs( i + 12 ) ] == a[ myabs( i + 13 ) ] ) 115 | a[ myabs( i + 14 ) ] += 9; 116 | 117 | a[ myabs( i + 12 ) ] &= 0x10; 118 | a[ myabs( i + 13 ) ] |= 0x10; 119 | a[ myabs( i + 14 ) ] ^= 0x10; 120 | a[ myabs( i + 12 ) ] += 7; 121 | a[ myabs( i + 13 ) ] -= 6; 122 | a[ myabs( i + 14 ) ] *= 5; 123 | a[ myabs( i + 14 ) ] /= 4; 124 | } 125 | } 126 | 127 | return a[ 10 ]; 128 | } //template 129 | 130 | #pragma GCC pop_options 131 | 132 | void validate_128mul() 133 | { 134 | // the gnu compiler generates mulhu for each of these, not mulh or mulhsu 135 | 136 | __int128 a = 0x4000000000000000; 137 | printf( "a: %llx %llx\n", (uint64_t) ( a >> 64) , (uint64_t) a ); 138 | a <<= 4; 139 | printf( "a: %llx %llx\n", (uint64_t) ( a >> 64) , (uint64_t) a ); 140 | 141 | __int128 b = 2; 142 | __int128 c = a * b; 143 | 144 | if ( 0 != ( 0xffffffff & c ) ) 145 | printf( "failure 1: lower part of multiply isn't 0\n" ); 146 | 147 | if ( ( c >> 64 ) != 0x8 ) 148 | printf( "failure 2: upper part of multiply isn't 0x8: %llx\n", (uint64_t) ( c >> 64 ) ); 149 | 150 | unsigned __int128 ua = 0x4000000000000000; 151 | printf( "ua: %llx %llx\n", (uint64_t) ( ua >> 64) , (uint64_t) ua ); 152 | ua <<= 4; 153 | printf( "ua: %llx %llx\n", (uint64_t) ( ua >> 64) , (uint64_t) ua ); 154 | 155 | unsigned __int128 ub = 2; 156 | unsigned __int128 uc = ua * ub; 157 | 158 | if ( 0 != ( 0xffffffff & uc ) ) 159 | printf( "failure 3: lower part of multiply isn't 0\n" ); 160 | 161 | if ( ( uc >> 64 ) != 0x8 ) 162 | printf( "failure 4: upper part of multiply isn't 0x8: %llx\n", (uint64_t) ( uc >> 64 ) ); 163 | 164 | a = -1; 165 | printf( "a: %llx %llx\n", (uint64_t) ( a >> 64) , (uint64_t) a ); 166 | 167 | a = -33; 168 | printf( "a: %llx %llx = %lld\n", (uint64_t) ( a >> 64) , (uint64_t) a, (int64_t) a ); 169 | 170 | c = a * b; 171 | if ( -66 != c ) 172 | printf( "failure 5: c: %llx %llx = %lld\n", (uint64_t) ( c >> 64) , (uint64_t) c, (int64_t) c ); 173 | 174 | c = a * ub; 175 | if ( -66 != c ) 176 | printf( "failure 6: c: %llx %llx = %lld\n", (uint64_t) ( c >> 64) , (uint64_t) c, (int64_t) c ); 177 | 178 | a = -7; 179 | b = -3; 180 | c = a * b; 181 | if ( 21 != c ) 182 | printf( "failure 7: c: %llx %llx = %lld\n", (uint64_t) ( c >> 64) , (uint64_t) c, (int64_t) c ); 183 | } // validate_128mul 184 | 185 | template void show_result( const char *text, T x ) 186 | { 187 | printf( "%s result: %ld\n", text, x ); 188 | } //show_result 189 | 190 | extern "C" int main() 191 | { 192 | validate_128mul(); 193 | 194 | int8_t i8min = -127, i8max = 127; 195 | int8_t i8 = test( i8min, i8max ); 196 | show_result( "int8_t", (int64_t) i8 ); 197 | 198 | uint8_t ui8min = 0, ui8max = 255; 199 | uint8_t u8 = test( ui8min, ui8max ); 200 | show_result( "uint8_t", (uint64_t) u8 ); 201 | 202 | int16_t i16min = -228, i16max = 227; 203 | int16_t i16 = test( i16min, i16max ); 204 | show_result( "int16_t", (int64_t) i16 ); 205 | 206 | uint16_t ui16min = 0, ui16max = 300; 207 | uint16_t u16 = test( ui16min, ui16max ); 208 | show_result( "uint16_t", (uint64_t) u16 ); 209 | 210 | int32_t i32min = -228, i32max = 227; 211 | int32_t i32 = test( i32min, i32max ); 212 | show_result( "int32_t", (int64_t) i32 ); 213 | 214 | uint32_t ui32min = 0, ui32max = 300; 215 | uint32_t u32 = test( ui32min, ui32max ); 216 | show_result( "uint32_t", (uint64_t) u32 ); 217 | 218 | int64_t i64min = -228, i64max = 227; 219 | int64_t i64 = test( i64min, i64max ); 220 | show_result( "int64_t", (int64_t) i64 ); 221 | 222 | uint64_t ui64min = 0, ui64max = 300; 223 | uint64_t u64 = test( ui64min, ui64max ); 224 | show_result( "uint64_t", (uint64_t) u64 ); 225 | 226 | __int128 i128min = -228, i128max = 227; 227 | __int128 i128 = test( i128min, i128max ); 228 | show_result( "int128_t", (int64_t) i128 ); 229 | 230 | unsigned __int128 ui128min = 0, ui128max = 300; 231 | unsigned __int128 u128 = test( ui128min, ui128max ); 232 | show_result( "uint128_t", (uint64_t) u128 ); 233 | 234 | printf( "end of the app\n" ); 235 | return 0; 236 | } //main 237 | 238 | -------------------------------------------------------------------------------- /c_tests/t_setjmp.c: -------------------------------------------------------------------------------- 1 | // sample code taken from stackoverflow. 2 | 3 | #include 4 | #include 5 | 6 | static jmp_buf buf; 7 | 8 | void second(void) 9 | { 10 | printf( "second\n" ); // prints 11 | longjmp( buf, 1 ); // jumps back to where setjmp was called - making setjmp now return 1 12 | } 13 | 14 | void first(void) 15 | { 16 | second(); 17 | printf( "first (if this prints there is a bug)\n" ); 18 | } 19 | 20 | int main() 21 | { 22 | if ( ! setjmp( buf ) ) 23 | first(); // when executed, setjmp returns 0 24 | else // when longjmp jumps back, setjmp returns 1 25 | printf( "back in main\n" ); // prints 26 | 27 | printf( "falling out of main\n" ); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /c_tests/tap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | template T __max( T a, T b ) 7 | { 8 | if ( a > b ) 9 | return a; 10 | return b; 11 | } 12 | 13 | template T __min( T a, T b ) 14 | { 15 | if ( a < b ) 16 | return a; 17 | return b; 18 | } 19 | 20 | int gcd( int m, int n ) 21 | { 22 | int a = 0; 23 | int b = __max( m, n ); 24 | int r = __min( m, n ); 25 | 26 | while ( 0 != r ) 27 | { 28 | a = b; 29 | b = r; 30 | r = a % b; 31 | } 32 | 33 | return b; 34 | } //gcd 35 | 36 | int randi() 37 | { 38 | //return rvos_rand() & 0x7fffffff; 39 | return rand(); 40 | } //randi 41 | 42 | // https://en.wikipedia.org/wiki/Ap%C3%A9ry%27s_theorem 43 | 44 | void first_implementation() 45 | { 46 | // use 128 bit ints for testing but also because the loop can go futher without integer overflow 47 | 48 | const unsigned __int128 total = 100000; //00; 49 | double sofar = 0; 50 | unsigned __int128 prev = 1; 51 | 52 | for ( unsigned __int128 i = 1; i <= total; i++ ) 53 | { 54 | sofar += (double) 1.0 / (double) ( i * i * i ); 55 | 56 | if ( i == ( prev * 10 ) ) 57 | { 58 | prev = i; 59 | printf( " at %12llu iterations: %.20lf\n", (uint64_t) i, sofar ); 60 | } 61 | } 62 | } //first_implementation 63 | 64 | int main() 65 | { 66 | printf( "starting, should tend towards 1.2020569031595942854...\n" ); 67 | 68 | first_implementation(); 69 | 70 | printf( "next implementation...\n" ); 71 | 72 | const int totalEntries = 10000; 73 | int totalCoprimes = 0; 74 | 75 | int prev = 1; 76 | 77 | for ( int i = 1; i <= totalEntries; i++ ) 78 | { 79 | int a = randi(); 80 | int b = randi(); 81 | int c = randi(); 82 | 83 | int greatest = gcd( a, gcd( b, c ) ); 84 | if ( 1 == greatest ) 85 | totalCoprimes++; 86 | 87 | if ( i == ( prev * 10 ) ) 88 | { 89 | prev = i; 90 | printf( " at %12d iterations: %.20lf\n", i, (double) i / (double) totalCoprimes ); 91 | } 92 | } 93 | 94 | printf( "tap completed with great success\n" ); 95 | exit( 1202 ); 96 | return 1202; 97 | } //main 98 | -------------------------------------------------------------------------------- /c_tests/tarray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifndef _countof 7 | #define _countof( X ) ( sizeof( X ) / sizeof( X[0] ) ) 8 | #endif 9 | 10 | #pragma pack( push, 1 ) 11 | struct SMany 12 | { 13 | uint8_t ui8; 14 | uint64_t ui64; 15 | uint16_t ui16; 16 | uint32_t ui32; 17 | int8_t i8; 18 | int64_t i64; 19 | int16_t i16; 20 | int32_t i32; 21 | }; 22 | 23 | static SMany amany_before[ 10 ]; 24 | static SMany amany[ 20 ]; 25 | static SMany amany_after[ 10 ]; 26 | #pragma pack(pop) 27 | 28 | uint64_t one_bits( uint64_t bits ) 29 | { 30 | if ( 64 == bits ) 31 | return ~ 0ull; 32 | return ( ( 1ull << bits ) - 1 ); 33 | } 34 | 35 | template void validate_array( T * a, size_t c ) 36 | { 37 | T sum = 0; 38 | for ( size_t i = 0; i < c; i++ ) 39 | sum += a[ i ]; 40 | 41 | uint64_t ones = one_bits( 8 * sizeof( T ) ); 42 | uint64_t result = (uint64_t) sum & ones; 43 | printf( "sum: %#llx\n", result ); 44 | } //validate_array 45 | 46 | template void test_array( T * a, size_t c ) 47 | { 48 | for ( size_t i = 0; i < c; i++ ) 49 | a[ i ] = (T) ( i - ( c / 2 ) ); 50 | 51 | validate_array( a, c ); 52 | } //test_array 53 | 54 | static char * appendHexNibble( char * p, uint8_t val ) 55 | { 56 | *p++ = ( val <= 9 ) ? val + '0' : val - 10 + 'a'; 57 | return p; 58 | } //appendHexNibble 59 | 60 | static char * appendHexByte( char * p, uint8_t val ) 61 | { 62 | p = appendHexNibble( p, ( val >> 4 ) & 0xf ); 63 | p = appendHexNibble( p, val & 0xf ); 64 | return p; 65 | } //appendBexByte 66 | 67 | static char * appendHexWord( char * p, uint16_t val ) 68 | { 69 | p = appendHexByte( p, ( val >> 8 ) & 0xff ); 70 | p = appendHexByte( p, val & 0xff ); 71 | return p; 72 | } //appendHexWord 73 | 74 | void ShowBinaryData( uint8_t * pData, uint32_t length, uint32_t indent ) 75 | { 76 | int64_t offset = 0; 77 | int64_t beyond = length; 78 | const int64_t bytesPerRow = 32; 79 | uint8_t buf[ bytesPerRow ]; 80 | char acLine[ 200 ]; 81 | 82 | while ( offset < beyond ) 83 | { 84 | char * pline = acLine; 85 | 86 | for ( uint32_t i = 0; i < indent; i++ ) 87 | *pline++ = ' '; 88 | 89 | pline = appendHexWord( pline, (uint16_t) offset ); 90 | *pline++ = ' '; 91 | *pline++ = ' '; 92 | 93 | int64_t end_of_row = offset + bytesPerRow; 94 | int64_t cap = ( end_of_row > beyond ) ? beyond : end_of_row; 95 | int64_t toread = ( ( offset + bytesPerRow ) > beyond ) ? ( length % bytesPerRow ) : bytesPerRow; 96 | memcpy( buf, pData + offset, toread ); 97 | uint64_t extraSpace = 2; 98 | 99 | for ( int64_t o = offset; o < cap; o++ ) 100 | { 101 | pline = appendHexByte( pline, buf[ o - offset ] ); 102 | *pline++ = ' '; 103 | if ( ( bytesPerRow > 16 ) && ( o == ( offset + 15 ) ) ) 104 | { 105 | *pline++ = ':'; 106 | *pline++ = ' '; 107 | extraSpace = 0; 108 | } 109 | } 110 | 111 | uint64_t spaceNeeded = extraSpace + ( ( bytesPerRow - ( cap - offset ) ) * 3 ); 112 | 113 | for ( uint64_t sp = 0; sp < ( 1 + spaceNeeded ); sp++ ) 114 | *pline++ = ' '; 115 | 116 | for ( int64_t o = offset; o < cap; o++ ) 117 | { 118 | char ch = buf[ o - offset ]; 119 | 120 | if ( (int8_t) ch < ' ' || 127 == ch ) 121 | ch = '.'; 122 | 123 | *pline++ = ch; 124 | } 125 | 126 | offset += bytesPerRow; 127 | *pline = 0; 128 | printf( "%s\n", acLine ); 129 | } 130 | } //ShowBinaryData 131 | 132 | void test_many() 133 | { 134 | memset( amany_before, 0, sizeof( amany_before ) ); 135 | memset( amany_after, 0, sizeof( amany_after ) ); 136 | 137 | for ( size_t i = 0; i < _countof( amany ); i++ ) 138 | { 139 | SMany & m = amany[ i ]; 140 | m.ui8 = i; 141 | m.ui64 = i * 8; 142 | m.ui16 = i * 2; 143 | m.ui32 = i * 4; 144 | m.i8 = - (int8_t) i; 145 | m.i64 = - (int64_t) ( i * 8 ); 146 | m.i16 = - (int16_t) ( i * 2 ); 147 | m.i32 = - (int32_t) ( i * 4 ); 148 | } 149 | 150 | memset( amany_before, 0, sizeof( amany_before ) ); 151 | memset( amany_after, 0, sizeof( amany_after ) ); 152 | 153 | for ( size_t i = 0; i < _countof( amany ); i++ ) 154 | { 155 | SMany & m = amany[ i ]; 156 | 157 | if ( m.ui8 != i ) 158 | printf( "i %u, ui8 is %llu, not %llu\n", (int) i, (uint64_t) m.ui8, (uint64_t) i ); 159 | if ( m.ui64 != i * 8 ) 160 | printf( "i %u, ui64 is %llu, not %llu\n", (int) i, (uint64_t) m.ui64, (uint64_t) i * 8 ); 161 | if ( m.ui16 != i * 2 ) 162 | printf( "i %u, ui16 is %llu, not %llu\n", (int) i, (uint64_t) m.ui16, (uint64_t) i * 2 ); 163 | if ( m.ui32 != i * 4 ) 164 | printf( "i %u, ui32 is %llu, not %llu\n", (int) i, (uint64_t) m.ui32, (uint64_t) i * 4 ); 165 | 166 | if ( m.i8 != - (int8_t) i ) 167 | printf( "i %u, i8 is %lld, not %lld\n", (int) i, (int64_t) m.i8, - (int64_t) i ); 168 | if ( m.i64 != - (int64_t) i * 8 ) 169 | printf( "i %u, i64 is %lld, not %lld\n", (int) i, (int64_t) m.ui64, - (int64_t) i * 8 ); 170 | if ( m.i16 != - (int16_t) i * 2 ) 171 | printf( "i %u, i16 is %lld, not %lld\n", (int) i, (int64_t) m.ui16, - (int64_t) i * 2 ); 172 | if ( m.i32 != - (int32_t) i * 4 ) 173 | printf( "i %u, i32 is %lld, not %lld\n", (int) i, (int64_t) m.ui32, - (int64_t) i * 4 ); 174 | } 175 | 176 | ShowBinaryData( (uint8_t *) amany, sizeof( amany ), 4 ); 177 | } //test_many 178 | 179 | int main( int argc, char * argv[] ) 180 | { 181 | int8_t ai8[ 16 ]; 182 | test_array( ai8, _countof( ai8 ) ); 183 | uint8_t aui8[ 16 ]; 184 | test_array( aui8, _countof( aui8 ) ); 185 | 186 | int16_t ai16[ 16 ]; 187 | test_array( ai16, _countof( ai16 ) ); 188 | uint16_t aui16[ 16 ]; 189 | test_array( aui16, _countof( aui16 ) ); 190 | 191 | int32_t ai32[ 16 ]; 192 | test_array( ai32, _countof( ai32 ) ); 193 | uint32_t aui32[ 16 ]; 194 | test_array( aui32, _countof( aui32 ) ); 195 | 196 | int64_t ai64[ 16 ]; 197 | test_array( ai64, _countof( ai64 ) ); 198 | uint64_t aui64[ 16 ]; 199 | test_array( aui64, _countof( aui64 ) ); 200 | 201 | // validate again to check for memory trashing 202 | 203 | validate_array( ai8, _countof( ai8 ) ); 204 | validate_array( aui8, _countof( aui8 ) ); 205 | validate_array( ai16, _countof( ai16 ) ); 206 | validate_array( aui16, _countof( aui16 ) ); 207 | validate_array( ai32, _countof( ai32 ) ); 208 | validate_array( aui32, _countof( aui32 ) ); 209 | validate_array( ai64, _countof( ai64 ) ); 210 | validate_array( aui64, _countof( aui64 ) ); 211 | 212 | test_array( ai16, _countof( ai16 ) ); 213 | test_array( aui16, _countof( aui16 ) ); 214 | test_array( ai8, _countof( ai8 ) ); 215 | test_array( aui8, _countof( aui8 ) ); 216 | 217 | test_many(); 218 | 219 | printf( "tarray completed with great success\n" ); 220 | return 0; 221 | } //main 222 | 223 | -------------------------------------------------------------------------------- /c_tests/tatomic.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | template void validate( std::atomic & a ) 8 | { 9 | a = 0x36; 10 | a++; 11 | assert( 0x37 == a ); 12 | a--; 13 | assert( 0x36 == a ); 14 | 15 | uint64_t v = a.fetch_add( 0x20 ); 16 | assert( 0x36 == v ); 17 | assert( 0x56 == a ); 18 | 19 | v = a.fetch_sub( 0x20 ); 20 | assert( 0x56 == v ); 21 | assert( 0x36 == a ); 22 | 23 | // min and max aren't in my version of g++ 24 | //v = a.fetch_max( 0x7a ); 25 | //assert( 0x7a == v ); 26 | //v = a.fetch_min( 2 ); 27 | //assert( 2 == v ); 28 | 29 | v = a.fetch_and( 0x44 ); 30 | assert( 4 == a ); 31 | assert( 0x36 == v ); 32 | 33 | a = 0x36; 34 | v = a.fetch_or( 1 ); 35 | assert( 0x37 == a ); 36 | assert( 0x36 == v ); 37 | 38 | a = 0x36; 39 | v = a.fetch_xor( 4 ); 40 | assert( 0x32 == a ); 41 | assert( 0x36 == v ); 42 | 43 | a = 0x36; 44 | T b = 0x36; 45 | T c = 0x37; 46 | bool result = a.compare_exchange_weak( b, c, std::memory_order_release, std::memory_order_relaxed ); 47 | assert( 0x37 == a ); 48 | assert( result ); 49 | } // validate 50 | 51 | int main( int argc, char * argv[] ) 52 | { 53 | std::atomic i8( 0 ); 54 | validate( i8 ); 55 | std::atomic ui8( 0 ); 56 | validate( ui8 ); 57 | std::atomic i16( 0 ); 58 | validate( i16 ); 59 | std::atomic ui16( 0 ); 60 | validate( ui16 ); 61 | std::atomic i32( 0 ); 62 | validate( i32 ); 63 | std::atomic ui32( 0 ); 64 | validate( ui32 ); 65 | std::atomic i64( 0 ); 66 | validate( i64 ); 67 | std::atomic ui64( 0 ); 68 | validate( ui64 ); 69 | 70 | // armos only has one core and supports one thread. but code will uses mutexes so validate they don't fail 71 | 72 | std::mutex mtx; 73 | mtx.lock(); 74 | mtx.unlock(); 75 | bool result = mtx.try_lock(); 76 | assert( true ); 77 | mtx.unlock(); 78 | 79 | printf( "test atomic completed with great success\n" ); 80 | return 0; 81 | } //main -------------------------------------------------------------------------------- /c_tests/tbits.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | template void test_bits( T a, T b ) 5 | { 6 | T r_and = ( a & b ); 7 | T r_or = ( a | b ); 8 | T r_xor = ( a ^ b ); 9 | T r_nota = ( ~a ); 10 | T r_notb = ( ~b ); 11 | 12 | printf( " and %llx, or %llx, xor %llx, nota %llx, notb %llx\n", 13 | (uint64_t) r_and, (uint64_t) r_or, (uint64_t) r_xor, (uint64_t) r_nota, (uint64_t) r_notb ); 14 | } //test_bits 15 | 16 | int main( int argc, char * argv[] ) 17 | { 18 | printf( "uint8_t:\n" ); 19 | test_bits( (uint8_t) 7, (uint8_t) 3 ); 20 | test_bits( (uint8_t) 7, (uint8_t) -3 ); 21 | test_bits( (uint8_t) -7, (uint8_t) 3 ); 22 | test_bits( (uint8_t) -7, (uint8_t) -3 ); 23 | test_bits( (uint8_t) -1, (uint8_t) -1 ); 24 | test_bits( (uint8_t) 247, (uint8_t) 3 ); 25 | test_bits( (uint8_t) 247, (uint8_t) -3 ); 26 | test_bits( (uint8_t) -247, (uint8_t) 3 ); 27 | test_bits( (uint8_t) -247, (uint8_t) -247 ); 28 | 29 | printf( "int8_t:\n" ); 30 | test_bits( (int8_t) 7, (int8_t) 3 ); 31 | test_bits( (int8_t) 7, (int8_t) -3 ); 32 | test_bits( (int8_t) -7, (int8_t) 3 ); 33 | test_bits( (int8_t) -7, (int8_t) -3 ); 34 | test_bits( (int8_t) -1, (int8_t) -1 ); 35 | test_bits( (int8_t) 247, (int8_t) 3 ); 36 | test_bits( (int8_t) 247, (int8_t) -3 ); 37 | test_bits( (int8_t) -247, (int8_t) 3 ); 38 | test_bits( (int8_t) -247, (int8_t) -247 ); 39 | 40 | printf( "uint16_t:\n" ); 41 | test_bits( (uint16_t) 7, (uint16_t) 3 ); 42 | test_bits( (uint16_t) 7, (uint16_t) -3 ); 43 | test_bits( (uint16_t) -7, (uint16_t) 3 ); 44 | test_bits( (uint16_t) -7, (uint16_t) -3 ); 45 | test_bits( (uint16_t) -1, (uint16_t) -1 ); 46 | test_bits( (uint16_t) 247, (uint16_t) 3 ); 47 | test_bits( (uint16_t) 247, (uint16_t) -3 ); 48 | test_bits( (uint16_t) -247, (uint16_t) 3 ); 49 | test_bits( (uint16_t) -247, (uint16_t) -247 ); 50 | 51 | printf( "int16_t:\n" ); 52 | test_bits( (int16_t) 7, (int16_t) 3 ); 53 | test_bits( (int16_t) 7, (int16_t) -3 ); 54 | test_bits( (int16_t) -7, (int16_t) 3 ); 55 | test_bits( (int16_t) -7, (int16_t) -3 ); 56 | test_bits( (int16_t) -1, (int16_t) -1 ); 57 | test_bits( (int16_t) 247, (int16_t) 3 ); 58 | test_bits( (int16_t) 247, (int16_t) -3 ); 59 | test_bits( (int16_t) -247, (int16_t) 3 ); 60 | test_bits( (int16_t) -247, (int16_t) -247 ); 61 | 62 | printf( "uint32_t:\n" ); 63 | test_bits( (uint32_t) 7, (uint32_t) 3 ); 64 | test_bits( (uint32_t) 7, (uint32_t) -3 ); 65 | test_bits( (uint32_t) -7, (uint32_t) 3 ); 66 | test_bits( (uint32_t) -7, (uint32_t) -3 ); 67 | test_bits( (uint32_t) -1, (uint32_t) -1 ); 68 | test_bits( (uint32_t) 247, (uint32_t) 3 ); 69 | test_bits( (uint32_t) 247, (uint32_t) -3 ); 70 | test_bits( (uint32_t) -247, (uint32_t) 3 ); 71 | test_bits( (uint32_t) -247, (uint32_t) -247 ); 72 | 73 | printf( "int32_t:\n" ); 74 | test_bits( (int32_t) 7, (int32_t) 3 ); 75 | test_bits( (int32_t) 7, (int32_t) -3 ); 76 | test_bits( (int32_t) -7, (int32_t) 3 ); 77 | test_bits( (int32_t) -7, (int32_t) -3 ); 78 | test_bits( (int32_t) -1, (int32_t) -1 ); 79 | test_bits( (int32_t) 247, (int32_t) 3 ); 80 | test_bits( (int32_t) 247, (int32_t) -3 ); 81 | test_bits( (int32_t) -247, (int32_t) 3 ); 82 | test_bits( (int32_t) -247, (int32_t) -247 ); 83 | 84 | printf( "uint64_t:\n" ); 85 | test_bits( (uint64_t) 7, (uint64_t) 3 ); 86 | test_bits( (uint64_t) 7, (uint64_t) -3 ); 87 | test_bits( (uint64_t) -7, (uint64_t) 3 ); 88 | test_bits( (uint64_t) -7, (uint64_t) -3 ); 89 | test_bits( (uint64_t) -1, (uint64_t) -1 ); 90 | test_bits( (uint64_t) 247, (uint64_t) 3 ); 91 | test_bits( (uint64_t) 247, (uint64_t) -3 ); 92 | test_bits( (uint64_t) -247, (uint64_t) 3 ); 93 | test_bits( (uint64_t) -247, (uint64_t) -247 ); 94 | 95 | printf( "int64_t:\n" ); 96 | test_bits( (int64_t) 7, (int64_t) 3 ); 97 | test_bits( (int64_t) 7, (int64_t) -3 ); 98 | test_bits( (int64_t) -7, (int64_t) 3 ); 99 | test_bits( (int64_t) -7, (int64_t) -3 ); 100 | test_bits( (int64_t) -1, (int64_t) -1 ); 101 | test_bits( (int64_t) 247, (int64_t) 3 ); 102 | test_bits( (int64_t) 247, (int64_t) -3 ); 103 | test_bits( (int64_t) -247, (int64_t) 3 ); 104 | test_bits( (int64_t) -247, (int64_t) -247 ); 105 | } //main 106 | 107 | -------------------------------------------------------------------------------- /c_tests/tcalloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void chkmem( char * p, int v, int c ) 6 | { 7 | unsigned char * pc = (unsigned char *) p; 8 | unsigned char val = (unsigned char) ( v & 0xff ); 9 | int i; 10 | 11 | if ( 0 == p ) 12 | { 13 | printf( "request to chkmem a null pointer\n" ); 14 | exit( 1 ); 15 | } 16 | 17 | for ( i = 0; i < c; i++ ) 18 | { 19 | if ( *pc != val ) 20 | { 21 | printf( "memory isn't as expected! p %p i %d, of count %d, val expected %#x, val found %#x\n", 22 | p, i, c, (unsigned char) v, (unsigned char) *pc ); 23 | 24 | exit( 1 ); 25 | } 26 | pc++; 27 | } 28 | } 29 | 30 | int main( int argc, char * argv[] ) 31 | { 32 | for ( int i = 0; i < 1000; i++ ) 33 | { 34 | int count = 1 + ( rand() % 255 ); 35 | char * p = (char *) calloc( count, 1 ); 36 | chkmem( p, 0, count); 37 | } 38 | 39 | printf( "tcalloc completed with great success\n" ); 40 | return 0; 41 | } -------------------------------------------------------------------------------- /c_tests/td.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | extern "C" int main() 8 | { 9 | double pi = 3.14159265358979323846264338327952884197169399375105820974944592307; 10 | 11 | char ac[100]; 12 | sprintf( ac, "sprintf double %.20f\n", pi ); 13 | printf( ac ); 14 | 15 | printf( "double from printf: %.20f\n", pi ); 16 | 17 | float f = 1.2020569; 18 | printf( "float from printf: %f\n", f ); 19 | 20 | double r = -f * pi; 21 | printf( "double from printf r: %lf\n", r ); 22 | 23 | double sq = sqrt( pi ); 24 | printf( "sqrt of pi: %lf\n", sq ); 25 | 26 | double radians = ( 30.0 * pi ) / 180.0; 27 | printf( "pi in radians: %lf\n", radians ); 28 | 29 | double s = sin( radians ); 30 | printf( "sin of 30 degress is %lf\n", s ); 31 | 32 | double c = cos( radians ); 33 | printf( "cos of 30 degrees is %lf\n", c ); 34 | 35 | double t = tan( radians ); 36 | printf( "tan of 30 degrees is %lf\n", t ); 37 | 38 | double d = atof( "1.0" ); 39 | double at = atan( d ); 40 | printf( "atan of %lf is %lf\n", d, at ); 41 | 42 | at = atan2( 0.3, 0.2 ); 43 | printf( "atan2 of 0.3, 0.2 is %lf\n", at ); 44 | 45 | c = acos( 0.3 ); 46 | printf( "acos of 0.3 is %lf\n", c ); 47 | 48 | s = asin( 0.3 ); 49 | printf( "asin of 0.3 is %lf\n", s ); 50 | 51 | d = tanh( 2.2 ); 52 | printf( "tanh of 2.2 is %lf\n", s ); 53 | 54 | d = log( 0.3 ); 55 | printf( "log of 0.3: %lf\n", d ); 56 | 57 | d = log10( 300.0 ); 58 | printf( "log10 of 300: %lf\n", d ); 59 | 60 | double b = 0.2; 61 | for ( double a = -0.5; a < 0.5; a += 0.1 ) 62 | { 63 | if ( a > b ) 64 | printf( "g," ); 65 | if ( a >= b ) 66 | printf( "ge," ); 67 | if ( a == b ) 68 | printf( "eq," ); 69 | if ( a < b ) 70 | printf( "l," ); 71 | if ( a <= b ) 72 | printf( "le," ); 73 | } 74 | printf( "\n" ); 75 | 76 | int exponent; 77 | double mantissa = frexp( pi, &exponent ); 78 | printf( "pi has mantissa: %lf, exponent %d\n", mantissa, exponent ); 79 | 80 | int loops = 1000; 81 | r = 1.0; 82 | for ( int i = 0; i < loops; i++ ) 83 | r *= 1.14157222; 84 | 85 | t = r; 86 | for ( int i = 0; i < loops; i++ ) 87 | r /= 1.14157222; 88 | 89 | printf( "r should be 1.0: %lf\n", r ); 90 | printf( " r high point %lf\n", t ); 91 | 92 | printf( "stop\n" ); 93 | return 0; 94 | } //main 95 | 96 | -------------------------------------------------------------------------------- /c_tests/terrno.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main( int argc, char * argv[] ) 8 | { 9 | FILE * fp = fopen( "notthere.txt", "r" ); 10 | if ( fp ) 11 | { 12 | printf( "notthere.txt was opened, unexpectedly. errno: %d\n", errno ); 13 | exit( 1 ); 14 | } 15 | 16 | printf( "errno opening a file for read that doesn't exist: %d (2 file not found expected)\n", errno ); 17 | 18 | #if 0 // this causes a watson dump 19 | int result = write( 55, "hello", 5 ); 20 | if ( -1 != result ) 21 | { 22 | printf( "write to invalid file descriptor succeeded result %d, errno %d\n", result, errno ); 23 | exit( 1 ); 24 | } 25 | 26 | printf( "errno doing write to an invalid file descriptor: %d\n", errno ); 27 | #endif 28 | 29 | int result = write( 0, "hello", 5 ); 30 | if ( -1 != result ) 31 | { 32 | printf( "write to stdin file descriptor succeeded result %d, errno %d\n", result, errno ); 33 | exit( 1 ); 34 | } 35 | 36 | printf( "errno doing write to stdin file descriptor: %d. (13 permission denied expected)\n", errno ); 37 | 38 | fp = fopen( "notthere.txt", "zzz" ); 39 | if ( fp ) 40 | { 41 | printf( "notthere.txt with invalid open flags was opened, unexpectedly. errno: %d\n", errno ); 42 | exit( 1 ); 43 | } 44 | 45 | printf( "errno opening a file for read with invalid open flags: %d (22 invalid argument expected)\n", errno ); 46 | 47 | printf( "success\n" ); 48 | return 0; 49 | } //main 50 | -------------------------------------------------------------------------------- /c_tests/tex.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class CUnwound 7 | { 8 | private: 9 | int x; 10 | public: 11 | CUnwound() : x( 44 ) {} 12 | ~CUnwound() { printf( "I am unwound, x should be 44: %d\n", x ); } 13 | void set( int val ) { x = val; } 14 | }; 15 | 16 | struct exceptional : std::exception 17 | { 18 | const char * what() const noexcept { return "exceptional"; } 19 | }; 20 | 21 | // without this, the call to operator new is optimized out 22 | 23 | #pragma GCC optimize("O0") 24 | #pragma clang optimize off 25 | 26 | int main() 27 | { 28 | printf( "top of tex\n" ); 29 | 30 | try 31 | { 32 | CUnwound unwound; 33 | throw exceptional(); 34 | unwound.set( 33 ); // should never be executed 35 | } 36 | catch ( exception & e ) 37 | { 38 | printf( "caught exception %s\n", e.what() ); 39 | } 40 | 41 | int successful = 0; 42 | 43 | try 44 | { 45 | printf( "attempting large allocations\n" ); 46 | for ( size_t i = 0; i < 1000; i++ ) 47 | { 48 | int volatile * myarray = new int[ 1000000 ]; 49 | if ( myarray ) 50 | successful++; 51 | else 52 | printf( "new failed but didn't raise!?!\n" ); 53 | //printf( "allocation %zd succeeded %p\n", i, myarray ); 54 | } 55 | printf( "large allocations succeeded?!? (%d)\n", successful ); 56 | } 57 | catch ( exception & e ) 58 | { 59 | printf( "caught a standard execption: %s\n", e.what() ); 60 | fflush( stdout ); 61 | } 62 | catch ( ... ) 63 | { 64 | printf( "caught generic exception\n" ); 65 | } 66 | 67 | printf( "leaving main\n" ); 68 | return 0; 69 | } 70 | 71 | -------------------------------------------------------------------------------- /c_tests/tf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #define _USE_MATH_DEFINES 6 | #include 7 | #include 8 | #include 9 | 10 | char *floattoa( char *buffer, double d, int precision ) 11 | { 12 | char * pbuf = buffer; 13 | 14 | if ( d < 0 ) 15 | { 16 | *pbuf++ = '-'; 17 | *pbuf = 0; 18 | d *= -1; 19 | } 20 | 21 | uint32_t whole = (uint32_t) (float) d; 22 | sprintf( pbuf, "%u", whole ); 23 | 24 | if ( precision > 0 ) 25 | { 26 | pbuf = buffer + strlen( buffer ); 27 | *pbuf++ = '.'; 28 | 29 | double fraction = d - whole; 30 | 31 | while ( precision > 0 ) 32 | { 33 | fraction *= 10.0; 34 | whole = fraction; 35 | *pbuf++ = '0' + whole; 36 | 37 | fraction -= whole; 38 | precision--; 39 | } 40 | 41 | *pbuf = 0; 42 | } 43 | 44 | return buffer; 45 | } //floattoa 46 | 47 | // less than full precision because libc only provides this much precision in trig functions 48 | 49 | #define TRIG_FLT_EPSILON 0.00002 /* 0.00000011920928955078 */ 50 | #define TRIG_DBL_EPSILON 0.00000002 /* 0.00000000000000022204 */ 51 | #define TRIG_LDBL_EPSILON 0.0000000000000002 /* 0.0000000000000000000000000000000001925930 */ 52 | 53 | void check_same_f( const char * operation, float a, float b ) 54 | { 55 | float diff = a - b; 56 | float abs_diff = fabsf( diff ); 57 | bool eq = ( abs_diff <= TRIG_FLT_EPSILON ); 58 | if ( !eq ) 59 | printf( "operation %s: float %.20f is not the same as float %.20f\n", operation, a, b ); 60 | } //check_same_f 61 | 62 | void check_same_d( const char * operation, double a, double b ) 63 | { 64 | double diff = a - b; 65 | double abs_diff = fabs( diff ); 66 | bool eq = ( abs_diff <= TRIG_DBL_EPSILON ); 67 | if ( !eq ) 68 | printf( "operation %s: double %.20lf is not the same as double %.20lf\n", operation, a, b ); 69 | } //check_same_d 70 | 71 | void check_same_ld( const char * operation, long double a, long double b ) 72 | { 73 | long double diff = a - b; 74 | long double abs_diff = fabsl( diff ); 75 | bool eq = ( abs_diff <= TRIG_LDBL_EPSILON ); 76 | if ( !eq ) 77 | { 78 | printf( "operation %s: long double %.20Lf is not the same as long double %.20Lf\n", operation, a, b ); 79 | exit( 0 ); 80 | } 81 | } //check_same_ld 82 | 83 | __int128 factorial( __int128 n ) 84 | { 85 | if ( 0 == n ) 86 | return 1; 87 | 88 | return n * factorial( n - 1 ); 89 | } //factorial 90 | 91 | long double my_sin_ld( long double x, int n = 18 ) 92 | { 93 | long double result = 0; 94 | __int128 sign = 1; 95 | 96 | for ( __int128 i = 1; i <= n; i++ ) 97 | { 98 | result += sign * powl( x, ( 2 * i - 1 ) ) / factorial( 2 * i - 1 ); 99 | sign *= -1; 100 | } 101 | 102 | return result; 103 | } //my_sin_ld 104 | 105 | double my_sin_d( double x, int n = 18 ) 106 | { 107 | double result = 0; 108 | __int128 sign = 1; 109 | 110 | for ( __int128 i = 1; i <= n; i++ ) 111 | { 112 | result += sign * pow( x, ( 2 * i - 1 ) ) / factorial( 2 * i - 1 ); 113 | sign *= -1; 114 | } 115 | 116 | return result; 117 | } //my_sin_d 118 | 119 | float my_sin_f( float x, int n = 18 ) 120 | { 121 | float result = 0; 122 | __int128 sign = 1; 123 | 124 | for ( __int128 i = 1; i <= n; i++ ) 125 | { 126 | result += sign * powf( x, ( 2 * i - 1 ) ) / factorial( 2 * i - 1 ); 127 | sign *= -1; 128 | } 129 | 130 | return result; 131 | } //my_sin_f 132 | 133 | void many_trigonometrics() 134 | { 135 | float f = ( -M_PI / 2 ) + 0x000001; // want to be >= negative half pi. 136 | 137 | //printf( "float epsilon: %.40lf\n", (double) FLT_EPSILON ); 138 | //printf( "double epsilon: %.40lf\n", (double) DBL_EPSILON ); 139 | //printf( "long double epsilon: %.40lf\n", (double) LDBL_EPSILON ); 140 | 141 | while ( f < ( M_PI / 2 ) ) 142 | { 143 | float fresult = tanf( f ); 144 | float fback = atanf( fresult ); 145 | check_same_f( "tan", f, fback ); 146 | 147 | double dresult = tan( (double) f ); 148 | double dback = atan( dresult ); 149 | check_same_d( "tan", (double) f, dback ); 150 | 151 | long double ldresult = tanl( (long double) f ); 152 | long double ldback = atanl( ldresult ); 153 | check_same_ld( "tan", (long double) f, ldback ); 154 | 155 | fresult = sinf( f ); 156 | fback = asinf( fresult ); 157 | check_same_f( "sin", f, fback ); 158 | 159 | fresult = my_sin_f( f ); 160 | fback = asinf( fresult ); 161 | check_same_f( "my sin", f, fback ); 162 | 163 | dresult = sin( (double) f ); 164 | dback = asin( dresult ); 165 | check_same_d( "sin", (double) f, dback ); 166 | 167 | dresult = my_sin_d( (double) f ); 168 | dback = asin( dresult ); 169 | check_same_d( "my sin", (double) f, dback ); 170 | 171 | ldresult = sinl( (long double) f ); 172 | ldback = asinl( ldresult ); 173 | check_same_ld( "sin", (long double) f, ldback ); 174 | 175 | ldresult = my_sin_ld( (long double) f ); 176 | ldback = asinl( ldresult ); 177 | check_same_ld( "my sin", (long double) f, ldback ); 178 | 179 | float f_cos = f + ( M_PI / 2 ); 180 | fresult = cosf( f_cos ); 181 | fback = acosf( fresult ); 182 | check_same_f( "cos", f_cos, fback ); 183 | 184 | dresult = cos( (double) f_cos ); 185 | dback = acos( dresult ); 186 | check_same_d( "cos", (double) f_cos, dback ); 187 | 188 | ldresult = cosl( f_cos ); 189 | ldback = acosl( ldresult ); 190 | check_same_ld( "cos", (long double) f_cos, ldback ); 191 | 192 | f += .01f; 193 | } 194 | } //many_trignometrics 195 | 196 | float square_root_f( float num ) 197 | { 198 | float x = num; 199 | float y = 1; 200 | const float e = 10.0f * FLT_EPSILON; 201 | 202 | while ( ( x - y ) > e ) 203 | { 204 | x = ( x + y ) / 2; 205 | y = num / x; 206 | } 207 | return x; 208 | } //square_root_f 209 | 210 | double square_root_d( double num ) 211 | { 212 | double x = num; 213 | double y = 1; 214 | const double e = 10.0f * DBL_EPSILON; 215 | 216 | while ( ( x - y ) > e ) 217 | { 218 | x = ( x + y ) / 2; 219 | y = num / x; 220 | } 221 | return x; 222 | } //square_root_d 223 | 224 | long double square_root_ld( long double num ) 225 | { 226 | long double x = num; 227 | long double y = 1; 228 | const long double e = 10.0f * LDBL_EPSILON; 229 | 230 | while ( ( x - y ) > e ) 231 | { 232 | x = ( x + y ) / 2; 233 | y = num / x; 234 | } 235 | return x; 236 | } //square_root_ld 237 | 238 | #pragma GCC optimize ("O0") 239 | 240 | extern "C" int main() 241 | { 242 | char ac[ 100 ]; 243 | 244 | floattoa( ac, -1.234567, 8 ); 245 | printf( "float converted by floattoa: %s\n", ac ); 246 | floattoa( ac, 1.234567, 8 ); 247 | printf( "float converted by floattoa: %s\n", ac ); 248 | floattoa( ac, 34.567, 8 ); 249 | printf( "float converted by floattoa: %s\n", ac ); 250 | 251 | printf( "float from printf: %f\n", 45.678 ); 252 | 253 | float f1 = 1.0; 254 | float f2 = 20.2; 255 | float fm1 = -1.342; 256 | float fr = f2 * fm1; 257 | float fd = 1000.0 / 3.0; 258 | float fs = sqrtf( fd ); 259 | 260 | printf( "division result: %f, square root %f\n", fd, fs ); 261 | 262 | floattoa( ac, fr, 6 ); 263 | printf( "float converted with floattoa: %s\n", ac ); 264 | 265 | printf( "result of 20.2 * -1.342: %f\n", fr ); 266 | 267 | double d = (double) fr; 268 | printf( "result of 20.2 * -1.342 as a double: %lf\n", d ); 269 | 270 | float pi = 3.14159265358979323846264338327952884197169399375105820974944592307; 271 | float radians = pi / 180.0 * 30.0; 272 | printf( "pi in radians: %f\n", radians ); 273 | 274 | float s = sinf( radians ); 275 | printf( "sinf of 30 degress is %lf\n", s ); 276 | 277 | float c = cosf( radians ); 278 | printf( "cosf of 30 degrees is %lf\n", c ); 279 | 280 | float t = tanf( radians ); 281 | printf( "tanf of 30 degrees is %lf\n", t ); 282 | 283 | float f = atof( "1.0" ); 284 | float at = atanf( f ); 285 | printf( "atanf of %lf is %lf\n", f, at ); 286 | 287 | at = atan2f( 0.3, 0.2 ); 288 | printf( "atan2f of 0.3, 0.2 is %lf\n", at ); 289 | 290 | c = acosf( 0.3 ); 291 | printf( "acosf of 0.3 is %lf\n", c ); 292 | 293 | s = asinf( 0.3 ); 294 | printf( "asinf of 0.3 is %lf\n", s ); 295 | 296 | f = tanhf( 2.2 ); 297 | printf( "tanhf of 2.2 is %lf\n", s ); 298 | 299 | f = logf( 0.3 ); 300 | printf( "logf of 0.3: %lf\n", f ); 301 | 302 | f = log10f( 300.0 ); 303 | printf( "log10f of 300: %lf\n", f ); 304 | 305 | int exponent; 306 | float mantissa = frexpf( pi, &exponent ); 307 | printf( "pi has mantissa: %lf, exponent %d\n", mantissa, exponent ); 308 | 309 | float b = 2.7; 310 | for ( float a = 2.0; a < 3.0; a += 0.1 ) 311 | { 312 | if ( a > b ) 313 | printf( "g," ); 314 | if ( a >= b ) 315 | printf( "ge," ); 316 | if ( a == b ) 317 | printf( "eq," ); 318 | if ( a < b ) 319 | printf( "l," ); 320 | if ( a <= b ) 321 | printf( "le," ); 322 | } 323 | printf( "\n" ); 324 | 325 | many_trigonometrics(); 326 | 327 | for ( float f = 1.0f; f < 100.0f; f += 1.38f ) 328 | check_same_f( "square root float", square_root_f( f ), sqrtf( f ) ); 329 | 330 | for ( double d = 1.0; d < 100.0; d += 1.38 ) 331 | check_same_d( "square root double", square_root_d( d ), sqrt( d ) ); 332 | 333 | for ( long double ld = 1.0; ld < 100.0; ld += 1.38 ) 334 | check_same_ld( "square root long double", square_root_ld( ld ), sqrtl( ld ) ); 335 | 336 | printf( "test tf completed with great success\n" ); 337 | exit( 0 ); 338 | } //main 339 | 340 | 341 | -------------------------------------------------------------------------------- /c_tests/tflags.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | bool fN = 0; 5 | bool fZ = 0; 6 | bool fC = 0; 7 | bool fV = 0; 8 | 9 | uint64_t add_with_carry64( uint64_t x, uint64_t y, bool carry, bool setflags ) 10 | { 11 | uint64_t result = x + y + (uint64_t) carry; 12 | 13 | if ( setflags ) 14 | { 15 | fN = ( (int64_t) result < 0 ); 16 | fZ = ( 0 == result ); 17 | 18 | // no 128-bit integers, so find fC and fV the hard way 19 | 20 | fC = ( ( result < x ) || ( result < y ) || ( result < (uint64_t) carry ) ); 21 | 22 | int64_t ix = (int64_t) x; 23 | int64_t iy = (int64_t) y; 24 | int64_t iresult = (int64_t) result; 25 | fV = ( ( ( ix > 0 && iy > 0 ) && ( iresult < ix || iresult < iy ) ) || 26 | ( ( ix < 0 && iy < 0 ) && ( iresult > ix || iresult > iy ) ) ); 27 | } 28 | return result; 29 | } //add_with_carry64 30 | 31 | uint64_t sub64( uint64_t x, uint64_t y, bool setflags ) 32 | { 33 | return add_with_carry64( x, ~y, true, setflags ); 34 | } //sub64 35 | 36 | uint32_t add_with_carry32( uint32_t x, uint32_t y, bool carry, bool setflags ) 37 | { 38 | uint64_t unsigned_sum = (uint64_t) x + (uint64_t) y + (uint64_t) carry; 39 | uint32_t result = (uint32_t) ( unsigned_sum & 0xffffffff ); 40 | 41 | if ( setflags ) 42 | { 43 | // this method of setting flags is as the Arm documentation suggests 44 | int64_t signed_sum = (int64_t) (int32_t) x + (int64_t) (int32_t) y + (uint64_t) carry; 45 | fN = ( (int32_t) result < 0 ); 46 | fZ = ( 0 == result ); 47 | fC = ( (uint64_t) result != unsigned_sum ); 48 | fV = ( (int64_t) (int32_t) result != signed_sum ); 49 | //tracer.Trace( " addwithcarry32 %#x with %#x, fN %d, fZ %d, fC %d, fV: %d\n", x, y, fN, fZ, fC, fV ); 50 | } 51 | return result; 52 | } //add_with_carry32 53 | 54 | uint32_t sub32( uint32_t x, uint32_t y, bool setflags ) 55 | { 56 | return add_with_carry32( x, ~y, true, setflags ); 57 | } //sub32 58 | 59 | int main( int argc, char * argv[] ) 60 | { 61 | //uint32_t result32 = sub32( 7, 7, true ); 62 | //printf( "result32: %u, fN %d, fZ %d, fC %d, fV %d\n", result32, fN, fZ, fC, fV ); 63 | uint64_t result64 = sub64( 0, 0, true ); 64 | printf( "result64: %llu, fN %d, fZ %d, fC %d, fV %d\n", result64, fN, fZ, fC, fV ); 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /c_tests/tlead.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main( int argc, char * argv[] ) 4 | { 5 | printf( "%.4d\n", 345 ); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /c_tests/tm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define allocs 69 7 | int logging = 1; 8 | 9 | extern "C" bool trace_instructions( bool trace ); 10 | 11 | static char * appendHexNibble( char * p, uint8_t val ) 12 | { 13 | *p++ = ( val <= 9 ) ? val + '0' : val - 10 + 'a'; 14 | return p; 15 | } //appendHexNibble 16 | 17 | static char * appendHexByte( char * p, uint8_t val ) 18 | { 19 | p = appendHexNibble( p, ( val >> 4 ) & 0xf ); 20 | p = appendHexNibble( p, val & 0xf ); 21 | return p; 22 | } //appendBexByte 23 | 24 | static char * appendHexWord( char * p, uint16_t val ) 25 | { 26 | p = appendHexByte( p, ( val >> 8 ) & 0xff ); 27 | p = appendHexByte( p, val & 0xff ); 28 | return p; 29 | } //appendHexWord 30 | 31 | void ShowBinaryData( uint8_t * pData, uint32_t length, uint32_t indent ) 32 | { 33 | int64_t offset = 0; 34 | int64_t beyond = length; 35 | const int64_t bytesPerRow = 32; 36 | uint8_t buf[ bytesPerRow ]; 37 | char acLine[ 200 ]; 38 | 39 | while ( offset < beyond ) 40 | { 41 | char * pline = acLine; 42 | 43 | for ( uint32_t i = 0; i < indent; i++ ) 44 | *pline++ = ' '; 45 | 46 | pline = appendHexWord( pline, (uint16_t) offset ); 47 | *pline++ = ' '; 48 | *pline++ = ' '; 49 | 50 | int64_t end_of_row = offset + bytesPerRow; 51 | int64_t cap = ( end_of_row > beyond ) ? beyond : end_of_row; 52 | int64_t toread = ( ( offset + bytesPerRow ) > beyond ) ? ( length % bytesPerRow ) : bytesPerRow; 53 | memcpy( buf, pData + offset, toread ); 54 | uint64_t extraSpace = 2; 55 | 56 | for ( int64_t o = offset; o < cap; o++ ) 57 | { 58 | pline = appendHexByte( pline, buf[ o - offset ] ); 59 | *pline++ = ' '; 60 | if ( ( bytesPerRow > 16 ) && ( o == ( offset + 15 ) ) ) 61 | { 62 | *pline++ = ':'; 63 | *pline++ = ' '; 64 | extraSpace = 0; 65 | } 66 | } 67 | 68 | uint64_t spaceNeeded = extraSpace + ( ( bytesPerRow - ( cap - offset ) ) * 3 ); 69 | 70 | for ( uint64_t sp = 0; sp < ( 1 + spaceNeeded ); sp++ ) 71 | *pline++ = ' '; 72 | 73 | for ( int64_t o = offset; o < cap; o++ ) 74 | { 75 | char ch = buf[ o - offset ]; 76 | 77 | if ( (int8_t) ch < ' ' || 127 == ch ) 78 | ch = '.'; 79 | 80 | *pline++ = ch; 81 | } 82 | 83 | offset += bytesPerRow; 84 | *pline = 0; 85 | printf( "%s\n", acLine ); 86 | } 87 | } //ShowBinaryData 88 | 89 | char * memset_x( char * p, int v, int c ) 90 | { 91 | unsigned char * pc = (unsigned char *) p; 92 | unsigned char val = (unsigned char) ( v & 0xff ); 93 | int i; 94 | 95 | if ( 0 == p ) 96 | { 97 | printf( "request to memset a null pointer\n" ); 98 | exit( 1 ); 99 | } 100 | 101 | if ( logging ) 102 | #ifdef CPMTIME 103 | printf( " memset p %u, val %x, c %d\n", p, val, c ); 104 | #else 105 | printf( " memset p %p, val %#x, count of bytes %d\n", p, val, c ); 106 | #endif 107 | 108 | for ( i = 0; i < c; i++ ) 109 | *pc++ = val; 110 | return p; 111 | } 112 | 113 | void chkmem( char * p, int v, int c ) 114 | { 115 | unsigned char * pc = (unsigned char *) p; 116 | unsigned char val = (unsigned char) ( v & 0xff ); 117 | int i; 118 | 119 | if ( 0 == p ) 120 | { 121 | printf( "request to chkmem a null pointer\n" ); 122 | exit( 1 ); 123 | } 124 | 125 | for ( i = 0; i < c; i++ ) 126 | { 127 | if ( *pc != val ) 128 | { 129 | #ifdef CPMTIME 130 | printf( "memory isn't as expected! p %u, v %d, c %d, *pc %d\n",p, v, c, *pc ); 131 | #else 132 | printf( "memory isn't as expected! p %p i %d, of count %d, val expected %#x, val found %#x\n", 133 | p, i, c, (unsigned char) v, (unsigned char) *pc ); 134 | ShowBinaryData( (uint8_t *) p, c, 4 ); 135 | #endif 136 | exit( 1 ); 137 | } 138 | pc++; 139 | } 140 | } 141 | 142 | int main( int argc, char * argv[] ) 143 | { 144 | int i, cb, j; 145 | char * ap[ allocs ]; 146 | char * pc; 147 | 148 | logging = ( argc > 1 ); 149 | pc = argv[ 0 ]; /* evade compiler warning */ 150 | 151 | for ( j = 0; j < 10; j++ ) 152 | { 153 | if ( logging ) 154 | printf( "in alloc mode pass %d\n", j ); 155 | 156 | for ( i = 0; i < allocs; i++ ) 157 | { 158 | cb = 8 + ( i * 10 ); 159 | int cb_calloc = cb + 5; 160 | if ( logging ) 161 | printf( " i, cb, cb_calloc: %d %d %d\n", i, cb, cb_calloc ); 162 | 163 | pc = (char *) calloc( cb_calloc, 1 ); 164 | chkmem( pc, 0, cb_calloc ); 165 | memset_x( pc, 0xcc, cb_calloc ); 166 | 167 | ap[ i ] = (char *) malloc( cb ); 168 | memset_x( ap[ i ], 0xaa, cb ); 169 | 170 | chkmem( pc, 0xcc, cb_calloc ); 171 | free( pc ); 172 | } 173 | 174 | if ( logging ) 175 | printf( "in free mode, even first\n" ); 176 | 177 | for ( i = 0; i < allocs; i += 2 ) 178 | { 179 | cb = 8 + ( i * 10 ); 180 | int cb_calloc = cb + 3; 181 | if ( logging ) 182 | printf( " i, cb, cb_calloc: %d %d %d\n", i, cb, cb_calloc ); 183 | 184 | pc = (char *) calloc( cb_calloc, 1 ); 185 | chkmem( pc, 0, cb_calloc ); 186 | memset_x( pc, 0xcc, cb_calloc ); 187 | 188 | chkmem( ap[ i ], 0xaa, cb ); 189 | memset_x( ap[ i ], 0xff, cb ); 190 | free( ap[ i ] ); 191 | 192 | chkmem( pc, 0xcc, cb_calloc ); 193 | free( pc ); 194 | } 195 | 196 | if ( logging ) 197 | printf( "in free mode, now odd\n" ); 198 | 199 | for ( i = 1; i < allocs; i += 2 ) 200 | { 201 | cb = 8 + ( i * 10 ); 202 | int cb_calloc = cb + 7; 203 | if ( logging ) 204 | printf( " i, cb, cb_calloc: %d %d %d\n", i, cb, cb_calloc ); 205 | 206 | pc = (char *) calloc( cb_calloc, 1 ); 207 | if ( logging ) 208 | printf( " calloc'ed memory at %p\n", pc ); 209 | chkmem( pc, 0, cb_calloc ); 210 | 211 | chkmem( ap[ i ], 0xaa, cb ); 212 | memset_x( ap[ i ], 0xff, cb ); 213 | free( ap[ i ] ); 214 | 215 | chkmem( pc, 0, cb_calloc ); 216 | free( pc ); 217 | } 218 | } 219 | 220 | printf( "tm has completed with great success\n" ); 221 | return 0; 222 | } 223 | -------------------------------------------------------------------------------- /c_tests/tmmap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void validate( void * amaps[], size_t i, size_t size ) 10 | { 11 | uint8_t * p = (uint8_t *) amaps[ i ]; 12 | uint8_t c = (uint8_t) ( i + 'a' ); 13 | for ( size_t x = 0; x < size; x++ ) 14 | { 15 | if ( p[x] != c ) 16 | { 17 | printf( "buffer %p number %d size %d doesn't have value %c at offset %d -- it has integer %d\n", 18 | p, (int) i, (int) size, c, (int) x, (int) p[x] ); 19 | exit( 1 ); 20 | } 21 | } 22 | } //validate 23 | 24 | int main( int argc, char * argv[] ) 25 | { 26 | const size_t cmaps = 32; // 64; 27 | void * amaps[ cmaps ]; 28 | bool verbose = ( argc > 1 ); 29 | 30 | printf( "MAP_PRIVATE: %#x\n", MAP_PRIVATE ); 31 | printf( "MAP_ANONYMOUS: %#x\n", MAP_ANONYMOUS ); 32 | printf( "MREMAP_MAYMOVE: %#x\n", MREMAP_MAYMOVE ); 33 | printf( "PROT_READ: %#x\n", PROT_READ ); 34 | printf( "PROT_WRITE: %#x\n", PROT_WRITE ); 35 | 36 | for ( size_t i = 0; i < cmaps; i++ ) 37 | amaps[ i ] = 0; 38 | 39 | for ( size_t i = 0; i < cmaps; i++ ) 40 | { 41 | size_t size = ( i + 1 ) * 4096; 42 | void * p = mmap( 0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 ); 43 | if ( (void *) -1 == p ) 44 | { 45 | printf( "unable to mmap %zu bytes, error %d = %s", size, errno, strerror( errno ) ); 46 | exit( 1 ); 47 | } 48 | if ( verbose ) 49 | printf( "mapped entry %d size %d as %p\n", (int) i, (int) size, p ); 50 | memset( p, i + 'a', size ); 51 | 52 | amaps[ i ] = p; 53 | } 54 | 55 | // free the even entries 56 | 57 | for ( size_t i = 0; i < cmaps; i += 2 ) 58 | { 59 | size_t size = ( i + 1 ) * 4096; 60 | validate( amaps, i, size ); 61 | int result = munmap( amaps[ i ], size ); 62 | if ( -1 == result ) 63 | { 64 | printf( "failed to unmap i %zu, error %d = %s\n", i, errno, strerror( errno ) ); 65 | exit( 1 ); 66 | } 67 | if ( verbose ) 68 | printf( "unmapped size %d as %p\n", (int) size, amaps[ i ] ); 69 | amaps[ i ] = 0; 70 | } 71 | 72 | // reallocate the odd entries to be twice or four times as large as they were 73 | 74 | for ( size_t i = 1; i < cmaps; i += 2 ) 75 | { 76 | size_t size = ( i + 1 ) * 4096; 77 | validate( amaps, i, size ); 78 | size_t new_size = ( i & 2 ) ? 2 * size : 4 * size; 79 | void * p = mremap( amaps[ i ], size, new_size, MREMAP_MAYMOVE ); 80 | if ( (void *) -1 == p ) 81 | { 82 | printf( "unable to mremap %d bytes, error %d = %s\n", (int) size, errno, strerror( errno ) ); 83 | exit( 1 ); 84 | } 85 | if ( verbose ) 86 | printf( "remapped entry %d from size %d to size %d as %p\n", (int) i, (int) size, (int) new_size, p ); 87 | memset( ( (uint8_t *) p ) + size, i + 'a', new_size - size ); // just initialize the new portion 88 | amaps[ i ] = p; 89 | } 90 | 91 | // allocate even entries as 8k each 92 | 93 | for ( size_t i = 0; i < cmaps; i += 2 ) 94 | { 95 | size_t size = 8192; 96 | void * p = mmap( 0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 ); 97 | if ( (void *) -1 == p ) 98 | { 99 | printf( "pass two unable to mmap %zu bytes, error %d = %s\n", size, errno, strerror( errno ) ); 100 | exit( 1 ); 101 | } 102 | if ( verbose ) 103 | printf( "mapped entry %d size %d as %p\n", (int) i, (int) size, p ); 104 | memset( p, i + 'a', size ); 105 | amaps[ i ] = p; 106 | } 107 | 108 | // free all entries 109 | 110 | for ( size_t i = 0; i < cmaps; i++ ) 111 | { 112 | size_t size = ( i + 1 ) * 4096; 113 | size = ( i & 1 ) ? ( i & 2 ) ? 2 * size : 4 * size : 8192; 114 | validate( amaps, i, size ); 115 | int result = munmap( amaps[ i ], size ); 116 | if ( -1 == result ) 117 | { 118 | printf( "failed to unmap i %zu, error %d = %s\n", i, errno, strerror( errno ) ); 119 | exit( 1 ); 120 | } 121 | if ( verbose ) 122 | printf( "unmapped entry %d size %d as %p\n", (int) i, (int) size, amaps[ i ] ); 123 | amaps[ i ] = 0; 124 | } 125 | 126 | printf( "mmap test completed with great success\n" ); 127 | return 0; 128 | } //main 129 | -------------------------------------------------------------------------------- /c_tests/tmuldiv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #if 0 6 | typedef unsigned char uint8_t; 7 | typedef signed char int8_t; 8 | typedef unsigned short uint16_t; 9 | typedef signed short int16_t; 10 | typedef unsigned long uint32_t; 11 | typedef signed long int32_t; 12 | typedef unsigned int uint; 13 | typedef int bool; 14 | enum { false, true }; 15 | #endif 16 | 17 | typedef unsigned int uint; 18 | 19 | #define _noinline __attribute__((noinline)) 20 | 21 | #define ab( x ) ( x < 0 ) ? ( -x ) : ( x ) 22 | 23 | _noinline void test_i8( int8_t i8A, int8_t i8B ) 24 | { 25 | int8_t i8C = i8A * i8B; 26 | printf( "i8 %d * %d: %d\n", (int) i8A, (int) i8B, (int) i8C ); 27 | i8C = i8A % i8B; 28 | printf( "i8 %d %% %d: %d\n", (int) i8A, (int) i8B, (int) i8C ); 29 | i8C = i8A / i8B; 30 | printf( "i8 %d / %d: %d\n", (int) i8A, (int) i8B, (int) i8C ); 31 | } 32 | 33 | _noinline void test_ui8( uint8_t ui8A, uint8_t ui8B ) 34 | { 35 | uint8_t ui8C = ui8A * ui8B; 36 | printf( "ui8 %u * %u: %u\n", (uint) ui8A, (uint) ui8B, (uint) ui8C ); 37 | ui8C = ui8A % ui8B; 38 | printf( "ui8 %u %% %u: %u\n", (uint) ui8A, (uint) ui8B, (uint) ui8C ); 39 | ui8C = ui8A / ui8B; 40 | printf( "ui8 %u / %u: %u\n", (uint) ui8A, (uint) ui8B, (uint) ui8C ); 41 | } 42 | 43 | _noinline void test_i16( int16_t i16A, int16_t i16B ) 44 | { 45 | int16_t i16C = i16A * i16B; 46 | printf( "i16 %d * %d: %d\n", (int) i16A, (int) i16B, (int) i16C ); 47 | i16C = i16A % i16B; 48 | printf( "i16 %d %% %d: %d\n", (int) i16A, (int) i16B, (int) i16C ); 49 | i16C = i16A / i16B; 50 | printf( "i16 %d / %d: %d\n", (int) i16A, (int) i16B, (int) i16C ); 51 | } 52 | 53 | _noinline void test_ui16( uint16_t ui16A, uint16_t ui16B ) 54 | { 55 | uint16_t ui16C = ui16A * ui16B; 56 | printf( "ui16 %u * %u: %u\n", (uint) ui16A, (uint) ui16B, (uint) ui16C ); 57 | ui16C = ui16A % ui16B; 58 | printf( "ui16 %u %% %u: %u\n", (uint) ui16A, (uint) ui16B, (uint) ui16C ); 59 | ui16C = ui16A / ui16B; 60 | printf( "ui16 %u / %u: %u\n", (uint) ui16A, (uint) ui16B, (uint) ui16C ); 61 | } 62 | 63 | _noinline void test_i32( int32_t i32A, int32_t i32B ) 64 | { 65 | int32_t i32C = i32A * i32B; 66 | printf( "i32 %d * %d: %d\n", i32A, i32B, i32C ); 67 | i32C = i32A % i32B; 68 | printf( "i32 %d %% %d: %d\n", i32A, i32B, i32C ); 69 | i32C = i32A / i32B; 70 | printf( "i32 %d / %d: %d\n", i32A, i32B, i32C ); 71 | } 72 | 73 | _noinline void test_ui32( uint32_t ui32A, uint32_t ui32B ) 74 | { 75 | uint32_t ui32C = ui32A * ui32B; 76 | printf( "ui32 %u * %u: %u\n", ui32A, ui32B, ui32C ); 77 | ui32C = ui32A % ui32B; 78 | printf( "ui32 %u %% %u: %u\n", ui32A, ui32B, ui32C ); 79 | ui32C = ui32A / ui32B; 80 | printf( "ui32 %u / %u: %u\n", ui32A, ui32B, ui32C ); 81 | } 82 | 83 | _noinline void test_i64( int64_t i64A, int64_t i64B ) 84 | { 85 | int64_t i64C = i64A * i64B; 86 | printf( "i64 %lld * %lld: %lld\n", i64A, i64B, i64C ); 87 | i64C = i64A % i64B; 88 | printf( "i64 %lld %% %lld: %lld\n", i64A, i64B, i64C ); 89 | i64C = i64A / i64B; 90 | printf( "i64 %lld / %lld: %lld\n", i64A, i64B, i64C ); 91 | } 92 | 93 | _noinline void test_ui64( uint64_t ui64A, uint64_t ui64B ) 94 | { 95 | uint64_t ui64C = ui64A * ui64B; 96 | printf( "ui64 %llu * %llu: %llu\n", ui64A, ui64B, ui64C ); 97 | ui64C = ui64A % ui64B; 98 | printf( "ui64 %llu %% %llu: %llu\n", ui64A, ui64B, ui64C ); 99 | ui64C = ui64A / ui64B; 100 | printf( "ui64 %llu / %llu: %llu\n", ui64A, ui64B, ui64C ); 101 | } 102 | 103 | int main() 104 | { 105 | printf( "app start\n" ); 106 | fflush( stdout ); 107 | 108 | test_i8( (int8_t) 3, (int8_t) 14 ); 109 | test_i8( (int8_t) 17, (int8_t) 14 ); 110 | test_i8( (int8_t) -3, (int8_t) 14 ); 111 | test_i8( (int8_t) -17, (int8_t) 14 ); 112 | test_i8( (int8_t) -3, (int8_t) -14 ); 113 | test_i8( (int8_t) -17, (int8_t) -14 ); 114 | 115 | test_ui8( (uint8_t) 3, (uint8_t) 14 ); 116 | test_ui8( (uint8_t) 17, (uint8_t) 14 ); 117 | test_ui8( (uint8_t) -3, (uint8_t) 14 ); 118 | test_ui8( (uint8_t) -17, (uint8_t) 14 ); 119 | test_ui8( (uint8_t) -3, (uint8_t) -14 ); 120 | test_ui8( (uint8_t) -17, (uint8_t) -14 ); 121 | 122 | test_i16( (int16_t) 3, (int16_t) 14 ); 123 | test_i16( (int16_t) 3700, (int16_t) 14 ); 124 | test_i16( (int16_t) -3, (int16_t) 14 ); 125 | test_i16( (int16_t) -3700, (int16_t) 14 ); 126 | test_i16( (int16_t) -3, (int16_t) -14 ); 127 | test_i16( (int16_t) -3700, (int16_t) -14 ); 128 | 129 | test_ui16( (uint16_t) 3, (uint16_t) 14 ); 130 | test_ui16( (uint16_t) 3700, (uint16_t) 14 ); 131 | test_ui16( (uint16_t) -3, (uint16_t) 14 ); 132 | test_ui16( (uint16_t) -3700, (uint16_t) 14 ); 133 | test_ui16( (uint16_t) -3, (uint16_t) -14 ); 134 | test_ui16( (uint16_t) -3700, (uint16_t) -14 ); 135 | 136 | test_i32( (int32_t) 3, (int32_t) 14 ); 137 | test_i32( (int32_t) 37000, (int32_t) 14 ); 138 | test_i32( (int32_t) -3, (int32_t) 14 ); 139 | test_i32( (int32_t) -37000, (int32_t) 14 ); 140 | test_i32( (int32_t) -3, (int32_t) -14 ); 141 | test_i32( (int32_t) -37000, (int32_t) -14 ); 142 | 143 | test_ui32( (uint32_t) 3, (uint32_t) 14 ); 144 | test_ui32( (uint32_t) 37000, (uint32_t) 14 ); 145 | test_ui32( (uint32_t) -3, (uint32_t) 14 ); 146 | test_ui32( (uint32_t) -37000, (uint32_t) 14 ); 147 | test_ui32( (uint32_t) -3, (uint32_t) -14 ); 148 | test_ui32( (uint32_t) -37000, (uint32_t) -14 ); 149 | 150 | test_i64( (int64_t) 3, (int64_t) 14 ); 151 | test_i64( (int64_t) 370000000, (int64_t) 14 ); 152 | 153 | test_i64( (int64_t) -3, (int64_t) 14 ); 154 | test_i64( (int64_t) -370000000, (int64_t) 14 ); 155 | test_i64( (int64_t) -3, (int64_t) -14 ); 156 | test_i64( (int64_t) -370000000, (int64_t) -14 ); 157 | 158 | test_ui64( (uint64_t) 3, (uint64_t) 14 ); 159 | test_ui64( (uint64_t) 370000000, (uint64_t) 14 ); 160 | test_ui64( (uint64_t) -3, (uint64_t) 14 ); 161 | test_ui64( (uint64_t) -370000000, (uint64_t) 14 ); 162 | test_ui64( (uint64_t) -3, (uint64_t) -14 ); 163 | test_ui64( (uint64_t) -370000000, (uint64_t) -14 ); 164 | 165 | printf( "tmuldiv ended with great success\n" ); 166 | fflush( stdout ); 167 | return 0; 168 | } 169 | 170 | -------------------------------------------------------------------------------- /c_tests/tp.bas: -------------------------------------------------------------------------------- 1 | 1 rem Tic Tac Toe solving app that learns what WOPR learned: you can't win 2 | 2 rem Only three starting positions are examined. Others are just reflections of these 3 | 3 rem b% -- The board 4 | 4 rem al% -- Alpha, for pruning 5 | 5 rem be% -- Beta, for pruning 6 | 6 rem l% -- Top-level loop iteration 7 | 7 rem wi% -- The winning piece (0 none, 1 X, 2, O ) 8 | 8 rem re% -- Resulting score of 4000/minmax board position. 5 draw, 6 X win, 4 Y win 9 | 9 rem sx% -- Stack array for "recursion" X can be P, V, A, or B for those variables. 10 | 10 rem v% -- Value of a board position 11 | 11 rem st% -- Stack Pointer. Even for alpha/beta pruning Minimize plys, Odd for Maximize 12 | 12 rem p% -- Current position where a new piece is played 13 | 14 rem rw% -- Row in the Winner function (2000) 14 | 15 rem cw% -- Column in the Winner function (2000) 15 | 18 rem mc% -- Move count total for debugging. Should be a multiple of 6493 16 | 19 rem Note: Can't use real recursion with GOSUB because stack is limited to roughly 5 deep 17 | 20 rem BASIC doesn't support goto/gosub using arrays for target line numbers 18 | 25 dim b%(9) 19 | 26 dim sp%(10) 20 | 27 dim sv%(10) 21 | 28 dim sa%(10) 22 | 29 dim sb%(10) 23 | 30 mc% = 0 24 | 31 rem print "start time: "; time$ 25 | 32 if 0 <> av% then lo% = av% else lo% = 1 26 | 40 for l% = 1 to lo% 27 | 41 mc% = 0 28 | 42 al% = 2 29 | 43 be% = 9 30 | 44 b%(0) = 1 31 | 45 gosub 4000 32 | 58 al% = 2 33 | 59 be% = 9 34 | 60 b%(0) = 0 35 | 61 b%(1) = 1 36 | 62 gosub 4000 37 | 68 al% = 2 38 | 69 be% = 9 39 | 70 b%(1) = 0 40 | 71 b%(4) = 1 41 | 72 gosub 4000 42 | 73 b%(4) = 0 43 | 74 rem print "mc: "; mc%; " l is "; l% 44 | 80 next l% 45 | 85 print elap$ ; " for "; lo%; " iterations" 46 | 86 rem print "end time: "; time$ 47 | 87 print "final move count "; mc% 48 | 100 end 49 | 50 | 2000 wi% = b%( 0 ) 51 | 2010 if 0 = wi% goto 2100 52 | 2020 if wi% = b%( 1 ) and wi% = b%( 2 ) then return 53 | 2030 if wi% = b%( 3 ) and wi% = b%( 6 ) then return 54 | 2100 wi% = b%( 3 ) 55 | 2110 if 0 = wi% goto 2200 56 | 2120 if wi% = b%( 4 ) and wi% = b%( 5 ) then return 57 | 2200 wi% = b%( 6 ) 58 | 2210 if 0 = wi% goto 2300 59 | 2220 if wi% = b%( 7 ) and wi% = b%( 8 ) then return 60 | 2300 wi% = b%( 1 ) 61 | 2310 if 0 = wi% goto 2400 62 | 2320 if wi% = b%( 4 ) and wi% = b%( 7 ) then return 63 | 2400 wi% = b%( 2 ) 64 | 2410 if 0 = wi% goto 2500 65 | 2420 if wi% = b%( 5 ) and wi% = b%( 8 ) then return 66 | 2500 wi% = b%( 4 ) 67 | 2510 if 0 = wi% then return 68 | 2520 if wi% = b%( 0 ) and wi% = b%( 8 ) then return 69 | 2530 if wi% = b%( 2 ) and wi% = b%( 6 ) then return 70 | 2540 wi% = 0 71 | 2550 return 72 | 73 | 4000 rem minmax function to find score of a board position 74 | 4010 rem recursion is simulated with gotos 75 | 4030 st% = 0 76 | 4040 v% = 0 77 | 4060 re% = 0 78 | 4100 mc% = mc% + 1 79 | 4102 rem gosub 3000 80 | 4104 if st% < 4 then goto 4150 81 | 4105 gosub 2000 82 | 4107 if 0 = wi% then goto 4140 83 | 4110 if wi% = 1 then re% = 6: goto 4280 84 | 4115 re% = 4 85 | 4116 goto 4280 86 | 4140 if st% = 8 then re% = 5: goto 4280 87 | 4150 if st% and 1 then v% = 2 else v% = 9 88 | 4160 p% = 0 89 | 4180 if 0 <> b%(p%) then goto 4500 90 | 4200 if st% and 1 then b%(p%) = 1 else b%(p%) = 2 91 | 4210 sp%(st%) = p% 92 | 4230 sv%(st%) = v% 93 | 4245 sa%(st%) = al% 94 | 4246 sb%(st%) = be% 95 | 4260 st% = st% + 1 96 | 4270 goto 4100 97 | 4280 st% = st% - 1 98 | 4290 p% = sp%(st%) 99 | 4310 v% = sv%(st%) 100 | 4325 al% = sa%(st%) 101 | 4326 be% = sb%(st%) 102 | 4328 b%(p%) = 0 103 | 4330 if st% and 1 then goto 4340 104 | 4331 if re% = 4 then goto 4530 105 | 4332 if re% < v% then v% = re% 106 | 4334 if v% < be% then be% = v% 107 | 4336 if be% <= al% then goto 4520 108 | 4338 goto 4500 109 | 4340 if re% = 6 then goto 4530 110 | 4341 if re% > v% then v% = re% 111 | 4342 if v% > al% then al% = v% 112 | 4344 if al% >= be% then goto 4520 113 | 4500 p% = p% + 1 114 | 4505 if p% < 9 then goto 4180 115 | 4520 re% = v% 116 | 4530 if st% = 0 then return 117 | 4540 goto 4280 118 | 119 | -------------------------------------------------------------------------------- /c_tests/tparity.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | bool is_parity_even8( uint8_t x ) // unused by apps and expensive to compute. 6 | { 7 | #ifdef _M_AMD64 8 | return ( ! ( __popcnt16( x ) & 1 ) ); // less portable, but faster. Not on Q9650 CPU 9 | #elif defined( __APPLE__ ) 10 | return ( ! ( std::bitset<8>( x ).count() & 1 ) ); 11 | #else 12 | printf( "result3\n" ); 13 | return ( ( ~ ( x ^= ( x ^= ( x ^= x >> 4 ) >> 2 ) >> 1 ) ) & 1 ); 14 | #endif 15 | } //is_parity_even8 16 | 17 | int main( int argc, char * argv[] ) 18 | { 19 | uint16_t ui16 = 0x963b; 20 | uint8_t x = (uint8_t) ui16; 21 | bool result = is_parity_even8( x ); 22 | printf( "result for %#x: %d\n", (int) x, (int) result ); 23 | } -------------------------------------------------------------------------------- /c_tests/tphi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | printf( "should tend towards 1.61803398874989484820458683436563811772030\n" ); 7 | const uint64_t limit = 40; 8 | unsigned __int128 prev2 = 1; 9 | unsigned __int128 prev1 = 1; 10 | uint64_t last_shown = 0; 11 | 12 | for ( uint64_t i = 1; i <= limit; i++ ) 13 | { 14 | unsigned __int128 next = prev1 + prev2; 15 | prev2 = prev1; 16 | prev1 = next; 17 | 18 | if ( i == ( last_shown + 5 ) ) 19 | { 20 | last_shown = i; 21 | printf( " at %2u iterations: %.16lf\n", (unsigned int) i, (double) prev1 / (double) prev2 ); 22 | } 23 | } 24 | 25 | printf( "done\n" ); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /c_tests/tpi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | const int HIGH_MARK = 500; // 2800; 6 | int r[HIGH_MARK + 1]; 7 | int i, k; 8 | int b, d; 9 | int iteration; 10 | 11 | const int iterations = 1; 12 | 13 | for ( iteration = 0; iteration < iterations; iteration++ ) { 14 | int c = 0; 15 | 16 | for (i = 0; i < HIGH_MARK; i++) { 17 | r[i] = 2000; 18 | } 19 | 20 | for (k = HIGH_MARK; k > 0; k -= 14) { 21 | d = 0; 22 | 23 | i = k; 24 | for (;;) { 25 | d += r[i] * 10000; 26 | b = 2 * i - 1; 27 | 28 | r[i] = d % b; 29 | d /= b; 30 | i--; 31 | if (i == 0) break; 32 | d *= i; 33 | } 34 | if ( iteration == ( iterations - 1 ) ) 35 | { 36 | int result = c + d / 10000; 37 | if ( result < 1000 ) // workaround for old apple printf bug 38 | printf( "0%.3d", result ); 39 | else 40 | printf( "%.4d", c + d / 10000 ); 41 | fflush( stdout ); 42 | } 43 | c = d % 10000; 44 | } 45 | } 46 | 47 | printf( "\n" ); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /c_tests/tprintf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | void cppreference() // from https://en.cppreference.com/w/c/io/fprintf 8 | { 9 | const char* s = "Hello"; 10 | printf("Strings:\n"); // same as puts("Strings"); 11 | printf(" padding:\n"); 12 | printf("\t[%10s]\n", s); 13 | printf("\t[%-10s]\n", s); 14 | printf("\t[%*s]\n", 10, s); 15 | printf(" truncating:\n"); 16 | printf("\t%.4s\n", s); 17 | printf("\t%.*s\n", 3, s); 18 | 19 | printf("Characters:\t%c %%\n", 'A'); 20 | 21 | printf("Integers:\n"); 22 | printf("\tDecimal:\t%i %d %.6i %i %.0i %+i %i\n", 23 | 1, 2, 3, 0, 0, 4,-4); 24 | printf("\tHexadecimal:\t%x %x %X %#x\n", 5, 10, 10, 6); 25 | printf("\tOctal:\t\t%o %#o %#o\n", 10, 10, 4); 26 | 27 | printf("Floating-point:\n"); 28 | printf("\tRounding:\t%f %.0f %.32f\n", 1.5, 1.5, 1.3); 29 | printf("\tPadding:\t%05.2f %.2f %5.2f\n", 1.5, 1.5, 1.5); 30 | printf("\tScientific:\t%E %e\n", 1.5, 1.5); 31 | printf("\tHexadecimal:\t%a %A\n", 1.5, 1.5); 32 | printf("\tSpecial values:\t0/0=%g 1/0=%g\n", 0.0 / 0.0, 1.0 / 0.0); 33 | 34 | printf("Fixed-width types:\n"); 35 | printf("\tLargest 32-bit value is %" PRIu32 " or %#" PRIx32 "\n", 36 | UINT32_MAX, UINT32_MAX ); 37 | } 38 | 39 | int main( int argc, char * argv[] ) 40 | { 41 | float f = 1.01; 42 | printf( "float: %f\n", f ); 43 | printf( " %3.3f\n", f ); 44 | printf( " %1.1f\n", f ); 45 | printf( " %.4f\n", f ); 46 | printf( " %4.f\n", f ); 47 | 48 | f = -6789.01234; 49 | printf( "float: %f\n", f ); 50 | printf( " %3.3f\n", f ); 51 | printf( " %1.1f\n", f ); 52 | printf( " %.4f\n", f ); 53 | printf( " %4.f\n", f ); 54 | 55 | double d = 1.01; 56 | printf( "double: %lf\n", d ); 57 | printf( " %3.3lf\n", d ); 58 | printf( " %1.1lf\n", d ); 59 | printf( " %.4lf\n", d ); 60 | printf( " %4.lf\n", d ); 61 | printf( " %e\n", d ); 62 | printf( " %a\n", d ); 63 | printf( " %g\n", d ); 64 | 65 | d = -6789.01234; 66 | printf( "double: %lf\n", d ); 67 | printf( " %3.3lf\n", d ); 68 | printf( " %1.1lf\n", d ); 69 | printf( " %.4lf\n", d ); 70 | printf( " %4.lf\n", d ); 71 | printf( " %e\n", d ); 72 | printf( " %a\n", d ); 73 | printf( " %g\n", d ); 74 | 75 | cppreference(); 76 | 77 | return 0; 78 | } -------------------------------------------------------------------------------- /c_tests/tregex.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int match_dos_wildcard( const char *filename, const char *pattern ) 8 | { 9 | if ( strlen( filename ) > 12 ) 10 | return false; 11 | if ( strlen( pattern ) > 12 ) 12 | return false; 13 | 14 | // Convert DOS wildcard pattern to POSIX regex 15 | char regex[ 50 ]; 16 | char *dest = regex; 17 | *dest++ = '^'; 18 | while ( *pattern ) 19 | { 20 | switch ( *pattern ) 21 | { 22 | case '*': 23 | *dest++ = '.'; 24 | *dest++ = '*'; 25 | break; 26 | case '?': 27 | *dest++ = '.'; 28 | break; 29 | case '.': 30 | *dest++ = '\\'; 31 | *dest++ = '.'; 32 | break; 33 | default: 34 | *dest++ = *pattern; 35 | } 36 | pattern++; 37 | } 38 | *dest++ = '$'; 39 | *dest = 0; 40 | 41 | if ( strlen( regex ) > ( 2 + 24 ) ) 42 | { 43 | printf( "regex expanded too much\n" ); 44 | exit( 1 ); 45 | } 46 | 47 | // Compile the regex 48 | regex_t regex_compiled; 49 | int cflags = REG_NOSUB | REG_ICASE; 50 | int reti = regcomp( ®ex_compiled, regex, cflags ); 51 | if ( reti ) 52 | { 53 | printf( "Could not compile regex, error %#x\n", reti ); 54 | exit( 1 ); 55 | } 56 | 57 | // Match the filename against the regex 58 | reti = regexec( ®ex_compiled, filename, 0, 0, 0 ); 59 | regfree( ®ex_compiled ); 60 | return ( 0 == reti ); 61 | } //match_dos_wildcard 62 | 63 | void test( const char * name, const char * pattern, bool expected ) 64 | { 65 | bool match = match_dos_wildcard( name, pattern); 66 | if ( match != expected ) 67 | { 68 | printf( "regex failure. name '%s', pattern '%s', expected %d\n", name, pattern, expected ); 69 | exit( 1 ); 70 | } 71 | } //test 72 | 73 | int main( int argc, char * argv[] ) 74 | { 75 | test( "foo.txt", "f*.txt", true ); 76 | test( "f.txt", "f*.txt", true ); 77 | test( "foo.txt", "f*", true ); 78 | test( "f.txt", "f*.txt", true ); 79 | test( "f", "f*.txt", false ); 80 | test( "foo", "f*.txt", false ); 81 | test( "f.txt", "f*", true ); 82 | test( "f", "f*", true ); 83 | test( "foo", "f*", true ); 84 | test( "foo", "?o?", true ); 85 | test( "foo", "*o?", true ); 86 | test( "foo", "*oo", true ); 87 | test( "foo", "f*oo", true ); 88 | test( "foo", "f?oo", false ); 89 | test( "foo", "*oox", false ); 90 | 91 | test( "foo.txt", "F*.txt", true ); 92 | test( "f.txt", "f*.TXT", true ); 93 | test( "foo.txt", "F*", true ); 94 | test( "f.txt", "F*.TXT", true ); 95 | 96 | test( "foo.pas", "f*.txt", false ); 97 | test( "foo.pas", "*.pas", true ); 98 | test( "foo.PAS", "*.pas", true ); 99 | test( "foo.bas", "*.pas", false ); 100 | test( "fOo.pas", "*.pas", true ); 101 | 102 | test( "f_o.pas", "*.pAs", true ); 103 | test( "zf_____o.pas", "*.pAs", true ); 104 | test( "bar.bab", "*.?A?", true ); 105 | 106 | printf( "regex test completed with great success\n" ); 107 | } //main 108 | -------------------------------------------------------------------------------- /c_tests/trw.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | void show_error( const char * str ) 9 | { 10 | printf( "error: %s, errno: %d\n", str, errno ); 11 | exit( 1 ); 12 | } 13 | 14 | #define BUF_ELEMENTS 32 15 | static short buf[ BUF_ELEMENTS ]; 16 | #define BUF_SIZE ( sizeof( buf ) ) 17 | 18 | int main() 19 | { 20 | int i, j, result; 21 | long int seek_offset, file_offset; 22 | 23 | int fd = open( "trw.dat", O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO ); 24 | if ( -1 == fd ) 25 | show_error( "unable to create data file" ); 26 | 27 | int buf_bytes = sizeof( buf ); 28 | 29 | for ( i = 0; i < 4096; i++ ) 30 | { 31 | for ( j = 0; j < BUF_ELEMENTS; j++ ) 32 | buf[ j ] = i; 33 | 34 | result = write( fd, (char *) buf, buf_bytes ); 35 | if ( buf_bytes != result ) 36 | show_error( "unable to write to file" ); 37 | } 38 | 39 | close( fd ); 40 | 41 | fd = open( "trw.dat", O_RDONLY ); 42 | if ( -1 == fd ) 43 | show_error( "unable to open data file read only" ); 44 | 45 | for ( i = 0; i < 4096; i++ ) 46 | { 47 | result = read( fd, (char *) buf, buf_bytes ); 48 | if ( buf_bytes != result ) 49 | { 50 | printf( "result: %d, i %d\n", result, i ); 51 | show_error( "unable to read from file at point A" ); 52 | } 53 | 54 | for ( j = 0; j < BUF_ELEMENTS; j++ ) 55 | if ( buf[ j ] != i ) 56 | { 57 | printf( "j %d, buf[j] %04x, i %d\n", j, buf[j], i ); 58 | show_error( "data read from file isn't what was expected at point A" ); 59 | } 60 | } 61 | 62 | close( fd ); 63 | 64 | fd = open( "trw.dat", O_RDWR ); //WRONLY ); 65 | if ( -1 == fd ) 66 | show_error( "unable to open data file write only" ); 67 | 68 | for ( i = 0; i < 4096; i++ ) 69 | { 70 | if ( 0 == ( i % 8 ) ) 71 | { 72 | seek_offset = (long int) i * BUF_SIZE; 73 | file_offset = lseek( fd, seek_offset, 0 ); 74 | if ( file_offset != seek_offset ) 75 | { 76 | printf( "file_offset %ld, seek_offset %ld\n", file_offset, seek_offset ); 77 | show_error( "lseek location not as expected" ); 78 | } 79 | 80 | for ( j = 0; j < BUF_ELEMENTS; j++ ) 81 | buf[ j ] = i + 0x4000; 82 | 83 | result = write( fd, (char *) buf, buf_bytes ); 84 | if ( buf_bytes != result ) 85 | show_error( "unable to write to file after lseek" ); 86 | } 87 | } 88 | 89 | close( fd ); 90 | 91 | fd = open( "trw.dat", O_RDONLY ); 92 | if ( -1 == fd ) 93 | show_error( "unable to open data file read only" ); 94 | 95 | for ( i = 4095; i >= 0; i-- ) 96 | { 97 | seek_offset = (long int) i * BUF_SIZE; 98 | file_offset = lseek( fd, seek_offset, 0 ); 99 | if ( file_offset != seek_offset ) 100 | { 101 | printf( "file_offset %ld, seek_offset %ld\n", file_offset, seek_offset ); 102 | show_error( "lseek location not as expected" ); 103 | } 104 | 105 | result = read( fd, (char *) buf, buf_bytes ); 106 | if ( buf_bytes != result ) 107 | show_error( "unable to read from file after lseek" ); 108 | 109 | for ( j = 0; j < BUF_ELEMENTS; j++ ) 110 | { 111 | if ( 0 == ( i % 8 ) ) 112 | { 113 | if ( buf[ j ] != i + 0x4000 ) 114 | show_error( "data read from file isn't what was expected at point B" ); 115 | } 116 | else 117 | { 118 | if ( buf[ j ] != i ) 119 | show_error( "data read from file isn't what was expected at point C" ); 120 | } 121 | } 122 | } 123 | 124 | close( fd ); 125 | 126 | #if 0 127 | result = remove( "trw.dat" ); 128 | if ( 0 != result ) 129 | show_error( "can't unlink test file" ); 130 | #endif 131 | 132 | printf( "trw completed with great success\n" ); 133 | return 0; 134 | } 135 | 136 | -------------------------------------------------------------------------------- /c_tests/ts.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void swap( char & a, char & b ) 7 | { 8 | char c = a; 9 | a = b; 10 | b = c; 11 | } //swap 12 | 13 | void reverse( char str[], int length ) 14 | { 15 | int start = 0; 16 | int end = length - 1; 17 | while ( start < end ) 18 | { 19 | swap( * ( str + start ), * ( str + end ) ); 20 | start++; 21 | end--; 22 | } 23 | } //reverse 24 | 25 | char * ui64toa( uint64_t num, char * str, int base ) 26 | { 27 | int i = 0; 28 | bool isNegative = false; 29 | 30 | if ( 0 == num ) 31 | { 32 | str[i++] = '0'; 33 | str[i] = '\0'; 34 | return str; 35 | } 36 | 37 | if ( num < 0 && 10 == base ) 38 | { 39 | isNegative = true; 40 | num = -num; 41 | } 42 | 43 | while ( 0 != num ) 44 | { 45 | int rem = num % base; 46 | str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0'; 47 | num = num/base; 48 | } 49 | 50 | if (isNegative) 51 | str[i++] = '-'; 52 | 53 | str[i] = '\0'; 54 | 55 | reverse( str, i ); 56 | 57 | return str; 58 | } //ui64toa 59 | 60 | char * ui32toa( uint32_t num, char * str, int base ) 61 | { 62 | int i = 0; 63 | bool isNegative = false; 64 | 65 | if ( 0 == num ) 66 | { 67 | str[i++] = '0'; 68 | str[i] = '\0'; 69 | return str; 70 | } 71 | 72 | if ( num < 0 && 10 == base ) 73 | { 74 | isNegative = true; 75 | num = -num; 76 | } 77 | 78 | while ( 0 != num ) 79 | { 80 | int rem = num % base; 81 | str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0'; 82 | num = num/base; 83 | } 84 | 85 | if (isNegative) 86 | str[i++] = '-'; 87 | 88 | str[i] = '\0'; 89 | 90 | reverse( str, i ); 91 | 92 | return str; 93 | } //ui32toa 94 | 95 | template T myabs( T x ) 96 | { 97 | if ( x < 0 ) 98 | return -x; 99 | return x; 100 | } //myabs 101 | 102 | #if defined( _MSC_VER ) || defined(WIN64) 103 | 104 | extern "C" void riscv_print_text( const char * p ) 105 | { 106 | printf( "%s", p ); 107 | } 108 | #endif 109 | 110 | template void show_result( T x ) 111 | { 112 | if ( 4 == sizeof( T ) ) 113 | printf( "sizeof T: %d, result: %x\n", (int) sizeof( T ), x ); 114 | else 115 | printf( "sizeof T: %d, result: %llx\n", (int) sizeof( T ), x ); 116 | } //show_result 117 | 118 | //#pragma GCC optimize ("O0") 119 | extern "C" int main() 120 | { 121 | printf( "top of app\n" ); 122 | 123 | // uint8_t * pb = (uint8_t *) malloc( 500000 ); 124 | // memset( pb, 0, 500000 ); 125 | // free( pb ); 126 | 127 | printf( "print an int %d\n", (int32_t) 27 ); 128 | printf( "print an int64_t %lld\n", (int64_t) 27 ); 129 | 130 | int8_t i8 = -1; 131 | i8 >>= 1; 132 | show_result( (uint8_t) i8 ); 133 | 134 | uint8_t ui8 = 0xff; 135 | ui8 >>= 1; 136 | show_result( ui8 ); 137 | 138 | int16_t i16 = -1; 139 | i16 >>= 1; 140 | show_result( (uint16_t) i16 ); 141 | 142 | uint16_t ui16 = 0xffff; 143 | ui16 >>= 1; 144 | show_result( ui16 ); 145 | 146 | int32_t i32 = -1; 147 | i32 >>= 1; 148 | show_result( (uint32_t) i32 ); 149 | 150 | uint32_t ui32 = 0xffffffff; 151 | ui32 >>= 1; 152 | show_result( ui32 ); 153 | 154 | int64_t i64 = -1; 155 | i64 >>= 1; 156 | show_result( i64 ); 157 | 158 | uint64_t ui64 = 0xffffffffffffffff; 159 | ui64 >>= 1; 160 | show_result( ui64 ); 161 | 162 | ////////////// 163 | 164 | printf( "now test left shifts\n" ); 165 | 166 | i8 = -1; 167 | i8 <<= 1; 168 | show_result( (uint8_t) i8 ); 169 | 170 | ui8 = 0xff; 171 | ui8 <<= 1; 172 | show_result( ui8 ); 173 | 174 | i16 = -1; 175 | i16 <<= 1; 176 | show_result( (uint16_t) i16 ); 177 | 178 | ui16 = 0xffff; 179 | ui16 <<= 1; 180 | show_result( ui16 ); 181 | 182 | i32 = -1; 183 | i32 <<= 1; 184 | show_result( (uint32_t) i32 ); 185 | 186 | ui32 = 0xffffffff; 187 | ui32 <<= 1; 188 | show_result( ui32 ); 189 | 190 | i64 = -1; 191 | i64 <<= 1; 192 | show_result( i64 ); 193 | 194 | ui64 = 0xffffffffffffffff; 195 | ui64 <<= 1; 196 | show_result( ui64 ); 197 | 198 | ////////////// 199 | 200 | printf( "now test comparisons\n" ); 201 | 202 | bool f0 = i8 == ui8; 203 | bool f1 = i8 > ui8; 204 | bool f2 = i8 >= ui8; 205 | bool f3 = i8 < ui8; 206 | bool f4 = i8 <= ui8; 207 | show_result( f0 | f1 | f2 | f3 | f4 ); 208 | 209 | f0 = i16 == ui16; 210 | f1 = i16 > ui16; 211 | f2 = i16 >= ui16; 212 | f3 = i16 < ui16; 213 | f4 = i16 <= ui16; 214 | show_result( f0 | f1 | f2 | f3 | f4 ); 215 | 216 | f0 = i32 == ui32; 217 | f1 = i32 > ui32; 218 | f2 = i32 >= ui32; 219 | f3 = i32 < ui32; 220 | f4 = i32 <= ui32; 221 | show_result( f0 | f1 | f2 | f3 | f4 ); 222 | 223 | f0 = i64 == ui64; 224 | f1 = i64 > ui64; 225 | f2 = i64 >- ui64; 226 | f3 = i64 < ui64; 227 | f4 = i64 <= ui64; 228 | show_result( f0 | f1 | f2 | f3 | f4 ); 229 | 230 | ////////////// 231 | 232 | f0 = i8 == i16; 233 | f1 = i8 > i16; 234 | f2 = i8 >= i16; 235 | f3 = i8 < i16; 236 | f4 = i8 <= i16; 237 | show_result( f0 | f1 | f2 | f3 | f4 ); 238 | 239 | f0 = i16 == i32; 240 | f1 = i16 > i32; 241 | f2 = i16 >= i32; 242 | f3 = i16 < i32; 243 | f4 = i16 <= i32; 244 | show_result( f0 | f1 | f2 | f3 | f4 ); 245 | 246 | f0 = i32 == i64; 247 | f1 = i32 > i64; 248 | f2 = i32 >= i64; 249 | f3 = i32 < i64; 250 | f4 = i32 <= i64; 251 | show_result( f0 | f1 | f2 | f3 | f4 ); 252 | 253 | f0 = i64 == ui8; 254 | f1 = i64 > ui8; 255 | f2 = i64 >- ui8; 256 | f3 = i64 < ui8; 257 | f4 = i64 <= ui8; 258 | show_result( f0 | f1 | f2 | f3 | f4 ); 259 | 260 | ////////////// 261 | 262 | f0 = i8 == 16; 263 | f1 = i8 > 16; 264 | f2 = i8 >= 16; 265 | f3 = i8 < 16; 266 | f4 = i8 <= 16; 267 | show_result( f0 | f1 | f2 | f3 | f4 ); 268 | 269 | f0 = i16 == 32; 270 | f1 = i16 > 32; 271 | f2 = i16 >= 32; 272 | f3 = i16 < 32; 273 | f4 = i16 <= 32; 274 | show_result( f0 | f1 | f2 | f3 | f4 ); 275 | 276 | f0 = i32 == 64; 277 | f1 = i32 > 64; 278 | f2 = i32 >= 64; 279 | f3 = i32 < 64; 280 | f4 = i32 <= 64; 281 | show_result( f0 | f1 | f2 | f3 | f4 ); 282 | 283 | f0 = i64 == 8; 284 | f1 = i64 > 8; 285 | f2 = i64 >= 8; 286 | f3 = i64 < 8; 287 | f4 = i64 <= 8; 288 | show_result( f0 | f1 | f2 | f3 | f4 ); 289 | 290 | ////////////////// 291 | 292 | printf( "testing printf\n" ); 293 | 294 | printf( " string: '%s'\n", "hello" ); 295 | printf( " char: '%c'\n", 'h' ); 296 | printf( " int: %d, %x\n", 27, 27 ); 297 | printf( " negative int: %d, %x\n", -27, -27 ); 298 | printf( " int64_t: %lld, %llx\n", (int64_t) 27, (int64_t) 27 ); 299 | printf( " negative int64_t: %lld, %llx\n", (int64_t) -27, (int64_t) -27 ); 300 | printf( " float: %f\n", 3.1415729 ); 301 | printf( " negative float: %f\n", -3.1415729 ); 302 | 303 | printf( "stop\n" ); 304 | return 0; 305 | } //main 306 | -------------------------------------------------------------------------------- /c_tests/tsimplef.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main( int argc, char * argv[] ) 8 | { 9 | //syscall( 0x2002, 1 ); 10 | float f = 3.1415927; 11 | printf( "float %f\n", f ); 12 | 13 | float f1 = 2.5f; 14 | float f2 = 3.5f; 15 | float f_mul = f1 * f2; 16 | float f_div = f1 / f2; 17 | float f_add = f1 + f2; 18 | float f_sub = f1 - f2; 19 | printf( "f1 %f * f2 %f = %f\n", f1, f2, f_mul ); 20 | printf( " div = %f\n", f_div ); 21 | printf( " add = %f\n", f_add ); 22 | printf( " sub = %f\n", f_sub ); 23 | 24 | double d1 = 9.72; 25 | double d2 = 13.321; 26 | double d_mul = d1 * d2; 27 | double d_div = d1 / d2; 28 | double d_add = d1 + d2; 29 | double d_sub = d1 - d2; 30 | printf( "d1 %lf * d2 %lf = %lf\n", d1, d2, d_mul ); 31 | printf( " div = %lf\n", d_div ); 32 | printf( " add = %lf\n", d_add ); 33 | printf( " sub = %lf\n", d_sub ); 34 | 35 | unsigned __int128 i128 = 1000; 36 | double d = (double) i128; 37 | printf( "double from int128: %lf\n", d ); 38 | 39 | printf( "tsimplef completed with great success\n"); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /c_tests/tstga.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main( int argc, char * argv[] ) 10 | { 11 | struct termios t = { 0 }; 12 | printf( "sizeof termios: %d\n", (int) sizeof( t ) ); 13 | 14 | memset( &t, 0, sizeof( t ) ); 15 | int result = tcgetattr( 1, &t ); 16 | printf( "result of tcgetattr for stdout: %d\n", result ); 17 | printf( "iflag: %#x\n", t.c_iflag ); 18 | printf( "oflag: %#x\n", t.c_oflag ); 19 | printf( "cflag: %#x\n", t.c_cflag ); 20 | printf( "lflag: %#x\n", t.c_lflag ); 21 | printf( "c_line %#x\n", t.c_line ); 22 | 23 | memset( &t, 0, sizeof( t ) ); 24 | result = tcgetattr( 0, &t ); 25 | printf( "result of tcgetattr for stdin: %d\n", result ); 26 | printf( "iflag: %#x\n", t.c_iflag ); 27 | printf( "oflag: %#x\n", t.c_oflag ); 28 | printf( "cflag: %#x\n", t.c_cflag ); 29 | printf( "lflag: %#x\n", t.c_lflag ); 30 | printf( "c_line %#x\n", t.c_line ); 31 | 32 | printf( "exiting test of tcgetattr\n" ); 33 | return 0; 34 | } -------------------------------------------------------------------------------- /c_tests/tstrlen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char ac[ 4096 ]; 6 | 7 | int main( int argc, char * argv[] ) 8 | { 9 | 10 | for ( int i = 0; i < sizeof( ac ); i++ ) 11 | ac[ i ] = ( 'a' + ( i % 26 ) ); 12 | 13 | for ( int i = 0; i < 1000; i++ ) 14 | { 15 | int start = ( (unsigned int) rand() % 300 ); 16 | int end = 1 + start + ( (unsigned int) rand() % 3000 ); 17 | int len = end - start; 18 | ac[ end ] = 0; 19 | int slen = strlen( ac + start ); 20 | 21 | if ( len != slen ) 22 | { 23 | printf( "iteration %d, len %d, strlen %d, start %d, end %d\n", i, len, slen, start, end ); 24 | exit( 1 ); 25 | } 26 | ac[ end ] = 'E'; 27 | } 28 | 29 | printf( "tstrlen completed with great success\n" ); 30 | return 0; 31 | } -------------------------------------------------------------------------------- /c_tests/ttime.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void show_local_time( const char * ptz ) 7 | { 8 | if ( 0 != ptz ) 9 | { 10 | char * penv = (char *) malloc( strlen( ptz ) + 4 ); 11 | strcpy( penv, "TZ=" ); 12 | strcat( penv, ptz ); 13 | putenv( penv ); 14 | printf( "set tz '%s' ", penv ); 15 | } 16 | 17 | const char * timezoneval = getenv( "TZ" ); 18 | if ( 0 == timezoneval ) 19 | timezoneval = "(null)"; 20 | 21 | time_t tt; 22 | time( &tt ); 23 | struct tm * t = localtime( &tt ); 24 | 25 | printf( "tz: '%s', year: %d, month %d, day %d, hour %d, min %d, sec %d\n", 26 | timezoneval, t->tm_year + 1900, 1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec ); 27 | } //show_local_time 28 | 29 | extern "C" int main() 30 | { 31 | printf( "before TZ is set: "); 32 | show_local_time( 0 ); 33 | printf( "east coast time: "); 34 | show_local_time( "EST+5" ); 35 | printf( "west coast time: "); 36 | show_local_time( "PST+8" ); 37 | printf( "TZ=: "); 38 | show_local_time( "" ); 39 | return 0; 40 | } //main 41 | 42 | 43 | -------------------------------------------------------------------------------- /c_tests/ttt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define ABPrune true 9 | #define WinLosePrune true 10 | #define SCORE_WIN 6 11 | #define SCORE_TIE 5 12 | #define SCORE_LOSE 4 13 | #define SCORE_MAX 9 14 | #define SCORE_MIN 2 15 | #define DefaultIterations 10 16 | 17 | #define PieceX 1 18 | #define PieceO 2 19 | #define PieceBlank 0 20 | 21 | int g_Iterations = DefaultIterations; 22 | 23 | char g_board[ 9 ]; 24 | 25 | char pos0func() 26 | { 27 | char x = g_board[0]; 28 | 29 | if ( ( x == g_board[1] && x == g_board[2] ) || 30 | ( x == g_board[3] && x == g_board[6] ) || 31 | ( x == g_board[4] && x == g_board[8] ) ) 32 | return x; 33 | return PieceBlank; 34 | } 35 | 36 | char pos1func() 37 | { 38 | char x = g_board[1]; 39 | 40 | if ( ( x == g_board[0] && x == g_board[2] ) || 41 | ( x == g_board[4] && x == g_board[7] ) ) 42 | return x; 43 | return PieceBlank; 44 | } 45 | 46 | char pos2func() 47 | { 48 | char x = g_board[2]; 49 | 50 | if ( ( x == g_board[0] && x == g_board[1] ) || 51 | ( x == g_board[5] && x == g_board[8] ) || 52 | ( x == g_board[4] && x == g_board[6] ) ) 53 | return x; 54 | return PieceBlank; 55 | } 56 | 57 | char pos3func() 58 | { 59 | char x = g_board[3]; 60 | 61 | if ( ( x == g_board[4] && x == g_board[5] ) || 62 | ( x == g_board[0] && x == g_board[6] ) ) 63 | return x; 64 | return PieceBlank; 65 | } 66 | 67 | char pos4func() 68 | { 69 | char x = g_board[4]; 70 | 71 | if ( ( x == g_board[0] && x == g_board[8] ) || 72 | ( x == g_board[2] && x == g_board[6] ) || 73 | ( x == g_board[1] && x == g_board[7] ) || 74 | ( x == g_board[3] && x == g_board[5] ) ) 75 | return x; 76 | return PieceBlank; 77 | } 78 | 79 | char pos5func() 80 | { 81 | char x = g_board[5]; 82 | 83 | if ( ( x == g_board[3] && x == g_board[4] ) || 84 | ( x == g_board[2] && x == g_board[8] ) ) 85 | return x; 86 | return PieceBlank; 87 | } 88 | 89 | char pos6func() 90 | { 91 | char x = g_board[6]; 92 | 93 | if ( ( x == g_board[7] && x == g_board[8] ) || 94 | ( x == g_board[0] && x == g_board[3] ) || 95 | ( x == g_board[4] && x == g_board[2] ) ) 96 | return x; 97 | return PieceBlank; 98 | } 99 | 100 | char pos7func() 101 | { 102 | char x = g_board[7]; 103 | 104 | if ( ( x == g_board[6] && x == g_board[8] ) || 105 | ( x == g_board[1] && x == g_board[4] ) ) 106 | return x; 107 | return PieceBlank; 108 | } 109 | 110 | char pos8func() 111 | { 112 | char x = g_board[8]; 113 | 114 | if ( ( x == g_board[6] && x == g_board[7] ) || 115 | ( x == g_board[2] && x == g_board[5] ) || 116 | ( x == g_board[0] && x == g_board[4] ) ) 117 | return x; 118 | return PieceBlank; 119 | } 120 | 121 | typedef char pfunc_t( void ); 122 | 123 | pfunc_t * winner_functions[9] = 124 | { 125 | pos0func, 126 | pos1func, 127 | pos2func, 128 | pos3func, 129 | pos4func, 130 | pos5func, 131 | pos6func, 132 | pos7func, 133 | pos8func, 134 | }; 135 | 136 | char LookForWinner() 137 | { 138 | char p = g_board[0]; 139 | if ( PieceBlank != p ) 140 | { 141 | if ( p == g_board[1] && p == g_board[2] ) 142 | return p; 143 | 144 | if ( p == g_board[3] && p == g_board[6] ) 145 | return p; 146 | } 147 | 148 | p = g_board[3]; 149 | if ( PieceBlank != p && p == g_board[4] && p == g_board[5] ) 150 | return p; 151 | 152 | p = g_board[6]; 153 | if ( PieceBlank != p && p == g_board[7] && p == g_board[8] ) 154 | return p; 155 | 156 | p = g_board[1]; 157 | if ( PieceBlank != p && p == g_board[4] && p == g_board[7] ) 158 | return p; 159 | 160 | p = g_board[2]; 161 | if ( PieceBlank != p && p == g_board[5] && p == g_board[8] ) 162 | return p; 163 | 164 | p = g_board[4]; 165 | if ( PieceBlank != p ) 166 | { 167 | if ( ( p == g_board[0] ) && ( p == g_board[8] ) ) 168 | return p; 169 | 170 | if ( ( p == g_board[2] ) && ( p == g_board[6] ) ) 171 | return p; 172 | } 173 | 174 | return PieceBlank; 175 | } /*LookForWinner*/ 176 | 177 | long g_Moves = 0; 178 | 179 | int MinMax( int alpha, int beta, int depth, int move ) 180 | { 181 | int value; 182 | char pieceMove; 183 | int p, score; 184 | pfunc_t * pf; 185 | 186 | g_Moves++; 187 | 188 | // printf( "moves %ld, %d %d %d %d %d %d %d %d %d, depth %d, move %d, alpha %d, beta %d\n", g_Moves, 189 | // g_board[0], g_board[1], g_board[2], g_board[3], g_board[4], g_board[5], g_board[6], g_board[7], g_board[8], 190 | // depth, move, alpha, beta ); 191 | 192 | if ( depth >= 4 ) 193 | { 194 | #if 0 195 | /* 1 iteration takes 3,825 ms with LookForWinner on a 4.77Mhz 8088 */ 196 | p = LookForWinner(); 197 | #else 198 | /* ...compared to 3,242 ms with function pointers */ 199 | pf = winner_functions[ move ]; 200 | p = (*pf)(); 201 | #endif 202 | 203 | if ( PieceBlank != p ) 204 | { 205 | if ( PieceX == p ) 206 | return SCORE_WIN; 207 | 208 | return SCORE_LOSE; 209 | } 210 | 211 | if ( 8 == depth ) 212 | return SCORE_TIE; 213 | } 214 | 215 | if ( depth & 1 ) 216 | { 217 | value = SCORE_MIN; 218 | pieceMove = PieceX; 219 | } 220 | else 221 | { 222 | value = SCORE_MAX; 223 | pieceMove = PieceO; 224 | } 225 | 226 | for ( p = 0; p < 9; p++ ) 227 | { 228 | if ( PieceBlank == g_board[ p ] ) 229 | { 230 | g_board[p] = pieceMove; 231 | score = MinMax( alpha, beta, depth + 1, p ); 232 | g_board[p] = PieceBlank; 233 | 234 | if ( depth & 1 ) 235 | { 236 | if ( WinLosePrune && SCORE_WIN == score ) 237 | return SCORE_WIN; 238 | 239 | if ( score > value ) 240 | { 241 | value = score; 242 | 243 | if ( ABPrune ) 244 | { 245 | if ( value >= beta ) 246 | return value; 247 | if ( value > alpha ) 248 | alpha = value; 249 | } 250 | } 251 | } 252 | else 253 | { 254 | if ( WinLosePrune && SCORE_LOSE == score ) 255 | return SCORE_LOSE; 256 | 257 | if ( score < value ) 258 | { 259 | value = score; 260 | 261 | if ( ABPrune ) 262 | { 263 | if ( value <= alpha ) 264 | return value; 265 | if ( value < beta ) 266 | beta = value; 267 | } 268 | } 269 | } 270 | } 271 | } 272 | 273 | return value; 274 | } /*MinMax*/ 275 | 276 | int FindSolution( int position ) 277 | { 278 | int times; 279 | 280 | memset( g_board, 0, sizeof g_board ); 281 | g_board[ position ] = PieceX; 282 | 283 | for ( times = 0; times < g_Iterations; times++ ) 284 | MinMax( SCORE_MIN, SCORE_MAX, 0, position ); 285 | 286 | return 0; 287 | } /*FindSolution*/ 288 | 289 | void ttt() 290 | { 291 | FindSolution( 0 ); 292 | FindSolution( 1 ); 293 | FindSolution( 4 ); 294 | } //ttt 295 | 296 | void * TTTThreadProc( void * param ) 297 | { 298 | int x = (int) (long long) param; 299 | FindSolution( x ); 300 | return 0; 301 | } //TTTThreadProc 302 | 303 | #if 0 304 | float elapsed( struct timeval & a, struct timeval & b ) 305 | { 306 | // printf shows floats/doubles off by 3 orders of magnitude 307 | // printf( "a sec %ld, a usec %ld, b sec %ld, b usec %ld\n", a.tv_sec, a.tv_usec, b.tv_sec, b.tv_usec ); 308 | // printf( "printf: secdiff %ld, usecdiff %ld\n", b.tv_sec - a.tv_sec, b.tv_usec - a.tv_usec ); 309 | // rvos_printf( "rvos_printf: secdiff %ld, usecdiff %ld\n", b.tv_sec - a.tv_sec, b.tv_usec - a.tv_usec ); 310 | 311 | int64_t aflat = a.tv_sec * 1000000 + a.tv_usec; 312 | int64_t bflat = b.tv_sec * 1000000 + b.tv_usec; 313 | 314 | int64_t diff = bflat - aflat; 315 | return diff / 1000.0f; 316 | } //elapsed 317 | #endif 318 | 319 | extern int main( int argc, char * argv[] ) 320 | { 321 | printf( "starting...\n" ); 322 | 323 | if ( 2 == argc ) 324 | sscanf( argv[ 1 ], "%d", &g_Iterations ); /* no atoi in MS C 1.0 */ 325 | 326 | // struct timeval tv; 327 | // gettimeofday( &tv, 0 ); 328 | 329 | ttt(); 330 | 331 | // struct timeval tv_after; 332 | // gettimeofday( &tv_after, 0 ); 333 | 334 | // float elap = elapsed( tv, tv_after ); 335 | 336 | printf( "done\n" ); 337 | printf( "%ld moves\n", g_Moves ); 338 | // printf( "%f milliseconds\n", elap ); 339 | fflush( stdout ); 340 | } //main 341 | 342 | 343 | -------------------------------------------------------------------------------- /djl_128.hxx: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // taken from various places on stackoverflow 4 | 5 | #include 6 | 7 | class CMultiply128 8 | { 9 | private: 10 | static uint64_t umul_32_32( uint32_t x, uint32_t y ) { return ( (uint64_t) x ) * y; } 11 | 12 | public: 13 | static void mul_u64_u64( uint64_t *rh, uint64_t *rl, uint64_t x, uint64_t y ) 14 | { 15 | uint32_t xlo = (uint32_t) x; 16 | uint32_t xhi = (uint32_t) ( x >> 32 ); 17 | uint32_t ylo = (uint32_t) y; 18 | uint32_t yhi = (uint32_t) ( y >> 32 ); 19 | 20 | uint64_t m0 = umul_32_32( xlo, ylo ); 21 | uint64_t m1 = umul_32_32( xhi, ylo ); 22 | uint64_t m2 = umul_32_32( xlo, yhi ); 23 | uint64_t m3 = umul_32_32( xhi, yhi ); 24 | m1 += ( m0 >> 32 ); 25 | m3 += ( m2 >> 32 ); 26 | m1 += ( m2 & UINT32_MAX ); 27 | 28 | *rh = m3 + ( m1 >> 32 ); 29 | *rl = ( m1 << 32 ) | ( m0 & UINT32_MAX ); 30 | } //mul_u64_u64 31 | 32 | static void mul_s64_s64( int64_t *rh, int64_t *rl, int64_t x, int64_t y ) 33 | { 34 | mul_u64_u64( (uint64_t *) rh, (uint64_t *) rl, (uint64_t) x, (uint64_t) y ); 35 | 36 | if ( x < 0 ) 37 | *rh -= y; 38 | if ( y < 0 ) 39 | *rh -= x; 40 | } //mul_s64_s64 41 | 42 | static uint64_t mul_u64_u64( uint64_t x, uint64_t y, uint64_t *rh ) 43 | { 44 | uint64_t rl; 45 | mul_u64_u64( rh, &rl, x, y ); 46 | return rl; 47 | } //mul_u64_u64 48 | 49 | static int64_t mul_s64_s64( int64_t x, int64_t y, int64_t *rh ) 50 | { 51 | int64_t rl; 52 | mul_s64_s64( rh, &rl, x, y ); 53 | return rl; 54 | } //mul_s64_s64 55 | }; 56 | -------------------------------------------------------------------------------- /djl_os.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | These are some utilities and abstractions for building on Windows and Linux 3 | */ 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #ifdef _WIN32 12 | 13 | #ifndef UNICODE 14 | #define UNICODE 15 | #endif 16 | #define WIN32_LEAN_AND_MEAN 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define not_inlined __declspec(noinline) 24 | #define force_inlined __forceinline 25 | 26 | inline void sleep_ms( uint64_t ms ) { SleepEx( (DWORD) ms, FALSE ); } 27 | 28 | inline bool file_exists( char const * pfile ) 29 | { 30 | uint32_t attr = GetFileAttributesA( pfile ); 31 | return ( ( INVALID_FILE_ATTRIBUTES != attr ) && ( ! ( FILE_ATTRIBUTE_DIRECTORY & attr ) ) ); 32 | } //file_exists 33 | 34 | inline void bump_thread_priority() { SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST ); } 35 | 36 | inline void set_process_affinity( uint64_t processAffinityMask ) 37 | { 38 | SetProcessAffinityMask( (HANDLE) -1, processAffinityMask ); 39 | } 40 | 41 | #elif defined( WATCOM ) 42 | 43 | #include 44 | #define MAX_PATH 255 45 | #define not_inlined 46 | #define force_inlined __inline 47 | 48 | inline void sleep_ms( uint64_t ms ) {} 49 | 50 | inline bool file_exists( char const * pfile ) 51 | { 52 | FILE * fp = fopen( pfile, "r" ); 53 | bool exists = false; 54 | if ( fp ) 55 | { 56 | fclose( fp ); 57 | exists = true; 58 | } 59 | return exists; 60 | } //file_exists 61 | 62 | inline void bump_thread_priority() {} 63 | inline void set_process_affinity( uint64_t processAffinityMask ) {} 64 | inline int getpid() { return 0; } 65 | #define _countof( X ) ( sizeof( X ) / sizeof( X[0] ) ) 66 | inline void swap( uint8_t & a, uint8_t & b ) { uint8_t c = a; a = b; b = c; } 67 | 68 | #else // Linux, MacOS, etc. 69 | 70 | #if !defined( OLDGCC ) && !defined( M68K ) 71 | #include 72 | #endif 73 | 74 | #ifdef M68K 75 | extern "C" int nanosleep( const struct timespec * duration, struct timespec * rem ); 76 | #endif 77 | 78 | #include 79 | #include 80 | #include 81 | #include 82 | 83 | #define not_inlined __attribute__ ((noinline)) 84 | #define force_inlined inline 85 | 86 | inline void bump_thread_priority() {} 87 | 88 | inline void set_process_affinity( uint64_t processAffinityMask ) 89 | { 90 | #if !defined(__APPLE__) && !defined( OLDGCC ) && !defined( M68K ) 91 | cpu_set_t mask; 92 | CPU_ZERO( &mask ); 93 | 94 | for ( long l = 0; l < 32; l++ ) 95 | { 96 | int b = ( 1 << l ); 97 | if ( 0 != ( b & processAffinityMask ) ) 98 | CPU_SET( l, &mask ); 99 | } 100 | 101 | // this does nothing on WSL 1 or 2 except make you believe it might work until you actually check 102 | int status = sched_setaffinity( 0, sizeof( mask ), &mask ); 103 | #endif 104 | } //set_process_affinity 105 | 106 | template < typename T, size_t N > size_t _countof( T ( & arr )[ N ] ) { return std::extent< T[ N ] >::value; } 107 | #define _stricmp strcasecmp 108 | #define MAX_PATH 1024 109 | 110 | inline char * strupr( char * s ) 111 | { 112 | for ( char * t = s; *t; t++ ) 113 | *t = toupper( *t ); 114 | return s; 115 | } //strupr 116 | 117 | inline char * _strupr( char * s ) { return strupr( s ); } 118 | 119 | inline char * strlwr( char * s ) 120 | { 121 | for ( char * t = s; *t; t++ ) 122 | *t = tolower( *t ); 123 | return s; 124 | } //strlwr 125 | 126 | inline uint64_t _abs64( int64_t x ) { return ( x > 0 ) ? x : -x; } 127 | 128 | inline char * _strlwr( char * s ) { return strlwr( s ); } 129 | 130 | inline void sleep_ms( uint64_t ms ) 131 | { 132 | uint64_t total_ns = ms * 1000000; 133 | long ns = (long) ( total_ns % 1000000000 ); 134 | long sec = (long) ( total_ns / 1000000000 ); 135 | struct timespec ts = { sec, ns }; 136 | 137 | #if !defined( OLDGCC ) 138 | nanosleep( &ts, 0 ); 139 | #endif 140 | } //sleep_ms 141 | 142 | inline bool file_exists( char const * pfile ) 143 | { 144 | FILE * fp = fopen( pfile, "r" ); 145 | bool exists = false; 146 | if ( fp ) 147 | { 148 | fclose( fp ); 149 | exists = true; 150 | } 151 | return exists; 152 | } //file_exists 153 | 154 | #endif 155 | 156 | template inline T get_max( T a, T b ) 157 | { 158 | if ( a > b ) 159 | return a; 160 | return b; 161 | } //get_max 162 | 163 | template inline T get_min( T a, T b ) 164 | { 165 | if ( a < b ) 166 | return a; 167 | return b; 168 | } //get_min 169 | 170 | template inline T round_up( T x, T multiple ) 171 | { 172 | if ( 0 == multiple ) 173 | return x; 174 | 175 | T remainder = x % multiple; 176 | if ( 0 == remainder ) 177 | return x; 178 | 179 | return x + multiple - remainder; 180 | } //round_up 181 | 182 | inline const char * target_platform() 183 | { 184 | #if defined( __riscv ) // g++ on linux 185 | return "riscv"; 186 | #elif defined( __amd64 ) // g++ on linux 187 | return "amd64"; 188 | #elif defined( __aarch64__ ) // g++ on linux 189 | return "arm64"; 190 | #elif defined( _M_AMD64 ) // msft on Windows 191 | return "amd64"; 192 | #elif defined( _M_ARM64 ) // msft on Windows 193 | return "arm64"; 194 | #elif defined( WATCOM ) // WATCOM for 8086 195 | return "8086"; 196 | #elif defined( _M_IX86 ) // msft on Windows 32-bit 197 | return "x86"; 198 | #elif defined( __ARM_32BIT_STATE ) // ARM32 on Raspberry PI (and more) 199 | return "arm32"; 200 | #else 201 | return "(other)"; 202 | #endif 203 | } //target_platform 204 | 205 | inline const char * build_type() 206 | { 207 | #ifdef NDEBUG 208 | return "release"; 209 | #else 210 | return "debug"; 211 | #endif 212 | } //build_type 213 | 214 | inline const char * compiler_used() 215 | { 216 | static char acver[ 100 ]; 217 | 218 | #if defined( __GNUC__ ) 219 | return "g++"; 220 | #elif defined( _MSC_VER ) 221 | snprintf( acver, sizeof( acver ), "msft C++ ver %u", _MSC_VER ); 222 | return acver; 223 | #elif defined( __clang__ ) 224 | return "clang"; 225 | #elif defined( WATCOM ) 226 | return "watcom"; 227 | #else 228 | return "unknown"; 229 | #endif 230 | } //compiler_used 231 | 232 | inline const char * build_platform() 233 | { 234 | #if defined( __APPLE__ ) 235 | return "apple"; 236 | #elif defined( __linux ) 237 | return "linux"; 238 | #elif defined( _WIN32 ) 239 | return "windows"; 240 | #elif defined( WATCOM ) 241 | return "windows"; 242 | #else 243 | return "unknown"; 244 | #endif 245 | } //build_platform 246 | 247 | inline const char * build_string() 248 | { 249 | static char bs[ 320 ]; 250 | snprintf( bs, sizeof( bs ), "Built for %s %s on %c%c %c%c%c %s %s by %s on %s\n", 251 | target_platform(), build_type(), __DATE__[4], __DATE__[5], 252 | __DATE__[0], __DATE__[1], __DATE__[2], &__DATE__[7], __TIME__, compiler_used(), build_platform() ); 253 | return bs; 254 | } //build_string 255 | 256 | #if defined( __GNUC__ ) || defined( __clang__ ) 257 | #define assume_false return( 0 ) // clearly terrible, but this code will never execute. ever. 258 | #define assume_false_return return // clearly terrible, but this code will never execute. ever. 259 | #elif defined( WATCOM ) 260 | #define assume_false return( 0 ) // clearly terrible, but this code will never execute. ever. 261 | #define __assume( x ) 262 | #else 263 | #define assume_false __assume( false ) 264 | #define assume_false_return __assume( false ) 265 | #endif 266 | 267 | inline long portable_filelen( int descriptor ) 268 | { 269 | #ifdef _WIN32 270 | long current = _lseek( descriptor, 0, SEEK_CUR ); 271 | long len = _lseek( descriptor, 0, SEEK_END ); 272 | _lseek( descriptor, current, SEEK_SET ); 273 | #else 274 | long current = lseek( descriptor, 0, SEEK_CUR ); 275 | long len = lseek( descriptor, 0, SEEK_END ); 276 | lseek( descriptor, current, SEEK_SET ); 277 | #endif 278 | return len; 279 | } //portable_filelen 280 | 281 | inline long portable_filelen( FILE * fp ) 282 | { 283 | long current = ftell( fp ); 284 | fseek( fp, 0, SEEK_END ); 285 | long len = ftell( fp ); 286 | fseek( fp, current, SEEK_SET ); 287 | return len; 288 | } //portable_filelen 289 | 290 | inline long portable_filelen( const char * p ) 291 | { 292 | FILE * fp = fopen( p, "r" ); 293 | if ( 0 != fp ) 294 | { 295 | long len = portable_filelen( fp ); 296 | fclose( fp ); 297 | return len; 298 | } 299 | 300 | return 0; 301 | } //portable_filelen 302 | 303 | class CFile 304 | { 305 | private: 306 | FILE * fp; 307 | 308 | public: 309 | CFile( FILE * file ) : fp( file ) {} 310 | ~CFile() { close(); } 311 | FILE * get() { return fp; } 312 | void close() 313 | { 314 | if ( NULL != fp ) 315 | { 316 | fclose( fp ); 317 | fp = NULL; 318 | } 319 | } 320 | }; 321 | 322 | inline char printable( uint8_t x ) 323 | { 324 | if ( x < ' ' || x >= 127 ) 325 | return ' '; 326 | return x; 327 | } //printable 328 | 329 | #if ( ( defined( __clang__ ) || defined( __GNUC__ ) ) && !defined( OLDGCC ) && !defined( M68K ) ) 330 | 331 | inline uint64_t flip_endian64( uint64_t x ) { return __builtin_bswap64( x ); } 332 | inline uint32_t flip_endian32( uint32_t x ) { return __builtin_bswap32( x ); } 333 | inline uint16_t flip_endian16( uint16_t x ) { return __builtin_bswap16( x ); } 334 | 335 | #elif defined( _MSC_VER ) 336 | 337 | inline uint64_t flip_endian64( uint64_t x ) { return _byteswap_uint64( x ); } 338 | inline uint32_t flip_endian32( uint32_t x ) { return _byteswap_ulong( x ); } 339 | inline uint16_t flip_endian16( uint16_t x ) { return _byteswap_ushort( x ); } 340 | 341 | #else 342 | 343 | inline uint64_t flip_endian64( uint64_t x ) 344 | { 345 | return ( ( x & 0xffull ) << 56 ) | ( ( x & 0xff00ull ) << 40 ) | ( ( x & 0xff0000ull ) << 24 ) | ( ( x & 0xff000000ull ) << 8 ) | 346 | ( ( x & 0xff00000000ull ) >> 8 ) | ( ( x & 0xff0000000000ull ) >> 24 ) | ( ( x & 0xff000000000000ull ) >> 40 ) | ( ( x & 0xff00000000000000ull ) >> 56 ); 347 | } //flip_endian64 348 | 349 | inline uint32_t flip_endian32( uint32_t x ) 350 | { 351 | return ( ( x & 0xff ) << 24 ) | ( ( x & 0xff00) << 8 ) | ( ( x & 0xff0000) >> 8 ) | ( ( x & 0xff000000 ) >> 24 ); 352 | } //flip_endian32 353 | 354 | inline uint16_t flip_endian16( uint16_t x ) 355 | { 356 | return ( ( ( x & 0xff00 ) >> 8 ) | ( ( x & 0xff ) << 8 ) ); 357 | } //flip_endian16 358 | 359 | #endif 360 | 361 | -------------------------------------------------------------------------------- /kendryte.ld: -------------------------------------------------------------------------------- 1 | /* 2 | * The MEMORY command describes the location and size of blocks of memory 3 | * in the target. You can use it to describe which memory regions may be 4 | * used by the linker, and which memory regions it must avoid. 5 | */ 6 | MEMORY 7 | { 8 | /* 9 | * Memory with CPU cache. 10 | *6M CPU SRAM 11 | */ 12 | ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = (6 * 1024 * 1024) 13 | /* 14 | * Memory without CPU cache 15 | * 6M CPU SRAM 16 | */ 17 | ram_nocache (wxa!ri) : ORIGIN = 0x40000000, LENGTH = (6 * 1024 * 1024) 18 | } 19 | 20 | PROVIDE( _rom_start = ORIGIN(rom) ); 21 | PROVIDE( _rom_end = ORIGIN(rom) + LENGTH(rom) ); 22 | PROVIDE( _ram_start = ORIGIN(ram) ); 23 | PROVIDE( _ram_end = ORIGIN(ram) + LENGTH(ram) ); 24 | PROVIDE( _io_start = 0x40000000 ); 25 | PROVIDE( _io_end = _io_start + LENGTH(ram) ); 26 | PROVIDE( _stack_size = 1 << 15 ); 27 | 28 | 29 | /* 30 | * The OUTPUT_ARCH command specifies the machine architecture where the 31 | * argument is one of the names used in the Kendryte library. 32 | */ 33 | OUTPUT_ARCH( "riscv" ) 34 | 35 | /* 36 | * The ENTRY command specifies the entry point (ie. first instruction to 37 | * execute). The symbol _start is defined in crt0.S 38 | */ 39 | ENTRY(_start) 40 | 41 | /* 42 | * The GROUP command is special since the listed archives will be 43 | * searched repeatedly until there are no new undefined references. We 44 | * need this since -lc depends on -lgloss and -lgloss depends on -lc. I 45 | * thought gcc would automatically include -lgcc when needed, but 46 | * in this file includes it explicitly here and I was seeing link errors 47 | * without it. 48 | */ 49 | /* GROUP( -lc -lgloss -lgcc ) */ 50 | 51 | /* 52 | * The linker only pays attention to the PHDRS command when generating 53 | * an ELF output file. In other cases, the linker will simply ignore PHDRS. 54 | */ 55 | PHDRS 56 | { 57 | ram_ro PT_LOAD; 58 | ram_init PT_LOAD; 59 | ram PT_NULL; 60 | } 61 | 62 | /* 63 | * This is where we specify how the input sections map to output 64 | * sections. 65 | */ 66 | SECTIONS 67 | { 68 | /* Program code segment, also known as a text segment */ 69 | .text : 70 | { 71 | PROVIDE( _text = ABSOLUTE(.) ); 72 | /* Initialization code segment */ 73 | KEEP( *(.text.start) ) 74 | KEEP( *(.text.systick) ) 75 | *(.text.unlikely .text.unlikely.*) 76 | *(.text.startup .text.startup.*) 77 | /* Normal code segment */ 78 | *(.text .text.*) 79 | *(.gnu.linkonce.t.*) 80 | 81 | . = ALIGN(8); 82 | PROVIDE( _etext = ABSOLUTE(.) ); 83 | } >ram AT>ram :ram_ro 84 | 85 | /* Read-only data segment */ 86 | .rodata : 87 | { 88 | *(.rdata) 89 | *(.rodata .rodata.*) 90 | *(.gnu.linkonce.r.*) 91 | } >ram AT>ram :ram_ro 92 | 93 | . = ALIGN(8); 94 | 95 | /* Init array and fini array */ 96 | .preinit_array : 97 | { 98 | PROVIDE_HIDDEN (__preinit_array_start = .); 99 | KEEP (*(.preinit_array)) 100 | PROVIDE_HIDDEN (__preinit_array_end = .); 101 | } >ram AT>ram :ram_ro 102 | 103 | .init_array : 104 | { 105 | PROVIDE_HIDDEN (__init_array_start = .); 106 | KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 107 | KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) 108 | PROVIDE_HIDDEN (__init_array_end = .); 109 | } >ram AT>ram :ram_ro 110 | 111 | .fini_array : 112 | { 113 | PROVIDE_HIDDEN (__fini_array_start = .); 114 | KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 115 | KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) 116 | PROVIDE_HIDDEN (__fini_array_end = .); 117 | } >ram AT>ram :ram_ro 118 | 119 | .ctors : 120 | { 121 | /* gcc uses crtbegin.o to find the start of 122 | the constructors, so we make sure it is 123 | first. Because this is a wildcard, it 124 | doesn't matter if the user does not 125 | actually link against crtbegin.o; the 126 | linker won't look for a file to match a 127 | wildcard. The wildcard also means that it 128 | doesn't matter which directory crtbegin.o 129 | is in. */ 130 | KEEP (*crtbegin.o(.ctors)) 131 | KEEP (*crtbegin?.o(.ctors)) 132 | /* We don't want to include the .ctor section from 133 | the crtend.o file until after the sorted ctors. 134 | The .ctor section from the crtend file contains the 135 | end of ctors marker and it must be last */ 136 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) 137 | KEEP (*(SORT(.ctors.*))) 138 | KEEP (*(.ctors)) 139 | } >ram AT>ram :ram_ro 140 | 141 | .dtors : 142 | { 143 | KEEP (*crtbegin.o(.dtors)) 144 | KEEP (*crtbegin?.o(.dtors)) 145 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) 146 | KEEP (*(SORT(.dtors.*))) 147 | KEEP (*(.dtors)) 148 | } >ram AT>ram :ram_ro 149 | 150 | . = ALIGN(8); 151 | 152 | .lalign : 153 | { 154 | . = ALIGN(8); 155 | PROVIDE( _data_lma = . ); 156 | } >ram AT>ram :ram_ro 157 | 158 | .dalign : 159 | { 160 | . = ALIGN(8); 161 | PROVIDE( _data = . ); 162 | } >ram AT>ram :ram_init 163 | 164 | . = ALIGN(8); 165 | 166 | /* .data, .sdata and .srodata segment */ 167 | .data : 168 | { 169 | /* Writable data segment (.data segment) */ 170 | *(.data .data.*) 171 | *(.gnu.linkonce.d.*) 172 | /* Have _gp point to middle of sdata/sbss to maximize displacement range */ 173 | . = ALIGN(8); 174 | PROVIDE( __global_pointer$ = ABSOLUTE(.) + 0x800); 175 | /* Writable small data segment (.sdata segment) */ 176 | *(.sdata .sdata.*) 177 | *(.gnu.linkonce.s.*) 178 | /* Read-only small data segment (.srodata segment) */ 179 | . = ALIGN(8); 180 | *(.srodata.cst16) 181 | *(.srodata.cst8) 182 | *(.srodata.cst4) 183 | *(.srodata.cst2) 184 | *(.srodata .srodata.*) 185 | /* Align _edata to cache line size */ 186 | . = ALIGN(64); 187 | PROVIDE( _edata = ABSOLUTE(.) ); 188 | } >ram AT>ram :ram_init 189 | 190 | /* .bss and .sbss segment */ 191 | .bss : 192 | { 193 | PROVIDE( _bss = ABSOLUTE(.) ); 194 | /* Writable uninitialized small data segment (.sbss segment)*/ 195 | *(.sbss .sbss.*) 196 | *(.gnu.linkonce.sb.*) 197 | *(.scommon) 198 | /* Uninitialized writeable data section (.bss segment)*/ 199 | *(.bss .bss.*) 200 | *(.gnu.linkonce.b.*) 201 | *(COMMON) 202 | 203 | . = ALIGN(8); 204 | PROVIDE( _ebss = ABSOLUTE(.) ); 205 | } >ram AT>ram :ram 206 | 207 | PROVIDE( _tls_data = ABSOLUTE(.) ); 208 | /* 209 | * Thread Local Storage (TLS) are per-thread global variables. 210 | * Compilers such as GCC provide a __thread keyword to mark global 211 | * variables as per-thread. Support is required in the program loader 212 | * and thread creator. 213 | */ 214 | 215 | /* Thread-local data segment, .tdata (initialized tls). */ 216 | .tdata : 217 | { 218 | KEEP( *(.tdata.begin) ) 219 | *(.tdata .tdata.*) 220 | *(.gnu.linkonce.td.*) 221 | KEEP( *(.tdata.end) ) 222 | } >ram AT>ram :ram 223 | 224 | /* Thread-local bss segment, .tbss (zero-initialized tls). */ 225 | .tbss : 226 | { 227 | *(.tbss .tbss.*) 228 | *(.gnu.linkonce.tb.*) 229 | KEEP( *(.tbss.end) ) 230 | } >ram AT>ram :ram 231 | 232 | /* 233 | * End of uninitalized data segement 234 | * 235 | * Actually the stack needs 16B alignment, and it won't hurt to also slightly 236 | * increase the alignment to 32 or even 64 (cache line size). 237 | * 238 | * Align _heap_start to cache line size 239 | */ 240 | . = ALIGN(64); 241 | PROVIDE( _end = ABSOLUTE(.) ); 242 | /* Leave 2 holes for stack & TLS, the size can set in kconfig */ 243 | PROVIDE( _heap_start = ABSOLUTE(.) + _stack_size * 2 ); 244 | PROVIDE( _tp0 = (_end + 63) & (-64) ); 245 | PROVIDE( _tp1 = _tp0 + _stack_size ); 246 | PROVIDE( _sp0 = _tp0 + _stack_size ); 247 | PROVIDE( _sp1 = _tp1 + _stack_size ); 248 | 249 | /* Heap end is at the end of memory, the memory size can set in kconfig */ 250 | PROVIDE( _heap_end = _ram_end ); 251 | } 252 | 253 | -------------------------------------------------------------------------------- /linuxem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define emulator_sys_rand 0x2000 4 | #define emulator_sys_print_double 0x2001 5 | #define emulator_sys_trace_instructions 0x2002 6 | #define emulator_sys_exit 0x2003 7 | #define emulator_sys_print_text 0x2004 8 | #define emulator_sys_get_datetime 0x2005 9 | #define emulator_sys_print_int64 0x2006 10 | #define emulator_sys_print_char 0x2007 11 | 12 | // Linux syscall numbers differ by ISA. InSAne. These are RISC and ARM64, which are the same! 13 | // Note that there are differences between these two sets. which is correct? 14 | // https://marcin.juszkiewicz.com.pl/download/tables/syscalls.html 15 | // https://github.com/westerndigitalcorporation/RISC-V-Linux/blob/master/linux/arch/s390/kernel/syscalls/syscall.tbl 16 | // https://blog.xhyeax.com/2022/04/28/arm64-syscall-table/ 17 | // https://syscalls.mebeim.net/?table=arm64/64/aarch64/latest 18 | 19 | #define SYS_getcwd 17 20 | #define SYS_fcntl 25 21 | #define SYS_ioctl 29 22 | #define SYS_mkdirat 34 23 | #define SYS_unlinkat 35 24 | #define SYS_renameat 38 25 | #define SYS_faccessat 48 26 | #define SYS_chdir 49 27 | #define SYS_openat 56 28 | #define SYS_close 57 29 | #define SYS_getdents64 61 30 | #define SYS_lseek 62 31 | #define SYS_read 63 32 | #define SYS_write 64 33 | #define SYS_writev 66 34 | #define SYS_pselect6 72 // or sigsuspend? 35 | #define SYS_ppoll_time32 73 36 | #define SYS_readlinkat 78 37 | #define SYS_newfstatat 79 38 | #define SYS_newfstat 80 39 | #define SYS_fsync 82 40 | #define SYS_fdatasync 83 41 | #define SYS_exit 93 42 | #define SYS_exit_group 94 43 | #define SYS_set_tid_address 96 44 | #define SYS_futex 98 45 | #define SYS_set_robust_list 99 46 | #define SYS_clock_gettime 113 47 | #define SYS_clock_nanosleep 115 48 | #define SYS_sched_setaffinity 122 49 | #define SYS_sched_getaffinity 123 50 | #define SYS_sched_yield 124 51 | #define SYS_tgkill 131 52 | #define SYS_signalstack 132 53 | #define SYS_sigaction 134 54 | #define SYS_rt_sigprocmask 135 55 | #define SYS_times 153 56 | #define SYS_uname 160 57 | #define SYS_getrusage 165 58 | #define SYS_prctl 167 59 | #define SYS_gettimeofday 169 60 | #define SYS_getpid 172 61 | #define SYS_getuid 174 62 | #define SYS_geteuid 175 63 | #define SYS_getgid 176 64 | #define SYS_getegid 177 65 | #define SYS_gettid 178 66 | #define SYS_sysinfo 179 67 | #define SYS_brk 214 68 | #define SYS_munmap 215 69 | #define SYS_mremap 216 70 | #define SYS_clone 220 71 | #define SYS_mmap 222 72 | #define SYS_mprotect 226 73 | #define SYS_madvise 233 74 | #define SYS_riscv_flush_icache 259 // not in docs; may be riscv only 75 | #define SYS_prlimit64 261 76 | #define SYS_renameat2 276 77 | #define SYS_getrandom 278 78 | #define SYS_rseq 293 79 | 80 | // open apparently undefined for riscv? the old RISC-V64 g++ compiler/runtime uses these syscalls 81 | 82 | #define SYS_open 1024 83 | #define SYS_link 1025 84 | #define SYS_unlink 1026 85 | #define SYS_mkdir 1030 86 | #define SYS_stat 1038 87 | #define SYS_lstat 1039 88 | #define SYS_time 1062 89 | 90 | // structs passed to syscalls. 91 | 92 | extern uint64_t swap_endian64( uint64_t x ); 93 | extern uint32_t swap_endian32( uint32_t x ); 94 | extern uint16_t swap_endian16( uint16_t x ); 95 | 96 | struct linux_timeval 97 | { 98 | uint64_t tv_sec; // time_t 99 | uint64_t tv_usec; // suseconds_t 100 | }; 101 | 102 | #pragma pack( push, 1 ) 103 | struct linux_timeval32 104 | { 105 | uint64_t tv_sec; // time_t 106 | uint32_t tv_usec; 107 | }; 108 | #pragma pack(pop) 109 | 110 | struct timespec_syscall 111 | { 112 | uint64_t tv_sec; 113 | uint64_t tv_nsec; 114 | 115 | void swap_endianness() 116 | { 117 | tv_sec = swap_endian64( tv_sec ); 118 | tv_nsec = swap_endian64( tv_nsec ); 119 | } 120 | }; 121 | 122 | struct linux_timeval_syscall 123 | { 124 | uint64_t tv_sec; // time_t 125 | uint64_t tv_usec; // suseconds_t 126 | }; 127 | 128 | struct linux_tms_syscall 129 | { 130 | uint64_t tms_utime; 131 | uint64_t tms_stime; 132 | uint64_t tms_cutime; 133 | uint64_t tms_cstime; 134 | }; 135 | 136 | struct linux_tms_syscall32 137 | { 138 | uint32_t tms_utime; 139 | uint32_t tms_stime; 140 | uint32_t tms_cutime; 141 | uint32_t tms_cstime; 142 | }; 143 | 144 | struct stat_linux_syscall 145 | { 146 | /* 147 | struct stat info run on a 64-bit RISC-V system 148 | sizeof s: 128 149 | offset size field 150 | 0 8 st_dev 151 | 8 8 st_ino 152 | 16 4 st_mode 153 | 20 4 st_nlink 154 | 24 4 st_uid 155 | 28 4 st_gid 156 | 32 8 st_rdev 157 | 48 8 st_size 158 | 56 4 st_blksize 159 | 64 8 st_blocks 160 | 72 16 st_atim 161 | 88 16 st_mtim 162 | 104 16 st_ctim 163 | 120 8 st_mystery_spot_2 164 | */ 165 | 166 | uint64_t st_dev; /* ID of device containing file */ 167 | uint64_t st_ino; /* Inode number */ 168 | uint32_t st_mode; /* File type and mode */ 169 | uint32_t st_nlink; /* Number of hard links */ 170 | uint32_t st_uid; /* User ID of owner */ 171 | uint32_t st_gid; /* Group ID of owner */ 172 | uint64_t st_rdev; /* Device ID (if special file) */ 173 | uint64_t st_mystery_spot; 174 | uint64_t st_size; /* Total size, in bytes */ 175 | uint64_t st_blksize; /* Block size for filesystem I/O */ 176 | uint64_t st_blocks; /* Number of 512 B blocks allocated */ 177 | 178 | /* Since POSIX.1-2008, this structure supports nanosecond 179 | precision for the following timestamp fields. 180 | For the details before POSIX.1-2008, see VERSIONS. */ 181 | 182 | struct timespec_syscall st_atim; /* Time of last access */ 183 | struct timespec_syscall st_mtim; /* Time of last modification */ 184 | struct timespec_syscall st_ctim; /* Time of last status change */ 185 | 186 | uint64_t st_mystery_spot_2; 187 | 188 | void swap_endianness() 189 | { 190 | st_dev = swap_endian64( st_dev ); 191 | st_ino = swap_endian64( st_ino ); 192 | st_mode = swap_endian32( st_mode ); 193 | st_nlink = swap_endian32( st_nlink ); 194 | st_uid = swap_endian32( st_uid ); 195 | st_gid = swap_endian32( st_gid ); 196 | st_rdev = swap_endian64( st_rdev ); 197 | st_mystery_spot = swap_endian64( st_mystery_spot ); 198 | st_size = swap_endian64( st_size ); 199 | st_blksize = swap_endian64( st_blksize ); 200 | st_blocks = swap_endian64( st_blocks ); 201 | st_atim.swap_endianness(); 202 | st_mtim.swap_endianness(); 203 | st_ctim.swap_endianness(); 204 | } 205 | }; 206 | 207 | #pragma warning(disable: 4200) // 0-sized array 208 | struct linux_dirent64_syscall 209 | { 210 | uint64_t d_ino; /* Inode number */ 211 | uint64_t d_off; /* Offset to next linux_dirent */ 212 | uint16_t d_reclen; /* Length of this linux_dirent */ 213 | uint8_t d_type; /* DT_DIR (4) if a dir, DT_REG (8) if a regular file */ 214 | char d_name[]; 215 | /* optional and not implemented. must be 0-filled 216 | char pad 217 | char d_type 218 | */ 219 | 220 | void swap_endianness() 221 | { 222 | d_ino = swap_endian64( d_ino ); 223 | d_off = swap_endian64( d_off ); 224 | d_reclen = swap_endian16( d_reclen ); 225 | } 226 | }; 227 | 228 | struct linux_rusage_syscall 229 | { 230 | struct linux_timeval ru_utime; /* user CPU time used */ 231 | struct linux_timeval ru_stime; /* system CPU time used */ 232 | long ru_maxrss; /* maximum resident set size */ 233 | long ru_ixrss; /* integral shared memory size */ 234 | long ru_idrss; /* integral unshared data size */ 235 | long ru_isrss; /* integral unshared stack size */ 236 | long ru_minflt; /* page reclaims (soft page faults) */ 237 | long ru_majflt; /* page faults (hard page faults) */ 238 | long ru_nswap; /* swaps */ 239 | long ru_inblock; /* block input operations */ 240 | long ru_oublock; /* block output operations */ 241 | long ru_msgsnd; /* IPC messages sent */ 242 | long ru_msgrcv; /* IPC messages received */ 243 | long ru_nsignals; /* signals received */ 244 | long ru_nvcsw; /* voluntary context switches */ 245 | long ru_nivcsw; /* involuntary context switches */ 246 | }; 247 | 248 | struct linux_rusage_syscall32 249 | { 250 | struct linux_timeval32 ru_utime; /* user CPU time used */ 251 | struct linux_timeval32 ru_stime; /* system CPU time used */ 252 | long ru_maxrss; /* maximum resident set size */ 253 | long ru_ixrss; /* integral shared memory size */ 254 | long ru_idrss; /* integral unshared data size */ 255 | long ru_isrss; /* integral unshared stack size */ 256 | long ru_minflt; /* page reclaims (soft page faults) */ 257 | long ru_majflt; /* page faults (hard page faults) */ 258 | long ru_nswap; /* swaps */ 259 | long ru_inblock; /* block input operations */ 260 | long ru_oublock; /* block output operations */ 261 | long ru_msgsnd; /* IPC messages sent */ 262 | long ru_msgrcv; /* IPC messages received */ 263 | long ru_nsignals; /* signals received */ 264 | long ru_nvcsw; /* voluntary context switches */ 265 | long ru_nivcsw; /* involuntary context switches */ 266 | }; 267 | 268 | struct pollfd_syscall 269 | { 270 | int fd; 271 | short events; 272 | short revents; 273 | }; 274 | 275 | #define SYS_NMLN 65 // appears to be true for Arm64. 276 | 277 | struct utsname_syscall 278 | { 279 | /** The information returned by uname(). */ 280 | /** The OS name. "Linux" on Android. */ 281 | char sysname[SYS_NMLN]; 282 | 283 | /** The name on the network. Typically "localhost" on Android. */ 284 | char nodename[SYS_NMLN]; 285 | 286 | /** The OS release. Typically something like "4.4.115-g442ad7fba0d" on Android. */ 287 | char release[SYS_NMLN]; 288 | 289 | /** The OS version. Typically something like "#1 SMP PREEMPT" on Android. */ 290 | char version[SYS_NMLN]; 291 | 292 | /** The hardware architecture. Typically "aarch64" on Android. */ 293 | char machine[SYS_NMLN]; 294 | 295 | /** The domain name set by setdomainname(). Typically "localdomain" on Android. */ 296 | char domainname[SYS_NMLN]; 297 | }; 298 | 299 | #define local_KERNEL_NCCS 19 300 | struct local_kernel_termios 301 | { 302 | uint32_t c_iflag; /* input mode flags */ 303 | uint32_t c_oflag; /* output mode flags */ 304 | uint32_t c_cflag; /* control mode flags */ 305 | uint32_t c_lflag; /* local mode flags */ 306 | uint8_t c_line; /* line discipline */ 307 | uint8_t c_cc[local_KERNEL_NCCS]; /* control characters */ 308 | 309 | void swap_endianness() 310 | { 311 | c_iflag = swap_endian32( c_iflag ); 312 | c_oflag = swap_endian32( c_oflag ); 313 | c_cflag = swap_endian32( c_cflag ); 314 | c_lflag = swap_endian32( c_lflag ); 315 | } 316 | }; 317 | 318 | -------------------------------------------------------------------------------- /m.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cl /DRVOS /nologo rvos.cxx riscv.cxx /I. /EHsc /DDEBUG /O2 /Oi /Fa /Qpar /Zi /link /OPT:REF user32.lib 3 | 4 | 5 | -------------------------------------------------------------------------------- /m.sh: -------------------------------------------------------------------------------- 1 | g++ -DRVOS -O3 -fno-builtin -I . rvos.cxx riscv.cxx -o rvos -static 2 | -------------------------------------------------------------------------------- /make_s.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | path=C:\Users\david\OneDrive\riscv-gcc\bin;%path% 5 | path=C:\Users\david\OneDrive\riscv-gcc\bin\riscv64-unknown-elf;%path% 6 | path=c:\users\david\onedrive\riscv-gcc\riscv64-unknown-elf\bin;%path% 7 | path=C:\Users\david\OneDrive\riscv-gcc\bin\libexec\gcc\riscv64-unknown-elf\8.2.0;%path% 8 | 9 | as -a=%1.lst -mabi=lp64f -march=rv64imaf -fpic %1.s -o %1.o 10 | as -a=riscv_shell.lst -mabi=lp64f -march=rv64imaf -fpic riscv_shell.s -o riscv_shell.o 11 | 12 | riscv64-unknown-elf-g++ ^ 13 | -mcmodel=medany -mabi=lp64f -march=rv64imaf -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields ^ 14 | -fno-zero-initialized-in-bss -Os -ggdb -nostartfiles -static -Wl,--gc-sections -Wl,-static -Wl,--whole-archive -Wl,--no-whole-archive ^ 15 | -Wl,-EL -Wl,--no-relax -T "kendryte.ld" "riscv_shell.o" "%1.o" -o "%1.elf" -Wl,--start-group -lgcc -lm -lc -Wl,-lgcc -lm -lc -Wl,--end-group 16 | 17 | -------------------------------------------------------------------------------- /mariscv.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | path=C:\Users\david\OneDrive\riscv-gcc\bin;%path% 5 | path=C:\Users\david\OneDrive\riscv-gcc\bin\riscv64-unknown-elf;%path% 6 | path=c:\users\david\onedrive\riscv-gcc\riscv64-unknown-elf\bin;%path% 7 | path=C:\Users\david\OneDrive\riscv-gcc\bin\libexec\gcc\riscv64-unknown-elf\8.2.0;%path% 8 | 9 | rem RVC is instruction compression for risc-v -- 16 bit compact-opcodes for many 32-bit opcodes 10 | rem set RVCFLAG=c 11 | 12 | rem COND_EXTENSION: if set, apps use RISC-V extension conditional move and conditional return instructions 13 | rem as -a=%1.lst -mabi=lp64f -march=rv64imaf%RVCFLAG% -fpic %1.s -o %1.o 14 | as -a=%1.lst --defsym COND_EXTENSION=1 -mabi=lp64f -march=rv64imaf%RVCFLAG% -fpic %1.s -o %1.o 15 | 16 | as -a=rvos_shell.lst -mabi=lp64f -march=rv64imaf%RVCFLAG% --defsym DEFINESTART=1 -fpic rvos_shell.s -o rvos_shell.o 17 | 18 | riscv64-unknown-elf-g++ ^ 19 | -mcmodel=medany -mabi=lp64f -march=rv64imaf%RVCFLAG% -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields ^ 20 | -fno-zero-initialized-in-bss -Os -ggdb -nostartfiles -static -Wl,--gc-sections -Wl,-static -Wl,--whole-archive -Wl,--no-whole-archive ^ 21 | -Wl,-EL -Wl,--no-relax "rvos_shell.o" "%1.o" -o "%1.elf" -Wl,--start-group -lgcc -lm -lc -Wl,-lgcc -lm -lc -Wl,--end-group 22 | 23 | -------------------------------------------------------------------------------- /marm64.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | del rvos.exe 3 | del rvos.pdb 4 | @echo on 5 | 6 | rem cl /nologo rvos.cxx riscv.cxx /I . /MT /Ot /Ox /Ob2 /Oi /Qpar /O2 /EHac /Zi /DNDEBUG /link ntdll.lib /OPT:REF 7 | cl /nologo rvos.cxx riscv.cxx /I . /MT /Ot /Ox /Ob2 /Oi /Qpar /O2 /EHac /Zi /DDEBUG /link ntdll.lib user32.lib /OPT:REF 8 | 9 | -------------------------------------------------------------------------------- /marm64r.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | del rvos.exe 3 | del rvos.pdb 4 | @echo on 5 | 6 | cl /nologo rvos.cxx riscv.cxx /MT /Ot /Ox /Ob2 /Oi /Qpar /O2 /EHac /Zi /DNDEBUG /link ntdll.lib user32.lib /OPT:REF 7 | 8 | -------------------------------------------------------------------------------- /mg.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | g++ -O3 -ggdb -D _MSC_VER rvos.cxx riscv.cxx -I ../djl -D DEBUG -o rvosg.exe -static 5 | 6 | 7 | -------------------------------------------------------------------------------- /mgr.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | rem can't use -Ofast because NaN support won't work 5 | g++ -O3 -ggdb -D RVOS -D _MSC_VER rvos.cxx riscv.cxx -I ../djl -D NDEBUG -o rvosg.exe -static 6 | 7 | 8 | -------------------------------------------------------------------------------- /minimal.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | SPIClass spi_(SPI0); // MUST be SPI0 for Maix series on board LCD 4 | Sipeed_ST7789 lcd(320, 240, spi_); 5 | 6 | extern "C" int bamain( void ); 7 | 8 | extern "C" void rvos_print_text( const char * pc ) 9 | { 10 | int y = lcd.getCursorY(); 11 | if ( ( y + 8 ) >= lcd.height() ) 12 | { 13 | lcd.fillScreen( COLOR_BLACK ); 14 | lcd.setCursor( 0, 0 ); 15 | } 16 | 17 | lcd.print( pc ); 18 | } //rvos_print_text 19 | 20 | void setup() 21 | { 22 | lcd.begin( 15000000, COLOR_BLACK ); // frequency and fill with red 23 | 24 | bamain(); 25 | } 26 | 27 | void loop() 28 | { 29 | while ( true ); 30 | } 31 | -------------------------------------------------------------------------------- /mmac.sh: -------------------------------------------------------------------------------- 1 | g++ -DRVOS -O3 -fno-builtin -I . rvos.cxx riscv.cxx -o rvos 2 | -------------------------------------------------------------------------------- /mr.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cl /DRVOS /W4 /wd4996 /nologo rvos.cxx riscv.cxx /I. /EHsc /DNDEBUG /GS- /GL /Ot /Ox /Ob3 /Oi /Qpar /Zi /Fa /FAs /link /OPT:REF user32.lib 3 | 4 | -------------------------------------------------------------------------------- /mr.sh: -------------------------------------------------------------------------------- 1 | # must use -O3 not -Ofast so NAN works 2 | g++ -DRVOS -flto -O3 -D NDEBUG -fno-builtin -I . rvos.cxx riscv.cxx -o rvos -static 3 | -------------------------------------------------------------------------------- /mrcl.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | path=c:\program files\microsoft visual studio\2022\community\vc\tools\llvm\x64\bin;%path% 4 | 5 | rem can't use -Ofast because Nan support won't work 6 | clang++ -DRVOS -DNDEBUG -Wno-psabi -I . -x c++ rvos.cxx riscv.cxx -o rvoscl.exe -O3 -static -fsigned-char -Wno-format -std=c++14 -Wno-deprecated-declarations -luser32.lib 7 | -------------------------------------------------------------------------------- /mrmac.sh: -------------------------------------------------------------------------------- 1 | g++ -DRVOS -flto -O3 -D NDEBUG -fno-builtin -I . rvos.cxx riscv.cxx -o rvos 2 | -------------------------------------------------------------------------------- /mrvos.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | rem -O Set optimization level to . 5 | rem -Ofast Optimize for speed disregarding exact standards compliance. 6 | rem -Og Optimize for debugging experience rather than speed or size. 7 | rem -Os Optimize for space rather than speed. 8 | 9 | set OPTFLAGS=-Ofast 10 | 11 | path=C:\Users\david\OneDrive\riscv-gcc\bin;%path% 12 | path=C:\Users\david\OneDrive\riscv-gcc\bin\riscv64-unknown-elf;%path% 13 | path=c:\users\david\onedrive\riscv-gcc\riscv64-unknown-elf\bin;%path% 14 | path=C:\Users\david\OneDrive\riscv-gcc\bin\libexec\gcc\riscv64-unknown-elf\8.2.0;%path% 15 | 16 | rem RVC is instruction compression for risc-v -- 16 bit compact-opcodes for many 32-bit opcodes 17 | set RVCFLAG=c 18 | 19 | riscv64-unknown-elf-g++ ^ 20 | rvos.cxx riscv.cxx ^ 21 | -I . -I ..\djl -D DEBUG -D OLDGCC ^ 22 | -mcmodel=medany -mabi=lp64f -march=rv64imaf%RVCFLAG% -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields ^ 23 | -fno-zero-initialized-in-bss %OPTFLAGS% -ggdb -static -Wl,--gc-sections -Wl,-static -Wl,--whole-archive -Wl,--no-whole-archive ^ 24 | -Wl,-EL -Wl,--no-relax -T "rvos.ld" ^ 25 | "tests\rvosutil.o" "tests\rvos_shell.o" ^ 26 | -o "rvos.elf" -Wl,--start-group -lgcc -lm -lc -Wl,-lgcc -lm -lc -Wl,--end-group 27 | 28 | 29 | -------------------------------------------------------------------------------- /mrvoself.sh: -------------------------------------------------------------------------------- 1 | #riscv64-unknown-linux-gnu-c++ -fno-builtin -Ofast -I . -ggdb -mcmodel=medany -mabi=lp64d -march=rv64imad rvos.cxx riscv.cxx -o rvos.elf -static --entry _start 2 | 3 | riscv64-unknown-linux-gnu-c++ -fno-builtin -I . -ggdb -mcmodel=medany -mabi=lp64d -march=rv64imadc rvos.cxx riscv.cxx -o rvos.elf -static -------------------------------------------------------------------------------- /mrvoselfr.sh: -------------------------------------------------------------------------------- 1 | #riscv64-unknown-linux-gnu-c++ -fno-builtin -Ofast -I . -ggdb -mcmodel=medany -mabi=lp64d -march=rv64imad rvos.cxx riscv.cxx -o rvos.elf -static --entry _start 2 | 3 | riscv64-unknown-linux-gnu-c++ -Ofast -D NDEBUG -fno-builtin -I . -ggdb -mcmodel=medany -mabi=lp64d -march=rv64imadc rvos.cxx riscv.cxx -o rvos.elf -static -------------------------------------------------------------------------------- /mrvosr.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | rem -O Set optimization level to . 5 | rem -Ofast Optimize for speed disregarding exact standards compliance. 6 | rem -Og Optimize for debugging experience rather than speed or size. 7 | rem -Os Optimize for space rather than speed. 8 | 9 | set OPTFLAGS=-Ofast 10 | 11 | path=C:\Users\david\OneDrive\riscv-gcc\bin;%path% 12 | path=C:\Users\david\OneDrive\riscv-gcc\bin\riscv64-unknown-elf;%path% 13 | path=c:\users\david\onedrive\riscv-gcc\riscv64-unknown-elf\bin;%path% 14 | path=C:\Users\david\OneDrive\riscv-gcc\bin\libexec\gcc\riscv64-unknown-elf\8.2.0;%path% 15 | 16 | rem RVC is instruction compression for risc-v -- 16 bit compact-opcodes for many 32-bit opcodes 17 | set RVCFLAG=c 18 | 19 | riscv64-unknown-elf-g++ ^ 20 | rvos.cxx riscv.cxx ^ 21 | -I . -I ..\djl -D NDEBUG -D OLDGCC ^ 22 | -mcmodel=medany -mabi=lp64f -march=rv64imaf%RVCFLAG% -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields ^ 23 | -fno-zero-initialized-in-bss %OPTFLAGS% -ggdb -static -Wl,--gc-sections -Wl,-static -Wl,--whole-archive -Wl,--no-whole-archive ^ 24 | -Wl,-EL -Wl,--no-relax -T "rvos.ld" ^ 25 | "tests\rvosutil.o" "tests\rvos_shell.o" ^ 26 | -o "rvos.elf" -Wl,--start-group -lgcc -lm -lc -Wl,-lgcc -lm -lc -Wl,--end-group 27 | 28 | 29 | -------------------------------------------------------------------------------- /runall.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | if "%1" == "" (set _runcmd=rvos -h:100) else (set _runcmd=%1 -h:100 ) 5 | if "%1" == "armos" (set _runcmd="..\armos\armos" -h:160 ..\armos\bin\rvos -h:100 ) 6 | if "%1" == "armoscl" (set _runcmd="..\armos\armoscl" -h:160 ..\armos\bin\rvoscl -h:100 ) 7 | if "%1" == "m68" (set _runcmd="..\m68\m68" -h:160 ..\m68\rvos\rvos -h:100 ) 8 | if "%1" == "nested" (set _runcmd=rvos -h:160 bin\rvos -h:100 ) 9 | 10 | set outputfile=runall_windows_test.txt 11 | echo %date% %time% >%outputfile% 12 | 13 | set _folderlist=bin0 bin1 bin2 bin3 binfast 14 | set _applist=tcmp t e printint sieve simple tmuldiv tpi ts ttt tarray tbits trw ^ 15 | tmmap tstr fileops ttime tm glob tap tsimplef tf td terrno ^ 16 | t_setjmp tex mm tao pis ttypes nantst sleeptm tatomic lenum tregex 17 | set _optlist=6 8 a d 3 i I m o r x 18 | 19 | ( for %%f in (%_folderlist%) do ( call :folderRun %%f ) ) 20 | 21 | set _rustfolders=bin0 bin1 bin2 bin3 22 | 23 | ( for %%f in (%_rustfolders%) do ( call :rustfolder %%f ) ) 24 | 25 | echo test ntvao 26 | echo test ntvao >>%outputfile% 27 | %_runcmd% bin\ntvao -c ttt1.hex >>%outputfile% 28 | 29 | echo test ntvcm 30 | echo test ntvcm >>%outputfile% 31 | %_runcmd% bin\ntvcm tttcpm.com >>%outputfile% 32 | 33 | echo test ntvdm 34 | echo test ntvdm >>%outputfile% 35 | %_runcmd% bin\ntvdm tttmasm.exe 1 >>%outputfile% 36 | 37 | echo test rvos 38 | echo test rvos >>%outputfile% 39 | %_runcmd% bin\rvos ttt.elf 1 >>%outputfile% 40 | 41 | echo test armos 42 | echo test armos >>%outputfile% 43 | %_runcmd% bin\armos ttt_arm64 1 >>%outputfile% 44 | 45 | echo %date% %time% >>%outputfile% 46 | diff baseline_%outputfile% %outputfile% 47 | 48 | goto :allDone 49 | 50 | :folderRun 51 | 52 | ( for %%a in (%_applist%) do ( call :appRun c_tests\%%f\%%a ) ) 53 | 54 | echo test c_tests\%~1\an 55 | echo test c_tests\%~1\an >>%outputfile% 56 | call :anTest c_tests\%~1 57 | 58 | echo test c_tests\%~1\ba 59 | echo test c_tests\%~1\ba >>%outputfile% 60 | call :baTest c_tests\%~1 61 | 62 | exit /b 0 63 | 64 | :appRun 65 | echo test %~1 66 | echo test %~1 >>%outputfile% 67 | %_runcmd% %~1 >>%outputfile% 68 | exit /b /o 69 | 70 | :rustRun 71 | echo test %~1 72 | echo test %~1 >>%outputfile% 73 | %_runcmd% %~1 >>%outputfile% 74 | exit /b /o 75 | 76 | :rustfolder 77 | set _rustlist=e ttt fileops ato tap real tphi mysort tmm 78 | ( for %%a in (%_rustlist%) do ( call :rustRun rust_tests\%%f\%%a ) ) 79 | exit /b /o 80 | 81 | :anTest 82 | %_runcmd% %~1\an david lee >>%outputfile% 83 | exit /b /o 84 | 85 | :baTest 86 | %_runcmd% %~1\ba tp.bas >>%outputfile% 87 | ( for %%o in (%_optlist%) do ( %_runcmd% %~1\ba -a:%%o -x tp.bas >>%outputfile% ) ) 88 | exit /b /o 89 | 90 | :allDone 91 | 92 | 93 | -------------------------------------------------------------------------------- /runall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | _rvoscmd="rvos" 4 | if [ "$1" = "nested" ]; then 5 | _rvoscmd="rvos -h:200 bin/rvos" 6 | elif [ "$1" = "rvoscl" ]; then 7 | _rvoscmd="rvoscl -h:200" 8 | elif [ "$1" = "armos" ]; then 9 | _rvoscmd="../ArmOS/armos -h:200 ../ArmOS/bin/rvos -h:100" 10 | elif [ "$1" = "armoscl" ]; then 11 | _rvoscmd="../ArmOS/armoscl -h:200 ../ArmOS/bin/rvos -h:100" 12 | elif [ "$1" = "m68" ]; then 13 | _rvoscmd="../m68/m68 -h:200 ../m68/rvos/rvos -h:100" 14 | fi 15 | 16 | outputfile="runall_linux_test.txt" 17 | date_time=$(date) 18 | echo "$date_time" >$outputfile 19 | 20 | for arg in tcmp t e printint sieve simple tmuldiv tpi ts tarray tbits trw tmmap tstr \ 21 | fileops ttime tm glob tap tsimplef tphi tf ttt td terrno t_setjmp tex \ 22 | mm tao pis ttypes nantst sleeptm tatomic lenum tregex; 23 | do 24 | echo $arg 25 | for opt in 0 1 2 3 fast; 26 | do 27 | echo c_tests/bin$opt/$arg >>$outputfile 28 | $_rvoscmd c_tests/bin$opt/$arg >>$outputfile 29 | done 30 | done 31 | 32 | echo test AN 33 | for opt in 0 1 2 3 fast; 34 | do 35 | echo c_tests/bin$opt/an david lee >>$outputfile 36 | $_rvoscmd c_tests/bin$opt/an david lee >>$outputfile 37 | done 38 | 39 | echo test BA 40 | for opt in 0 1 2 3 fast; 41 | do 42 | echo c_tests/bin$opt/ba c_tests/tp.bas >>$outputfile 43 | $_rvoscmd c_tests/bin$opt/ba c_tests/tp.bas >>$outputfile 44 | for codegen in 6 8 a d 3 i I m o r x; 45 | do 46 | $_rvoscmd c_tests/bin$opt/ba -a:$codegen -x c_tests/tp.bas >>$outputfile 47 | done 48 | done 49 | 50 | for arg in e ttt fileops ato tap real tphi mysort tmm; 51 | do 52 | echo $arg 53 | for opt in 0 1 2 3; 54 | do 55 | echo rust_tests/bin$opt/$arg >>$outputfile 56 | $_rvoscmd rust_tests/bin$opt/$arg >>$outputfile 57 | done 58 | done 59 | 60 | date_time=$(date) 61 | echo "$date_time" >>$outputfile 62 | diff baseline_$outputfile $outputfile 63 | -------------------------------------------------------------------------------- /rust_tests/acos.rs: -------------------------------------------------------------------------------- 1 | fn main() 2 | { 3 | let r32 : f32 = 1.0 / 3.14159; 4 | //println!( "r32: {}", r32 ); 5 | let r32acos : f32 = r32.acos(); 6 | println!( "r32 acos: {}", r32acos ); 7 | } //main 8 | 9 | -------------------------------------------------------------------------------- /rust_tests/e.rs: -------------------------------------------------------------------------------- 1 | const DIGITS_TO_FIND: usize = 200; //9009; 2 | 3 | fn main() 4 | { 5 | println!( "testing finding e" ); 6 | let mut limit: usize = DIGITS_TO_FIND; 7 | let mut x: usize = 0; 8 | let mut a: [ usize; DIGITS_TO_FIND ] = [ 1; DIGITS_TO_FIND ]; 9 | 10 | a[1] = 2; 11 | a[0] = 0; 12 | while limit > 9 { 13 | limit = limit - 1; 14 | let mut n: usize = limit; 15 | while 0 != n { 16 | a[n] = x % n; 17 | x = 10 * a[ n - 1 ] + x / n; 18 | n = n - 1; 19 | } 20 | print!( "{}", x ); 21 | } 22 | 23 | println!( "\nexiting finding e with great success" ); 24 | } //main 25 | 26 | -------------------------------------------------------------------------------- /rust_tests/fileops.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidly/rvos/bb04161987b5abeb3a97eb3d2d2e1d604f053226/rust_tests/fileops.dat -------------------------------------------------------------------------------- /rust_tests/fileops.rs: -------------------------------------------------------------------------------- 1 | use std::process; 2 | use std::fs::File; 3 | use std::io::Read; 4 | use std::io::Write; 5 | use std::io::Seek; 6 | use std::io::SeekFrom; 7 | 8 | fn main() -> std::io::Result<()> 9 | { 10 | let block_count = 128; 11 | let block_len = 256; 12 | let data_len = 128; 13 | let mut data : Vec = Vec::with_capacity( data_len ); 14 | let mut val: u8 = 0x10; 15 | 16 | for _i in 0..data_len { 17 | data.push( val ); 18 | } 19 | 20 | { 21 | let mut test_file = File::create( "fileops.dat" )?; 22 | 23 | for _o in 0..block_count { 24 | test_file.seek( SeekFrom::Start( _o * block_len ) )?; 25 | 26 | val += 1; 27 | for _i in 0..data_len { 28 | data[ _i ] = val; 29 | } 30 | 31 | test_file.write_all( &data )?; 32 | test_file.flush()?; 33 | } 34 | } 35 | 36 | { 37 | val = 0x91; 38 | let mut test_file = File::open( "fileops.dat" )?; 39 | 40 | for _o in (0..block_count).rev() { 41 | test_file.seek( SeekFrom::Start( _o * block_len ) )?; 42 | 43 | val -= 1; 44 | test_file.read_exact( & mut data )?; 45 | 46 | for _i in 0..data_len { 47 | if val != data[ _i ] { 48 | println!( "data value at _o {} and _i {}: {} isn't {}", _o, _i, data[ _i ], val ); 49 | process::exit( 0 ); 50 | } 51 | } 52 | } 53 | } 54 | 55 | println!( "exiting fileops with great success" ); 56 | Ok(()) 57 | } 58 | 59 | -------------------------------------------------------------------------------- /rust_tests/m.bat: -------------------------------------------------------------------------------- 1 | rem rustc --emit asm -O %1.rs 2 | rustc --edition 2021 -O %1.rs 3 | 4 | -------------------------------------------------------------------------------- /rust_tests/m.sh: -------------------------------------------------------------------------------- 1 | rustc --edition 2021 --emit asm -O $1.rs 2 | rustc --edition 2021 -O -C target-feature=+crt-static $1.rs 3 | -------------------------------------------------------------------------------- /rust_tests/mall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | for arg in ato e fileops mysort real tap td tphi ttt tmm; 5 | do 6 | echo $arg 7 | 8 | for optflag in 0 1 2 3; 9 | do 10 | mkdir bin"$optflag" 2>/dev/null 11 | rustc --edition 2021 --out-dir bin"$optflag" -C overflow-checks=off -C opt-level="$optflag" -C target-feature=+crt-static "$arg".rs 12 | done 13 | done 14 | 15 | -------------------------------------------------------------------------------- /rust_tests/mysort.rs: -------------------------------------------------------------------------------- 1 | 2 | use std::fs::File; 3 | use std::io::{BufReader, BufRead, Write}; 4 | 5 | fn main() -> std::io::Result<()> 6 | { 7 | let mut vec = vec![]; 8 | 9 | { 10 | let file_in = File::open( "words.txt" )?; 11 | let reader = BufReader::new( file_in ); 12 | 13 | for line in reader.lines() { 14 | let line = line?; 15 | if line.len() > 0 { 16 | vec.push( line ); 17 | } 18 | } 19 | } 20 | 21 | println!( "element count in vector: {}", vec.len() ); 22 | 23 | vec.sort(); 24 | vec.dedup(); 25 | 26 | println!( "element count after dedup: {}", vec.len() ); 27 | 28 | let mut file_out = File::create( "sorted.txt" )?; 29 | 30 | for n in 0..vec.len()-1 { 31 | write!( file_out, "{}\n", vec[ n ] )?; 32 | } 33 | 34 | file_out.sync_data()?; 35 | 36 | Ok(()) 37 | } 38 | -------------------------------------------------------------------------------- /rust_tests/real.rs: -------------------------------------------------------------------------------- 1 | fn main() 2 | { 3 | println!( "testing real number operations" ); 4 | 5 | let r32 : f32 = 1.0 / 3.14159; 6 | println!( "r32: {}", r32 ); 7 | let r64 : f64 = 1.0 / 2.71828; 8 | println!( "r64: {}", r64 ); 9 | 10 | let r32sin : f32 = r32.sin(); 11 | println!( "r32 sin: {}", r32sin ); 12 | let r64sin : f64 = r64.sin(); 13 | println!( "r64 sin: {}", r64sin ); 14 | 15 | let r32cos : f32 = r32.cos(); 16 | println!( "r32 cos: {}", r32cos ); 17 | let r64cos : f64 = r64.cos(); 18 | println!( "r64 cos: {}", r64cos ); 19 | 20 | let r32tan : f32 = r32.tan(); 21 | println!( "r32 tan: {}", r32tan ); 22 | let r64tan : f64 = r64.tan(); 23 | println!( "r64 tan: {}", r64tan ); 24 | 25 | let r32asin : f32 = r32.asin(); 26 | println!( "r32 asin: {}", r32asin ); 27 | let r64asin : f64 = r64.asin(); 28 | println!( "r64 asin: {}", r64asin ); 29 | 30 | let r32acos : f32 = r32.acos(); 31 | println!( "r32 acos: {}", r32acos ); 32 | let r64acos : f64 = r64.acos(); 33 | println!( "r64 acos: {}", r64acos ); 34 | 35 | let r32atan : f32 = r32.atan(); 36 | println!( "r32 atan: {}", r32atan ); 37 | let r64atan : f64 = r64.atan(); 38 | println!( "r64 atan: {}", r64atan ); 39 | 40 | let mut _r32x : f32 = 1.6666666666667; 41 | for x in 0..=800 42 | { 43 | _r32x += x as f32 / 200f32; 44 | _r32x *= 1.002020202; 45 | } 46 | 47 | let mut _r64x : f64 = 1.6666666666667; 48 | for x in 0..=800 49 | { 50 | _r64x += x as f64 / 200f64; 51 | _r64x *= 1.002020202; 52 | } 53 | 54 | println!( "_r32x = {_r32x}" ); 55 | println!( "_r64x = {_r64x}" ); 56 | _r64x += _r32x as f64; 57 | println!( "sum: = {_r64x}" ); 58 | 59 | let mut r32_total : f32 = 0.0; 60 | let mut r64_total : f64 = 0.0; 61 | let mut r32_loop : f32 = 0.05; 62 | let mut r64_loop : f64 = 0.05; 63 | 64 | for _x in 0..=30 65 | { 66 | r32_loop += 0.104; 67 | r64_loop += 0.104; 68 | r32_total += r32_loop.sin(); 69 | r64_total += r64_loop.sin(); 70 | r32_total += r32_loop.cos(); 71 | r64_total += r64_loop.cos(); 72 | r32_total += r32_loop.tan(); 73 | r64_total += r64_loop.tan(); 74 | } 75 | 76 | println!( "32 total {}, 64 total {}", r32_total, r64_total ); 77 | println!( "exiting real number testing with great success" ); 78 | } //main 79 | 80 | -------------------------------------------------------------------------------- /rust_tests/rvfeat.rs: -------------------------------------------------------------------------------- 1 | use std::arch::is_riscv_feature_detected; 2 | 3 | //macro_rules! is_riscv_feature_detected { 4 | // ("rv32i") => { ... }; 5 | // ("zifencei") => { ... }; 6 | // ("zihintpause") => { ... }; 7 | // ("rv64i") => { ... }; 8 | // ("m") => { ... }; 9 | // ("a") => { ... }; 10 | // ("zicsr") => { ... }; 11 | // ("zicntr") => { ... }; 12 | // ("zihpm") => { ... }; 13 | // ("f") => { ... }; 14 | // ("d") => { ... }; 15 | // ("q") => { ... }; 16 | // ("c") => { ... }; 17 | // ("zfinx") => { ... }; 18 | // ("zdinx") => { ... }; 19 | // ("zhinx") => { ... }; 20 | // ("zhinxmin") => { ... }; 21 | // ("ztso") => { ... }; 22 | // ("rv32e") => { ... }; 23 | // ("rv128i") => { ... }; 24 | // ("zfh") => { ... }; 25 | // ("zfhmin") => { ... }; 26 | // ("b") => { ... }; 27 | // ("j") => { ... }; 28 | // ("p") => { ... }; 29 | // ("v") => { ... }; 30 | // ("zam") => { ... }; 31 | // ("s") => { ... }; 32 | // ("svnapot") => { ... }; 33 | // ("svpbmt") => { ... }; 34 | // ("svinval") => { ... }; 35 | // ("h") => { ... }; 36 | // ("zba") => { ... }; 37 | // ("zbb") => { ... }; 38 | // ("zbc") => { ... }; 39 | // ("zbs") => { ... }; 40 | // ("zbkb") => { ... }; 41 | // ("zbkc") => { ... }; 42 | // ("zbkx") => { ... }; 43 | // ("zknd") => { ... }; 44 | // ("zkne") => { ... }; 45 | // ("zknh") => { ... }; 46 | // ("zksed") => { ... }; 47 | // ("zksh") => { ... }; 48 | // ("zkr") => { ... }; 49 | // ("zkn") => { ... }; 50 | // ("zks") => { ... }; 51 | // ("zk") => { ... }; 52 | // ("zkt") => { ... }; 53 | // ($t:tt,) => { ... }; 54 | // ($t:tt) => { ... }; 55 | //} 56 | 57 | fn main() 58 | { 59 | println!( "testing risc-v features" ); 60 | } //main 61 | 62 | -------------------------------------------------------------------------------- /rust_tests/tap.rs: -------------------------------------------------------------------------------- 1 | use std::cmp; 2 | 3 | // don't take a dependency on the rand crate, so it builds with rustc 4 | 5 | extern "C" { 6 | fn srand( seed: usize ); 7 | fn rand() -> usize; 8 | } 9 | 10 | fn my_rand() -> usize { 11 | unsafe { 12 | return rand(); 13 | } 14 | } 15 | 16 | fn my_srand( seed: usize ) { 17 | unsafe { 18 | srand( seed ); 19 | } 20 | } 21 | 22 | fn rand32() -> u32 { 23 | // rand() in the C runtime generally returns numbers <= 32767 24 | 25 | let a : u32 = my_rand() as u32; 26 | let b : u32 = my_rand() as u32; 27 | return a | ( b << 16 ); 28 | } 29 | 30 | fn first_implementation() 31 | { 32 | println!( "first implementation..." ); 33 | 34 | const TOTAL: u64 = 1000000; 35 | let mut sofar: f64 = 0.0; 36 | let mut prev_times_ten: u64 = 10; 37 | let mut _i: u64; 38 | 39 | for _i in 1..TOTAL+1 { 40 | let _f: f64 = _i as f64; 41 | sofar += 1.0 / ( _f * _f * _f ); 42 | 43 | if _i == ( prev_times_ten ) { 44 | prev_times_ten = _i * 10; 45 | println!( " {:<22} at {} iterations", sofar, _i ); 46 | } 47 | } 48 | } //first_implementation 49 | 50 | fn gcd( m: u32, n: u32 ) -> u32 51 | { 52 | let mut a: u32; 53 | let mut b: u32 = cmp::max( m, n ); 54 | let mut r: u32 = cmp::min( m, n ); 55 | 56 | while 0 != r 57 | { 58 | a = b; 59 | b = r; 60 | r = a % b; 61 | } 62 | 63 | return b; 64 | } //gcd 65 | 66 | fn second_implementation() 67 | { 68 | println!( "second implementation..." ); 69 | 70 | my_srand( 0xbaebeabad00bee ); 71 | const TOTAL: u64 = 100000; 72 | let mut total_coprimes: u64 = 0; 73 | let mut prev_times_ten: u64 = 10; 74 | let mut _i: u64; 75 | 76 | for _i in 1..TOTAL+1 { 77 | let a: u32 = rand32(); 78 | let b: u32 = rand32(); 79 | let c: u32 = rand32(); 80 | 81 | let greatest: u32 = gcd( a, gcd( b, c ) ); 82 | if 1 == greatest { 83 | total_coprimes = 1 + total_coprimes; 84 | } 85 | 86 | if _i == ( prev_times_ten ) { 87 | prev_times_ten = _i * 10; 88 | println!( " {:<22} at {} iterations", _i as f64 / total_coprimes as f64, _i ); 89 | } 90 | } 91 | } //second_implementation 92 | 93 | fn main() 94 | { 95 | println!( "starting, should tend towards 1.2020569031595942854..." ); 96 | 97 | first_implementation(); 98 | second_implementation(); 99 | 100 | println!( "exiting finding ap with great success" ); 101 | } //main 102 | 103 | 104 | -------------------------------------------------------------------------------- /rust_tests/td.rs: -------------------------------------------------------------------------------- 1 | fn main() 2 | { 3 | let r64 : f64 = 2.71828; 4 | println!( "r64: {}", r64 ); 5 | println!( "exiting real number testing with great success" ); 6 | } //main 7 | 8 | -------------------------------------------------------------------------------- /rust_tests/tmm.rs: -------------------------------------------------------------------------------- 1 | #![allow(arithmetic_overflow)] 2 | 3 | const ARRAY_DIM: usize = 20; 4 | 5 | /* 6 | use std::ops:: {Add, AddAssign, Mul, MulAssign }; 7 | pub fn matrix_ops() -> T 8 | where 9 | T: Sized + Default + Add, 10 | { 11 | let mut sum: T; 12 | let mut a: [ [ T; ARRAY_DIM ]; ARRAY_DIM ]; 13 | let mut b: [ [ T; ARRAY_DIM ]; ARRAY_DIM ]; 14 | let mut c: [ [ T; ARRAY_DIM ]; ARRAY_DIM ]; 15 | 16 | sum = T::Zero(); 17 | return sum; 18 | } 19 | */ 20 | 21 | fn main() 22 | { 23 | /* 24 | let r64sum: f64 = matrix_ops(); 25 | println!( "sum: {}", r64sum ); 26 | */ 27 | 28 | let mut _x: usize; 29 | let mut _i: usize; 30 | let mut _j: usize; 31 | let mut _k: usize; 32 | 33 | let mut a: [ [ f64; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0.0; ARRAY_DIM ]; ARRAY_DIM ]; 34 | let mut b: [ [ f64; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0.0; ARRAY_DIM ]; ARRAY_DIM ]; 35 | let mut c: [ [ f64; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0.0; ARRAY_DIM ]; ARRAY_DIM ]; 36 | let mut sum: f64 = 0.0; 37 | 38 | let mut af32: [ [ f32; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0.0; ARRAY_DIM ]; ARRAY_DIM ]; 39 | let mut bf32: [ [ f32; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0.0; ARRAY_DIM ]; ARRAY_DIM ]; 40 | let mut cf32: [ [ f32; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0.0; ARRAY_DIM ]; ARRAY_DIM ]; 41 | let mut sumf32: f32 = 0.0; 42 | 43 | let mut au32: [ [ u32; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0; ARRAY_DIM ]; ARRAY_DIM ]; 44 | let mut bu32: [ [ u32; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0; ARRAY_DIM ]; ARRAY_DIM ]; 45 | let mut cu32: [ [ u32; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0; ARRAY_DIM ]; ARRAY_DIM ]; 46 | let mut sumu32: u32 = 0; 47 | 48 | let mut au16: [ [ u16; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0; ARRAY_DIM ]; ARRAY_DIM ]; 49 | let mut bu16: [ [ u16; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0; ARRAY_DIM ]; ARRAY_DIM ]; 50 | let mut cu16: [ [ u16; ARRAY_DIM ]; ARRAY_DIM ] = [ [ 0; ARRAY_DIM ]; ARRAY_DIM ]; 51 | let mut sumu16: u16 = 0; 52 | 53 | for _x in 0..100 { 54 | for _i in 0..ARRAY_DIM { 55 | for _j in 0..ARRAY_DIM { 56 | a[ _i ][ _j ] = ( _i + _j + 2 ) as f64; 57 | } 58 | } 59 | 60 | for _i in 0..ARRAY_DIM { 61 | for _j in 0..ARRAY_DIM { 62 | b[ _i ][ _j ] = ( ( _i + _j + 2 ) / ( _j + 1 ) ) as f64; 63 | } 64 | } 65 | 66 | for _i in 0..ARRAY_DIM { 67 | for _j in 0..ARRAY_DIM { 68 | c[ _i ][ _j ] = 0.0; 69 | } 70 | } 71 | 72 | for _i in 0..ARRAY_DIM { 73 | for _j in 0..ARRAY_DIM { 74 | for _k in 0..ARRAY_DIM { 75 | c[ _i ][ _j ] += a[ _i ][ _k ] * b[ _k ][ _j ]; 76 | } 77 | } 78 | } 79 | 80 | sum = 0.0; 81 | for _i in 0..ARRAY_DIM { 82 | for _j in 0..ARRAY_DIM { 83 | sum += c[ _i ][ _j ]; 84 | } 85 | } 86 | 87 | if 465880.000000 != sum { 88 | println!( "invalid sum found!!" ); 89 | } 90 | 91 | for _i in 0..ARRAY_DIM { 92 | for _j in 0..ARRAY_DIM { 93 | af32[ _i ][ _j ] = ( _i + _j + 2 ) as f32; 94 | } 95 | } 96 | 97 | for _i in 0..ARRAY_DIM { 98 | for _j in 0..ARRAY_DIM { 99 | bf32[ _i ][ _j ] = ( ( _i + _j + 2 ) / ( _j + 1 ) ) as f32; 100 | } 101 | } 102 | 103 | for _i in 0..ARRAY_DIM { 104 | for _j in 0..ARRAY_DIM { 105 | cf32[ _i ][ _j ] = 0.0; 106 | } 107 | } 108 | 109 | for _i in 0..ARRAY_DIM { 110 | for _j in 0..ARRAY_DIM { 111 | for _k in 0..ARRAY_DIM { 112 | cf32[ _i ][ _j ] += af32[ _i ][ _k ] * bf32[ _k ][ _j ]; 113 | } 114 | } 115 | } 116 | 117 | sumf32 = 0.0; 118 | for _i in 0..ARRAY_DIM { 119 | for _j in 0..ARRAY_DIM { 120 | sumf32 += cf32[ _i ][ _j ]; 121 | } 122 | } 123 | 124 | if 465880.000000 != sumf32 { 125 | println!( "invalid sumf32 found!!" ); 126 | } 127 | for _i in 0..ARRAY_DIM { 128 | for _j in 0..ARRAY_DIM { 129 | au32[ _i ][ _j ] = ( _i + _j + 2 ) as u32; 130 | } 131 | } 132 | 133 | for _i in 0..ARRAY_DIM { 134 | for _j in 0..ARRAY_DIM { 135 | bu32[ _i ][ _j ] = ( ( _i + _j + 2 ) / ( _j + 1 ) ) as u32; 136 | } 137 | } 138 | 139 | for _i in 0..ARRAY_DIM { 140 | for _j in 0..ARRAY_DIM { 141 | cu32[ _i ][ _j ] = 0; 142 | } 143 | } 144 | 145 | for _i in 0..ARRAY_DIM { 146 | for _j in 0..ARRAY_DIM { 147 | for _k in 0..ARRAY_DIM { 148 | cu32[ _i ][ _j ] += au32[ _i ][ _k ] * bu32[ _k ][ _j ]; 149 | } 150 | } 151 | } 152 | 153 | sumu32 = 0; 154 | for _i in 0..ARRAY_DIM { 155 | for _j in 0..ARRAY_DIM { 156 | sumu32 += cu32[ _i ][ _j ]; 157 | } 158 | } 159 | 160 | if 465880 != sumu32 { 161 | println!( "invalid sumu32 found!!" ); 162 | } 163 | for _i in 0..ARRAY_DIM { 164 | for _j in 0..ARRAY_DIM { 165 | au16[ _i ][ _j ] = ( _i + _j + 2 ) as u16; 166 | } 167 | } 168 | 169 | for _i in 0..ARRAY_DIM { 170 | for _j in 0..ARRAY_DIM { 171 | bu16[ _i ][ _j ] = ( ( _i + _j + 2 ) / ( _j + 1 ) ) as u16; 172 | } 173 | } 174 | 175 | for _i in 0..ARRAY_DIM { 176 | for _j in 0..ARRAY_DIM { 177 | cu16[ _i ][ _j ] = 0; 178 | } 179 | } 180 | 181 | for _i in 0..ARRAY_DIM { 182 | for _j in 0..ARRAY_DIM { 183 | for _k in 0..ARRAY_DIM { 184 | cu16[ _i ][ _j ] += au16[ _i ][ _k ] * bu16[ _k ][ _j ]; 185 | } 186 | } 187 | } 188 | 189 | sumu16 = 0; 190 | for _i in 0..ARRAY_DIM { 191 | for _j in 0..ARRAY_DIM { 192 | sumu16 += cu16[ _i ][ _j ]; 193 | } 194 | } 195 | 196 | if 7128 != sumu16 { 197 | println!( "invalid sumu16 found!! {}", sumu16 ); 198 | } 199 | } 200 | 201 | println!( "sum f64: {}", sum ); 202 | println!( "sum f32: {}", sumf32 ); 203 | println!( "sum u32: {}", sumu32 ); 204 | println!( "sum u16: {}", sumu16 ); 205 | println!( "exiting matrix multiply testing with great success" ); 206 | } //main 207 | 208 | -------------------------------------------------------------------------------- /rust_tests/tphi.rs: -------------------------------------------------------------------------------- 1 | const LIMIT: u64 = 40; 2 | 3 | fn main() 4 | { 5 | println!( "phi should tend towards 1.61803398874989484820458683436563811772030" ); 6 | let mut prev2: u128 = 1; 7 | let mut prev1: u128 = 1; 8 | let mut last_shown: u64 = 0; 9 | let mut _i: u64; 10 | 11 | for _i in 1..LIMIT+1 { 12 | let next: u128 = prev1 + prev2; 13 | prev2 = prev1; 14 | prev1 = next; 15 | 16 | if _i == ( last_shown + 5 ) 17 | { 18 | last_shown = _i; 19 | println!( " at {:4} iterations: {}", _i, prev1 as f64 / prev2 as f64 ); 20 | } 21 | } 22 | 23 | println!( "exiting finding phi with great success" ); 24 | } 25 | -------------------------------------------------------------------------------- /rvos.ld: -------------------------------------------------------------------------------- 1 | /* 2 | * The MEMORY command describes the location and size of blocks of memory 3 | * in the target. You can use it to describe which memory regions may be 4 | * used by the linker, and which memory regions it must avoid. 5 | */ 6 | MEMORY 7 | { 8 | ram (wxa!ri) : ORIGIN = 0x10000, LENGTH = (1024 * 1024 * 1024) 9 | } 10 | 11 | PROVIDE( _ram_start = ORIGIN(ram) ); 12 | PROVIDE( _ram_end = ORIGIN(ram) + LENGTH(ram) ); 13 | PROVIDE( _stack_size = 1 << 15 ); 14 | 15 | 16 | /* 17 | * The OUTPUT_ARCH command specifies the machine architecture where the 18 | * argument is one of the names used in the Kendryte library. 19 | */ 20 | OUTPUT_ARCH( "riscv" ) 21 | 22 | /* 23 | * The ENTRY command specifies the entry point (ie. first instruction to 24 | * execute). The symbol _start is defined in crt0.S 25 | */ 26 | ENTRY(_start) 27 | 28 | /* 29 | * The GROUP command is special since the listed archives will be 30 | * searched repeatedly until there are no new undefined references. We 31 | * need this since -lc depends on -lgloss and -lgloss depends on -lc. I 32 | * thought gcc would automatically include -lgcc when needed, but 33 | * in this file includes it explicitly here and I was seeing link errors 34 | * without it. 35 | */ 36 | /* GROUP( -lc -lgloss -lgcc ) */ 37 | 38 | /* 39 | * The linker only pays attention to the PHDRS command when generating 40 | * an ELF output file. In other cases, the linker will simply ignore PHDRS. 41 | */ 42 | PHDRS 43 | { 44 | ram_ro PT_LOAD; 45 | ram_init PT_LOAD; 46 | ram PT_NULL; 47 | } 48 | 49 | /* 50 | * This is where we specify how the input sections map to output 51 | * sections. 52 | */ 53 | SECTIONS 54 | { 55 | /* Program code segment, also known as a text segment */ 56 | .text : 57 | { 58 | PROVIDE( _text = ABSOLUTE(.) ); 59 | /* Initialization code segment */ 60 | KEEP( *(.text.start) ) 61 | KEEP( *(.text.systick) ) 62 | *(.text.unlikely .text.unlikely.*) 63 | *(.text.startup .text.startup.*) 64 | /* Normal code segment */ 65 | *(.text .text.*) 66 | *(.gnu.linkonce.t.*) 67 | 68 | . = ALIGN(8); 69 | PROVIDE( _etext = ABSOLUTE(.) ); 70 | } >ram AT>ram :ram_ro 71 | 72 | /* Read-only data segment */ 73 | .rodata : 74 | { 75 | *(.rdata) 76 | *(.rodata .rodata.*) 77 | *(.gnu.linkonce.r.*) 78 | } >ram AT>ram :ram_ro 79 | 80 | . = ALIGN(8); 81 | 82 | /* Init array and fini array */ 83 | .preinit_array : 84 | { 85 | PROVIDE_HIDDEN (__preinit_array_start = .); 86 | KEEP (*(.preinit_array)) 87 | PROVIDE_HIDDEN (__preinit_array_end = .); 88 | } >ram AT>ram :ram_ro 89 | 90 | .init_array : 91 | { 92 | PROVIDE_HIDDEN (__init_array_start = .); 93 | KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 94 | KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) 95 | PROVIDE_HIDDEN (__init_array_end = .); 96 | } >ram AT>ram :ram_ro 97 | 98 | .fini_array : 99 | { 100 | PROVIDE_HIDDEN (__fini_array_start = .); 101 | KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 102 | KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) 103 | PROVIDE_HIDDEN (__fini_array_end = .); 104 | } >ram AT>ram :ram_ro 105 | 106 | .ctors : 107 | { 108 | /* gcc uses crtbegin.o to find the start of 109 | the constructors, so we make sure it is 110 | first. Because this is a wildcard, it 111 | doesn't matter if the user does not 112 | actually link against crtbegin.o; the 113 | linker won't look for a file to match a 114 | wildcard. The wildcard also means that it 115 | doesn't matter which directory crtbegin.o 116 | is in. */ 117 | KEEP (*crtbegin.o(.ctors)) 118 | KEEP (*crtbegin?.o(.ctors)) 119 | /* We don't want to include the .ctor section from 120 | the crtend.o file until after the sorted ctors. 121 | The .ctor section from the crtend file contains the 122 | end of ctors marker and it must be last */ 123 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) 124 | KEEP (*(SORT(.ctors.*))) 125 | KEEP (*(.ctors)) 126 | } >ram AT>ram :ram_ro 127 | 128 | .dtors : 129 | { 130 | KEEP (*crtbegin.o(.dtors)) 131 | KEEP (*crtbegin?.o(.dtors)) 132 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) 133 | KEEP (*(SORT(.dtors.*))) 134 | KEEP (*(.dtors)) 135 | } >ram AT>ram :ram_ro 136 | 137 | . = ALIGN(8); 138 | 139 | .lalign : 140 | { 141 | . = ALIGN(8); 142 | PROVIDE( _data_lma = . ); 143 | } >ram AT>ram :ram_ro 144 | 145 | .dalign : 146 | { 147 | . = ALIGN(8); 148 | PROVIDE( _data = . ); 149 | } >ram AT>ram :ram_init 150 | 151 | . = ALIGN(8); 152 | 153 | /* .data, .sdata and .srodata segment */ 154 | .data : 155 | { 156 | /* Writable data segment (.data segment) */ 157 | *(.data .data.*) 158 | *(.gnu.linkonce.d.*) 159 | /* Have _gp point to middle of sdata/sbss to maximize displacement range */ 160 | . = ALIGN(8); 161 | PROVIDE( __global_pointer$ = ABSOLUTE(.) + 0x800); 162 | /* Writable small data segment (.sdata segment) */ 163 | *(.sdata .sdata.*) 164 | *(.gnu.linkonce.s.*) 165 | /* Read-only small data segment (.srodata segment) */ 166 | . = ALIGN(8); 167 | *(.srodata.cst16) 168 | *(.srodata.cst8) 169 | *(.srodata.cst4) 170 | *(.srodata.cst2) 171 | *(.srodata .srodata.*) 172 | /* Align _edata to cache line size */ 173 | . = ALIGN(64); 174 | PROVIDE( _edata = ABSOLUTE(.) ); 175 | } >ram AT>ram :ram_init 176 | 177 | /* .bss and .sbss segment */ 178 | .bss : 179 | { 180 | PROVIDE( _bss = ABSOLUTE(.) ); 181 | /* Writable uninitialized small data segment (.sbss segment)*/ 182 | *(.sbss .sbss.*) 183 | *(.gnu.linkonce.sb.*) 184 | *(.scommon) 185 | /* Uninitialized writeable data section (.bss segment)*/ 186 | *(.bss .bss.*) 187 | *(.gnu.linkonce.b.*) 188 | *(COMMON) 189 | 190 | . = ALIGN(8); 191 | PROVIDE( _ebss = ABSOLUTE(.) ); 192 | } >ram AT>ram :ram 193 | 194 | PROVIDE( _tls_data = ABSOLUTE(.) ); 195 | /* 196 | * Thread Local Storage (TLS) are per-thread global variables. 197 | * Compilers such as GCC provide a __thread keyword to mark global 198 | * variables as per-thread. Support is required in the program loader 199 | * and thread creator. 200 | */ 201 | 202 | /* Thread-local data segment, .tdata (initialized tls). */ 203 | .tdata : 204 | { 205 | KEEP( *(.tdata.begin) ) 206 | *(.tdata .tdata.*) 207 | *(.gnu.linkonce.td.*) 208 | KEEP( *(.tdata.end) ) 209 | } >ram AT>ram :ram 210 | 211 | /* Thread-local bss segment, .tbss (zero-initialized tls). */ 212 | .tbss : 213 | { 214 | *(.tbss .tbss.*) 215 | *(.gnu.linkonce.tb.*) 216 | KEEP( *(.tbss.end) ) 217 | } >ram AT>ram :ram 218 | 219 | /* 220 | * End of uninitalized data segement 221 | * 222 | * Actually the stack needs 16B alignment, and it won't hurt to also slightly 223 | * increase the alignment to 32 or even 64 (cache line size). 224 | * 225 | * Align _heap_start to cache line size 226 | */ 227 | . = ALIGN(64); 228 | PROVIDE( _end = ABSOLUTE(.) ); 229 | /* Leave 2 holes for stack & TLS, the size can set in kconfig */ 230 | PROVIDE( _heap_start = ABSOLUTE(.) + _stack_size * 2 ); 231 | PROVIDE( _tp0 = (_end + 63) & (-64) ); 232 | PROVIDE( _tp1 = _tp0 + _stack_size ); 233 | PROVIDE( _sp0 = _tp0 + _stack_size ); 234 | PROVIDE( _sp1 = _tp1 + _stack_size ); 235 | 236 | /* Heap end is at the end of memory, the memory size can set in kconfig */ 237 | PROVIDE( _heap_end = _ram_end ); 238 | } 239 | 240 | --------------------------------------------------------------------------------