├── .gitattributes ├── .gitignore ├── 020gen.e ├── CompilerLicense.md ├── EEC-1.0.0-src.readme ├── LICENSE.md ├── ModuleFromFD.e ├── ModuleFromProto.e ├── README.md ├── ToolsLicense.md ├── TrackHit.e ├── assembler.e ├── binary.e ├── ceemodule.e ├── codegen.e ├── common.e ├── compiler.e ├── diself.e ├── dishunk.e ├── dumpmod.e ├── ec68kifuncs.asm ├── ecmodtrans.e ├── eecelf.e ├── eecmain.e ├── emptycache.e ├── inline68.e ├── inlineppc.e ├── libstubs.e ├── make68kifuncs.script ├── makedist.script ├── makeeec.script ├── makelibmod.e ├── makeppcifuncs.script ├── makeppcifuncs_os4.script ├── makesrcdist.script ├── makestartups.script ├── multilibraryx.e ├── opcodes68.e ├── opcodesppc.e ├── ppcdisasm.e ├── ppcgen.e ├── ppcifuncs.asm ├── runtime.e ├── startup_amigaos.e ├── startup_amigaos4.e ├── startup_morphos.e ├── support.e ├── viewcache.e └── viewmodule.e /.gitattributes: -------------------------------------------------------------------------------- 1 | *.e linguist-language=e 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.uaem 2 | *.o 3 | *.m 4 | *.info 5 | -------------------------------------------------------------------------------- /CompilerLicense.md: -------------------------------------------------------------------------------- 1 | 2 | # THE ECX COMPILER LICENSE 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | - Redistributions must not be of commercial nature and must be free of charge. 8 | 9 | - Copyright notices and this LICENSE may not be altered or removed from any 10 | source code. 11 | 12 | - Redistributions in binary form must reproduce all copyright notices and 13 | this LICENSE in the documentation and/or other materials provided with 14 | the distribution. 15 | 16 | - Redistributions of modified source code should not be misrepresented 17 | as the original and must clearly show who has modified it. 18 | 19 | - Redistributions of modified binaries should not be misrepresented as the 20 | original and must use a different program name and a different archive name. 21 | 22 | - Redistributions of modified binaries must in the documentation and/or other 23 | materials provided with the distribution, provide a brief explanation about 24 | how your work is based on this work. 25 | 26 | This software is provided 'as-is', without any express or implied warranty. 27 | In no event will the author(s) be held liable for any damages arising from 28 | the use of this software. Use at your own risk. 29 | -------------------------------------------------------------------------------- /EEC-1.0.0-src.readme: -------------------------------------------------------------------------------- 1 | short: EEC source code 2 | uploader: samuraileumas yahoo com 3 | author: Samuel D. Crow and Leif Salomonsson 4 | type: dev/e 5 | version: 1.0.0 6 | architecture: generic 7 | 8 | This is the source code of Enhanced E Compiler. 9 | 10 | EEC is an E Compiler derived from ECX, it supports 68020+FPU and 11 | PowerPC cpus, AmigaOS 3.1 and MorphOS operating systems. 12 | 13 | Experimental support for AmigaOS 4 is also included. 14 | 15 | The main compiler sources comes under this license: 16 | 17 | 18 | /*********** THE ECX COMPILER LICENSE ******************************* 19 | 20 | Redistribution and use in source and binary forms, with or without 21 | modification, are permitted provided that the following conditions are met: 22 | 23 | o Redistributions must not be of commercial nature and must be free of charge. 24 | 25 | o Copyright notices and this LICENSE may not be altered or removed from any 26 | source code. 27 | 28 | o Redistributions in binary form must reproduce all copyright notices and 29 | this LICENSE in the documentation and/or other materials provided with 30 | the distribution. 31 | 32 | o Redistributions of modified source code should not be misrepresented 33 | as the original and must clearly show who has modified it. 34 | 35 | o Redistributions of modified binaries should not be misrepresented as the 36 | original and must use a different program name and a different archive name. 37 | 38 | o Redistributions of modified binaries must in the documentation and/or other 39 | materials provided with the distribution, provide a brief explanation about 40 | how your work is based on this work. 41 | 42 | This software is provided 'as-is', without any express or implied warranty. 43 | In no event will the author(s) be held liable for any damages arising from 44 | the use of this software. Use at your own risk. 45 | 46 | ************ END OF ECX COMPILER LICENSE ***************************/ 47 | 48 | 49 | Parts of the compiler comes under simpler licenses with less conditions. 50 | 51 | The startup/library codes and internal functions comes under zlib/libpng 52 | license. 53 | 54 | The support tools comes under the ECX TOOLS LICENSE, 55 | see ToolLicense.md 56 | 57 | Each source describes what license it uses. 58 | 59 | The compiler is written in E, 60 | Startup/library codes are written in E, 61 | internal functions are written in 68k assembler + ppc assembler, 62 | Support tools are written in E. 63 | 64 | To build the compiler you will need: 65 | 66 | 1. 67 | A special version of EC (called testec, see separate archive), 68 | to build the 68k version of ECX. 69 | 70 | 2. 71 | AsmOne or similar to assemble the 68k internal functions into amiga link object. 72 | 73 | 3. 74 | PAsm or similar to assemble the ppc internal functions into amiga link object. 75 | 76 | 4. 77 | ECX(!) to compile startup/library code modules. 78 | 79 | 80 | Leif Salomonsson [dev blubbedev net] Sept 2013 81 | 82 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | # EEC Licensing terms 3 | 4 | As a derivative of ECX, the EEC compiler source files fall under the [ECX Compiler License](CompilerLicense.md): 5 | 6 | - eecmain.e 7 | - compiler.e 8 | - codegen.e 9 | - assembler.e 10 | - common.e 11 | - support.e 12 | - inline68.e 13 | - inlineppc.e 14 | - ecmodtrans.e 15 | - m68gen.e 16 | - ppcgen.e 17 | - libstubs.e 18 | - runtime.e 19 | 20 | 21 | The EEC support tools fall under the [ECX Tools License](ToolsLicense.md): 22 | 23 | - DisELF.e 24 | - DisHunk.e 25 | - ModuleFromProto.e 26 | - ModuleFromFD.e 27 | - TrackHit.e 28 | - ViewCache.e 29 | - EmptyCache.e 30 | - ViewModule.e 31 | - CeeModule.e 32 | - MakeLibMod.e 33 | 34 | The following source files are under [ZLib/LibPNG License](https://opensource.org/licenses/Zlib): 35 | 36 | - DisassemblePPC.e 37 | - Startup_AmigaOS.e 38 | - Startup_MorphOS.e 39 | - Startup_AmigaOS4.e 40 | - MultiLibraryX.e 41 | - Opcodes68.e 42 | - OpcodesPPC.e 43 | - ec68kIFuncs.asm 44 | - PPCIFuncs.asm 45 | 46 | The following have a custom license (copied here for your viewing convenience): 47 | 48 | - EECELF.e 49 | - Binary.e 50 | 51 | 1. no copyright notice is removed or altered. 52 | 1. altered source must be clearly marked as such. 53 | -------------------------------------------------------------------------------- /ModuleFromFD.e: -------------------------------------------------------------------------------- 1 | /* ModuleFromFD by Leif Salomonsson [ecx tele2 se] is Copyright (c) 2004-2007 .*/ 2 | /* Released under ECX TOOLS LICENSE, see ECXTOOLSLICENSE.TXT */ 3 | 4 | -> July 2004 5 | -> produces ecx binary module. 6 | 7 | -> Dec 2004: SYSV offset fix. add 2 to the offset! 8 | 9 | -> Jan 2005. FDs using no base (sysv) didnt work.. *FIXING* 10 | -> also added support for (sysv,r12base) 11 | 12 | -> Jan 2005. v49. new arg: INC/N. WIth this offset increment can be 13 | -> set to something else than -6, could be useful for "OS4-FDs". 14 | -> new arg: BIAS/N 15 | 16 | -> Sept 2005: >10 args bugfix. made the parsing of functions a bit less picky. 17 | -> bugfix: did not longword align sizeof resulting module. 18 | 19 | -> July 2008: added prefix option. prefixes names of functions. 20 | 21 | 22 | MODULE '*binary' 23 | 24 | /* automatic errorchecking */ 25 | RAISE "ARGS" IF ReadArgs()=NIL 26 | RAISE "OPEN" IF Open()=NIL 27 | RAISE "FILE" IF FileLength() < 1 28 | RAISE "MEM" IF New()=NIL 29 | 30 | 31 | DEF mod:PTR TO moduleheader, labelsarray[1024]:ARRAY OF LONG, numlabs=0, g_linenum=1 32 | 33 | PROC getStrOfs(str) 34 | DEF a, len, offset=0, newstr 35 | FOR a := 0 TO numlabs-1 36 | IF StrCmp(str, labelsarray[a]) THEN RETURN offset 37 | len := EstrLen(labelsarray[a]) 38 | offset := offset + len + 1 39 | ENDFOR 40 | len := EstrLen(str) 41 | newstr := String(len) 42 | IF newstr = NIL THEN Raise("MEM") 43 | StrCopy(newstr, str) 44 | labelsarray[numlabs++] := newstr 45 | ENDPROC offset 46 | 47 | PROC getWordLen(str) 48 | DEF c:REG, i:REG 49 | i := 0 50 | WHILE (c := str[i]) 51 | SELECT 128 OF c 52 | CASE "0" TO "9", "A" TO "Z", "a" TO "z", "_", "*", "." 53 | i++ 54 | DEFAULT 55 | RETURN i 56 | ENDSELECT 57 | ENDWHILE 58 | ENDPROC i 59 | 60 | PROC reportErr(err, info=NIL) 61 | WriteF('ERROR at line \d: \s \s\s\s\n', g_linenum, err, 62 | IF info THEN '"' ELSE '', 63 | IF info THEN info ELSE '', 64 | IF info THEN '"' ELSE '') 65 | Raise("ERR") 66 | ENDPROC 67 | 68 | 69 | 70 | ENUM ARG_FD, ARG_MODDIR, ARG_BASE, ARG_VERB, ARG_NAMEFIX, ARG_INC, ARG_BIAS, 71 | ARG_PREFIX, NROFARGS 72 | 73 | PROC main() HANDLE 74 | DEF temp:PTR TO LONG, rdargs 75 | DEF ffh=NIL, mfh=NIL 76 | DEF info:PTR TO modinfo 77 | DEF libi:PTR TO modlibi, lfunc:PTR TO modlfunc, lfuncarg:PTR TO lfuncarg 78 | DEF ffile[256]:STRING 79 | DEF mdir[200]:STRING 80 | DEF bias, public=TRUE, basename[50]:STRING 81 | DEF verbose=FALSE, showprivate=FALSE, namefix=TRUE, lowerbase=TRUE 82 | DEF nrofparams 83 | DEF count=NIL 84 | DEF str[1000]:STRING 85 | DEF pnum, rnum, params[16]:ARRAY OF LONG, regs[16]:ARRAY OF LONG 86 | DEF a, t, line, s, wptr:PTR TO LONG 87 | DEF fbuf, fsize 88 | DEF c, base=NIL, v, r 89 | DEF inc, prefix[20]:STRING 90 | 91 | WriteF(' - \s\n', {version}) 92 | 93 | NEW temp[NROFARGS] 94 | 95 | /* read args */ 96 | rdargs := ReadArgs( 97 | 'FD/A,MODULEDIR/A,BASE/K,VERBOSE/S,NAMEFIX/S,INC/N,BIAS/N,PREFIX/K', 98 | temp, NIL) 99 | 100 | /* get args */ 101 | StrCopy(ffile, temp[ARG_FD]) 102 | 103 | WriteF(' .. processing "\s" ..\n', ffile) 104 | 105 | StrCopy(mdir, temp[ARG_MODDIR]) 106 | IF temp[ARG_BASE] THEN base := StrCopy(String(StrLen(temp[ARG_BASE])),temp[ARG_BASE]) 107 | 108 | verbose := temp[ARG_VERB] 109 | 110 | namefix := temp[ARG_NAMEFIX] 111 | 112 | IF temp[ARG_INC] THEN inc := Long(temp[ARG_INC]) ELSE inc := -6 113 | IF temp[ARG_BIAS] THEN bias := Long(temp[ARG_BIAS]) ELSE bias := -30 114 | 115 | IF temp[ARG_PREFIX] THEN StrCopy(prefix, temp[ARG_PREFIX]) 116 | 117 | /* free args */ 118 | FreeArgs(rdargs) 119 | 120 | ffh := Open(ffile, OLDFILE) 121 | 122 | fsize := FileLength(ffile) 123 | fbuf := NewR(fsize+8) + 4 124 | a := NewR(Mul(fsize,2)+4) 125 | IF Read(ffh,fbuf,fsize) <> fsize THEN Raise("READ") 126 | Close(ffh) ; ffh := NIL 127 | 128 | mod := NewR(SIZEOF moduleheader + (fsize*3) + 1000) 129 | info := mod + SIZEOF moduleheader 130 | info.count := 1 131 | mod.libiinfo := info - mod 132 | libi := info + SIZEOF modinfo 133 | lfunc := libi + SIZEOF modlibi 134 | 135 | s := fbuf 136 | 137 | WHILE (c := s[]) 138 | SELECT 128 OF c 139 | CASE "*" 140 | t := InStr(s, '\n') 141 | IF t < 1 THEN reportErr('comment not terminated') 142 | IF verbose 143 | StrCopy(str, s, t+1) 144 | WriteF(str) 145 | ENDIF 146 | s := s + t 147 | CASE " ", "\t" 148 | s++ 149 | CASE "\n" 150 | g_linenum++ 151 | s++ 152 | CASE "#" 153 | s++ 154 | IF s[]++ <> "#" THEN reportErr('"#" expected') 155 | IF StrCmp(s, 'base ', STRLEN) 156 | s := s + STRLEN 157 | t := getWordLen(s) 158 | IF t = NIL THEN reportErr('basename expected') 159 | IF s[] = "_" 160 | StrCopy(basename, s+1, t-1) 161 | ELSE 162 | StrCopy(basename, s, t) 163 | ENDIF 164 | LowerStr(basename) 165 | IF base = NIL THEN libi.basename := getStrOfs(basename) 166 | s := s + t 167 | ELSEIF StrCmp(s, 'bias ', STRLEN) 168 | s := s + STRLEN 169 | v,r := Val(s) 170 | IF r = NIL THEN reportErr('bias expected') 171 | bias := -v 172 | s := s + r 173 | ELSEIF StrCmp(s, 'public', STRLEN) 174 | s := s + STRLEN 175 | public := TRUE 176 | ELSEIF StrCmp(s, 'private', STRLEN) 177 | s := s + STRLEN 178 | public := FALSE 179 | ELSEIF StrCmp(s, 'end', STRLEN) 180 | s[] := NIL 181 | ELSE 182 | reportErr('unknown directive') 183 | ENDIF 184 | CASE "_", "a" TO "z", "A" TO "Z" 185 | IF public 186 | IF base 187 | StrCopy(basename, base) 188 | libi.basename := getStrOfs(basename) 189 | base := NIL 190 | ENDIF 191 | StrCopy(str, prefix) 192 | t := getWordLen(s) 193 | StrAdd(str, s, t) 194 | IF namefix 195 | IF str[0] > 96 THEN str[0] := str[0] - 32 196 | IF str[1] < 91 197 | str[1] := str[1] + 32 198 | IF str[2] < 91 199 | IF str[3] = "_" 200 | str[2] := str[2] + 32 201 | ENDIF 202 | ENDIF 203 | ENDIF 204 | ENDIF 205 | IF verbose 206 | WriteF('\s\n', str) 207 | ENDIF 208 | lfunc.name := getStrOfs(str) 209 | s := s + t 210 | IF s[]++ <> "(" THEN reportErr('"(" expected') 211 | s := TrimStr(s) 212 | pnum := 0 213 | WHILE (t := getWordLen(s)) 214 | StrCopy(str, s, t) 215 | params[pnum++] := getStrOfs(str) 216 | s := TrimStr(s + t) 217 | EXIT s[]=")" 218 | IF s[]++ <> "," THEN reportErr('"," expected') 219 | WHILE s[] = " " DO s++ 220 | ENDWHILE 221 | s++ 222 | lfunc.nrofargs := pnum 223 | IF s[]++ <> "(" THEN reportErr('"(" expected') 224 | rnum := 0 225 | WHILE (t := getWordLen(s)) 226 | StrCopy(str, s, t) 227 | s := s + t 228 | t := Long(str) 229 | IF t = "base" 230 | lfunc.basernum := rnum + 3 231 | ELSEIF t = "sysv" 232 | lfunc.type := 1 233 | ELSEIF t = "r12b" 234 | lfunc.basernum := 12 235 | ENDIF 236 | regs[rnum++] := t 237 | s := TrimStr(s) 238 | EXIT s[] = ")" 239 | IF s[] <> "/" 240 | IF s[] <> "," THEN reportErr('"," or "/" expected') 241 | ENDIF 242 | s++ 243 | WHILE s[] = " " DO s++ 244 | ENDWHILE 245 | s++ 246 | IF lfunc.type = 0 247 | IF rnum < pnum THEN reportErr('registers dont match arguments') 248 | ELSE 249 | IF lfunc.basernum = 3 THEN t := 4 ELSE t := 3 250 | ENDIF 251 | lfuncarg := lfunc + SIZEOF modlfunc 252 | FOR a := 0 TO pnum-1 253 | lfuncarg.name := params[a] 254 | IF lfunc.type = 0 255 | lfuncarg.rtype := IF Shr(regs[a],24) = "d" THEN 0 ELSE 1 256 | lfuncarg.rnum := Shr(regs[a],16) AND $FF - 48 257 | ELSE 258 | lfuncarg.rtype := IF t > 10 THEN PPCARGRTYPE_STACKRX ELSE PPCARGRTYPE_RX 259 | lfuncarg.rnum := IF t > 10 THEN t++ - 11 * 4 + 8 ELSE t++ 260 | ENDIF 261 | lfuncarg++ 262 | ENDFOR 263 | lfunc.baseofs := bias + IF lfunc.type = 1 THEN 2 ELSE 0 264 | lfunc.totalsize := lfuncarg - lfunc 265 | lfunc := lfuncarg 266 | libi.nroflfuncs := libi.nroflfuncs + 1 267 | ELSE 268 | t := InStr(s, '\n') 269 | s := s + IF t = -1 THEN StrLen(s) ELSE t 270 | ENDIF 271 | bias := bias + inc 272 | DEFAULT 273 | reportErr('unexpected characters') 274 | ENDSELECT 275 | 276 | ENDWHILE 277 | 278 | mod.identification := "ECXM" 279 | mod.headsize := SIZEOF moduleheader 280 | info := lfunc 281 | mod.strtabinfo := info - mod 282 | wptr := info + SIZEOF modinfo 283 | FOR a := 0 TO numlabs-1 284 | s := labelsarray[a] 285 | CopyMem(s, wptr, EstrLen(s)) 286 | wptr := wptr + EstrLen(s) + 1 287 | ENDFOR 288 | mod.modsize := (wptr - mod) + 3 AND -4 289 | 290 | StrCopy(str, mdir) 291 | t := InStr(basename, 'base') 292 | IF t = -1 293 | t := InStr(basename, 'device') 294 | IF t = -1 295 | t := InStr(basename, 'resource') 296 | IF t = -1 297 | t := ALL 298 | ENDIF 299 | ENDIF 300 | ENDIF 301 | StrAdd(str, basename, t) 302 | StrAdd(str, '.m') 303 | 304 | mod.modversion := 1 305 | 306 | setsum(mod) 307 | 308 | mfh := Open(str, NEWFILE) 309 | 310 | Write(mfh, mod, mod.modsize) 311 | 312 | IF verbose 313 | WriteF('\e[31m - processed \d functions\n', libi.nroflfuncs) 314 | WriteF(' - base : \s\n', basename) 315 | ENDIF 316 | 317 | EXCEPT DO 318 | SELECT exception 319 | CASE "ARGS" ; PutStr('Bad Args!\n') 320 | CASE "OPEN" ; PutStr('Open file error!\n') 321 | CASE "READ" ; PutStr('Read file error!\n') 322 | CASE "ERR" ; PutStr('Aborted.\n') 323 | CASE "MEM" ; PutStr('Not enough memory!\n') 324 | CASE "^C" ; PutStr('User aborted!\n') 325 | DEFAULT 326 | IF exception > 0 THEN PutStr('unknown exception occoured!\n') 327 | ENDSELECT 328 | IF ffh THEN Close(ffh) 329 | IF mfh THEN Close(mfh) 330 | ENDPROC 331 | 332 | PROC setsum(m:PTR TO moduleheader) 333 | DEF lptr:REG PTR TO LONG, longsize:REG, sum=NIL:REG 334 | 335 | lptr := m.checksumstart 336 | longsize := Div(m + m.modsize - lptr,4) + 1 337 | 338 | WHILE longsize-- DO sum := sum + lptr[]++ 339 | 340 | m.checksum := sum 341 | 342 | ENDPROC 343 | 344 | CHAR '$VER: ' 345 | version: 346 | CHAR 'ModuleFromFD by LS 2004-08',0 347 | 348 | 349 | 350 | -------------------------------------------------------------------------------- /ModuleFromProto.e: -------------------------------------------------------------------------------- 1 | 2 | /* ModuleFromProto by Leif Salomonsson [ecx tele2 se] is Copyright (c) 2006-2007 */ 3 | /* Released under ECX TOOLS LICENSE, see ECXTOOLSLICENSE.TXT */ 4 | 5 | -> April 2006. 6 | -> C PROTO TO ECXMODULE CONVERTER 7 | -> This should be final solution, no more over-extended FD crap. 8 | 9 | -> 20060416: added typedef support, made "int" buildin type 10 | -> 2007: 1.2: removed some built in AROS STACK_XXX types, why did I add them ? 11 | 12 | -> Aug 2007: 1.3: added arg SYSCALL/S. 13 | 14 | -> March 2008 1.4: added ability to ask user when stumbling on unknown type and 15 | -> automatically add it. Also now Uppercases first letter of function name. 16 | 17 | -> Sept 2008: support for long long, (u)int64 types.. and APICALL. 18 | -> October 2008: added IFACENAME/K 19 | 20 | -> October 2008: modleformat now records varargs. LFFLAG_VARARGS 21 | 22 | MODULE '*binary' 23 | 24 | DEF g_namefix 25 | 26 | /* automatic errorchecking */ 27 | RAISE "ARGS" IF ReadArgs()=NIL 28 | RAISE "OPEN" IF Open()=NIL 29 | RAISE "FILE" IF FileLength() < 1 30 | RAISE "MEM" IF New()=NIL 31 | 32 | OBJECT typedef 33 | type 34 | name 35 | next 36 | ENDOBJECT 37 | 38 | 39 | DEF mod:PTR TO moduleheader 40 | DEF g_labelsarray[1024]:ARRAY OF LONG, g_numlabs=0 41 | DEF g_linenum=1 42 | DEF g_itemsarray[500]:ARRAY OF LONG 43 | DEF g_bias, g_inc 44 | DEF g_verbose 45 | DEF g_basereg 46 | DEF g_typedefs:PTR TO typedef 47 | DEF g_kernel=FALSE 48 | 49 | PROC getStrOfs(str) 50 | DEF a, len, offset=0, newstr 51 | FOR a := 0 TO g_numlabs-1 52 | IF StrCmp(str, g_labelsarray[a]) THEN RETURN offset 53 | len := EstrLen(g_labelsarray[a]) 54 | offset := offset + len + 1 55 | ENDFOR 56 | len := EstrLen(str) 57 | newstr := String(len) 58 | IF newstr = NIL THEN Raise("MEM") 59 | StrCopy(newstr, str) 60 | g_labelsarray[g_numlabs++] := newstr 61 | ENDPROC offset 62 | 63 | PROC getWordLen(str) 64 | DEF c:REG, i:REG 65 | i := 0 66 | WHILE (c := str[i]) 67 | SELECT 128 OF c 68 | CASE "0" TO "9", "A" TO "Z", "a" TO "z", "_" 69 | i++ 70 | DEFAULT 71 | RETURN i 72 | ENDSELECT 73 | ENDWHILE 74 | ENDPROC i 75 | 76 | PROC reportErr(err, info=NIL) 77 | WriteF('ERROR at line \d: \s \s\s\s\n', g_linenum, err, 78 | IF info THEN '"' ELSE '', 79 | IF info THEN info ELSE '', 80 | IF info THEN '"' ELSE '') 81 | Raise("ERR") 82 | ENDPROC 83 | 84 | 85 | 86 | ENUM ARG_PROTO, 87 | ARG_MODDIR, 88 | ARG_BASENAME, 89 | ARG_BASECONFIG, 90 | ARG_VERBOSE, 91 | ARG_INC, 92 | ARG_BIAS, 93 | ARG_IFACENAME, 94 | ARG_NAMEFIX, 95 | ARG_SYSCALL, 96 | NROFARGS 97 | 98 | 99 | PROC main() HANDLE 100 | DEF temp:PTR TO LONG, rdargs 101 | DEF ffh=NIL, mfh=NIL 102 | DEF info:PTR TO modinfo 103 | DEF libi:PTR TO modlibi, lfunc:PTR TO modlfunc 104 | DEF ffile[256]:STRING 105 | DEF mdir[200]:STRING 106 | DEF count=NIL 107 | DEF str[1000]:STRING 108 | DEF a, t, wptr:PTR TO LONG 109 | DEF fbuf, fsize 110 | DEF r, s 111 | DEF basename[100]:STRING 112 | DEF ifacename[100]:STRING, mref:PTR TO modref 113 | 114 | WriteF('\s\n', {version}) 115 | 116 | NEW temp[NROFARGS] 117 | 118 | /* read args */ 119 | rdargs := ReadArgs( 120 | 'PROTOTYPE/A,'+ 121 | 'MODULEDIR/A,'+ 122 | 'BASENAME/A,'+ 123 | 'BASECONFIG/A,'+ 124 | 'VERBOSE/S,'+ 125 | 'INC/N,'+ 126 | 'BIAS/N,'+ 127 | 'IFACENAME/K,'+ 128 | 'NAMEFIX/S,'+ 129 | 'SYSCALL/S', 130 | temp, NIL) 131 | 132 | /* get args */ 133 | StrCopy(ffile, temp[ARG_PROTO]) 134 | 135 | WriteF(' .. processing "\s" ..\n', ffile) 136 | 137 | StrCopy(mdir, temp[ARG_MODDIR]) 138 | 139 | StrCopy(basename, temp[ARG_BASENAME]) 140 | 141 | g_inc := -6 142 | g_bias := -28 143 | 144 | IF temp[ARG_IFACENAME] 145 | StrCopy(ifacename, temp[ARG_IFACENAME]) 146 | g_inc := 4 147 | g_bias := 76 148 | ENDIF 149 | 150 | g_namefix := temp[ARG_NAMEFIX] 151 | 152 | g_verbose := temp[ARG_VERBOSE] 153 | 154 | IF temp[ARG_INC] THEN g_inc := Long(temp[ARG_INC]) 155 | 156 | IF temp[ARG_BIAS] THEN g_bias := Long(temp[ARG_BIAS]) 157 | 158 | StrCopy(str, temp[ARG_BASECONFIG]) 159 | UpperStr(str) 160 | IF StrCmp(str, 'NOBASE') 161 | g_basereg := NIL 162 | ELSEIF StrCmp(str, 'BASESYSV') 163 | g_basereg := 3 164 | ELSEIF StrCmp(str, 'SYSVBASE') 165 | g_basereg := -1 166 | ELSEIF StrCmp(str, 'R12BASE') 167 | g_basereg := 12 168 | ELSE 169 | reportErr('unsupported BASECONFIG', str) 170 | ENDIF 171 | 172 | IF temp[ARG_SYSCALL] THEN g_kernel := TRUE 173 | 174 | /* free args */ 175 | FreeArgs(rdargs) 176 | 177 | ffh := Open(ffile, OLDFILE) 178 | 179 | fsize := FileLength(ffile) 180 | fbuf := NewR(fsize+8) + 4 181 | a := NewR(Mul(fsize,2)+4) 182 | IF Read(ffh,fbuf,fsize) <> fsize THEN Raise("READ") 183 | Close(ffh) ; ffh := NIL 184 | 185 | mod := NewR(SIZEOF moduleheader + (fsize*3) + 1000) 186 | info := mod + SIZEOF moduleheader 187 | info.count := 1 188 | mod.libiinfo := info - mod 189 | libi := info + SIZEOF modinfo 190 | lfunc := libi + SIZEOF modlibi 191 | 192 | ->StrCopy(str, basename) 193 | libi.basename := getStrOfs(IF ifacename[] THEN ifacename ELSE basename) 194 | 195 | wptr := process(fbuf, libi, lfunc) 196 | 197 | IF ifacename[] 198 | info := wptr 199 | mod.xrefginfo := info - mod 200 | info.count := 1 201 | info.rsrvd := NIL 202 | info.misc := NIL 203 | mref := info + SIZEOF modinfo 204 | mref.name := getStrOfs(basename) 205 | mref.ltype := 4 206 | mref.info := NIL 207 | mref.numrefs := 0 208 | wptr := mref + SIZEOF modref -> (8) 209 | ENDIF 210 | 211 | info := wptr 212 | mod.identification := "ECXM" 213 | mod.headsize := SIZEOF moduleheader 214 | mod.strtabinfo := info - mod 215 | wptr := info + SIZEOF modinfo 216 | FOR a := 0 TO g_numlabs-1 217 | s := g_labelsarray[a] 218 | CopyMem(s, wptr, EstrLen(s)) 219 | wptr := wptr + EstrLen(s) + 1 220 | ENDFOR 221 | mod.modsize := (wptr - mod) + 3 AND -4 222 | 223 | StrCopy(str, mdir) 224 | t := InStr(basename, 'base') 225 | IF t = -1 226 | t := InStr(basename, 'device') 227 | IF t = -1 228 | t := InStr(basename, 'resource') 229 | IF t = -1 230 | t := ALL 231 | ENDIF 232 | ENDIF 233 | ENDIF 234 | StrAdd(str, basename, t) 235 | StrAdd(str, '.m') 236 | 237 | mod.modversion := 1 238 | 239 | setsum(mod) 240 | 241 | mfh := Open(str, NEWFILE) 242 | 243 | Write(mfh, mod, mod.modsize) 244 | 245 | IF g_verbose 246 | WriteF('\e[31m - processed \d functions\n', libi.nroflfuncs) 247 | WriteF(' - base : \s\n', basename) 248 | IF EstrLen(ifacename) THEN WriteF(' - iface: \s\n', ifacename) 249 | WriteF(' - ecxmodule : \s\n', str) 250 | ENDIF 251 | 252 | EXCEPT DO 253 | SELECT exception 254 | CASE "ARGS" ; PutStr('Bad Args!\n') 255 | CASE "OPEN" ; PutStr('Open file error!\n') 256 | CASE "READ" ; PutStr('Read file error!\n') 257 | CASE "ERR" ; PutStr('Aborted.\n') 258 | CASE "MEM" ; PutStr('Not enough memory!\n') 259 | CASE "^C" ; PutStr('User aborted!\n') 260 | DEFAULT 261 | IF exception > 0 THEN PutStr('unknown exception occoured!\n') ELSE PutStr('Done.\n') 262 | ENDSELECT 263 | IF ffh THEN Close(ffh) 264 | IF mfh THEN Close(mfh) 265 | ENDPROC 266 | 267 | PROC setsum(m:PTR TO moduleheader) 268 | DEF lptr:REG PTR TO LONG, longsize:REG, sum=NIL:REG 269 | 270 | lptr := m.checksumstart 271 | longsize := Div(m + m.modsize - lptr,4) + 1 272 | 273 | WHILE longsize-- DO sum := sum + lptr[]++ 274 | 275 | m.checksum := sum 276 | 277 | ENDPROC 278 | 279 | -> items: values > 1000 : labels (lowercase | uppercase | "_"), {lowercase | uppercase | digit | "_"} 280 | -> values < 1000 : special chars: "(" ")" "*" "," 281 | 282 | PROC process(s, libi:PTR TO modlibi, lfunc:PTR TO modlfunc) 283 | DEF incomment=FALSE 284 | DEF c, t, pos, len, a 285 | DEF iptr:PTR TO LONG 286 | DEF ireg, freg, sofs:PTR TO LONG, vreg 287 | DEF lfuncarg:PTR TO lfuncarg, tstr[100]:STRING 288 | 289 | iptr := g_itemsarray 290 | 291 | 292 | 293 | prcs_againhuh: 294 | 295 | WHILE (c := s[]) 296 | 297 | IF incomment 298 | SELECT c 299 | CASE "/" 300 | IF s[1] = "*" 301 | s := s + 2 302 | incomment++ 303 | ELSE 304 | s++ 305 | ENDIF 306 | CASE "*" 307 | IF s[1] = "/" 308 | s := s + 2 309 | incomment-- 310 | ELSE 311 | s++ 312 | ENDIF 313 | CASE 10 314 | s++ 315 | g_linenum++ 316 | DEFAULT 317 | s++ 318 | ENDSELECT 319 | JUMP prcs_againhuh 320 | ELSEIF c = "/" 321 | IF s[1] = "*" 322 | s := s + 2 323 | incomment := 1 324 | JUMP prcs_againhuh 325 | ELSEIF s[1] = "/" 326 | pos := InStr(s, '\n') 327 | s := s + IF pos > -1 THEN pos ELSE StrLen(s) 328 | JUMP prcs_againhuh 329 | ENDIF 330 | ENDIF 331 | 332 | SELECT 128 OF c 333 | CASE " ", "\t" 334 | s++ 335 | CASE "\n" 336 | g_linenum++ 337 | s++ 338 | IF iptr[-1] <> "," THEN iptr := g_itemsarray -> line can be broken with "," 339 | CASE "_", "a" TO "z", "A" TO "Z" 340 | len := getWordLen(s) 341 | iptr[]++ := StrCopy(String(len), s) 342 | s := s + len 343 | CASE ",", "(", ")", "*" 344 | iptr[]++ := c 345 | s++ 346 | CASE "#" -> just skip lines beginning with this (preprocessor) 347 | pos := InStr(s, '\n') 348 | s := s + IF pos > -1 THEN pos ELSE StrLen(s) 349 | CASE "." 350 | s++ 351 | IF s[] = "." 352 | s++ 353 | IF s[] = "." 354 | s++ 355 | iptr[]++ := "." -> "." as item signals "..." 356 | ENDIF 357 | ENDIF 358 | CASE ";" 359 | -> a prototype/typedef "line" has ended, lets parse the items 360 | iptr[]++ := ";" -> we need a termination 361 | s++ 362 | iptr := g_itemsarray 363 | 364 | IF iptr[] < 256 THEN reportErr('label expected') 365 | 366 | IF StrCmp(iptr[], 'typedef') 367 | 368 | iptr++ 369 | IF iptr[] < 256 THEN reportErr('label expected') 370 | iptr, t := parsetype(iptr) 371 | IF iptr[] < 256 THEN reportErr('alias expected') 372 | addTypeDef(t, iptr[]) 373 | 374 | ELSE 375 | 376 | iptr,t := parsetype(iptr) 377 | lfunc.return := IF t = -1 THEN 0 ELSE t 378 | 379 | IF iptr[] < 256 THEN reportErr('function name expected') 380 | IF StrCmp(iptr[], 'APICALL') 381 | iptr++ 382 | IF iptr[]++ <> "(" THEN reportErr('"(" exected') 383 | IF iptr[]++ <> "*" THEN reportErr('"*" exected') 384 | IF iptr[] < 256 THEN reportErr('label expected') 385 | StrCopy(tstr, iptr[]++) 386 | IF iptr[]++ <> ")" THEN reportErr('")" exected') 387 | ELSE 388 | StrCopy(tstr, iptr[]++) 389 | ENDIF 390 | 391 | IF g_namefix 392 | IF tstr[0] > 96 THEN tstr[0] := tstr[0] - 32 393 | IF tstr[1] < 91 394 | tstr[1] := tstr[1] + 32 395 | IF tstr[2] < 91 396 | IF tstr[3] = "_" 397 | tstr[2] := tstr[2] + 32 398 | ENDIF 399 | ENDIF 400 | ENDIF 401 | ENDIF 402 | 403 | IF tstr[] > "Z" THEN tstr[] := tstr[] - 32 404 | 405 | IF g_verbose THEN WriteF(' \s\n', tstr) 406 | lfunc.name := getStrOfs(tstr) 407 | 408 | IF iptr[]++ <> "(" THEN reportErr('"(" expected') 409 | 410 | lfunc.type := 1 411 | 412 | lfuncarg := lfunc + SIZEOF modlfunc 413 | 414 | ireg := IF g_basereg = 3 THEN 4 ELSE 3 415 | freg := 1 416 | sofs := 8 417 | vreg := 2 418 | a := 0 419 | 420 | WHILE iptr[] > 256 -> while label 421 | EXIT iptr[] = "." -> "." is actually "..." 422 | iptr, t := parsetype(iptr) 423 | EXIT t = -1 -> VOID 424 | IF (g_basereg = 3) AND (a=0) 425 | -> skip first arg if basesysv 426 | a := 1 427 | iptr++ 428 | ELSE 429 | lfunc.nrofargs := lfunc.nrofargs + 1 430 | IF iptr[] > 256 -> argname ? 431 | lfuncarg.name := getStrOfs(iptr[]++) 432 | ENDIF 433 | IF t = 0 434 | lfuncarg.rtype := IF ireg > 10 THEN PPCARGRTYPE_STACKRX ELSE PPCARGRTYPE_RX 435 | lfuncarg.rnum := IF ireg > 10 THEN sofs++ ELSE ireg++ 436 | ELSEIF t = 1 437 | lfuncarg.rtype := PPCARGRTYPE_FX 438 | lfuncarg.rnum := freg++ 439 | ELSEIF t = 2 440 | lfuncarg.rtype := PPCARGRTYPE_VX 441 | lfuncarg.rnum := vreg++ 442 | ELSEIF t = 3 443 | lfuncarg.rtype := PPCARGRTYPE_RX2 444 | IF ireg < 10 445 | lfuncarg.rnum := ireg++ 446 | ireg++ 447 | ELSE 448 | lfuncarg.rtype := PPCARGRTYPE_STACKRX2 449 | lfuncarg.rnum := sofs++ 450 | sofs++ 451 | ENDIF 452 | ENDIF 453 | lfuncarg++ 454 | ENDIF 455 | EXIT iptr[] <> "," 456 | iptr++ 457 | ENDWHILE 458 | 459 | IF iptr[] = "." 460 | iptr++ 461 | lfunc.flags := lfunc.flags OR LFFLAG_VARARGS -> Oct 2008. 462 | ENDIF 463 | 464 | IF iptr[] <> ")" THEN reportErr('")" expected') 465 | 466 | IF g_basereg = -1 467 | lfunc.nrofargs := lfunc.nrofargs - 1 468 | lfuncarg-- 469 | ENDIF 470 | 471 | lfunc.basertype := IF g_basereg <> -1 THEN 0 ELSE (IF ireg > 10 THEN 1 ELSE 0) 472 | lfunc.basernum := IF g_basereg <> -1 THEN g_basereg ELSE (IF ireg > 10 THEN sofs ELSE ireg) 473 | -> 1.3 474 | IF g_kernel 475 | lfunc.flags := LFFLAG_KERNELFUNC 476 | lfunc.basertype := 0 477 | lfunc.basernum := 0 478 | ENDIF 479 | lfunc.baseofs := g_bias 480 | g_bias := g_bias + g_inc 481 | lfunc.totalsize := lfuncarg - lfunc 482 | lfunc := lfuncarg 483 | libi.nroflfuncs := libi.nroflfuncs + 1 484 | 485 | ENDIF 486 | 487 | iptr := g_itemsarray -> reset 488 | iptr[] := NIL -> destroy old data incase another ";" immediately turns up 489 | 490 | DEFAULT 491 | s++ 492 | ->reportErr('unexpected characters') 493 | ENDSELECT 494 | 495 | ENDWHILE 496 | 497 | IF incomment > 0 THEN reportErr('start of comment without end') 498 | 499 | 500 | ENDPROC lfunc 501 | 502 | PROC parsetype(iptr:PTR TO LONG) 503 | DEF t=0, str[100]:STRING 504 | 505 | StrCopy(str, iptr[]) 506 | LowerStr(str) 507 | 508 | IF StrCmp(str, 'const') 509 | iptr++ 510 | StrCopy(str, iptr[]) 511 | LowerStr(str) 512 | ENDIF 513 | 514 | IF StrCmp(str, 'struct') 515 | t := 0 516 | iptr++ -> skip struct 517 | iptr++ -> skip structname 518 | IF iptr[]++ <> "*" THEN reportErr('function returns object by *value*, WTF ?!?') 519 | ELSEIF StrCmp(str, 'signed') 520 | iptr++ 521 | iptr++ -> skip long/int/short/char 522 | t := 0 523 | ELSEIF StrCmp(str, 'unsigned') 524 | iptr++ 525 | iptr++ -> skip long/int/short/char 526 | t := 0 527 | ELSEIF StrCmp(str, 'void') 528 | iptr++ 529 | t := -1 530 | ELSEIF StrCmp(str, 'long') 531 | iptr++ 532 | IF iptr[] > 256 533 | StrCopy(str, iptr[]) 534 | LowerStr(str) 535 | IF StrCmp(str, 'long') 536 | iptr++ 537 | t := 3 538 | ELSE 539 | t := 0 540 | ENDIF 541 | ELSE 542 | t := 0 543 | ENDIF 544 | ELSEIF StrCmp(str, 'int') 545 | iptr++ 546 | t := 0 547 | ELSEIF StrCmp(str, 'short') 548 | iptr++ 549 | t := 0 550 | ELSEIF StrCmp(str, 'char') 551 | iptr++ 552 | t := 0 553 | ELSE 554 | -> integer or float as return 555 | t := customtype(iptr[]++) 556 | ENDIF 557 | 558 | WHILE iptr[] = "(" -> pointer to function stuff 559 | t := 0 560 | REPEAT 561 | iptr++ 562 | IF iptr[] = ";" THEN reportErr('")" expected') 563 | UNTIL iptr[] = ")" 564 | iptr++ 565 | ENDWHILE 566 | 567 | WHILE iptr[] = "*" 568 | iptr++ 569 | -> pointer (integer) as return 570 | t := 0 571 | ENDWHILE 572 | 573 | ENDPROC iptr, t 574 | 575 | PROC customtype(str) 576 | DEF t=0 577 | DEF s[100]:STRING, rstr[10]:STRING 578 | DEF td:PTR TO typedef 579 | 580 | StrCopy(s, str) 581 | UpperStr(s) 582 | 583 | IF StrCmp(s, 'APTR') ; t := 0 584 | ELSEIF StrCmp(s, 'CONST_APTR') ; t := 0 585 | ELSEIF StrCmp(s, 'ULONG') ; t := 0 586 | ELSEIF StrCmp(s, 'LONGBITS') ; t := 0 587 | ELSEIF StrCmp(s, 'WORD') ; t := 0 588 | ELSEIF StrCmp(s, 'UWORD') ; t := 0 589 | ELSEIF StrCmp(s, 'WORDBITS') ; t := 0 590 | ELSEIF StrCmp(s, 'BYTE') ; t := 0 591 | ELSEIF StrCmp(s, 'UBYTE') ; t := 0 592 | ELSEIF StrCmp(s, 'BYTEBITS') ; t := 0 593 | ELSEIF StrCmp(s, 'RPTR') ; t := 0 594 | ELSEIF StrCmp(s, 'STRPTR') ; t := 0 595 | ELSEIF StrCmp(s, 'CONST_STRPTR') ; t := 0 596 | ELSEIF StrCmp(s, 'SHORT') ; t := 0 597 | ELSEIF StrCmp(s, 'USHORT') ; t := 0 598 | ELSEIF StrCmp(s, 'COUNT') ; t := 0 599 | ELSEIF StrCmp(s, 'UCOUNT') ; t := 0 600 | ELSEIF StrCmp(s, 'CPTR') ; t := 0 601 | ELSEIF StrCmp(s, 'FLOAT') ; t := 1 602 | ELSEIF StrCmp(s, 'DOUBLE') ; t := 1 603 | ELSEIF StrCmp(s, 'BOOL') ; t := 0 604 | ELSEIF StrCmp(s, 'TEXT') ; t := 0 605 | 606 | ELSEIF StrCmp(s, 'IPTR') ; t := 0 607 | 608 | ELSEIF StrCmp(s, 'TAG') ; t := 0 609 | ELSEIF StrCmp(s, 'INT64') ; t := 3 610 | ELSEIF StrCmp(s, 'INT32') ; t := 0 611 | ELSEIF StrCmp(s, 'INT16') ; t := 0 612 | ELSEIF StrCmp(s, 'INT8') ; t := 0 613 | ELSEIF StrCmp(s, 'UINT') ; t := 0 614 | ELSEIF StrCmp(s, 'UINT64') ; t := 3 615 | ELSEIF StrCmp(s, 'UINT32') ; t := 0 616 | ELSEIF StrCmp(s, 'UINT16') ; t := 0 617 | ELSEIF StrCmp(s, 'UINT8') ; t := 0 618 | ELSEIF StrCmp(s, 'UQUAD') ; t := 3 619 | ELSEIF StrCmp(s, 'QUAD') ; t := 3 620 | 621 | ELSE 622 | 623 | td := g_typedefs 624 | WHILE td 625 | t := td.type 626 | EXIT StrCmp(s, td.name) 627 | td := td.next 628 | ENDWHILE 629 | 630 | IF td = NIL 631 | -> oh, not recognized, lets ask user then.. 632 | WriteF('Type "\s" is not recognized.. should it go into (i)nteger, (f)loat, (v)ector, (w)ide register ?: ', s) 633 | ReadStr(stdin, rstr) 634 | t := rstr[] 635 | SELECT t 636 | CASE "i" ; t := 0 637 | CASE "f" ; t := 1 638 | CASE "v" ; t := 2 639 | CASE "w" ; t := 3 640 | DEFAULT ; WriteF('Bad choice! Lets say you ment "i" then..\n') ; t := 0 641 | ENDSELECT 642 | addTypeDef(t, s) 643 | ENDIF 644 | 645 | ENDIF 646 | 647 | ENDPROC t 648 | 649 | PROC addTypeDef(type, name) 650 | DEF td:PTR TO typedef 651 | NEW td 652 | td.type := type 653 | td.name := StrCopy(String(StrLen(name)), name) 654 | UpperStr(td.name) 655 | td.next := g_typedefs 656 | g_typedefs := td 657 | ENDPROC 658 | 659 | CHAR '$VER: ' 660 | version: 661 | CHAR 'ModuleFromProto 1.5 (XX.10.2008) Copyright (c) Leif Salomonsson 2006-2008',0 662 | 663 | 664 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Enhanced E Compiler 2 | 3 | EEC is an advanced compiler for the AmigaE programming language. It's based on ECX by Leif Salmonsson with the intention of adding optimization and new backends. 4 | 5 | ## Build Instructions 6 | 7 | 1. Configure FS-UAE or WinUAE to have at least a full 68020 or better and 128 MiB of Z3 Fast RAM on AmigaOS 3.1 up to AmigaOS 3.9. 8 | 1. Install VAsmm68k_mot for the 68k startup code. 9 | 1. Install VAsmPPC_std for the MorphOS and AmigaOS4 PowerPC startup code. 10 | 1. Set the protection bits on the script files as follows: `spat protect #?.script srwd` 11 | 1. Execute the following AmigaDOS scripts to generate the startup codes: make68kifuncs.script, makeppcifuncs.script and makeppcifuncs_os4.script 12 | 1. Also install [E-VO](http://aminet.net/package/dev/e/evo) (Must be v3.5.1 or higher of E-VO) 13 | 1. Finally, install the latest version of [ECX](https://github.com/EEC-Developers/eec/releases/download/precursor/ecx-2.3.1.lha) 14 | 1. Execute the following in the ECX/bin directory: `Copy ECX.68k EEC.020 clone` 15 | 1. Execute makedir ecxmodules:eec to create the directory for eec modules 16 | 1. Execute makestartups.script to create the modules. 17 | 1. Bootstrap the executable by typing: 18 | 19 | `makeeec.script evo` 20 | 21 | 1. You now have a compiled 020 version of EEC which can be used to build the remaining executables by typing: 22 | 23 | `makeeec.script morphos` 24 | 25 | `makeeec.script amigaos4` 26 | 27 | `makeeec.script amigaos` 28 | 29 | -------------------------------------------------------------------------------- /ToolsLicense.md: -------------------------------------------------------------------------------- 1 | 2 | # ECX TOOLS LICENSE 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, is permitted provided that the following conditions are met: 6 | 7 | - Copyright notices may not be altered or removed from any source code. 8 | 9 | - Redistributions of modified source code should not be misrepresented 10 | as the original and must clearly show who has modified it. 11 | 12 | - Redistributions of modified binaries should not be misrepresented as the 13 | original and must clearly show who has modified it. 14 | 15 | This software is provided 'as-is', without any express or implied warranty. 16 | In no event will the author(s) be held liable for any damages arising from 17 | the use of this software. Use at your own risk. 18 | 19 | -------------------------------------------------------------------------------- /TrackHit.e: -------------------------------------------------------------------------------- 1 | -> TrackHit.e by Leif Salomonsson is Copyright (c) 2003-2008 2 | -> Released under ECX TOOLS LICENSE, see ECXTOOLSLICENSE.TXT 3 | 4 | MODULE 'dos/doshunks' 5 | 6 | -> 2006: now expects no "NIL" long before "LINE" long.. like ELF format.. 7 | -> 2007: HAH, now it actually works good :) 8 | -> 2007: adapted to small change in line format. 9 | 10 | RAISE "FILE" IF FileLength()=-1, 11 | "OPEN" IF Open()=NIL, 12 | "ARGS" IF ReadArgs()=NIL 13 | 14 | OBJECT symb 15 | next 16 | name 17 | offset 18 | ENDOBJECT 19 | 20 | DEF symblist:PTR TO symb 21 | 22 | PROC main() HANDLE 23 | DEF fbuf, flen 24 | DEF fh=NIL, rdargs=NIL, args:PTR TO LONG 25 | DEF name, line, source, offset, symbol:PTR TO symb 26 | DEF read 27 | 28 | NEW args[5] 29 | 30 | /* read agrs */ 31 | rdargs := ReadArgs('FILE/A,'+ 32 | 'OFFSET/A', 33 | args, NIL) 34 | 35 | name := args[0] 36 | offset, read := Val(args[1]) 37 | 38 | IF read = 0 THEN Raise("VAL") 39 | 40 | flen := FileLength(name) 41 | fbuf := NewR(flen+4) 42 | fh := Open(name, OLDFILE) 43 | Read(fh, fbuf, flen) 44 | Close(fh) ; fh := NIL 45 | 46 | 47 | WriteF('TrackHit 1.1\nCopyright (c) 2003-2007 Leif Salomonsson\n -> \q\s\q, $\h\n', name, offset) 48 | 49 | line, source, symbol := trackhit(fbuf, offset) 50 | 51 | IF line = FALSE THEN line := -1 52 | IF source = NIL THEN source := '???' 53 | IF symbol = NIL THEN symbol := [0,'???',-1]:symb 54 | 55 | WriteF('SOURCE \q\s\q\nLINE \d, below symbol \q\s\q ($\h)\n', source, line, symbol.name, symbol.offset) 56 | 57 | EXCEPT DO 58 | 59 | IF rdargs THEN FreeArgs(rdargs) 60 | 61 | IF fh THEN Close(fh) 62 | 63 | 64 | SELECT exception 65 | CASE "ARGS" ; WriteF('Error: args\n') 66 | CASE "FILE" ; WriteF('Error: file\n') 67 | CASE "OPEN" ; WriteF('Error: open\n') 68 | CASE "FORM" ; WriteF('Error: format -> \s\n', exceptioninfo) 69 | CASE "MEM" ; WriteF('Error: mem\n') 70 | CASE "VAL" ; WriteF('Error: offset argument invalid\n') 71 | ENDSELECT 72 | ENDPROC 73 | 74 | OBJECT line 75 | line 76 | offset 77 | ENDOBJECT 78 | 79 | PROC trackhit(ptr:PTR TO LONG, ofs) 80 | DEF a, b, c:PTR TO LONG, d, linenum=FALSE, source=FALSE, symbol=FALSE 81 | DEF symbnode:PTR TO symb, rofs, t, end 82 | DEF line:PTR TO line, tline:PTR TO line 83 | 84 | IF ptr[]++ <> HUNK_HEADER THEN Throw("FORM", 'not executable file') 85 | WHILE ptr[] DO ptr := ptr + 4 + Mul(4,ptr[]) 86 | ptr++ 87 | b := ptr[]++ -> nr of hunks 88 | ptr := ptr + 8 -> skip fisrt/last hunk nums 89 | ptr := ptr + Mul(4,b) -> skip sizes 90 | 91 | IF ptr[]++ <> HUNK_CODE THEN Throw("FORM", 'code hunk not found') 92 | ptr := ptr + Mul(4,ptr[]) + 4 -> skip code 93 | 94 | IF ptr[] = HUNK_ABSRELOC32 95 | ptr++ 96 | WHILE (a := ptr[]++) DO ptr := ptr + Mul(a,4) + 4 97 | ENDIF 98 | 99 | IF ptr[] = HUNK_END THEN ptr++ 100 | 101 | IF ptr[] <> HUNK_DEBUG THEN Throw("FORM", 'debug hunk not found (Compile with DEBUG)') 102 | 103 | WHILE (ptr[] = HUNK_DEBUG) 104 | ptr++ 105 | a := ptr[]++ -> size in longs 106 | end := ptr + Mul(a,4) 107 | IF ptr[] = "LDBG" 108 | tline := NIL 109 | d := NIL 110 | WHILE ptr[]++ = "LDBG" 111 | t := ptr[]++ -> numlines 112 | b := ptr + 4 -> save ptr to name 113 | line := ptr + Shl(ptr[]++, 2) + 4-> jump over name 114 | IF (ofs >= line.offset) AND (ofs <= line[t-1].offset) 115 | d := b 116 | WHILE t 117 | t-- 118 | IF line.offset <= ofs THEN tline := line 119 | line++ 120 | ENDWHILE 121 | ELSE 122 | ptr := line + Mul(t, SIZEOF line) 123 | ENDIF 124 | EXIT d 125 | ENDWHILE 126 | IF d 127 | source := d 128 | linenum := tline.line 129 | ENDIF 130 | 131 | ENDIF 132 | ptr := end 133 | ENDWHILE 134 | 135 | IF ptr[]++ = HUNK_SYMBOL 136 | WHILE (a := ptr[]++) -> name len in longs 137 | NEW symbnode 138 | symbnode.name := ptr -> name 139 | ptr := ptr + (a*4) -> skip name 140 | symbnode.offset := ptr[]++ -> offset 141 | addSymb(symbnode) 142 | ENDWHILE 143 | ->printSymbols() 144 | symbol := findSymb(ofs) 145 | 146 | ENDIF 147 | 148 | ENDPROC linenum, source, symbol 149 | 150 | PROC addSymb(s:PTR TO symb) 151 | DEF symb:PTR TO symb, prev=NIL:PTR TO symb 152 | 153 | 154 | symb := symblist 155 | WHILE symb 156 | IF s.offset < symb.offset 157 | IF prev 158 | prev.next := s 159 | s.next := symb 160 | ELSE 161 | symblist := s 162 | s.next := symb 163 | ENDIF 164 | RETURN 165 | ELSE 166 | prev := symb 167 | symb := symb.next 168 | ENDIF 169 | ENDWHILE 170 | 171 | IF prev THEN prev.next := s ELSE symblist := s 172 | 173 | ENDPROC 174 | 175 | PROC findSymb(ofs) 176 | DEF symb:PTR TO symb, prev=NIL:PTR TO symb 177 | symb := symblist 178 | WHILE symb 179 | EXIT symb.offset > ofs 180 | prev := symb 181 | symb := symb.next 182 | ENDWHILE 183 | 184 | ENDPROC prev 185 | 186 | PROC printSymbols() 187 | DEF s:PTR TO symb 188 | s := symblist 189 | 190 | WHILE s 191 | WriteF('\s = \d\n', s.name, s.offset) 192 | s := s.next 193 | ENDWHILE 194 | 195 | ENDPROC NIL 196 | 197 | CHAR '$VER: TrackHit July 2003-07 by LS',0 198 | -------------------------------------------------------------------------------- /assembler.e: -------------------------------------------------------------------------------- 1 | -> ECX/assembler.e 2 | 3 | /* ECX by Leif Salomonsson [ecx tele2 se] is Copyright (c) 2002-2008 */ 4 | /* Released under the ECX COMPILER LICENSE, See ECXCOMPILERLICENSE.TXT */ 5 | 6 | OPT MODULE 7 | OPT PREPROCESS 8 | 9 | -> assembler.e, created May 2008. code extracted from codegen.e and ecxmain.e 10 | 11 | ->#define DBG_ASSEM 12 | 13 | MODULE '*opcodes68' 14 | MODULE '*opcodesppc' 15 | MODULE '*compiler' 16 | MODULE '*binary' -> REFxxx 17 | MODULE '*common' -> reportErr(), reportIErr() 18 | 19 | EXPORT DEF 20 | g_codeptr:PTR TO LONG, 21 | g_codebuf, 22 | g_codelablist:PTR TO genlab, 23 | link_reloc32list:PTR TO LONG, 24 | link_nrofreloc32s, 25 | link_codesize 26 | 27 | DEF g_relstrings 28 | 29 | -> 1.10.0: moved here. now of genlab and put in g_codelablist as 30 | -> well as g_relstrings 31 | EXPORT OBJECT relstr OF genlab 32 | next:PTR TO relstr 33 | string:PTR TO CHAR 34 | ENDOBJECT 35 | 36 | 37 | #define NewLabel (g_codelablist := NEW [0,g_codelablist,0,0]:genlab) 38 | #define PutLabel(codelab) genlab.offset := g_codeptr - g_codebuf + link_codesize 39 | #define AddReloc(ofs) link_reloc32list := link_nrofreloc32s++ BUT NEW [link_reloc32list, ofs]:LONG 40 | #define CurrentOffset (g_codeptr - g_codebuf + link_codesize) 41 | #define PutAlign(size) g_codeptr := g_codeptr + (size-1) AND (-size) 42 | 43 | EXPORT PROC newLabel() 44 | DEF r 45 | r := NewLabel 46 | ENDPROC r 47 | EXPORT PROC putLabel(genlab:PTR TO genlab) 48 | PutLabel(genlab) 49 | ENDPROC 50 | EXPORT PROC addReloc(ofs) 51 | AddReloc(ofs) 52 | ENDPROC 53 | EXPORT PROC currentOffset() 54 | DEF r 55 | r := CurrentOffset 56 | ENDPROC r 57 | EXPORT PROC putAlign(size) 58 | PutAlign(size) 59 | ENDPROC 60 | 61 | EXPORT PROC put24ofs(code:PTR TO LONG, ofs) 62 | code[] := ofs AND $3FFFFFC OR code[] 63 | ENDPROC 64 | 65 | EXPORT PROC patchReferences() 66 | DEF lab:PTR TO codelab, labref:PTR TO labref, a, t, b 67 | 68 | #ifdef DBG_ASSEM 69 | DEBUGF('patchReferences()\n') 70 | #endif 71 | 72 | lab := g_codelablist 73 | WHILE lab 74 | labref := lab.labrefs 75 | WHILE labref 76 | a := labref.type 77 | SELECT a 78 | CASE REF32 -> 68k 79 | b := lab.offset - labref.offset 80 | PutLong(g_codebuf + labref.offset - link_codesize, b) 81 | CASE REF24 -> ppc only 82 | b := lab.offset - labref.offset 83 | put24ofs(g_codebuf + labref.offset - link_codesize, b) 84 | CASE REF16 -> 68k only 85 | b := lab.offset - labref.offset 86 | IF b > 32767 THEN reportErr('too large distance', IF lab.identID THEN lab.name ELSE NIL) 87 | PutInt(g_codebuf + labref.offset - link_codesize, b) 88 | CASE REF14 -> ppc only 89 | b := lab.offset - labref.offset 90 | IF b > 32764 THEN reportErr('too large distance', IF lab.identID THEN lab.name ELSE NIL) 91 | PutInt((t := g_codebuf + labref.offset - link_codesize + 2), Int(t) OR b) 92 | CASE REFADR -> 68k / ppc 93 | PutLong(g_codebuf + labref.offset - link_codesize, lab.offset) 94 | AddReloc(labref.offset) 95 | CASE REF1616 -> ppc only 96 | b := lab.offset - labref.offset 97 | t := g_codebuf + labref.offset - link_codesize 98 | PutInt(t + 6, b AND $FFFF) 99 | PutInt(t + 10, (Shr(b,16) AND $FFFF) + IF b AND $8000 THEN 1 ELSE 0) 100 | DEFAULT 101 | WriteF('type = \d\n', a) 102 | IF lab.identID THEN WriteF('name = \s\n', lab.name) 103 | reportIErr(' patchRefs() type') 104 | ENDSELECT 105 | labref := labref.next 106 | ENDWHILE 107 | lab := lab.codelink 108 | ENDWHILE 109 | 110 | #ifdef DBG_ASSEM 111 | DEBUGF('patchReferences() DONE\n') 112 | #endif 113 | ENDPROC 114 | 115 | -> 1.10.0, now merges strings (MUST be estrings!) 116 | EXPORT PROC addRelStr(str) 117 | DEF relstr:PTR TO relstr, ref:PTR TO labref 118 | relstr := g_relstrings 119 | WHILE relstr 120 | IF EstrLen(str) = EstrLen(relstr.string) 121 | IF StrCmp(relstr.string, str, EstrLen(str)) 122 | RETURN relstr 123 | ENDIF 124 | ENDIF 125 | relstr := relstr.next 126 | ENDWHILE 127 | relstr := NEW [NIL, 128 | g_codelablist, 129 | NIL, 130 | NIL, 131 | g_relstrings, str]:relstr 132 | g_relstrings := relstr 133 | g_codelablist := relstr 134 | ENDPROC relstr 135 | 136 | -> moved back here 1.9.0 137 | -> 1.10.0 mods for merged strings 138 | EXPORT PROC putRelocStrings() 139 | DEF relstr:PTR TO relstr, t 140 | 141 | #ifdef DBG_ASSEM 142 | DEBUGF('putRelocStrings()\n') 143 | #endif 144 | 145 | relstr := g_relstrings 146 | WHILE relstr 147 | relstr.offset := CurrentOffset 148 | CopyMem(relstr.string, g_codeptr, t := EstrLen(relstr.string)) 149 | g_codeptr := g_codeptr + t + 1 150 | relstr := relstr.next 151 | ENDWHILE 152 | PutAlign(4) 153 | ENDPROC 154 | 155 | EXPORT PROC putReloc(lab:PTR TO codelab) 156 | #ifdef DBG_ASSEM 157 | DEBUGF('putReloc32($\h): \d\n', lab, lab.offset) 158 | #endif 159 | IF lab.offset = NIL 160 | lab.labrefs := NEW [lab.labrefs,CurrentOffset,REFADR]:labref 161 | g_codeptr++ 162 | ELSE 163 | AddReloc(CurrentOffset) 164 | g_codeptr[]++ := lab.offset 165 | ENDIF 166 | ENDPROC 167 | 168 | -> handy 169 | -> v45. better have in one place 170 | -> "reg" CANNOT be r0 ! 171 | EXPORT PROC ppcliw(reg,val) 172 | IF (Abs(val) < 32768) AND (val <> $80000000) -> 1.10.0 fix 173 | ppcaddi(reg,0,val AND $FFFF) 174 | ELSE 175 | ppcaddi(reg,0,val AND $FFFF) 176 | ppcaddis(reg,reg,Shr(val,16) AND $FFFF + IF val AND $8000 THEN 1 ELSE 0) 177 | ENDIF 178 | ENDPROC 179 | 180 | -> v45. 181 | EXPORT PROC ppcaddiw(d,s,val) 182 | ppcaddi(d,s,val AND $FFFF) 183 | IF (Abs(val) > $7FFF) OR (val = $80000000) -> 1.10.0 fix 184 | ppcaddis(d,d,Shr(val,16) AND $FFFF + IF val AND $8000 THEN 1 ELSE 0) 185 | ENDIF 186 | ENDPROC 187 | 188 | -> v55 189 | -> may trash r0 ! 190 | -> dreg may NOT be r0 ! 191 | -> dreg and sreg may NOT be same ! 192 | EXPORT PROC ppcdiviw(dreg, sreg, imm) 193 | SELECT imm 194 | CASE 1 195 | RETURN 196 | CASE 2 197 | ppcsrawi(sreg,dreg,1,0) 198 | ppcaddze(dreg,dreg,0,0) 199 | CASE 4 200 | ppcsrawi(sreg,dreg,2,0) 201 | ppcaddze(dreg,dreg,0,0) 202 | CASE 8 203 | ppcsrawi(sreg,dreg,3,0) 204 | ppcaddze(dreg,dreg,0,0) 205 | CASE 16 206 | ppcsrawi(sreg,dreg,4,0) 207 | ppcaddze(dreg,dreg,0,0) 208 | CASE 32 209 | ppcsrawi(sreg,dreg,5,0) 210 | ppcaddze(dreg,dreg,0,0) 211 | CASE 64 212 | ppcsrawi(sreg,dreg,6,0) 213 | ppcaddze(dreg,dreg,0,0) 214 | CASE 128 215 | ppcsrawi(sreg,dreg,7,0) 216 | ppcaddze(dreg,dreg,0,0) 217 | CASE 256 218 | ppcsrawi(sreg,dreg,8,0) 219 | ppcaddze(dreg,dreg,0,0) 220 | CASE 512 221 | ppcsrawi(sreg,dreg,9,0) 222 | ppcaddze(dreg,dreg,0,0) 223 | CASE 1024 224 | ppcsrawi(sreg,dreg,10,0) 225 | ppcaddze(dreg,dreg,0,0) 226 | CASE 2048 227 | ppcsrawi(sreg,dreg,11,0) 228 | ppcaddze(dreg,dreg,0,0) 229 | CASE 4096 230 | ppcsrawi(sreg,dreg,12,0) 231 | ppcaddze(dreg,dreg,0,0) 232 | CASE 8192 233 | ppcsrawi(sreg,dreg,13,0) 234 | ppcaddze(dreg,dreg,0,0) 235 | DEFAULT 236 | ppcliw(dreg,imm) 237 | ppcdivw(dreg,sreg,dreg,0,0) 238 | ENDSELECT 239 | ENDPROC 240 | 241 | EXPORT PROC ppcblab(lab:PTR TO genlab,aa,lk) 242 | IF lab.offset 243 | ppcb(Shr(lab.offset - CurrentOffset,2),aa,lk) 244 | ELSE 245 | lab.labrefs := NEW [lab.labrefs, CurrentOffset, REF24]:labref 246 | ppcb(NIL,aa,lk) 247 | ENDIF 248 | ENDPROC 249 | 250 | EXPORT PROC ppcbclab(bo,bl,lab:PTR TO genlab,aa,lk) 251 | DEF d 252 | IF lab.offset 253 | d := lab.offset - CurrentOffset 254 | IF Abs(d) > 32764 THEN reportErr('too large distance',NIL) 255 | ppcbc(bo,bl,Shr(d,2),aa,lk) 256 | ELSE 257 | lab.labrefs := NEW [lab.labrefs, CurrentOffset, REF14]:labref 258 | ppcbc(bo,bl,NIL,aa,lk) 259 | ENDIF 260 | ENDPROC 261 | 262 | EXPORT PROC ppcaddilab(d,a,glob:PTR TO gvar) 263 | glob.labrefs := NEW [glob.labrefs, CurrentOffset+2]:LONG 264 | ppcaddi(d,a,glob.offset) 265 | ENDPROC 266 | 267 | EXPORT PROC ppclacode(d,lab:PTR TO genlab) 268 | DEF t 269 | IF lab.offset 270 | ppcb(1,0,1) 271 | t := lab.offset-CurrentOffset 272 | IF Abs(t) < $7FFF 273 | ppcmfspr(d,8) 274 | ppcaddi(d,d,t) 275 | ELSE 276 | ppcmfspr(d,8) 277 | ppcaddi(d,d,t AND $FFFF) 278 | ppcaddis(d,d,Shr(t,16) AND $FFFF + IF t AND $8000 THEN 1 ELSE 0) 279 | ENDIF 280 | ELSE 281 | ppcb(1,0,1) 282 | lab.labrefs := NEW [lab.labrefs, CurrentOffset, REF1616]:labref 283 | ppcmfspr(d,8) 284 | ppcaddi(d,d,NIL) 285 | ppcaddis(d,d,NIL) 286 | ENDIF 287 | ENDPROC 288 | 289 | EXPORT PROC ppclwzlab(d,a,glob:PTR TO gvar) 290 | glob.labrefs := NEW [glob.labrefs, CurrentOffset+2]:LONG 291 | ppclwz(d,a,glob.offset) 292 | ENDPROC 293 | 294 | EXPORT PROC ppcstwlab(s,a,glob:PTR TO gvar) 295 | glob.labrefs := NEW [glob.labrefs, CurrentOffset+2]:LONG 296 | ppcstw(s,a,glob.offset) 297 | ENDPROC 298 | 299 | EXPORT PROC ppclfslab(d,a,glob:PTR TO gvar) 300 | glob.labrefs := NEW [glob.labrefs, CurrentOffset+2]:LONG 301 | ppclfs(d,a,glob.offset) 302 | ENDPROC 303 | 304 | EXPORT PROC ppclfdlab(d,a,glob:PTR TO gvar) 305 | glob.labrefs := NEW [glob.labrefs, CurrentOffset+2]:LONG 306 | ppclfd(d,a,glob.offset) 307 | ENDPROC 308 | 309 | EXPORT PROC ppcstfslab(s,a,glob:PTR TO gvar) 310 | glob.labrefs := NEW [glob.labrefs, CurrentOffset+2]:LONG 311 | ppcstfs(s,a,glob.offset) 312 | ENDPROC 313 | 314 | EXPORT PROC ppcstfdlab(s,a,glob:PTR TO gvar) 315 | glob.labrefs := NEW [glob.labrefs, CurrentOffset+2]:LONG 316 | ppcstfd(s,a,glob.offset) 317 | ENDPROC 318 | 319 | 320 | /* 68k low level stuff */ 321 | 322 | #define ADDGLOBREF(_a_) lab.labrefs := NEW [lab.labrefs, CurrentOffset+_a_]:LONG 323 | 324 | EXPORT PROC bsrlab(lab:PTR TO genlab, forcefar=FALSE) 325 | DEF t 326 | #ifdef DBG_ASSEM 327 | DEBUGF('bsrlab(lab=$\h) \d\n', lab, lab.offset) 328 | #endif 329 | t := lab.offset - CurrentOffset-2 330 | IF lab.offset 331 | IF forcefar -> 2.0, nilcheck 332 | bsrofs32(t) 333 | ELSEIF Abs(t) < 32767 334 | bsrofs16(t) 335 | ELSE 336 | bsrofs32(t) 337 | ENDIF 338 | ELSE 339 | lab.labrefs := NEW [lab.labrefs, CurrentOffset+2, REF32]:labref 340 | bsrofs32(NIL) 341 | ENDIF 342 | ENDPROC 343 | 344 | EXPORT PROC bcclab(cc,lab:PTR TO codelab) 345 | DEF pcofs, t 346 | #ifdef DBG_ASSEM 347 | DEBUGF('bcclab(cc=\d, lab=$\h)\n', cc, lab) 348 | #endif 349 | pcofs := CurrentOffset + 2 350 | IF lab.offset 351 | t := lab.offset - pcofs 352 | IF Abs(t) < 128 353 | RETURN bccofs8(cc,t) 354 | ELSEIF Abs(t) < 32767 355 | RETURN bccofs16(cc,t) 356 | ELSE 357 | reportErr('Too large distance', lab.name) -> too large distance 358 | ENDIF 359 | ENDIF 360 | lab.labrefs := NEW [lab.labrefs, pcofs, REF16]:labref 361 | bccofs16(cc,NIL) 362 | ENDPROC 363 | 364 | EXPORT PROC dbcclab(cc,dx,lab:PTR TO codelab) 365 | DEF t 366 | t := lab.offset - CurrentOffset - 2 367 | IF Abs(t) > 32767 THEN reportErr('Too large distance', lab.name) 368 | IF lab.offset 369 | dbccofs(cc,dx,t) 370 | ELSE 371 | lab.labrefs := NEW [lab.labrefs, CurrentOffset+2, REF16]:labref 372 | dbccofs(cc,dx,NIL) 373 | ENDIF 374 | ENDPROC 375 | 376 | -> optimisations implemented: 377 | -> move.l #0, lab(ax) -> clr.l lab(ax) 378 | -> cmp.l #0, lab(ax) -> tst.l lab(ax) 379 | -> add.l #imm, lab(ax) -> addq.l #imm, lab(ax) 380 | -> sub.l #imm, lab(ax) -> subq.l #imm, lab(ax) 381 | 382 | EXPORT PROC moveldxaxplab(dx,axp,lab:PTR TO gvar) 383 | ADDGLOBREF(2) 384 | movedxaxpofs(SIZE_L,dx,axp,NIL) 385 | ENDPROC 386 | 387 | EXPORT PROC movelaxaxplab(ax,axp,lab:PTR TO gvar) 388 | ADDGLOBREF(2) 389 | moveaxaxpofs(SIZE_L,ax,axp,NIL) 390 | ENDPROC 391 | 392 | EXPORT PROC movelaxpaxplab(axp1,axp2,lab:PTR TO gvar) 393 | ADDGLOBREF(2) 394 | moveaxpaxpofs(SIZE_L,axp1,axp2,NIL) 395 | ENDPROC 396 | 397 | EXPORT PROC movelaxpiaxplab(axp1,axp2,lab:PTR TO gvar) 398 | ADDGLOBREF(2) 399 | moveaxpiaxpofs(SIZE_L,axp1,axp2,NIL) 400 | ENDPROC 401 | 402 | EXPORT PROC movelaxpdaxplab(axp1,axp2,lab:PTR TO gvar) 403 | ADDGLOBREF(2) 404 | moveaxpdaxpofs(SIZE_L,axp1,axp2,NIL) 405 | ENDPROC 406 | 407 | EXPORT PROC movelaxpofsaxplab(axp1,ofs,axp2,lab:PTR TO gvar) 408 | ADDGLOBREF(4) 409 | moveaxpofsaxpofs(SIZE_L,axp1,ofs,axp2,NIL) 410 | ENDPROC 411 | 412 | EXPORT PROC movelaxplabaxplab(axp1,lab1:PTR TO gvar,axp2,lab2:PTR TO gvar) 413 | lab1.labrefs := NEW [lab1.labrefs, CurrentOffset+2]:LONG 414 | lab2.labrefs := NEW [lab2.labrefs, CurrentOffset+4]:LONG 415 | moveaxpofsaxpofs(SIZE_L,axp1,NIL,axp2,NIL) 416 | ENDPROC 417 | 418 | EXPORT PROC movelaxpxaxplab(axp1,idrx,scale,d,axp2,lab:PTR TO gvar) 419 | ADDGLOBREF(4) 420 | moveaxpxaxpofs(SIZE_L,axp1,idrx,scale,d,axp2,NIL) 421 | ENDPROC 422 | 423 | EXPORT PROC movelimmaxplab(imm,axp,lab:PTR TO gvar) 424 | IF imm=0 THEN RETURN clrlaxplab(axp,lab) 425 | ADDGLOBREF(6) 426 | movelimmaxpofs(imm,axp,NIL) 427 | ENDPROC 428 | 429 | EXPORT PROC clrlaxplab(axp,lab:PTR TO gvar) 430 | ADDGLOBREF(2) 431 | clraxpofs(SIZE_L,axp,NIL) 432 | ENDPROC 433 | 434 | EXPORT PROC movelpcplabaxplab(lab1:PTR TO codelab,axp,lab2:PTR TO gvar) 435 | lab1.labrefs := NEW [lab1.labrefs, CurrentOffset+2,REF16]:labref 436 | lab2.labrefs := NEW [lab2.labrefs, CurrentOffset+4]:LONG 437 | movepcpofsaxpofs(SIZE_L,NIL,axp,NIL) 438 | ENDPROC 439 | EXPORT PROC movelpcplabdx(lab1:PTR TO codelab,dx) 440 | lab1.labrefs := NEW [lab1.labrefs, CurrentOffset+2,REF16]:labref 441 | movepcpofsdx(SIZE_L,NIL,dx) 442 | ENDPROC 443 | EXPORT PROC movelpcplabax(lab1:PTR TO codelab,ax) 444 | lab1.labrefs := NEW [lab1.labrefs, CurrentOffset+2,REF16]:labref 445 | movepcpofsax(SIZE_L,NIL,ax) 446 | ENDPROC 447 | EXPORT PROC movelpcplabaxp(lab1:PTR TO codelab,ax) 448 | lab1.labrefs := NEW [lab1.labrefs, CurrentOffset+2,REF16]:labref 449 | movepcpofsaxp(SIZE_L,NIL,ax) 450 | ENDPROC 451 | EXPORT PROC movelpcplabaxpi(lab1:PTR TO codelab,ax) 452 | lab1.labrefs := NEW [lab1.labrefs, CurrentOffset+2,REF16]:labref 453 | movepcpofsaxpi(SIZE_L,NIL,ax) 454 | ENDPROC 455 | EXPORT PROC movelpcplabaxpd(lab1:PTR TO codelab,ax) 456 | lab1.labrefs := NEW [lab1.labrefs, CurrentOffset+2,REF16]:labref 457 | movepcpofsaxpd(SIZE_L,NIL,ax) 458 | ENDPROC 459 | EXPORT PROC movelpcplabaxpofs(lab1:PTR TO codelab,axp,ofs) 460 | lab1.labrefs := NEW [lab1.labrefs, CurrentOffset+2,REF16]:labref 461 | movepcpofsaxpofs(SIZE_L,NIL,axp,ofs) 462 | ENDPROC 463 | 464 | EXPORT PROC movelaxplabdx(axp,lab:PTR TO gvar,dx) 465 | ADDGLOBREF(2) 466 | moveaxpofsdx(SIZE_L,axp,NIL,dx) 467 | ENDPROC 468 | 469 | EXPORT PROC movelaxplabax(axp,lab:PTR TO gvar,ax) 470 | ADDGLOBREF(2) 471 | moveaxpofsax(SIZE_L,axp,NIL,ax) 472 | ENDPROC 473 | 474 | EXPORT PROC moveaxplabaxp(s,axp1,lab:PTR TO gvar,axp2) 475 | ADDGLOBREF(2) 476 | moveaxpofsaxp(s,axp1,NIL,axp2) 477 | ENDPROC 478 | 479 | EXPORT PROC movelaxplabaxpi(axp1,lab:PTR TO gvar,axp2) 480 | ADDGLOBREF(2) 481 | moveaxpofsaxpi(SIZE_L,axp1,NIL,axp2) 482 | ENDPROC 483 | 484 | EXPORT PROC movelaxplabaxpd(axp1,lab:PTR TO gvar,axp2) 485 | ADDGLOBREF(2) 486 | moveaxpofsaxpd(SIZE_L,axp1,NIL,axp2) 487 | ENDPROC 488 | 489 | EXPORT PROC moveaxplabaxpofs(s,axp1,lab:PTR TO gvar,axp2,ofs) 490 | ADDGLOBREF(2) 491 | moveaxpofsaxpofs(s,axp1,NIL,axp2,ofs) 492 | ENDPROC 493 | 494 | EXPORT PROC moveaxplabaxpx(s,axp1,lab:PTR TO gvar,axp2,idrx,scale,d) 495 | ADDGLOBREF(2) 496 | moveaxpofsaxpx(s,axp1,NIL,axp2,idrx,scale,d) 497 | ENDPROC 498 | 499 | EXPORT PROC leapcplabax(lab:PTR TO codelab,ax) 500 | DEF pcofs, t 501 | pcofs := CurrentOffset + 2 502 | IF lab.offset 503 | t := lab.offset - pcofs 504 | IF Abs(t) < 32768 505 | leapcpofsax(t, ax) 506 | ELSE 507 | ->lab.labrefs := NEW [lab.labrefs, pcofs, REFADR]:labref 508 | putMOVEI(SIZE_L,ax,M1,lab.offset) ->movelimmax(NIL, ax) 509 | AddReloc(pcofs) 510 | ENDIF 511 | ELSE 512 | lab.labrefs := NEW [lab.labrefs, pcofs, REFADR]:labref 513 | putMOVEI(SIZE_L,ax,M1,NIL) ->movelimmax(NIL, ax) 514 | ENDIF 515 | ENDPROC 516 | 517 | EXPORT PROC leaaxplabax(axp,lab:PTR TO gvar,ax) 518 | ADDGLOBREF(2) 519 | leaaxpofsax(axp,NIL,ax) 520 | ENDPROC 521 | 522 | EXPORT PROC cmplimmaxplab(imm,ax,lab:PTR TO gvar) 523 | IF imm=0 THEN RETURN tstlaxplab(ax,lab) 524 | ADDGLOBREF(6) 525 | cmplimmaxpofs(imm,ax,NIL) 526 | ENDPROC 527 | 528 | EXPORT PROC tstlaxplab(ax,lab:PTR TO gvar) 529 | ADDGLOBREF(2) 530 | tstaxpofs(SIZE_L,ax,NIL) 531 | ENDPROC 532 | 533 | EXPORT PROC cmplaxplabdx(ax,lab:PTR TO gvar,dx) 534 | ADDGLOBREF(2) 535 | cmpaxpofsdx(SIZE_L,ax,NIL,dx) 536 | ENDPROC 537 | 538 | EXPORT PROC cmplaxplabax(axp,lab:PTR TO gvar,ax) 539 | ADDGLOBREF(2) 540 | cmpaxpofsax(SIZE_L,axp,NIL,ax) 541 | ENDPROC 542 | 543 | EXPORT PROC sublimmaxplab(imm,axp,lab:PTR TO gvar) 544 | IF Abs(imm) < 9 AND (imm > 0) THEN RETURN subqlaxplab(imm,axp,lab) 545 | ADDGLOBREF(6) 546 | sublimmaxpofs(imm,axp,NIL) 547 | ENDPROC 548 | 549 | EXPORT PROC subqlaxplab(imm,axp,lab:PTR TO gvar) 550 | ADDGLOBREF(2) 551 | subqaxpofs(SIZE_L,imm,axp,NIL) 552 | ENDPROC 553 | 554 | EXPORT PROC subldxaxplab(dx,axp,lab:PTR TO gvar) 555 | ADDGLOBREF(2) 556 | subdxaxpofs(SIZE_L,dx,axp,NIL) 557 | ENDPROC 558 | 559 | EXPORT PROC sublaxplabdx(axp,lab:PTR TO gvar,dx) 560 | ADDGLOBREF(2) 561 | subaxpofsdx(SIZE_L,axp,NIL,dx) 562 | ENDPROC 563 | 564 | EXPORT PROC sublaxplabax(axp,lab:PTR TO gvar,ax) 565 | ADDGLOBREF(2) 566 | subaxpofsax(SIZE_L,axp,NIL,ax) 567 | ENDPROC 568 | 569 | EXPORT PROC addlimmaxplab(imm,axp,lab:PTR TO gvar) 570 | IF Abs(imm) < 9 AND (imm > 0) THEN RETURN addqlaxplab(imm, axp, lab) 571 | ADDGLOBREF(6) 572 | addlimmaxpofs(imm,axp,NIL) 573 | ENDPROC 574 | 575 | EXPORT PROC addqlaxplab(imm,axp,lab:PTR TO gvar) 576 | ADDGLOBREF(2) 577 | addqaxpofs(SIZE_L,imm,axp,NIL) 578 | ENDPROC 579 | 580 | EXPORT PROC addldxaxplab(dx,axp,lab:PTR TO gvar) 581 | ADDGLOBREF(2) 582 | adddxaxpofs(SIZE_L,dx,axp,NIL) 583 | ENDPROC 584 | 585 | EXPORT PROC addlaxplabdx(axp,lab:PTR TO gvar,dx) 586 | ADDGLOBREF(2) 587 | addaxpofsdx(SIZE_L,axp,NIL,dx) 588 | ENDPROC 589 | 590 | EXPORT PROC addlaxplabax(axp,lab:PTR TO gvar,ax) 591 | ADDGLOBREF(2) 592 | addaxpofsax(SIZE_L,axp,NIL,ax) 593 | ENDPROC 594 | 595 | EXPORT PROC fmoveaxplabfpx(fs,axp,lab:PTR TO gvar,fpx) 596 | put16(Shl(%1111001000000 OR M5,3) OR axp) 597 | put16(Shl(Shl(%010000 OR fs,3) OR fpx,7) OR %0000000) 598 | ADDGLOBREF(0) 599 | put16(NIL) 600 | ENDPROC 601 | 602 | EXPORT PROC fmovefpxaxplab(fs,fpx,axp,lab:PTR TO gvar) 603 | put16(Shl(%1111001000000 OR M5,3) OR axp) 604 | put16(Shl(Shl(%011000 OR fs,3) OR fpx,7) OR %0000000) 605 | ADDGLOBREF(0) 606 | put16(NIL) 607 | ENDPROC 608 | -------------------------------------------------------------------------------- /binary.e: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | ** ECX/binary.e. 3 | ** Copyright (c) Leif Salomonsson 2002-2008. 4 | ** Redistribution of this source is allowed as long as: 5 | ** 1. no copyright notice is removed or altered. 6 | ** 2. altered source must be clearly marked as such. 7 | *************************************************************************/ 8 | 9 | OPT MODULE 10 | OPT EXPORT 11 | OPT PREPROCESS 12 | 13 | MODULE 'exec/semaphores' 14 | MODULE 'exec/lists' 15 | MODULE 'exec/nodes' 16 | 17 | EXPORT CONST MODULEVERSION = 1 18 | 19 | EXPORT ENUM CPU_NONE = -1, -> 2.0 20 | CPU_M68,-> 1.10.0 21 | CPU_PPC 22 | 23 | -> v2.0 procedures/lfuncs 24 | ENUM PPCARGRTYPE_RX, 25 | PPCARGRTYPE_STACKRX, 26 | PPCARGRTYPE_FX, 27 | PPCARGRTYPE_VX, 28 | PPCARGRTYPE_RX2, 29 | PPCARGRTYPE_STACKRX2 30 | 31 | -> 2.3 32 | ENUM M68ARGTYPE_STACK, 33 | M68ARGTYPE_FREG, 34 | M68ARGTYPE_STACK_WIDE 35 | 36 | EXPORT OBJECT modulecache OF ss 37 | ident:INT -> 1.8.0 "MC" (was pad:INT) 38 | modlist:mlh 39 | rsrvd:LONG 40 | ENDOBJECT 41 | 42 | OBJECT modinfo 43 | rsrvd:LONG 44 | count:LONG 45 | misc:LONG 46 | ENDOBJECT 47 | 48 | OBJECT modextens -> internal structure, not actually part of moduleformat 49 | codelist:LONG 50 | rname:PTR TO CHAR 51 | referenced:INT 52 | secondary:INT 53 | ENDOBJECT 54 | 55 | ENUM OSID_NONE, 56 | OSID_AMIGAOS, 57 | OSID_AMIGAOS4, 58 | OSID_MORPHOS, 59 | OSID_AROS, 60 | OSID_LINUX 61 | 62 | OBJECT moduleheader 63 | succ:PTR TO moduleheader -> NIL on disk 64 | pred:PTR TO moduleheader -> NIL on disk 65 | identification:LONG -> "ECXM" 66 | mname:PTR TO CHAR -> name of module 67 | mnamelen:INT -> len of name 68 | headsize:INT -> SIZEOF moduleheader 69 | modextens:PTR TO modextens -> v45 70 | rsrvd[16]:ARRAY 71 | checksum:LONG 72 | checksumstart[1]:ARRAY OF LONG 73 | cpu:INT -> 0=68k, 1=ppc 74 | cpubits:INT -> flags, currently NIL. 75 | modsize:LONG -> total size of module 76 | stacksize:LONG 77 | osversion:INT 78 | modversion:INT -> v45: 1 79 | keepnil:LONG -> WAS oschars[4]:ARRAY OF CHAR (DONTUSE THIS) -> 1.5.6 "\0\0\0\0"/"AOS3"/"ABOX"/"AOS4"/"AROS" 80 | dummymod:LONG -> TRUE if dummy modulehead in cache (1.10.0) 81 | rsrvd2:LONG 82 | osid:LONG -> 2.0, OSID_XXX 83 | strtabinfo 84 | macroinfo 85 | libiinfo 86 | constinfo 87 | procinfo 88 | objectinfo 89 | moduleinfo 90 | codeinfo 91 | ifuncinfo 92 | xrefginfo 93 | dreldinfo 94 | globinfo 95 | datainfo 96 | relocinfo 97 | lineinfo 98 | debuginfo 99 | const64info -> 1.8.0 (not used yet) 100 | relainfo -> 1.10.0 -> elf relocations (to support HA/LO type relocs) (not used yet) 101 | globinitinfo -> 2.2 102 | xglobderefinfo -> 2.2 103 | ENDOBJECT /* SIZEOF = 160 */ 104 | 105 | OBJECT modmacro -> compatible with macro ! 106 | rsrvd:INT 107 | totalsize:INT -> to skip to next 108 | name:LONG 109 | type:CHAR -> 0:define macro, 1:define macro function, 2:asm macro, 3:varargs macor 110 | nrofargs:CHAR 111 | bodysize:INT -> including longalign+nilterm 112 | pad:LONG -> used internally 113 | -> IF Odd(type) THEN args[nrofargs]:ARRAY OF LONG 114 | -> body[bodysize]:ARRAY OF CHAR 115 | ENDOBJECT 116 | 117 | OBJECT modlibi 118 | basename:LONG 119 | totalsize:LONG 120 | nroflfuncs:INT 121 | rsrvd:INT 122 | -> lfuncs[nroflfuncs]:ARRAY OF modlfunc 123 | ENDOBJECT 124 | 125 | OBJECT lfuncarg -> v45 126 | name:LONG -> v46 127 | rsrvd:CHAR 128 | rtype:CHAR 129 | rnum:INT 130 | ENDOBJECT 131 | 132 | OBJECT modlfunc -> compatible with lfunc ! 133 | rsrvd:INT 134 | totalsize:INT -> v44 135 | name:LONG 136 | nrofargs:CHAR 137 | type:CHAR -> 0=68k abi, 1=ppc sysv abi 138 | baseofs:INT 139 | basernum:CHAR -> for ppc sysv 140 | return:CHAR -> sysv: o=rx, 1=fx, 2:vx, 3:wide 141 | basertype:CHAR -> 0:rx, 1:stack, 255:monolithic calling 142 | flags:CHAR ->1.7.1 LFFLAG_XXX 143 | dummy[2]:ARRAY OF LONG -> we need extra space internally 144 | -> regs[nrofparams]:ARRAY OF lfuncarg 145 | ENDOBJECT 146 | 147 | SET LFFLAG_KERNELFUNC, 148 | LFFLAG_VARARGS -> 2.0 149 | 150 | OBJECT modconst 151 | name:LONG 152 | value:LONG 153 | ENDOBJECT 154 | 155 | OBJECT double 156 | high:LONG 157 | low:LONG 158 | ENDOBJECT 159 | 160 | OBJECT modconst64 -> not used yet 161 | name:LONG 162 | flags:LONG 163 | value:double 164 | ENDOBJECT 165 | 166 | SET PROCF_EMPTY, -> not really used yet 167 | PROCF_CLMETH 168 | 169 | OBJECT modlabel 170 | name:LONG 171 | offset:LONG 172 | rsrvd:CHAR 173 | flags:CHAR -> v46,47 PROCF_XXX 174 | totalsize:INT -> if 12, then we are a label, and no more data. 175 | ENDOBJECT 176 | 177 | OBJECT modproc OF modlabel -> also used for methods and labels 178 | nrofargs:CHAR 179 | nrofdefaults:CHAR 180 | return:CHAR -> 0:integer reg, 1:double reg, 2:vector, 3:wide 181 | selfreg:CHAR -> v45, for methods 182 | -> params[nrofparams]:ARRAY OF modarg 183 | ENDOBJECT 184 | 185 | /* 186 | OBJECT oldmodstatic OF modlabel 187 | -> up till now compatible with modproc 188 | nrofargs:CHAR -> 0, to be compatible with older tools 189 | statflags:CHAR -> MEMBF_XXX 190 | statesize:CHAR -> 1,2,4,8,255 191 | unused:CHAR 192 | -> at this point same size as modproc 193 | statobj:LONG -> name of object if any. 194 | ENDOBJECT /* SIZEOF = 20 */ 195 | */ 196 | 197 | -> changed v2.2 198 | OBJECT modstatic OF modlabel 199 | -> up till now compatible with modproc 200 | nrofargs:CHAR -> 0, to be compatible with older tools 201 | statflags:CHAR -> MEMBF_XXX 202 | keepnil:CHAR -> NIL, this is proc.return to old code. 203 | statesize:CHAR -> 1,2,4,8,255 204 | -> at this point same size as modproc 205 | statobj:LONG -> name of object if any. 206 | sizeof:LONG -> yeah.. for SIZEOF support 207 | ENDOBJECT /* SIZEOF = 24 */ 208 | 209 | -> v49 210 | #define MODPROC_RETURN1(ret) (ret AND $3) 211 | #define MODPROC_RETURN2(ret) (Shr(ret,2) AND $3) 212 | #define MODPROC_RETURN3(ret) (Shr(ret,4) AND $3) 213 | #define MODPROC_RETURN4(ret) (Shr(ret,6) AND $3) 214 | #define MAKE_MODPROC_RETURN(r1,r2,r3,r4) r1 \ 215 | OR Shl(r2,2)\ 216 | OR Shl(r3,4)\ 217 | OR Shl(r4,6) 218 | 219 | OBJECT modarg 220 | name:LONG -> 221 | defval:LONG 222 | rsrvd:CHAR 223 | rtype:CHAR -> 0:rx, 1:stack, 2:fx, 3:vector 224 | rnum:INT -> regnum or stackoffset or nil CHANGED v46 225 | ENDOBJECT 226 | 227 | SET OFLAG_NOCLASSINFO -> 1.8.1, set for object with only class methods. useful at new/end 228 | 229 | OBJECT modobject 230 | name:LONG 231 | nrofmembers:INT 232 | nrofmethods:INT 233 | sizeof:INT 234 | flags:CHAR -> OFLAG_XXX (was: rsrvd) 235 | alignment:CHAR -> v1.5 236 | totalsize:LONG -> of modobject 237 | -> members[nrofmembers]:ARRAY OF modmember 238 | -> IF nrofmethods THEN modclass:modclass 239 | ENDOBJECT 240 | 241 | OBJECT modclass 242 | classofs:INT -> classinfo in object 243 | destofs:INT -> destructor ( .end() ), or -1 244 | offset:LONG -> classinfo in code 245 | supername:LONG -> 1.10.0 it is back. only for inheritation inside same module, otherwise see ref_inherit 246 | rsrvd2:LONG 247 | -> methods[modobject.nrofmethods]:ARRAY OF modproc 248 | ENDOBJECT 249 | 250 | -> v48 251 | SET MEMBF_PRIVATE, -> only used internally in ECX 252 | MEMBF_FLOAT, -> set if DOUBLE, PTR TO DOUBLE, ARRAY OF DOUBLE 253 | MEMBF_SIGNED, -> v49. signed/unsigned (LONG/INT, PTR TO LONG/INT, ARRAY OF LONG/INT) 254 | MEMBF_VECTOR -> was "forgotten" added 1.7 255 | 256 | OBJECT modmember -> same as "member" !! v44 257 | size:CHAR, esize:CHAR, numes:INT 258 | object:LONG 259 | offset:INT 260 | flags:INT -> (was: rsrvd) v48: MEMBF_XXX or NIL 261 | name:LONG 262 | ENDOBJECT 263 | 264 | OBJECT vdbghead -> used in executables 265 | vdbgid:LONG -> "VDBG" 266 | namelongs:LONG 267 | strtablongs:LONG 268 | numdebugs:LONG 269 | rsrvd:LONG -> NIL 270 | ENDOBJECT 271 | -> sourcename[namelongs]:ARRAY OF LONG 272 | -> strtab[strtablongs]:ARRAY OF LONG 273 | -> debugs[numdebugs]:ARRAY OF vardbg 274 | 275 | 276 | OBJECT vardbg -> changed again v50 277 | name:LONG -> name of variable 278 | inproc:LONG -> name of procedure 279 | ofobject:LONG -> name of methods object, if variable of method 280 | scope:CHAR -> 0:internglob, 1:relocglob, 2:xrefglob, 3:global 281 | varsize:CHAR -> 0/1/2/4/8/16 282 | varesize:CHAR -> 0/1/2/4/8/16/255 283 | varreg:CHAR -> D0-D7:0-7 / A0-A7:8-15 / R0-R31:0-31 284 | varofs:INT -> -1:variable is register, else ofs(reg). 285 | varflags:INT -> MEMBF_SIGNED, MEMBF_FLOAT, MEMBF_VECTOR, or NIL 286 | varobject:LONG -> if type.esize=255, else NIL 287 | ENDOBJECT /* SIZEOF = 24 */ 288 | 289 | ENUM VDSCOPE_INTERN, -> modules / main 290 | VDSCOPE_RELOC, -> modules only 291 | VDSCOPE_XREF, -> modules only 292 | VDSCOPE_GLOBAL, -> main (exe) 293 | VDSCOPE_PROC 294 | 295 | OBJECT modmodule 296 | name:LONG -> negative names are relative ! 297 | totalsize:LONG -> total size of this modmodule 298 | rsrvd:INT 299 | numsymbs:INT -> nr of symbols referenced 300 | -> modrefs[numsymbs]:ARRAY OF modref 301 | ENDOBJECT 302 | 303 | OBJECT modref 304 | name:LONG -> or "num" for ifuncs 305 | ltype:CHAR -> NIL for ifuncs 306 | info:CHAR -> numparams for PROC, NIL for ifuncs 307 | numrefs:INT 308 | -> refs[numrefs]:ARRAY OF LONG -> [type:8, offset:24] 309 | ENDOBJECT 310 | 311 | 312 | CONST REF32 = 0, 313 | REF24 = 1, 314 | REFADR = 2, 315 | REF1616 = 3, 316 | REF_INHERIT = 4, -> V47 class inheritation between modules 317 | /* internal types */ 318 | REF16 = 5, 319 | REF14 = 6 320 | 321 | 322 | CONST LTYPE_LAB = 0, 323 | LTYPE_PROC = 1, 324 | LTYPE_CLASS = 2, 325 | LTYPE_STATIC = 3-> 1.9.0 326 | 327 | -> 2.2 328 | 329 | OBJECT xglobderef 330 | totalsize:LONG -> SIZEOF xglobderef 331 | name:LONG 332 | esize:CHAR 333 | rsrvd1:CHAR 334 | rsrvd2:INT 335 | object:LONG 336 | ENDOBJECT 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /ceemodule.e: -------------------------------------------------------------------------------- 1 | /* CeeModule.e by Leif Salomonsson is Copyright (c) 2008 */ 2 | /* Released under ECX TOOLS LICENSE, see ECXTOOLSLICENSE.TXT */ 3 | 4 | -> Prints out ECX module in C-friendlier way. 5 | 6 | -> Libraryfunctions as either FD or Prototypes. 7 | -> Objects as Structs. 8 | -> Constants as #defines. 9 | 10 | -> Requires ecx 1.10+ compiled modules to display libfunc argument names properly. 11 | 12 | -> May 2008: 1.0 13 | -> Sep 2009: 1.1: made types into exec/types.h style instead. 14 | -> Mar 2010: 1.2: silly field array print bug fixed. 15 | 16 | MODULE '*binary' 17 | MODULE 'dos/dos' 18 | 19 | OBJECT args 20 | module 21 | libprotos 22 | ENDOBJECT 23 | 24 | PROC main() HANDLE 25 | DEF fh=NIL, str[256]:STRING, rdargs=NIL, args:PTR TO args 26 | DEF fib:fileinfoblock, flen, fbuf, filename[300]:STRING 27 | DEF a, b, c, lptr:PTR TO LONG, e, fdofs 28 | DEF head:PTR TO moduleheader 29 | DEF strtable 30 | DEF info:PTR TO modinfo 31 | DEF object:PTR TO modobject 32 | DEF libi:PTR TO modlibi 33 | DEF lfunc:PTR TO modlfunc 34 | DEF param:PTR TO modarg 35 | DEF member:PTR TO modmember 36 | DEF lparam:PTR TO lfuncarg 37 | 38 | NEW args 39 | 40 | /* read agrs */ 41 | rdargs := ReadArgs('MODULE/A,LIBPROTOS/S', args, NIL) 42 | 43 | IF rdargs = NIL THEN Raise("ARGS") 44 | 45 | StrCopy(str, args.module) 46 | 47 | IF StrCmp(str+EstrLen(str)-2, '.m') = FALSE THEN StrAdd(str, '.m') 48 | StrCopy(filename, str) 49 | 50 | fh := Open(filename, OLDFILE) 51 | IF fh = NIL 52 | StrCopy(str, 'ECXMODULES:') 53 | StrAdd(str, filename) 54 | StrCopy(filename, str) 55 | fh := Open(filename, OLDFILE) 56 | IF fh = NIL THEN Raise("OPEN") 57 | ENDIF 58 | 59 | PrintF('CeeModule 1.2 by LS 2008-10 -> \q\s\q\n\n', filename) 60 | 61 | ExamineFH(fh, fib) 62 | flen := fib.size 63 | fbuf := NewR(flen+4) 64 | Read(fh, fbuf, flen) 65 | head := fbuf 66 | 67 | IF head.identification <> "ECXM" THEN Raise("FORM") 68 | 69 | IF head.modversion < 1 THEN Raise("TOLD") -> 1.11 70 | 71 | IF head.modsize <> flen THEN Raise("SIZE") -> 1.11 72 | 73 | IF head.osversion THEN PrintF('/* OSVERSION: \d */ \n\n', head.osversion) 74 | 75 | info := head + head.strtabinfo 76 | strtable := info + SIZEOF modinfo 77 | 78 | /* FD */ 79 | info := head.libiinfo 80 | IF info <> NIL AND (args.libprotos = FALSE) 81 | info := info + head 82 | libi := info + SIZEOF modinfo 83 | c := info.count + 1 84 | WHILE c-- 85 | PrintF('##base _\s\n##bias 30\n', libi.basename + strtable) 86 | fdofs := -30 87 | lfunc := libi + SIZEOF modlibi 88 | FOR a := 0 TO libi.nroflfuncs-1 89 | IF lfunc.baseofs < (fdofs + IF lfunc.type = 1 THEN 2 ELSE 0) 90 | PrintF('##private\n') 91 | WHILE lfunc.baseofs < (fdofs + IF lfunc.type = 1 THEN 2 ELSE 0) 92 | PrintF('Private_\d'+'()\n', -fdofs) 93 | fdofs := fdofs - 6 94 | ENDWHILE 95 | PrintF('##public\n') 96 | ENDIF 97 | PrintF('\s(', lfunc.name + strtable) 98 | lparam := lfunc + SIZEOF modlfunc 99 | FOR b := 0 TO lfunc.nrofargs-1 100 | PrintF('\s', lparam[b].name + strtable) 101 | IF b < (lfunc.nrofargs-1) THEN PrintF(',') 102 | ENDFOR 103 | PrintF(')') 104 | 105 | IF lfunc.type = 0 106 | PrintF('(') 107 | FOR b := 0 TO lfunc.nrofargs-1 108 | PrintF('\c\d', IF lparam[b].rtype = 0 THEN "d" ELSE "a", lparam[b].rnum) 109 | IF b < (lfunc.nrofargs-1) THEN PrintF(',') 110 | ENDFOR 111 | PrintF(')') 112 | ELSE 113 | IF lfunc.basertype = 0 114 | IF lfunc.basernum = 12 115 | PrintF('(sysv,r12base)') 116 | ELSEIF lfunc.basernum = 3 117 | PrintF('(base,sysv)') 118 | ELSEIF lfunc.basernum 119 | PrintF('(sysv,base)') 120 | ELSE 121 | PrintF('(sysv)') 122 | ENDIF 123 | ELSE 124 | PrintF('(sysv,base)') 125 | ENDIF 126 | ENDIF 127 | PrintF('\n') 128 | lfunc := lfunc + lfunc.totalsize 129 | fdofs := fdofs - 6 130 | ENDFOR 131 | PrintF('##end\n\n') 132 | libi := libi + libi.totalsize 133 | ENDWHILE 134 | ENDIF 135 | 136 | /* PROTO */ 137 | info := head.libiinfo 138 | IF info <> NIL AND (args.libprotos <> FALSE ) 139 | info := info + head 140 | libi := info + SIZEOF modinfo 141 | c := info.count + 1 142 | WHILE c-- 143 | lfunc := libi + SIZEOF modlibi 144 | FOR a := 0 TO libi.nroflfuncs-1 145 | PrintF('\l\s \s(', 146 | ListItem(['LONG','DOUBLE','VECTOR','LONG LONG'], lfunc.return), 147 | lfunc.name + strtable) 148 | lparam := lfunc + SIZEOF modlfunc 149 | FOR b := 0 TO lfunc.nrofargs-1 150 | PrintF('\s \s', 151 | ListItem(['LONG','LONG','DOUBLE','VECTOR','LONG LONG', 'LONG LONG'], lparam[b].rtype), 152 | lparam[b].name + strtable) 153 | IF b < (lfunc.nrofargs-1) THEN PrintF(',') 154 | ENDFOR 155 | PrintF(');\n') 156 | lfunc := lfunc + lfunc.totalsize 157 | ENDFOR 158 | libi := libi + libi.totalsize 159 | ENDWHILE 160 | ENDIF 161 | 162 | 163 | /* STRUCT */ 164 | info := head.objectinfo 165 | IF info 166 | info := info + head 167 | object := info + SIZEOF modinfo 168 | c := info.count + 1 169 | WHILE c-- 170 | PrintF('struct \s {\n', object.name + strtable) 171 | member := object + SIZEOF modobject 172 | a := object.nrofmembers + 1 173 | WHILE a-- 174 | PrintF(' \s;\n', 175 | ctypestr50(member.size, 176 | member.esize, 177 | member.numes, 178 | member.object + strtable, 179 | member.flags, 180 | member.name + strtable, 181 | str)) 182 | member++ 183 | ENDWHILE 184 | PrintF('}; /* SIZEOF = \d */\n\n', object.sizeof) 185 | object := object + object.totalsize 186 | ENDWHILE 187 | ENDIF 188 | 189 | /* #DEFINE */ 190 | info := head.constinfo 191 | IF info 192 | info := info + head 193 | lptr := info + SIZEOF modinfo 194 | b := info.count + 1 195 | WHILE b-- 196 | PrintF('#define \s \s\n', lptr[]++ + strtable, valstr(lptr[]++, str)) 197 | ENDWHILE 198 | PrintF('\n') 199 | ENDIF 200 | 201 | PrintF('\n') 202 | 203 | EXCEPT DO 204 | 205 | IF fh THEN Close(fh) 206 | IF rdargs THEN FreeArgs(rdargs) 207 | SELECT exception 208 | CASE "MEM" ; PrintF('Error: out of memory.\n') 209 | CASE "FORM" ; PrintF('Error: not an ecx module.\n') 210 | CASE "ARGS" ; PrintF('Error: bad arguments.\n') 211 | CASE "OPEN" ; PrintF('Error: could not open file.\n') 212 | CASE "TOLD" ; PrintF('Error: module is too old.\n') 213 | CASE "SIZE" ; PrintF('Error: module is corrupt (wrong modsize).\n') 214 | CASE NIL 215 | DEFAULT ; PrintF('Error: unknown.\n') 216 | ENDSELECT 217 | 218 | ENDPROC exception 219 | 220 | 221 | 222 | PROC valstr(val, str) 223 | IF val = $80000000 -> this value actually gets smaller than 255 when Abs():ed. 224 | StringF(str, '0x\h', val) 225 | ELSEIF Abs(val) > 255 226 | StringF(str, '0x\h', val) 227 | ELSE 228 | StringF(str, '\d', val) 229 | ENDIF 230 | ENDPROC str 231 | 232 | PROC ctypestr50(size, esize, numes, object, flags, name, str) 233 | SELECT size 234 | CASE 0 235 | SELECT esize 236 | CASE 1 ; StringF(str, 237 | IF flags AND MEMBF_SIGNED THEN 'BYTE \s'+'[\d]' ELSE 'CHAR \s'+'[\d]', 238 | name, numes) 239 | CASE 2 ; StringF(str, 240 | IF flags AND MEMBF_SIGNED THEN 'WORD \s'+'[\d]' ELSE 'UWORD \s'+'[\d]', 241 | name, numes) 242 | CASE 4 ; StringF(str, 243 | IF flags AND MEMBF_FLOAT THEN 'FLOAT \s'+'[\d]' ELSE 244 | (IF flags AND MEMBF_SIGNED THEN 'LONG \s'+'[\d]' ELSE 'ULONG \s'+'[\d]'), 245 | name, numes) 246 | CASE 8 ; StringF(str, 247 | IF flags AND MEMBF_FLOAT THEN 'DOUBLE \s'+'[\d]' ELSE 'QUAD \s'+'[\d]', 248 | name, numes) 249 | CASE 16 ; StringF(str, 'vector \s'+'[\d]', name, numes) 250 | CASE 255 ; IF numes = 1 251 | StringF(str, 'struct \s \s', object, name) 252 | ELSE 253 | StringF(str, 'struct \s \s'+'[\d]', object, name, numes) 254 | ENDIF 255 | ENDSELECT 256 | CASE 1 ; StringF(str, IF flags AND MEMBF_SIGNED THEN 'BYTE \s' ELSE 'CHAR \s', name) 257 | CASE 2 ; StringF(str, IF flags AND MEMBF_SIGNED THEN 'WORD \s' ELSE 'UWORD \s', name) 258 | CASE 4 259 | SELECT esize 260 | CASE 0 ; StringF(str, IF flags AND MEMBF_SIGNED THEN 'LONG \s' ELSE 261 | (IF flags AND MEMBF_FLOAT THEN 'FLOAT \s' ELSE 'ULONG \s'), 262 | name) 263 | CASE 1 ; StringF(str, 264 | IF flags AND MEMBF_SIGNED THEN 'BYTE *\s' ELSE 'CHAR *\s', name) 265 | CASE 2 ; StringF(str, 266 | IF flags AND MEMBF_SIGNED THEN 'WORD *\s' ELSE 'UWORD *\s', name) 267 | CASE 4 ; StringF(str, IF flags AND MEMBF_SIGNED THEN 'LONG *\s' ELSE 268 | (IF flags AND MEMBF_FLOAT THEN 'FLOAT *\s' ELSE 'ULONG *\s'), name) 269 | CASE 8 ; StringF(str, 270 | IF flags AND MEMBF_FLOAT THEN 'DOUBLE *\s' ELSE 'QUAD *\s', name) 271 | CASE 16 ; StringF(str, 'vector *\s', name) 272 | CASE 255 ; StringF(str, 'struct \s *\s', object, name) 273 | ENDSELECT 274 | CASE 8 275 | StringF(str, IF flags AND MEMBF_FLOAT THEN 'DOUBLE \s' ELSE 'QUAD \s', name) 276 | CASE 16 277 | StringF(str, 'vector \s', name) 278 | SELECT esize 279 | CASE 4 ; StringF(str, 280 | IF flags AND MEMBF_FLOAT THEN 'vector float \s' ELSE 'vector long \s', name) 281 | CASE 2 ; StringF(str, 282 | IF flags AND MEMBF_SIGNED THEN 'vector short \s' ELSE 'vector unsigned short \s', 283 | name) 284 | CASE 1 ; StringF(str, 285 | IF flags AND MEMBF_SIGNED THEN 'vector signed char \s' ELSE 'vector char', 286 | name) 287 | ENDSELECT 288 | ENDSELECT 289 | ENDPROC str 290 | 291 | 292 | -------------------------------------------------------------------------------- /common.e: -------------------------------------------------------------------------------- 1 | -> ECX/common.e 2 | 3 | /* ECX by Leif Salomonsson [ecx tele2 se] is Copyright (c) 2002-2008 */ 4 | /* Released under the ECX COMPILER LICENSE, See ECXCOMPILERLICENSE.TXT */ 5 | 6 | OPT MODULE 7 | OPT PREPROCESS 8 | 9 | -> common.e new file created Sept 2007. Moved some common stuff out of ecx52.e source. 10 | 11 | ->#define DBG_HASH 12 | 13 | MODULE '*compiler' 14 | MODULE '*binary' 15 | MODULE 'dos/dos' 16 | 17 | EXPORT DEF itmz_labelhashtable:PTR TO LONG -> main inits 18 | EXPORT DEF g_symbolssize -> main reads 19 | 20 | -> we "import" these from main (error reporting) 21 | EXPORT DEF g_currentproc:PTR TO proc, g_linenum, g_sourcename 22 | EXPORT DEF g_nowarn 23 | EXPORT DEF g_warnlist, g_optmodule 24 | 25 | EXPORT PROC newString(size) IS String(size) 26 | 27 | 28 | EXPORT PROC endString(s:PTR TO LONG) IS DisposeLink(s) 29 | 30 | 31 | PROC hashNewHLN(str, i) 32 | DEF hln:PTR TO hln, len, nstr 33 | #ifdef DBG_HASH 34 | DEBUGF('hashNewHLN(\a\s\a, \d)\n', str, i) 35 | #endif 36 | NEW hln 37 | len := StrLen(str) 38 | nstr := String(len) 39 | IF nstr = NIL THEN Raise("MEM") 40 | hln.name := nstr 41 | StrCopy(nstr, str) 42 | hln.hnext := itmz_labelhashtable[i] 43 | itmz_labelhashtable[i] := hln 44 | g_symbolssize := g_symbolssize + len -> v40. to get idea of max strtabsize/symbolhunksize 45 | ENDPROC hln 46 | 47 | PROC hashFindHLN(str, i) 48 | DEF hln:PTR TO hln 49 | #ifdef DBG_HASH 50 | DEBUGF('hashFindHLN(\a\s\a, \d)\n ', str, i) 51 | #endif 52 | hln := itmz_labelhashtable[i] 53 | WHILE hln 54 | IF StrCmp(hln.name, str) THEN RETURN hln 55 | hln := hln.hnext 56 | ENDWHILE 57 | ENDPROC NIL 58 | 59 | EXPORT PROC getLabelHLN(str) 60 | DEF hln:PTR TO hln, i 61 | #ifdef DBG_HASH 62 | DEBUGF('getLabelHLN(\a\s\a) : ', str) 63 | #endif 64 | i := hashfunc(str) 65 | hln := hashFindHLN(str, i) 66 | IF hln = NIL THEN hln := hashNewHLN(str, i) 67 | #ifdef DBG_HASH 68 | DEBUGF('I:\d HLN:$\h = [$\h,$\h]\n', i, hln,hln.ident,hln.ident2) 69 | #endif 70 | ENDPROC hln 71 | 72 | EXPORT PROC hashfunc(s) -> v50 73 | DEF i, v=0, a=1, c 74 | #ifdef DBG_HASH 75 | DEBUGF('hashfunc(\a\s\a) : ', s) 76 | #endif 77 | WHILE (c := s[]++) 78 | v := v * a + c 79 | a++ 80 | ENDWHILE 81 | i := Abs(Mod(v, LHASHSIZE)) 82 | #ifdef DBG_HASH 83 | DEBUGF('Abs(Mod(\h, \d)) = \d\n', v, LHASHSIZE, i) 84 | #endif 85 | i := Min(i, LHASHSIZE-1) -> work around mos emu bug 86 | ENDPROC i 87 | 88 | 89 | EXPORT PROC reportErr(err, extra=NIL) 90 | DEF str[100]:STRING 91 | 92 | WriteF('ERROR: \s \s\s\s\n', 93 | err, 94 | IF extra THEN '"' ELSE '', 95 | IF extra THEN extra ELSE '', 96 | IF extra THEN '"' ELSE '') 97 | 98 | IF g_currentproc THEN WriteF('Procedure: \s\n', g_currentproc.name) 99 | 100 | IF g_linenum <> 0 THEN WriteF('Line \d: \s\n', Abs(g_linenum), getSourceLine(str)) 101 | 102 | Raise("ERR") 103 | ENDPROC 104 | 105 | EXPORT PROC reportIErr(err, extra=NIL) -> v48 106 | DEF str[100]:STRING 107 | 108 | WriteF('INTERNAL ERROR: \s \s\s\s\n', 109 | err, 110 | IF extra THEN '"' ELSE '', 111 | IF extra THEN extra ELSE '', 112 | IF extra THEN '"' ELSE '') 113 | 114 | IF g_currentproc THEN WriteF('Procedure: \s\n', g_currentproc.name) 115 | 116 | IF g_linenum <> 0 THEN WriteF('Line \d: \s\n', Abs(g_linenum), getSourceLine(str)) 117 | 118 | Raise("ERR") 119 | ENDPROC 120 | 121 | -> 1.10.0: added "more" arg 122 | EXPORT PROC addWarning(err,more=NIL) 123 | DEF warn:PTR TO warn, errlen, str, tstr[256]:STRING 124 | IF g_nowarn THEN RETURN 125 | StringF(tstr, '\s \c\s\c', err, 126 | IF more THEN "\q" ELSE " ", 127 | IF more THEN more ELSE '', 128 | IF more THEN "\q" ELSE " ") 129 | 130 | warn := g_warnlist 131 | WHILE warn 132 | IF StrCmp(warn.message, tstr) 133 | warn.count := warn.count + 1 134 | RETURN 135 | ENDIF 136 | warn := warn.next 137 | ENDWHILE 138 | 139 | str := String(EstrLen(tstr)) 140 | IF str = NIL THEN Raise("MEM") 141 | StrCopy(str, tstr) 142 | g_warnlist := NEW [g_warnlist, str, 1]:warn 143 | 144 | ENDPROC 145 | 146 | PROC getSourceLine(strbuf) HANDLE 147 | DEF fname[200]:STRING 148 | DEF fh=NIL, fbuf, mem=NIL 149 | DEF fib:fileinfoblock 150 | DEF linenr=1 151 | 152 | IF g_linenum = -1 THEN RETURN StrCopy(strbuf, '???') 153 | 154 | StrCopy(fname, g_sourcename) 155 | fh := Open(fname, OLDFILE) 156 | IF fh = NIL THEN Throw("OPEN", fname) 157 | IF ExamineFH(fh, fib) = NIL THEN Throw("EXAM", fname) 158 | mem := NewR(4+fib.size) 159 | fbuf := mem 160 | IF Read(fh, fbuf, fib.size) <> fib.size THEN Throw("READ", fname) 161 | /* find line */ 162 | WHILE (fbuf[]<>NIL) AND (linenr <> g_linenum) 163 | IF fbuf[] = 10 THEN linenr++ 164 | fbuf++ 165 | ENDWHILE 166 | IF linenr = g_linenum -> line found 167 | strCopyNL(strbuf, fbuf) 168 | ELSE 169 | StrCopy(strbuf, '???') 170 | ENDIF 171 | 172 | EXCEPT DO 173 | IF fh THEN Close(fh) 174 | IF mem THEN Dispose(mem) 175 | ReThrow() 176 | ENDPROC strbuf 177 | 178 | PROC strCopyNL(estr, str) 179 | DEF pos=NIL 180 | pos := InStr(str, '\n') 181 | IF pos = -1 182 | StrCopy(estr, str) 183 | RETURN NIL, EstrLen(estr) 184 | ELSE 185 | StrCopy(estr, str, pos) 186 | RETURN str+pos+1, pos 187 | ENDIF 188 | ENDPROC 189 | 190 | -> returns ptr to member. 191 | -> "mname": hashed name. 192 | EXPORT PROC findMember(o:PTR TO object, mname) 193 | DEF m:REG PTR TO member, a:REG 194 | a := o.nrofmembers 195 | WHILE a 196 | a-- 197 | m := o.membertable[a] 198 | IF m 199 | IF m.name = mname THEN RETURN m 200 | ENDIF 201 | ENDWHILE 202 | ENDPROC NIL 203 | 204 | -> used from expressions. returns ptr to proc, mid. 205 | -> "mname": hashed name 206 | EXPORT PROC findMethod(o:PTR TO object, mname) 207 | DEF m:REG PTR TO proc, a:REG 208 | a := o.nrofmethods 209 | WHILE a 210 | a-- 211 | m := o.methodtable[a] 212 | IF m 213 | IF m.name = mname THEN RETURN m, a 214 | ENDIF 215 | ENDWHILE 216 | ENDPROC NIL, NIL 217 | 218 | /* 219 | -> 1.6.0 220 | EXPORT PROC addMethDbgSym(oname, methname, methoffset) 221 | DEF hln:PTR TO hln, str[300]:STRING, label:PTR TO codelab 222 | 223 | IF g_optmodule THEN RETURN 224 | 225 | StrCopy(str, oname) 226 | StrAdd(str, '.') 227 | StrAdd(str, methname) 228 | 229 | NEW label 230 | label.offset := methoffset 231 | label.ltype := LTYPE_LAB 232 | label.identID := IDENT_LABEL 233 | 234 | hln := getLabelHLN(str) 235 | label.name := hln.name 236 | hln.ident := label 237 | 238 | ENDPROC 239 | */ 240 | 241 | -> 1.6.0 242 | EXPORT OBJECT strtabcontext 243 | memory:PTR TO CHAR 244 | offset:LONG 245 | count:LONG 246 | ENDOBJECT 247 | 248 | -> 1.10.0 moved here 249 | EXPORT PROC getTableStrOfs(stc:PTR TO strtabcontext, str, merge=FALSE) 250 | DEF len, ofs, ptr 251 | 252 | #ifdef DBG_BMOD 253 | DEBUGF('getTableStrOfs($\h, \a\s\a, \d) : ', stc, str, merge) 254 | #endif 255 | 256 | IF merge 257 | ptr := stc.memory 258 | WHILE ptr[] 259 | IF StrCmp(str, ptr) 260 | ofs := ptr - (stc.memory) 261 | #ifdef DBG_BMOD 262 | DEBUGF('\d\n', ofs) 263 | #endif 264 | RETURN ofs 265 | ENDIF 266 | ptr := ptr + StrLen(ptr) + 1 267 | ENDWHILE 268 | ENDIF 269 | 270 | stc.count := stc.count + 1 271 | 272 | ptr := stc.memory 273 | len := StrLen(str) + 1 274 | ofs := stc.offset 275 | CopyMem(str, ptr + ofs, len) 276 | stc.offset := ofs + len 277 | 278 | #ifdef DBG_BMOD 279 | DEBUGF('\d\n', ofs) 280 | #endif 281 | 282 | ENDPROC ofs 283 | -------------------------------------------------------------------------------- /compiler.e: -------------------------------------------------------------------------------- 1 | -> ECX/compiler.e 2 | 3 | /* ECX by Leif Salomonsson [ecx tele2 se] is Copyright (c) 2002-2008 */ 4 | /* Released under the ECX COMPILER LICENSE, See ECXCOMPILERLICENSE.TXT */ 5 | 6 | 7 | -> Sept 2007: changes to work with new codegen.e 8 | 9 | OPT MODULE 10 | OPT EXPORT 11 | OPT PREPROCESS 12 | 13 | MODULE '*binary' 14 | 15 | #ifdef ECX_VERSION 16 | #define DEBUGF WriteF 17 | ->#define DEBUGF DebugF 18 | #endif 19 | 20 | #ifndef ECX_VERSION 21 | #define DEBUGF WriteF 22 | #define Word Int 23 | #endif 24 | 25 | #define IFUNCDEF(name,args,defs,rets,f) \ 26 | [5, 0, 0, 0, 0,0,0,0, name, 0,0, 0, 0, args, defs, rets, f, 0]:lif 27 | 28 | #define IFUNCDEF2(name,code,codelen,args,defs,rets,f) \ 29 | [5, 0, 0, 0, 0,0,0,0, name, 0,0, code, codelen, args, defs, rets, f, 0]:lif 30 | 31 | CONST MEMF_CLEAR=$10000, MEMF_PUBLIC=1 32 | 33 | CONST TEMPSTRLEN = 16000, TEMPARRAYLEN=2048 -> 1.5.3 34 | 35 | CONST LHASHSIZE=1024 36 | 37 | CONST IDENT_NONE = 0, 38 | IDENT_CONST = 1, 39 | IDENT_VARIABLE = 2, 40 | IDENT_LABEL = 3, -> proc, asmlab 41 | IDENT_LFUNC = 4, 42 | IDENT_IFUNC = 5, 43 | IDENT_MACRO = 6, 44 | IDENT_REG = 7, 45 | IDENT_KEYWORD = 8, -> v46, its back! 46 | IDENT2_OBJECT = 9, 47 | IDENT2_ASM = 10, 48 | IDENT2_ASMMACRO = 11 -> v46 49 | 50 | ENUM IT_NEWLINE=10, -> 10 (newline),-> linenumber in info (set by .parse()) 51 | IT_LABEL=128, -> anycase label, string in info 52 | IT_VALUE, -> integer value, value in info v43: now is float if .num=1 53 | IT_STRING, -> quoted string, string in info 54 | ->IT_ASIZE, -> v35: .L .W .B etc 55 | IT_REG, -> v43:info : PTR TO reg 56 | IT_ASM, -> info: PTR TO asm, 57 | IT_IFUNC, -> v44. its back! info: PTR TO lif 58 | IT_LFUNC, -> v44. its back! info: PTR TO lfunc 59 | 60 | /* special types created by syntax parser only! */ 61 | IT_PFUNC, ->IT_FUNCTION, -> proc 62 | IT_IMMEDLIST, 63 | IT_VAREXP, -> if .num then .num is index of assignexp 64 | IT_EXPRESSION, 65 | IT_SUBSTATEMENT, -> v38 66 | IT_PROC, -> v40 : created by proc_key ! 67 | IT_VFUNC, -> v44. variable function. lex:hln sntx:var 68 | IT_OBJECT, -> v44. lex:hln sntx:object 69 | IT_VARIABLE, -> v44 lex:hln sntx:var 70 | IT_IFEXP, -> v44 . 71 | IT_UNIEXP, -> v44 72 | IT_CELLEXP, -> v44 73 | IT_NEWSTRING, -> v44 74 | IT_PRIVLAB, -> v48 "^x:" priveta label def for MACROs 75 | IT_MASSIGN, -> v49. multiassign (v1,v2,.. := exp) 76 | IT_LABADR, -> v49 77 | IT_VARADR, -> v49 78 | IT_MEMBER, -> v50, pass1 ptrtypeing, pass2 preDeref() creates it 79 | IT_LABDEREF, -> 1.9.0 v54 80 | 81 | KEY_BASE, 82 | KW_NEW, 83 | KW_END, 84 | KW_AND, 85 | KW_OR, 86 | KW_BUT, 87 | KW_OPT, 88 | KW_MODULE, 89 | KW_OBJECT, 90 | KW_ENDOBJECT, 91 | KW_CONST, 92 | KW_SET, 93 | KW_ENUM, 94 | KW_PROC, 95 | KW_ENDPROC, 96 | KW_IS, 97 | KW_DEF, 98 | KW_SUPER, 99 | KW_FOR, 100 | KW_STEP, 101 | KW_ENDFOR, 102 | KW_LOOP, 103 | KW_ENDLOOP, 104 | KW_WHILE, 105 | KW_ENDWHILE, 106 | KW_REPEAT, 107 | KW_UNTIL, 108 | KW_JUMP, 109 | KW_REG, 110 | KW_IF, 111 | KW_THEN, 112 | KW_ELSE, 113 | KW_ELSEIF, 114 | KW_ENDIF, 115 | KW_SELECT, 116 | KW_CASE, 117 | KW_DEFAULT, 118 | KW_ENDSELECT, 119 | KW_CHAR, 120 | KW_INT, 121 | KW_LONG, 122 | KW_STRING, 123 | KW_LIST, 124 | KW_ARRAY, 125 | KW_PTR, 126 | KW_TO, 127 | KW_DO, 128 | KW_OF, 129 | ->KW_STRLEN, 130 | KW_EXPORT, 131 | KW_SIZEOF, 132 | KW_RETURN, 133 | KW_EXCEPT, 134 | KW_HANDLE, 135 | KW_EXIT, 136 | KW_RAISE, 137 | KW_UNI, -> unification (<=>) 138 | 139 | /* special "keywords" */ 140 | KW_ASSIGN, -> := 141 | KW_ISNE, -> <> 142 | KW_ISGE, -> >=, => 143 | KW_ISLE, -> <=, =< 144 | KW_PTYPE, -> :: 145 | KW_PLUSPLUS, -> ++ 146 | KW_MINMIN, -> -- 147 | KW_MODIFY, -> V46: +=, *=, etc. "+", KW_OR, etc in .info. 148 | 149 | KW_SHL, -> SHL 150 | KW_SHR, -> SHR 151 | KW_NOP, 152 | KW_LIBRARY, 153 | KW_INCBIN, -> v3 154 | KW_INC, 155 | KW_DEC, -> v40 156 | 157 | KW_DOUBLE, 158 | KW_QUAD, -> v50 reserved for future 159 | KW_VECTOR, 160 | KW_CLASS, -> v47 161 | KW_VOID, -> v47 162 | 163 | KW_BYTE, -> v49! 164 | KW_WORD, -> v49 165 | KW_FLOAT, -> v49, back AGAIN! 166 | KW_REAL, -> v50 167 | 168 | KW_WIDE, -> V50. The new 64bit "LONG" 169 | KW_ULONG, -> v50, future vector subtype 170 | 171 | KW_OFFSETOF, -> 1.5.6 172 | 173 | KW_UWIDE, -> 1.6.1 174 | 175 | KW_USES, -> 1.7.1 176 | KW_LINKOBJECT, -> 1.7.1 177 | KW_AS, -> 1.8.0 178 | 179 | KW_STATIC, -> 1.9.0 180 | 181 | /* 1.10.0 inverted versions */ 182 | KW_IFN, 183 | KW_ELSEIFN, 184 | KW_WHILEN, 185 | KW_UNTILN, 186 | KW_EXITN, 187 | -> 1.10.0 188 | KW_XOR, 189 | KW_ASR, -> >> 190 | 191 | KW_ABS -> 2.2 192 | 193 | OBJECT ident 194 | identID:LONG 195 | ENDOBJECT /* SIZEOF = 4 */ 196 | 197 | OBJECT reg OF ident -> item.info 198 | type:CHAR -> normal DRX/ARX/RX/FPX or special "V"/"P" 199 | num:CHAR -> register number 200 | referenced:INT -> 1 if used 201 | name:PTR TO CHAR 202 | ENDOBJECT 203 | 204 | OBJECT keyword OF ident 205 | id:LONG 206 | ENDOBJECT 207 | 208 | OBJECT asm OF ident -> item.info 209 | name:PTR TO CHAR 210 | data:PTR TO LONG 211 | ENDOBJECT 212 | 213 | OBJECT macro OF ident -> compatible with modmacro !! 214 | name:PTR TO CHAR 215 | type:CHAR -> 0:define, 1:definefunc, 2:asmmacro, 3:varargs definefunc (v44) 216 | nrofargs:CHAR -> if type <> 0, else NIL. 217 | rsrvd:INT 218 | ascii:PTR TO CHAR 219 | ->--------------- 220 | params:PTR TO LONG -> if type=1, else NIL. for exported macros 221 | next:PTR TO macro -> v44, for exported macros 222 | ENDOBJECT 223 | 224 | OBJECT const OF ident 225 | value:LONG 226 | -> for exported consts 227 | name:PTR TO CHAR 228 | next:PTR TO const 229 | ENDOBJECT 230 | 231 | OBJECT hln 232 | name:PTR TO CHAR 233 | ident:PTR TO ident -> normal idents 234 | ident2:PTR TO ident -> v37, objects, asm 235 | hnext:PTR TO hln 236 | ENDOBJECT /* SIZEOF = 16 */ 237 | 238 | OBJECT item 239 | data:CHAR 240 | num:CHAR -> for some syntax types 241 | info:PTR TO hln -> or value:LONG or PTR TO ident / PTR TO item.. depending.. 242 | /* 1.8.0 */ 243 | info2:LONG -> lower part of 64 bit values 244 | ENDOBJECT /* SIZEOF = 10 */ 245 | 246 | 247 | -> 8 8 16 32 1 1 248 | /* type size esize numes object float signed 249 | CHAR memb 1, 0, 0, 0, 0, 0 250 | BYTE memb 1, 0, 0, 0, 0, 1 251 | INT memb 2, 0, 0, 0, 0, 1 252 | WORD memb 2, 0, 0, 0, 0, 0 253 | LONG memb 4, 0, 0, 0, 0, 1 254 | LONG 4, 1, 0, 0, 0, 1 255 | FLOAT 4, 0, 0, 0, 1, 1 256 | DOUBLE 8, 0, 0, 0, 1, 1 257 | VECTOR 16, 0, 0, 0, 0, 0 258 | CVECT 16, 1, 16, 0, 0, 0 259 | BVECT 16, 1, 16, 0, 0, 1 260 | IVECT 16, 2, 8, 0, 0, 1 261 | WVECT 16, 2, 8, 0, 0, 0 262 | LVECT 16, 4, 4, 0, 0, 1 263 | UVECT 16, 4, 4, 0, 0, 0 264 | FVECT 16, 4, 4, 0, 1, 0 265 | CPTR 4, 1, 0, 0, 0, 0 266 | BPTR 4, 1, 0, 0, 0, 1 267 | IPTR 4, 2, 0, 0, 0, 0 268 | WPTR 4, 2, 0, 0, 0, 1 269 | LPTR 4, 4, 0, 0, 0, 1 270 | FPTR 4, 4, 0, 0, 1, 1 271 | DPTR 4, 8, 0, 0, 1, 0 272 | VPTR 4, 16, 0, 0, 0, 0 273 | CARRAY 0, 1, #, 0, 0, 0 274 | BARRAY 0, 1, #, 0, 0, 1 275 | IARRAY 0, 2, #, 0, 0, 1 276 | WARRAY 0, 2, #, 0, 0, 0 277 | LARRAY 0, 4, #, 0, 0, 1 278 | FARRAY 0, 4, #, 0, 1, 1 279 | DARRAY 0, 8, #, 0, 1, 1 280 | VARRAY 0, 16, #, 0, 0, 0 281 | OPTR 4, 255, 0, obj, 0, 0 282 | OARRAY 0, 255, #, obj, 0, 0 283 | OBJECT 0, 255, 1, obj, 0, 0 284 | */ 285 | 286 | -> v49 absorbed "type" 287 | OBJECT member -> compatible with modmember ! 288 | size:CHAR -> 0/1/2/4/8 [ARRAY/CHAR/INT/LONG/DOUBLE] 289 | esize:CHAR -> 0/1/2/4/8/255 [NOT_PTR/CPTR/IPTR/LPTR/DPTR/OPTR] 290 | numes:INT -> 1-32767 elements, or 0. 291 | object:PTR TO object -> ... 292 | offset:INT -> offset from beginning. (v49. unused when type for variable) 293 | flags:INT 294 | name:PTR TO CHAR -> hashed 295 | ENDOBJECT /* SIZEOF = 16 */ 296 | 297 | 298 | OBJECT genlab OF ident 299 | codelink:PTR TO genlab 300 | offset:LONG 301 | labrefs 302 | ENDOBJECT 303 | 304 | OBJECT codelab OF genlab -> user labels and procedures 305 | exported:CHAR, rsrvd:CHAR, referenced:CHAR, ltype:CHAR 306 | name:PTR TO CHAR -> backpointer to hln.name 307 | next:PTR TO codelab -> procedures/labels 308 | dblabnext:PTR TO codelab -> v56, link all debug symbols together 309 | ENDOBJECT 310 | 311 | -> 1.9.0 for STATIC data. 312 | OBJECT statlab OF codelab 313 | deref:member -> size=0, esize=x, flags=x, object=x or NIL, numes=0 314 | sizeof:LONG -> 2.2 315 | ENDOBJECT 316 | 317 | -> 2.2 318 | OBJECT loclab OF codelab -> chained off proc.loclabs through loclab.next 319 | hln:hln -> "fake" hln pointing back to loclab 320 | ENDOBJECT 321 | 322 | OBJECT rwref -> immed lists in rw section 323 | next:PTR TO rwref 324 | offset:LONG 325 | ENDOBJECT 326 | 327 | OBJECT lif OF codelab ->genlab 328 | code:LONG -> align 2 329 | codelen:LONG -> align 4 330 | params:PTR TO LONG -> LIST. was: LONG. used by frontend 331 | defaults:PTR TO LONG -> LIST: used by frontend 332 | returns:PTR TO LONG -> was:LONG [0=Dx/Rx,1=Fx,2=RX2] used by frontend 333 | flags:LONG -> was: inline. 1=inline, 2=varargs. used by bridge/front 334 | raise:PTR TO raise -> v44 ! 335 | ENDOBJECT 336 | 337 | CONST VTYPE_GLOB = 0, 338 | VTYPE_LOC = 1 339 | 340 | -> 1.6.1 341 | CONST GTYPE_DEF = 0, 342 | GTYPE_BASE = 1, 343 | GTYPE_XREF = 2, 344 | GTYPE_INTERNAL = 3 -> 1.7.1 345 | 346 | /* 1.9.0 extracted arg out of var */ 347 | OBJECT arg OF ident -> compatible with modarg ! 348 | defd:LONG 349 | pad:CHAR 350 | rtype:CHAR 351 | rnum:INT 352 | ->-------------------- 353 | type:member -> v49 (was: type:type) 354 | ENDOBJECT 355 | 356 | OBJECT var OF arg 357 | hln:PTR TO hln -> locals need to reach hln (also inherited submodule methods -> module) 358 | o:CHAR, defo:CHAR 359 | offset:INT 360 | d:PTR TO var 361 | oldident:LONG -> for locals/args 362 | trok:INT -> bool. if FALSE, DO NOT use .treg !! (set to false when stymbling on {var}) v43 363 | breg:CHAR -> baseregister 364 | treg:CHAR -> used by tanslator. 365 | intreg:INT -> v50 BOOL 366 | vtype:CHAR -> VTYPE_GLOB/VTYPE_LOC 367 | link:CHAR -> 1 if moduleglobal, else 0. (1=needs relocation) 368 | cmplx:INT -> TRUE/FALSE 369 | next:PTR TO var -> v42 370 | usage:INT 371 | saveoffset:INT -> v46 -> save/restore regvar at this offset 372 | argsarray:PTR TO LONG -> 1.9.0, varfuncs 373 | multiret:PTR TO multireturn -> 1.9.0, varfuncs. may be NIL 374 | ->------------------- 375 | cbenable:INT -> v50, copyback enable, TRUE/FALSE (not used yet) 376 | flushme:INT -> v50, contents of .treg should be written back. (not used yet) 377 | nextuse:INT -> v50, pass1 fills it in with total # of accs. pass2 decrements it. (not used yet) 378 | varchain:PTR TO var -> v50 (1.5.1) chains ALL _locals_ together! 379 | ENDOBJECT 380 | 381 | OBJECT gvar OF var 382 | export:CHAR 383 | gtype:CHAR -> 1.6.1 384 | padd:INT 385 | labrefs:PTR TO labref -> [next,offset]:labref 386 | xname:PTR TO CHAR -> 1.8.0. only for LINKOBJECT mode. 387 | ENDOBJECT 388 | 389 | OBJECT lfunc OF ident -> compatible with modlfunc ! 390 | name:PTR TO CHAR -> hashed 391 | nrofargs:CHAR 392 | type:CHAR -> NIL for now 393 | baseofs:INT 394 | basernum:CHAR -> ppc native functions only 395 | return:CHAR -> 396 | basertype:CHAR -> v46, 0:rx, 1:stack 397 | flags:CHAR -> LFFLAG_XXX, 1.7.1 398 | basehln:PTR TO hln -> librarybase hln (so that any var may be used) 399 | raise:PTR TO raise -> v44 ! 400 | regs[16]:ARRAY OF lfuncarg 401 | ENDOBJECT 402 | 403 | OBJECT object OF codelab 404 | nrofmembers:INT 405 | nrofmethods:INT 406 | sizeof:LONG -> v50 ,made LONG to be able to detect larger than 32k error 407 | membertable:PTR TO LONG 408 | methodtable:PTR TO LONG 409 | privatesuper:INT -> not used yet 410 | startline:INT -> useful for errors in finnishObjects() 411 | super:PTR TO object -> if superobject 412 | classofs:INT -> v44. offset in object of classinfo. 413 | destofs:INT -> v44. offset of endmethod in classinfo, or -1 for no endmethod. 414 | addedmethods:PTR TO proc-> proc_key just adds metohods here, nothing more. v44 415 | alignment:CHAR -> v49. normally 2. 4 if contains float/doubles, 16 if vectors 416 | flags:CHAR -> 1.8.0 OFLAG_XXX 417 | modmethtab:PTR TO LONG -> 1.10.0 418 | ENDOBJECT 419 | 420 | -> v49, for functionreturns and multiple assigment 421 | OBJECT multireturn 422 | ros[4]:ARRAY OF LONG 423 | rds[4]:ARRAY OF LONG 424 | ENDOBJECT 425 | 426 | 427 | OBJECT proc OF codelab 428 | nrofargs:CHAR 429 | nrofdefaults:CHAR 430 | cpu:INT -> v40: 0=68k, 1=ppc 431 | argarray:PTR TO LONG 432 | args32:PTR TO var -> v46 433 | args64:PTR TO var -> v46 434 | args128:PTR TO var -> v48, not used yet 435 | object:PTR TO object -> if method, else NIL 436 | locals32:PTR TO var -> v45. 437 | locals00:PTR TO var -> v45. 438 | locals64:PTR TO var -> v45. 439 | locals128:PTR TO var -> v48, not used yet 440 | framesize:LONG -> v44 used by ppc back. v58 68k too. 441 | maxcallargs:INT -> v44. used by ppc back. set in pass 1. 442 | maxcalldepth:INT -> v44. ppc. maximum depth of nested functioncalls. 0=no functioncalls 443 | handle:INT -> bool 444 | except:INT -> v58 bool 445 | pad:INT 446 | selfvar:PTR TO var -> v47 447 | flags:LONG -> v47. PROCF_EMPTY, PROCF_CLMETH 448 | numregalloc:CHAR 449 | numfregalloc:CHAR 450 | selfreg:CHAR -> v45. for now always 12 451 | mret:multireturn -> v49, replaces .return 452 | varchain:PTR TO var -> v50 (1.5.1) chains ALL locals/params together! 453 | raise:PTR TO raise -> 2.2 454 | loclabs:PTR TO loclab -> 2.2 455 | ENDOBJECT 456 | 457 | 458 | OBJECT raise 459 | condition:INT -> "EQ"/"NE"/"LT"/"GT"/"LE"/"GE" 460 | pad:INT 461 | excval 462 | trigval 463 | ENDOBJECT /* SIZEOF = 16 */ 464 | 465 | OBJECT entry OF lfunc 466 | prochln:PTR TO hln -> same hln as procedure 467 | label:codelab 468 | ENDOBJECT 469 | 470 | 471 | 472 | OBJECT linedef 473 | next 474 | line 475 | offset 476 | ENDOBJECT 477 | 478 | 479 | 480 | ->unreferenced 481 | OBJECT unref 482 | next:PTR TO unref 483 | name:PTR TO CHAR 484 | count:LONG 485 | ENDOBJECT 486 | 487 | OBJECT warn -> v45. g_warnlist 488 | next:PTR TO warn 489 | message:PTR TO CHAR 490 | count:LONG 491 | ENDOBJECT 492 | 493 | OBJECT undefglob -> v50 494 | next:PTR TO undefglob 495 | name:PTR TO CHAR 496 | ENDOBJECT 497 | 498 | 499 | /* preprocessor */ 500 | CONST MACROBUFSIZE = 16000 501 | 502 | -> v49 503 | #define LoopUsageMod(usage) (usage*8) 504 | #define SelectUsageMod(usage) (usage/8) 505 | #define IfUsageMod(usage) (usage) 506 | CONST SIMPLEUSAGE = 2 507 | CONST ASSIGNUSAGE = 4 508 | CONST MINALLOCUSAGE = 12 509 | 510 | -> v49 511 | OBJECT it_funccall 512 | data -> depends on type 513 | numpars -> # of params issued 514 | info -> libbase for libcalls, or NIL. 515 | ENDOBJECT 516 | -> items follow until .data = NIL 517 | 518 | OBJECT litem OF item -> 1.5.1 used by immedlist2 getlist 519 | pad:INT 520 | next:PTR TO litem 521 | ENDOBJECT 522 | 523 | OBJECT it_immedlist 524 | numelems:INT -> # of elements in list 525 | newed:INT -> TRUE if NEW [] 526 | offset:LONG -> starting offet into g_databuf to support alignment 527 | sizeof:LONG -> size in bytes of list 528 | esize:CHAR -> 0=object, 1, 2, 4, 8 529 | eflags:CHAR -> MEMBF_FLOAT or NIL 530 | cmplx:INT -> TRUE if LIST 531 | object:PTR TO object -> if esize=0 532 | ->type:LONG -> -4=LIST,1=CHAR,2=INT,4=LONG,8=DOUBLE,>1000=object 533 | litems:PTR TO litem -> 1.5.1 linked items !! 534 | ENDOBJECT 535 | ->-> items follow until .data = NIL -> 1.5.1: no items here!! 536 | 537 | -> direct access to ifuncs array 538 | 539 | /* removed 1.10.0 540 | 541 | CONST IF68K_THROW = 100, 542 | IF68K_FASTNEW = 110, 543 | IF68K_FASTDISPOSE = 109, 544 | IF68K_RAISE = 82, 545 | IF68K_CONS = 128 546 | 547 | -> direct access to ifuncsppc array 548 | 549 | CONST IFPPC_FASTNEW = 0, 550 | IFPPC_FASTDISPOSE = 1, 551 | IFPPC_STRINGF_OLD = 5, 552 | IFPPC_RAISE = 6, 553 | IFPPC_THROW = 7, 554 | IFPPC_WRITEF_OLD = 23, 555 | IFPPC_PRINTF_OLD = 24, 556 | IFPPC_I_2_F = 40, 557 | IFPPC_TEXTF_OLD = 77, 558 | IFPPC_DEBUGF_OLD = 94, 559 | IFPPC_STR_FMT_OLD = 96 560 | */ 561 | 562 | -> 1.5.4 563 | OBJECT it_varexp 564 | var:PTR TO var 565 | postkey:CHAR -> KW_NEW / KW_END / KW_SUPER / NIL 566 | -> modification, or NIL. 567 | -> KW_ASSIGN / "+" / "-" / "*" / "/" / KW_AND / KW_OR / KW_SHL / KW_SHR / NIL 568 | assignmod:CHAR 569 | -> index of modification expression if any, or NIL. always NIL for NEW/END/SUPER. 570 | index:CHAR 571 | rsrvd:CHAR 572 | ENDOBJECT 573 | -> items follow until n.data = NIL 574 | 575 | -> 1.5.4 not used yet 576 | OBJECT it_expression 577 | quoted:INT -> TRUE / FALSE 578 | prefloat:INT -> TRUE / FALSE (IF !...) 579 | preneg:INT -> TRUE / FALSE (IF -x...) 580 | ENDOBJECT 581 | -> items follow until n.data = NIL 582 | 583 | -> 1.10.0 584 | ENUM MODE_DEFAULT, 585 | MODE_FLOAT, 586 | MODE_D64 587 | 588 | 589 | 590 | OBJECT labref 591 | next:PTR TO labref 592 | offset:LONG 593 | type:LONG -> if external proc/label: REF32/REF24/RE1616, else REF16/REF14/REF32/REF24 594 | ENDOBJECT 595 | 596 | 597 | 598 | ->moved here 1.10.0 599 | #define AREG g_areg 600 | #define DREG g_dreg 601 | #define FREG g_freg 602 | #define VREG g_vreg 603 | #define D64REG g_d64reg 604 | 605 | -> 1.10.0 moved back in here (needed by new inline.e) 606 | EXPORT ENUM 607 | NO_OP, 608 | RX, -> n 609 | DRX, -> n 610 | ARX, -> n 611 | FPX, -> n 612 | VX, -> n -> v48 613 | VAR, -> var/gvar 614 | DV, -> v 615 | ARXPO, -> :LONG 616 | ARXPX, -> :LONG 617 | LAB, -> codelab (inline asm) 618 | VAR64, -> var (v45!) 619 | VAR128, -> 128bit vector v48, not used yet 620 | D64, -> 1.10.0 for a virtual WIDE register 621 | X2R, -> only used for WIDE returns (handled by secureReturn()) 622 | NROFOPS 623 | 624 | 625 | #define NEWMEM(size) New(size) 626 | #define NEWMEMR(size) NewR(size) 627 | #define DISPOSE(mem) Dispose(mem) 628 | #define FASTNEW(size) FastNew(size) 629 | #define ALLOCMEM(size,flags) AllocMem(size,flags) 630 | #define FREEMEM(mem,size) FreeMem(mem,size) 631 | 632 | OBJECT it_statlist 633 | len:LONG 634 | sizeof:LONG 635 | esize:CHAR 636 | flags:CHAR 637 | cplx:INT 638 | object:PTR TO object 639 | ENDOBJECT 640 | 641 | 642 | -------------------------------------------------------------------------------- /diself.e: -------------------------------------------------------------------------------- 1 | -> DisELF by Leif Salomonsson [ecx tele2 se] is Copyright (c) 2003-2007. 2 | -> Released under ECX TOOLS LICENSE, see ECXTOOLSLICENSE.TXT 3 | 4 | OPT PREPROCESS 5 | 6 | MODULE '*eecelf' 7 | MODULE '*ppcdisasm' 8 | 9 | -> Jan, Apr, Jul 2003 10 | -> Jan 2004: added HIT option. 11 | -> fixed mtspr, mfspr 12 | -> Apr 2004: added SECT option: SECT sectname. 13 | 14 | -> todo: show symbols within code disasm. 15 | 16 | -> May 2004: now interprets .line sections. 17 | 18 | -> fixed fabs in ppcdisasm.e 19 | 20 | -> April 2007: fixes to HIT information.. 21 | -> April 2007: adjstments for sligthly changed .line format (numlines added) 22 | 23 | -> Aug 2007: - fixed some STT_XXX names that was wrong. 24 | -> - added bunch of reloc types missing 25 | -> - added getrelocname(id,str), added mos specific relocs 26 | -> - replaced cx() functions with char() func and fixed a bug, thx Stefan H. 27 | 28 | -> June 2008: some improvements on page header display. 29 | 30 | -> June 2011: adding symbol disassembly. also needs ecx now. 31 | 32 | -> bug: only shows first smbol in a section that 33 | -> matches a hit.. 34 | 35 | RAISE "FILE" IF FileLength()=-1, 36 | "OPEN" IF Open()=NIL, 37 | "ARGS" IF ReadArgs()=NIL, 38 | "^C" IF CtrlC()=TRUE 39 | 40 | PROC shr(x,v) 41 | #ifndef ECX_VERSION 42 | MOVE.L x, D0 43 | MOVE.L v, D1 44 | LSR.L D1, D0 45 | ENDPROC D0 46 | #endif 47 | 48 | #ifdef ECX_VERSION 49 | ENDPROC x SHR v 50 | #endif 51 | 52 | 53 | OBJECT args 54 | file 55 | dis 56 | hit 57 | sect 58 | label 59 | ENDOBJECT 60 | 61 | STATIC phdrtypes = ['NULL', 62 | 'LOAD', 63 | 'DYNAMIC', 64 | 'INTERP', 65 | 'NOTE', 66 | 'SHLIB', 67 | 'PHDR', 68 | '???'] 69 | 70 | STATIC shdrtypes = ['', 71 | 'PROGBITS', 72 | 'SYMTAB', 73 | 'STRTAB', 74 | 'RELA', 75 | 'HASH', 76 | 'DYNAMIC', 77 | '7', 78 | 'NOBITS', 79 | 'REL', 80 | '10', 81 | 'DYNSYM', 82 | '???'] 83 | 84 | 85 | 86 | STATIC symbolbinds = ['LOCAL', 87 | 'GLOBAL', 88 | 'WEAK', 89 | '???'] 90 | 91 | STATIC symboltypes = ['NOTYPE', 92 | 'OBJECT', 93 | 'FUNC', 94 | 'SECTION', 95 | 'FILE', 96 | 'COMMON', 97 | 'TLS', 98 | '???'] 99 | 100 | DEF args:args 101 | DEF fbuf, flen 102 | 103 | PROC main() HANDLE 104 | DEF fh=NIL, rdargs=NIL 105 | DEF ehdr:PTR TO ehdr, phdr:PTR TO phdr, phnum 106 | DEF shdr:PTR TO shdr, shnum 107 | DEF shstrtable, a, b, t 108 | DEF sym:PTR TO sym 109 | DEF shdr2:PTR TO shdr, strtable 110 | DEF rel:PTR TO rel, rela:PTR TO rela 111 | DEF str[100]:STRING 112 | DEF c, hit, sectname[12]:STRING 113 | 114 | 115 | /* read agrs */ 116 | rdargs := ReadArgs('FILE/A,'+ 117 | 'DIS/S,'+ 118 | 'HIT/N,'+ 119 | 'SECT/K,'+ 120 | 'LABEL/K', 121 | args, NIL) 122 | 123 | flen := FileLength(args.file) 124 | fbuf := NewR(flen+4) 125 | fh := Open(args.file, OLDFILE) 126 | Read(fh, fbuf, flen) 127 | Close(fh) ; fh := NIL 128 | 129 | WriteF('\s -> \q\s\q\n', {verstr}, args.file) 130 | 131 | hit := IF args.hit THEN Long(args.hit) ELSE -1 132 | IF args.sect THEN StrCopy(sectname, args.sect) 133 | 134 | ehdr := fbuf 135 | 136 | IF ehdr.ident[EI_MAG0] <> 127 THEN Throw("FORM", 'elf id') 137 | IF ehdr.ident[EI_MAG1] <> "E" THEN Throw("FORM", 'elf id') 138 | IF ehdr.ident[EI_MAG2] <> "L" THEN Throw("FORM", 'elf id') 139 | IF ehdr.ident[EI_MAG3] <> "F" THEN Throw("FORM", 'elf id') 140 | 141 | IF ehdr.ident[EI_CLASS] <> ELFCLASS32 THEN Raise("BITS") 142 | IF ehdr.ident[EI_DATA] <> ELFDATA2MSB THEN Raise("ENDI") 143 | 144 | IF hit > -1 145 | showhit(hit, ehdr) 146 | Raise(0) 147 | ENDIF 148 | 149 | IF args.label 150 | show_label(ehdr, args.label) 151 | Raise(0) 152 | ENDIF 153 | 154 | IF EstrLen(sectname) = NIL 155 | 156 | WriteF('EHDR\n') 157 | WriteF(' BITS=\d, ENDIAN=\s, IDENT[8-11]=\z$\h[8] IDENT[12-15]=\z$\h[8]\n', 158 | IF Long(4+ehdr.ident) = 2 THEN 64 ELSE 32, IF Long(8+ehdr.ident) = 1 THEN 'LITTLE' ELSE 'BIG',Long(8+ehdr.ident) ,Long(12+ehdr.ident)) 159 | WriteF(' TYPE=\s, MACHINE=\d, VERSION=\d, FLAGS=$\h\n', ListItem(['0','REL','EXEC','DYN','???'], ehdr.type), ehdr.machine, ehdr.version, ehdr.flags) 160 | WriteF(' ENTRY=\d, PHOFF=$\h, SHOFF=$\h\n', ehdr.entry, ehdr.phoff, ehdr.shoff) 161 | WriteF(' EHSIZE=\d, PHENTSIZE=\d, PHNUM=\d\n', ehdr.ehsize, ehdr.phentsize, ehdr.phnum) 162 | WriteF(' SHENTSIZE=\d, SHNUM=\d, SHSTRNDX=\d\n', ehdr.shentsize, ehdr.shnum, ehdr.shstrndx) 163 | 164 | a := 0 165 | WHILE phdr := get_phdr(ehdr, a) 166 | 167 | WriteF('PHDR \d[3], \s[6], $\h[6], \d[6], \d[6], \d[6], \d[6], ', a, 168 | IF phdr.type <= ListLen(phdrtypes) THEN ListItem(phdrtypes,phdr.type) ELSE StringF(str, '\d', phdr.type), 169 | phdr.offset, phdr.vaddr, phdr.paddr, phdr.filesz, phdr.memsz) 170 | 171 | t := phdr.flags 172 | SetStr(str, 0) 173 | IF t AND PF_R 174 | StrAdd(str, 'R ') 175 | t := t AND Not(PF_R) 176 | ENDIF 177 | IF t AND PF_W 178 | StrAdd(str, 'W ') 179 | t := t AND Not(PF_W) 180 | ENDIF 181 | IF t AND PF_X 182 | StrAdd(str, 'X ') 183 | t := t AND Not(PF_X) 184 | ENDIF 185 | IF t 186 | WriteF('\h[8], \d\n', phdr.flags, phdr.align) 187 | ELSE 188 | WriteF('\s[6], \d\n', str, phdr.align) 189 | ENDIF 190 | 191 | a++ 192 | CtrlC() 193 | 194 | ENDWHILE 195 | 196 | ENDIF 197 | 198 | shdr := get_shdr(ehdr, ehdr.shstrndx) 199 | shstrtable := ehdr + shdr.offset 200 | 201 | a := 0 202 | WHILE shdr := get_shdr(ehdr, a) 203 | 204 | IF EstrLen(sectname) 205 | IF shdr.name < 0 THEN JUMP _sectionskip 206 | IF StrCmp(shdr.name + shstrtable, sectname) = FALSE 207 | JUMP _sectionskip 208 | ENDIF 209 | ENDIF 210 | 211 | WriteF('SHDR \z\d[3] \l\s[12] \l\s[10] ', a, 212 | IF shdr.name > -1 THEN shstrtable + shdr.name ELSE StringF(str, '$\h', shdr.name), 213 | IF shdr.type <= ListLen(shdrtypes) THEN ListItem(shdrtypes,shdr.type) ELSE StringF(str, '\d', shdr.type)) 214 | 215 | t := shdr.flags 216 | SetStr(str, 0) 217 | IF t AND SHF_WRITE 218 | StrAdd(str, 'WRITE ') 219 | t := t AND Not(SHF_WRITE) 220 | ENDIF 221 | IF t AND SHF_ALLOC 222 | StrAdd(str, 'ALLOC ') 223 | t := t AND Not(SHF_ALLOC) 224 | ENDIF 225 | IF t AND SHF_EXECINSTR 226 | StrAdd(str, 'EXECINSTR ') 227 | t := t AND Not(SHF_EXECINSTR) 228 | ENDIF 229 | IF t THEN StringF(str, '$\h ', shdr.flags) 230 | WriteF('\s[20]', str) 231 | 232 | WriteF('\r\d[2] \d[2] (\z\d[3]) \d, $\h, \d, \d\n', 233 | shdr.addralign, shdr.entsize, shdr.link, 234 | shdr.size, shdr.offset, shdr.info, shdr.addr) 235 | 236 | IF (shdr.type = SHT_SYMTAB) OR (shdr.type = SHT_DYNSYM) 237 | shdr2 := get_shdr(ehdr, shdr.link) 238 | strtable := ehdr + shdr2.offset 239 | b := 0 240 | WHILE sym := get_shent(ehdr, shdr, b) 241 | WriteF(' SYM \r\z\d[6] (\z\d[3]) L\z\r\h[8] \l\s[7] \l\s[7] \a\s\a \d, \d\n', b++, 242 | sym.shndx, 243 | sym.value, 244 | IF ST_BIND(sym.info) <= ListLen(symbolbinds) THEN ListItem(symbolbinds, 245 | ST_BIND(sym.info)) ELSE StringF(str, '\d', ST_BIND(sym.info)), 246 | IF ST_TYPE(sym.info) <= ListLen(symboltypes) THEN ListItem(symboltypes, 247 | ST_TYPE(sym.info)) ELSE StringF(str, '\d', ST_TYPE(sym.info)), 248 | strtable + sym.name, 249 | sym.size, 250 | sym.other) 251 | CtrlC() 252 | ENDWHILE 253 | ELSEIF (shdr.type = SHT_REL) AND (args.dis<>FALSE) 254 | shdr2 := get_shdr(ehdr, shdr.link) -> symbol shdr 255 | sym := ehdr + shdr2.offset -> symboltable 256 | shdr2 := get_shdr(ehdr, shdr2.link) -> str shdr 257 | strtable := ehdr + shdr2.offset 258 | b := 0 259 | WHILE rel := get_shent(ehdr, shdr, b) 260 | WriteF(' REL \r\z\d[6] (\z\d[3]) L\z\h[7] \a\s\a \s = L\z\h[7]\n', 261 | b++, 262 | R_SYM(rel.info), 263 | rel.offset, 264 | sym[R_SYM(rel.info)].name + strtable, 265 | getrelocname(R_TYPE(rel.info), str), 266 | peekSym(ehdr, sym[R_SYM(rel.info)], rel.offset)) 267 | CtrlC() 268 | ENDWHILE 269 | ELSEIF (shdr.type = SHT_RELA) AND (args.dis <> FALSE) 270 | shdr2 := get_shdr(ehdr, shdr.link) -> symbol shdr 271 | sym := ehdr + shdr2.offset -> symboltable 272 | shdr2 := get_shdr(ehdr, shdr2.link) -> str shdr 273 | strtable := ehdr + shdr2.offset 274 | b := 0 275 | WHILE rela := get_shent(ehdr, shdr, b) 276 | WriteF(' RELA \r\z\d[6] (\z\d[3]) L\z\h[7] \a\s\a \s, $\h\n', 277 | b++, 278 | R_SYM(rela.info), 279 | rela.offset, 280 | sym[R_SYM(rela.info)].name + strtable, 281 | getrelocname(R_TYPE(rela.info), str), 282 | rela.addend) 283 | CtrlC() 284 | ENDWHILE 285 | ELSEIF (shdr.type = SHT_PROGBITS) AND (args.dis<>FALSE) 286 | b := 0 287 | c := ehdr + shdr.offset 288 | WHILE b < shdr.size 289 | IF shdr.flags AND SHF_EXECINSTR 290 | dodis(b, Long(c), str) 291 | WriteF(' L\z\h[7]: \l\s[24] [\z\r\h[8]] \a\c\c\c\c\a (\d\n', 292 | b, str, Long(c), char(c), char(c+1), char(c+2), char(c+3), b) 293 | ELSE 294 | WriteF(' L\z\h[7]: [\z\r\h[8]] \a\c\c\c\c\a (\d\n', 295 | b, Long(c), char(c), char(c+1), char(c+2), char(c+3), b) 296 | ENDIF 297 | b := b + 4 298 | c := c + 4 299 | CtrlC() 300 | ENDWHILE 301 | ENDIF 302 | 303 | _sectionskip: 304 | 305 | a++ 306 | CtrlC() 307 | 308 | ENDWHILE 309 | 310 | WriteF('\n') 311 | 312 | EXCEPT DO 313 | IF fh THEN Close(fh) 314 | 315 | IF rdargs THEN FreeArgs(rdargs) 316 | 317 | SELECT exception 318 | CASE "FILE" ; WriteF('unable to open file.\n') 319 | CASE "OPEN" ; WriteF('unable to open file.\n') 320 | CASE "ARGS" ; WriteF('bad args.\n') 321 | CASE "FORM" ; WriteF('format is not understood: \s.\n', exceptioninfo) 322 | CASE "^C" ; WriteF('user aborted.\n') 323 | CASE "BITS" ; WriteF('elf is not of 32bit type') 324 | CASE "ENDI" ; WriteF('elf is not big endian') 325 | ENDSELECT 326 | ENDPROC 327 | 328 | PROC getrelocname(id, str) 329 | DEF relocnames, relocnames200 330 | 331 | relocnames := ['NONE', 332 | 'ADDR32', 333 | 'ADDR24', 334 | 'ADDR16', 335 | 'ADDR16_LO', 336 | 'ADDR16_HI', 337 | 'ADDR16_HA', 338 | 'ADDR14', 339 | 'ADDR14_BRTAKEN', 340 | 'ADDR14_BRNTAKEN', 341 | 'REL24', 342 | 'REL14', 343 | 'REL14_BRTAKEN', 344 | 'REL14_BRNTAKEN', 345 | 'GOT16', 346 | 'GOT16_LO', 347 | 'GOT16_HI', 348 | 'GOT16_HA', 349 | 'PLTREL24', 350 | 'COPY', 351 | 'GLOB_DAT', 352 | 'JMP_SLOT', 353 | 'RELATIVE', 354 | 'LOCAL24PC', 355 | 'UADDR32', 356 | 'UADDR16', 357 | 'REL32', 358 | 'PLT32', 359 | 'PLTREL32', 360 | 'PLT16_LO', 361 | 'PLT16_HI', 362 | 'PLT16_HA', 363 | 'SDAREL16', 364 | 'SECTOFF', 365 | 'SECTOFF_LO', 366 | 'SECTOFF_HI', 367 | 'SECTOFF_HA'] 368 | 369 | relocnames200 := ['MORPHOS_DREL', 370 | 'MORPHOS_DREL_LO', 371 | 'MORPHOS_DREL_HI', 372 | 'MORPHOS_DREL_HA'] 373 | 374 | IF id < ListLen(relocnames) 375 | StrCopy(str, ListItem(relocnames,id)) 376 | ELSEIF id < (ListLen(relocnames200)+200) 377 | StrCopy(str, ListItem(relocnames200, id-200)) 378 | ELSE 379 | StringF(str, '\d', id) 380 | ENDIF 381 | 382 | ENDPROC str 383 | 384 | PROC peekSym(ehdr:PTR TO ehdr, sym:PTR TO sym, offset) 385 | DEF shdr:PTR TO shdr 386 | shdr := get_shdr(ehdr, sym.shndx) 387 | ENDPROC Long(ehdr + shdr.offset + offset) 388 | 389 | PROC char(ptr) 390 | DEF c 391 | c := Char(ptr) 392 | IF (c > 31) AND (c < 127) THEN RETURN c 393 | ENDPROC "." 394 | 395 | 396 | 397 | CHAR 0, '$VER:' 398 | verstr: 399 | CHAR 'DisELF 1.10 by LS 2003-11', 0 400 | 401 | 402 | OBJECT line 403 | line 404 | offset 405 | ENDOBJECT 406 | 407 | PROC showhit(ofs:PTR TO LONG, ehdr:PTR TO ehdr) 408 | DEF shdr:PTR TO shdr, shnum 409 | DEF shstrtable, a, b, t, c:PTR TO LONG 410 | DEF shdr2:PTR TO shdr, strtable 411 | DEF str[100]:STRING 412 | DEF sym:PTR TO sym, offsetsym:PTR TO sym 413 | DEF lptr:PTR TO LONG, d, line:PTR TO line, tline:PTR TO line 414 | 415 | ofs := ofs AND $FFFFFC 416 | 417 | shdr := get_shdr(ehdr, ehdr.shstrndx) 418 | shstrtable := ehdr + shdr.offset 419 | 420 | a := 0 421 | WHILE shdr := get_shdr(ehdr, a) 422 | 423 | IF shdr.type = SHT_PROGBITS 424 | IF shdr.flags AND SHF_EXECINSTR 425 | IF shdr.size > ofs 426 | WriteF('\n HIT at offset $\h in section \d:\n\n', ofs, a) 427 | 428 | IF ofs > 3 429 | c := ehdr + shdr.offset + ofs - 4 430 | dodis(ofs-4, c[], str) 431 | WriteF(' L\z\h[7]: \l\s[24] [\z\r\h[8]] \a\c\c\c\c\a\n', 432 | ofs-4, str, c[], char(c), char(c+1), char(c+2), char(c+3)) 433 | ENDIF 434 | 435 | c := ehdr + shdr.offset + ofs 436 | dodis(ofs, c[], str) 437 | WriteF('-->L\z\h[7]: \l\s[24] [\z\r\h[8]] \a\c\c\c\c\a\n', 438 | ofs, str, c[], char(c), char(c+1), char(c+2), char(c+3)) 439 | 440 | c := ehdr + shdr.offset + ofs + 4 441 | dodis(ofs+4, c[], str) 442 | WriteF(' L\z\h[7]: \l\s[24] [\z\r\h[8]] \a\c\c\c\c\a\n', 443 | ofs+4, str, c[], char(c), char(c+1), char(c+2), char(c+3)) 444 | ENDIF ; ENDIF ; ENDIF 445 | 446 | IF (shdr.type = SHT_SYMTAB) OR (shdr.type = SHT_DYNSYM) 447 | sym := ehdr + shdr.offset -> symboltable 448 | shdr2 := get_shdr(ehdr, shdr.link) -> 449 | strtable := ehdr + shdr2.offset 450 | offsetsym := NIL 451 | FOR b := 0 TO (shdr.size / shdr.entsize) -1 452 | IF sym.shndx > 0 453 | IF sym.value <= ofs 454 | IF offsetsym 455 | IF sym.value > offsetsym.value THEN offsetsym := sym 456 | ELSE 457 | offsetsym := sym 458 | ENDIF 459 | ENDIF 460 | ENDIF 461 | sym := sym + shdr.entsize 462 | CtrlC() 463 | ENDFOR 464 | IF offsetsym 465 | IF StrLen(offsetsym.name + strtable) 466 | WriteF('\n Below symbol \a\s\a ($\h) in section \d\n', 467 | strtable + offsetsym.name, 468 | offsetsym.value, 469 | offsetsym.shndx) 470 | ENDIF 471 | ENDIF 472 | ENDIF 473 | 474 | IF (shdr.type = SHT_PROGBITS) AND (shdr.flags = NIL) AND (shdr.name > 0) 475 | IF StrCmp(shdr.name + shstrtable, '.ldbg') 476 | tline := NIL 477 | d := NIL 478 | lptr := shdr.offset + ehdr 479 | WHILE lptr[]++ = "LDBG" 480 | ->WriteF('"LINE" numlines=\d name=\s\n', lptr[], lptr + 8) 481 | t := lptr[]++ -> numlines 482 | b := lptr + 4 -> save ptr to name 483 | line := lptr + Shl(lptr[]++, 2) + 4-> jump over name 484 | ->WriteF('low offset=\d, highoffset=\d\n', line.offset, line[t-1].offset) 485 | IF (ofs >= line.offset) AND (ofs <= line[t-1].offset) 486 | d := b 487 | WHILE t 488 | t-- 489 | IF line.offset <= ofs THEN tline := line 490 | line++ 491 | ENDWHILE 492 | lptr := line 493 | ELSE 494 | lptr := line + Mul(t, SIZEOF line) 495 | ENDIF 496 | EXIT d 497 | ENDWHILE 498 | IF d 499 | WriteF('\n Source: "\s"\n Line: \d\n', d, tline.line) 500 | ENDIF 501 | ENDIF 502 | ENDIF 503 | 504 | a++ 505 | 506 | CtrlC() 507 | 508 | ENDWHILE 509 | 510 | WriteF('\n') 511 | 512 | ENDPROC 513 | 514 | -> 1.10 515 | PROC get_phdr(ehdr:PTR TO ehdr, i) 516 | IF i >= ehdr.phnum THEN RETURN NIL 517 | ENDPROC ehdr + ehdr.phoff + (i * ehdr.phentsize) 518 | 519 | PROC get_shdr(ehdr:PTR TO ehdr, i) 520 | IF i >= ehdr.shnum THEN RETURN NIL 521 | ENDPROC ehdr + (ehdr.shoff) + (ehdr.shentsize * i) 522 | 523 | PROC get_shent(ehdr:PTR TO ehdr, shdr:PTR TO shdr, i) 524 | IF (i * shdr.entsize) >= shdr.size THEN RETURN NIL 525 | ENDPROC ehdr + shdr.offset + (shdr.entsize * i) 526 | 527 | PROC find_sym(ehdr:PTR TO ehdr, name) 528 | DEF a, shdr:PTR TO shdr, sym:PTR TO sym, shdr2:PTR TO shdr, b, strtable 529 | a := 0 530 | WHILE shdr := get_shdr(ehdr, a) 531 | IF (shdr.type = SHT_SYMTAB) OR (shdr.type = SHT_DYNSYM) 532 | shdr2 := get_shdr(ehdr, shdr.link) -> 533 | strtable := ehdr + shdr2.offset 534 | b := 0 535 | WHILE sym := get_shent(ehdr, shdr, b++) 536 | IF StrCmp(name, strtable + sym.name) THEN RETURN sym 537 | ENDWHILE 538 | ENDIF 539 | a++ 540 | ENDWHILE 541 | ENDPROC NIL 542 | 543 | PROC show_label(ehdr, name) 544 | DEF sym:PTR TO sym, shdr:PTR TO shdr, ofs:PTR TO LONG, endofs, c:PTR TO LONG 545 | DEF str[128]:STRING 546 | 547 | sym := find_sym(ehdr, name) 548 | IFN sym THEN RETURN NIL 549 | IF ST_TYPE(sym.info) = NIL THEN RETURN NIL 550 | shdr := get_shdr(ehdr, sym.shndx) 551 | IFN shdr THEN RETURN NIL 552 | IF shdr.type <> SHT_PROGBITS THEN RETURN NIL 553 | 554 | WriteF('\nLabel "\s" in section \d @ offset $\h with size \d and other \d:\n\n', 555 | name, 556 | sym.shndx, 557 | sym.value, 558 | sym.size, 559 | sym.other) 560 | 561 | ofs := sym.value 562 | endofs := ofs + sym.size 563 | c := ehdr + shdr.offset + ofs 564 | 565 | WHILE ofs < endofs 566 | 567 | dodis(ofs, c[], str) 568 | WriteF(' L\z\h[7]: \l\s[24] [\z\r\h[8]] \a\c\c\c\c\a\n', 569 | ofs, str, c[], char(c), char(c+1), char(c+2), char(c+3)) 570 | ofs++ 571 | c++ 572 | ENDWHILE 573 | 574 | WriteF('\n') 575 | 576 | ENDPROC TRUE 577 | -------------------------------------------------------------------------------- /dishunk.e: -------------------------------------------------------------------------------- 1 | -> DisHunk by Leif Salomonsson is Copyright (c) 2003-2007. 2 | -> Released under ECX TOOLS LICENSE, see ECXTOOLSLICENSE.TXT 3 | 4 | OPT PREPROCESS 5 | 6 | MODULE 'dos/doshunks' 7 | MODULE '*ppcdisasm' 8 | 9 | DEF fbuf, flen, disasm 10 | DEF hunksizes:PTR TO LONG 11 | 12 | -> EC uses ASR for Shr()! 13 | PROC shr(x,v) 14 | #ifndef ECX_VERSION 15 | MOVE.L x, D0 16 | MOVE.L v, D1 17 | LSR.L D1, D0 18 | ENDPROC D0 19 | #endif 20 | #ifdef ECX_VERSION 21 | ENDPROC x SHR v 22 | #endif 23 | 24 | PROC main() HANDLE 25 | DEF fh=NIL, ptr:PTR TO LONG, str[24]:STRING, rdargs=NIL, args[2]:ARRAY OF LONG 26 | 27 | args[]:=0 28 | args[1]:=0 29 | 30 | /* read agrs */ 31 | rdargs := ReadArgs('FILE/A,'+ 32 | 'DIS/S', 33 | args, NIL) 34 | 35 | IF rdargs = NIL THEN Raise("ARGS") 36 | flen := FileLength(args[]) 37 | IF flen = 0 THEN Raise("FLEN") 38 | fbuf := NewR(flen+4) 39 | fh := Open(args[], OLDFILE) 40 | IF fh = NIL THEN Raise("OPEN") 41 | IF Read(fh, fbuf, flen) <> flen THEN Raise("READ") 42 | Close(fh) ; fh := NIL 43 | ptr := fbuf 44 | 45 | disasm := args[1] 46 | 47 | WHILE (ptr := dohunk(ptr)) 48 | ENDWHILE 49 | 50 | 51 | EXCEPT DO 52 | 53 | IF rdargs THEN FreeArgs(rdargs) 54 | IF fh THEN Close(fh) 55 | 56 | SELECT exception 57 | CASE "ARGS" ; WriteF('Error: wrong arguments!\n') 58 | CASE "OPEN" ; WriteF('Error: could not open file!\n') 59 | CASE "FLEN" ; WriteF('Error: file is empty!\n') 60 | CASE "MEM" ; WriteF('Error: out of memory!\n') 61 | CASE NIL 62 | DEFAULT ; WriteF('Error: unknown!\n') 63 | ENDSELECT 64 | 65 | ENDPROC exception 66 | 67 | PROC c0(ptr) 68 | DEF c 69 | c := Char(ptr) 70 | IF (c > 31) AND (c < 128) THEN RETURN c 71 | ENDPROC "." 72 | 73 | PROC c1(ptr) 74 | DEF c 75 | c := Char(ptr+1) 76 | IF (c > 31) AND (c < 128) THEN RETURN c 77 | ENDPROC "." 78 | 79 | PROC c2(ptr) 80 | DEF c 81 | c := Char(ptr+2) 82 | IF (c > 31) AND (c < 128) THEN RETURN c 83 | ENDPROC "." 84 | 85 | PROC c3(ptr) 86 | DEF c 87 | c := Char(ptr+3) 88 | IF (c > 31) AND (c < 128) THEN RETURN c 89 | ENDPROC "." 90 | 91 | 92 | PROC dohunk(ptr:PTR TO LONG) HANDLE 93 | DEF long, pc:PTR TO LONG, clen, str[100]:STRING, r=NIL, a, b, c=NIL, hunknum 94 | long := ptr[]++ 95 | SELECT long 96 | CASE HUNK_UNIT ; PrintF('HUNK_UNIT \s\n', ptr+4) ; r := ptr + 4 + Mul(ptr[],4) 97 | CASE HUNK_NAME ; PrintF('HUNK_NAME \s\n', ptr+4) ; r := ptr + 4 + Mul(ptr[],4) 98 | CASE HUNK_CODE ; PrintF('HUNK_CODE\n size: \d bytes\n', Mul(4,ptr[])) 99 | clen := ptr[]++ 100 | pc := ptr 101 | r := ptr + Mul(4,clen) 102 | IF disasm 103 | WHILE clen 104 | dodis(pc-ptr, pc[], str) 105 | PrintF('L\z\h[7]: \l\s[24] [\z\r\h[8]] \a\c\c\c\c\a (\d\n', 106 | pc-ptr, str, pc[], c0(pc), c1(pc), c2(pc), c3(pc), pc-ptr) 107 | clen-- 108 | pc++ 109 | IF CtrlC() THEN Raise(0) 110 | ENDWHILE 111 | ENDIF 112 | CASE $3F7 ; PrintF('HUNK_PPC_CODE\n size: \d bytes\n', Mul(4,ptr[])) 113 | clen := ptr[]++ 114 | pc := ptr 115 | r := ptr + Mul(4,clen) 116 | IF disasm 117 | WHILE clen 118 | dodis(pc-ptr, pc[], str) 119 | PrintF('L\z\h[7]: \l\s[24] [\z\r\h[8]] \a\c\c\c\c\a\n', 120 | pc-ptr, str, pc[], c0(pc), c1(pc), c2(pc), c3(pc)) 121 | clen-- 122 | pc++ 123 | IF CtrlC() THEN Raise(0) 124 | ENDWHILE 125 | ENDIF 126 | CASE HUNK_DATA ; PrintF('HUNK_DATA\n size: \d bytes\n', Mul(4,ptr[])) 127 | clen := ptr[]++ 128 | pc := ptr 129 | r := ptr + Mul(4,clen) 130 | IF disasm 131 | WHILE clen 132 | PrintF('L\z\h[7]: $\h[8] \a\c\c\c\c\a\n', 133 | pc-ptr, pc[], c0(pc), c1(pc), c2(pc), c3(pc)) 134 | clen-- 135 | pc++ 136 | IF CtrlC() THEN Raise(0) 137 | ENDWHILE 138 | ENDIF 139 | CASE HUNK_BSS ; PrintF('HUNK_BSS\n size: \d bytes\n', Mul(4,ptr[]++)) 140 | r := ptr 141 | CASE HUNK_ABSRELOC32 ; PrintF('HUNK_(ABS)RELOC32\n') 142 | WHILE (a := ptr[]++) 143 | PrintF(' \d entrys to hunk \d\n', a, hunknum := ptr[]++) 144 | ->ptr := ptr + Mul(4,a) 145 | FOR b := 0 TO a-1 146 | IF ptr[] < 0 147 | PrintF(' broken offset $\h\n', ptr[]) 148 | ELSEIF ptr[] > Mul(hunksizes[hunknum], 4) 149 | PrintF(' broken offset $\h\n', ptr[]) 150 | ELSE 151 | IF disasm THEN PrintF(' $\h\n', ptr[]) 152 | ENDIF 153 | ptr++ 154 | ENDFOR 155 | ENDWHILE 156 | r := ptr 157 | CASE HUNK_RELOC16 158 | CASE HUNK_RELRELOC16 159 | CASE HUNK_RELOC8 160 | CASE HUNK_RELRELOC8 161 | CASE HUNK_EXT ; PrintF('HUNK_EXT\n') 162 | WHILE ptr[] 163 | a := Char(ptr) -> type 164 | b := Char(ptr+3) -> len of name in longs 165 | ptr++ 166 | c := NIL 167 | SELECT 256 OF a 168 | CASE EXT_SYMB ; PrintF(' SYMB ') 169 | CASE EXT_DEF ; PrintF(' DEF ') ; c++ 170 | CASE EXT_ABS ; PrintF(' ABS ') 171 | CASE EXT_REF32 ; PrintF(' REF32 ') 172 | CASE EXT_REF16 ; PrintF(' REF16 ') 173 | CASE EXT_DEXT32 ; PrintF(' DEXT32 ') 174 | CASE EXT_DEXT16 ; PrintF(' DEXT16 ') 175 | CASE EXT_RELREF32 ; PrintF(' RELREF32 ') 176 | DEFAULT ; PrintF(' ??? ') 177 | ENDSELECT 178 | PrintF('\l\s[20] ', ptr) 179 | ptr := ptr + (b*4) -> skip name 180 | a := ptr[]++ -> nr of offsets 181 | IF c = NIL THEN PrintF('(\d references)', a) 182 | PrintF('\n') 183 | WHILE a 184 | IF disasm THEN PrintF(' $\h\n', ptr[]) 185 | ptr++ 186 | a-- 187 | ENDWHILE 188 | IF CtrlC() THEN Raise(0) 189 | ENDWHILE 190 | ptr++ -> skip NIL-long 191 | r := ptr 192 | CASE HUNK_SYMBOL ; PrintF('HUNK_SYMBOL\n') 193 | WHILE (a := ptr[]++) -> name len in longs 194 | PrintF(' \s : ', ptr) 195 | ptr := ptr + (a*4) 196 | PrintF(' $\h\n', ptr[]++) 197 | ENDWHILE 198 | r := ptr 199 | CASE HUNK_DEBUG ; PrintF('HUNK_DEBUG\n') 200 | a := ptr[]++ 201 | PrintF(' size: \d bytes\n', Mul(a,4)) 202 | ->ptr := ptr + 2 203 | WHILE a 204 | IF disasm THEN PrintF(' $\z\h[8] \a\c\c\c\c\a\n', ptr[], c0(ptr),c1(ptr),c2(ptr),c3(ptr)) 205 | ptr++ 206 | a-- 207 | IF CtrlC() THEN Raise(0) 208 | ENDWHILE 209 | r := ptr 210 | CASE HUNK_END ; PrintF('HUNK_END\n') ; r := ptr 211 | CASE HUNK_HEADER ; PrintF('HUNK_HEADER\n') 212 | a := 0 213 | WHILE ptr[] 214 | PrintF(' hunk \d \a\s\a\n', a, ptr+4) 215 | ptr := ptr + 4 + Mul(4,ptr[]) 216 | ENDWHILE 217 | ptr++ 218 | 219 | b := ptr[]++ -> nr of hunks 220 | PrintF(' nr of hunks: \d (\d-\d)\n', b, ptr[0], ptr[1]) 221 | ptr := ptr + 8 -> skip fisrt/last hunk nums 222 | 223 | hunksizes := ptr -> save for reloc debug 224 | 225 | FOR a := 0 TO b-1 226 | PrintF(' hunk \d size: \d bytes\n', a, Mul(4,ptr[]++)) 227 | ENDFOR 228 | 229 | r := ptr 230 | CASE HUNK_OVERLAY 231 | CASE HUNK_BREAK 232 | CASE HUNK_DREL32 233 | CASE HUNK_DREL16 234 | CASE HUNK_DREL8 235 | CASE HUNK_LIB 236 | CASE HUNK_INDEX 237 | CASE HUNK_RELOC32SHORT 238 | CASE HUNK_RELRELOC32 239 | CASE HUNK_ABSRELOC16 240 | CASE NIL ; PrintF('done.\n') ; RETURN NIL 241 | DEFAULT 242 | PrintF('HUNK_unknown! ID: $\h\n', long) ; r := NIL 243 | ENDSELECT 244 | EXCEPT 245 | RETURN NIL 246 | ENDPROC r 247 | 248 | -------------------------------------------------------------------------------- /dumpmod.e: -------------------------------------------------------------------------------- 1 | 2 | ->OPT POWERPC 3 | 4 | -> private tool for dumping a cached module to disk (by LS) PUBLIC DOMAIN. 5 | 6 | MODULE '*binary' 7 | MODULE 'dos/dos' 8 | MODULE 'exec/lists' 9 | MODULE 'exec/nodes' 10 | 11 | 12 | PROC main() HANDLE 13 | DEF modulecache=NIL:PTR TO modulecache 14 | DEF cmh:PTR TO moduleheader, t=NIL, fh 15 | DEF m:PTR TO moduleheader 16 | 17 | modulecache := FindSemaphore('EcxCache') 18 | IF modulecache = NIL THEN Raise("NOCA") 19 | cmh := modulecache.modlist.head 20 | 21 | PrintF('dumping \s\n', arg) 22 | 23 | WHILE cmh.succ 24 | IF StrCmp(cmh.mname, arg) 25 | fh := Open('t:t.m', NEWFILE) 26 | Write(fh, cmh, cmh.modsize) 27 | Close(fh) 28 | Raise(0) 29 | ENDIF 30 | cmh := cmh.succ 31 | ENDWHILE 32 | 33 | PrintF('not found!\n') 34 | 35 | EXCEPT DO 36 | 37 | SELECT exception 38 | CASE "NOCA" ; PrintF('no cache available!\n') 39 | CASE "MEM" ; PrintF('Out of memory\n') 40 | ENDSELECT 41 | ENDPROC 42 | 43 | -------------------------------------------------------------------------------- /eecelf.e: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | ** EEC/eecelf.e 3 | ** derived from 4 | ** ECX/ecxelf.e . 5 | ** Copyright (c) Leif Salomonsson 2002-2007. 6 | ** Redistribution of this source is allowed as long as: 7 | ** 1. no copyright notice is removed or altered. 8 | ** 2. altered source must be clearly marked as such. 9 | **********************************************************************/ 10 | 11 | OPT MODULE 12 | OPT EXPORT 13 | OPT PREPROCESS 14 | 15 | 16 | ENUM EI_MAG0, 17 | EI_MAG1, 18 | EI_MAG2, 19 | EI_MAG3, 20 | EI_CLASS, 21 | EI_DATA, 22 | EI_VERSION, 23 | EI_PAD, 24 | EI_NIDENT=16 25 | 26 | ENUM ELFCLASSNONE, 27 | ELFCLASS32, 28 | ELFCLASS64 29 | 30 | ENUM ELFDATANONE, 31 | ELFDATA2LSB, 32 | ELFDATA2MSB 33 | 34 | CONST ET_REL = 1, 35 | ET_EXEC = 2, 36 | ET_DYN = 3 37 | 38 | CONST EM_68K=4, EM_PPC = 20 39 | 40 | CONST EV_CURRENT = 1 41 | 42 | OBJECT ehdr 43 | ident[EI_NIDENT]:ARRAY OF CHAR -> ["\$7F\~ELF", $01020100, NIL, NIL]:LONG 44 | type:INT -> ET_REL 45 | machine:INT -> EM_PPC 46 | version:LONG -> 1 47 | entry:LONG -> 0 48 | phoff:LONG -> usually SIZEOF ehdr 49 | shoff:LONG -> 50 | flags:LONG -> NIL 51 | ehsize:INT -> SIZEOF ehdr 52 | phentsize:INT -> SIZEOF phdr 53 | phnum:INT -> number of phdr`s 54 | shentsize:INT -> SIZEOF shdr 55 | shnum:INT -> number of shdr`s 56 | shstrndx:INT -> 57 | ENDOBJECT 58 | 59 | ENUM PT_NULL, 60 | PT_LOAD, 61 | PT_DYNAMIC, 62 | PT_INTERP, 63 | PT_NOTE, 64 | PT_SHLIB, 65 | PT_PHDR 66 | 67 | SET PF_X, -> executable 68 | PF_W, -> write 69 | PF_R -> read 70 | 71 | OBJECT phdr 72 | type:LONG -> PT_xxx, normally PT_LOAD 73 | offset:LONG -> offset in file of code/data 74 | vaddr:LONG -> 0 for current targets 75 | paddr:LONG -> 0 for current targets 76 | filesz:LONG -> size on disk 77 | memsz:LONG -> same as filesz for code 78 | flags:LONG -> PF_R OR PF_X for code 79 | align:LONG -> 4 for code 80 | ENDOBJECT 81 | 82 | CONST SHN_ABS = $FFF1, 83 | SHN_COMMON = $FFF2 84 | 85 | CONST SHT_NULL = 0, 86 | SHT_PROGBITS = 1, 87 | SHT_SYMTAB = 2, 88 | SHT_STRTAB = 3, 89 | SHT_RELA = 4, 90 | SHT_HASH = 5, 91 | SHT_DYNAMIC = 6, 92 | SHT_NOBITS = 8, 93 | SHT_REL = 9, 94 | SHT_DYNSYM = 11 95 | 96 | SET SHF_WRITE, 97 | SHF_ALLOC, 98 | SHF_EXECINSTR 99 | 100 | OBJECT shdr 101 | name:LONG 102 | type:LONG 103 | flags:LONG 104 | addr:LONG 105 | offset:LONG 106 | size:LONG 107 | link:LONG 108 | info:LONG 109 | addralign:LONG 110 | entsize:LONG 111 | ENDOBJECT 112 | 113 | ENUM STB_LOCAL, 114 | STB_GLOBAL, 115 | STB_WEAK, 116 | STB_NUM 117 | 118 | CONST STB_LOOS = 10 119 | CONST STB_HIOS = 12 120 | CONST STB_LOPROC = 13 121 | CONST STB_HIPROC = 15 122 | 123 | ENUM STT_NOTYPE, 124 | STT_OBJECT, 125 | STT_FUNC, 126 | STT_SECTION, 127 | STT_FILE, -> 1.7.1: was missing 128 | STT_COMMON, -> 1.7.1: was missing 129 | STT_TLS -> 1.7.1 was missing 130 | 131 | #define ST_BIND(val) (Shr(val,4) AND $FFFFFFF) 132 | #define ST_TYPE(val) ((val) AND $F) 133 | #define ST_INFO(bind,type) (Shl(bind, 4) + (type)) 134 | 135 | OBJECT sym 136 | name:LONG 137 | value:LONG 138 | size:LONG 139 | info:CHAR -> ST_INFO 140 | other:CHAR 141 | shndx:INT 142 | ENDOBJECT 143 | 144 | ENUM R_PPC_NONE, 145 | R_PPC_ADDR32, 146 | R_PPC_ADDR24, 147 | R_PPC_ADDR16, 148 | R_PPC_ADDR16_LO, 149 | R_PPC_ADDR16_HI, 150 | R_PPC_ADDR16_HA, 151 | R_PPC_ADDR14, 152 | R_PPC_ADDR14_BRTAKEN, 153 | R_PPC_ADDR14_BRNTAKEN, 154 | R_PPC_REL24, 155 | R_PPC_REL14, 156 | R_PPC_REL14_BRTAKEN, 157 | R_PPC_REL14_BRNTAKEN, 158 | R_PPC_GOT16, 159 | R_PPC_GOT16_LO, 160 | R_PPC_GOT16_HI, 161 | R_PPC_GOT16_HA, 162 | R_PPC_PLTREL24, 163 | R_PPC_COPY, 164 | R_PPC_GLOB_DAT, 165 | R_PPC_JMP_SLOT, 166 | R_PPC_RELATIVE, 167 | R_PPC_LOCAL24PC, 168 | R_PPC_UADDR32, 169 | R_PPC_UADDR16, 170 | R_PPC_REL32, 171 | R_PPC_PLT32, 172 | R_PPC_PLTREL32, 173 | R_PPC_PLT16_LO, 174 | R_PPC_PLT16_HI, 175 | R_PPC_PLT16_HA, 176 | R_PPC_SDAREL16, 177 | R_PPC_SECTOFF, 178 | R_PPC_SECTOFF_LO, 179 | R_PPC_SECTOFF_HI, 180 | R_PPC_SECTOFF_HA 181 | 182 | /* MorphOS additions */ 183 | CONST R_PPC_MORPHOS_DREL = 200, 184 | R_PPC_MORPHOS_DREL_LO = 201, 185 | R_PPC_MORPHOS_DREL_HI = 202, 186 | R_PPC_MORPHOS_DREL_HA = 203 187 | 188 | /* AmigaOS4 additions */ 189 | CONST R_PPC_AMIGAOS_BREL = 210, 190 | R_PPC_AMIGAOS_BREL_LO = 211, 191 | R_PPC_AMIGAOS_BREL_HI = 212, 192 | R_PPC_AMIGAOS_BREL_HA = 213 193 | 194 | 195 | ENUM R_68K_NONE, 196 | R_68K_32, 197 | R_68K_16, 198 | R_68K_8, 199 | R_68K_PC32 200 | 201 | #define R_SYM(val) Shr(val,8) 202 | #define R_TYPE(val) ((val) AND $FF) 203 | #define R_INFO(sym,type) (Shl(sym, 8) OR (type)) 204 | 205 | OBJECT rel 206 | offset:LONG 207 | info:LONG 208 | ENDOBJECT 209 | 210 | OBJECT rela OF rel 211 | addend:LONG 212 | ENDOBJECT 213 | 214 | 215 | -------------------------------------------------------------------------------- /emptycache.e: -------------------------------------------------------------------------------- 1 | -> EmptyCache by Leif Salomonsson [ecx tele2 se] is Copyrigh (c) 2003-2007. 2 | -> Released under ECX TOOLS LICENSE, see ECXTOOLSLICENSE.TXT 3 | 4 | -> February 2009: called InStr() with a zero rempat, FIXED. 5 | 6 | MODULE '*binary' 7 | MODULE 'dos/dos' 8 | MODULE 'exec/lists' 9 | MODULE 'exec/nodes' 10 | 11 | 12 | PROC main() HANDLE 13 | DEF modulecache=NIL:PTR TO modulecache 14 | DEF cmh:PTR TO moduleheader, succ, rempat=NIL, rem 15 | 16 | IF StrLen(arg) THEN rempat := arg 17 | 18 | Forbid() 19 | modulecache := FindSemaphore('EcxCache') 20 | Permit() 21 | IF modulecache = NIL THEN Raise("NOCA") 22 | IF modulecache.ident <> "MC" THEN Raise("MCC") 23 | IF AttemptSemaphore(modulecache) = NIL THEN Raise("ASEM") 24 | cmh := modulecache.modlist.head 25 | 26 | PrintF('EmptyCache 1.4 by LS 2003-2009\n') 27 | 28 | WHILE cmh.succ 29 | ->WriteF('cmh=$\h, cmh.mnamelen=\d, cmh.mname=$\h, cmh.mname="\s"\n', 30 | ->cmh, cmh.mnamelen, cmh.mname, cmh.mname) 31 | succ := cmh.succ 32 | rem := FALSE 33 | IF rempat = 0 34 | rem := TRUE 35 | ELSEIF InStr(cmh.mname, rempat) <> -1 36 | rem := TRUE 37 | ELSE 38 | rem := FALSE 39 | ENDIF 40 | IF rem 41 | Remove(cmh) 42 | FreeMem(cmh.mname, cmh.mnamelen+1) 43 | FreeMem(cmh, cmh.modsize) 44 | ENDIF 45 | cmh := succ 46 | ENDWHILE 47 | 48 | PrintF('done.\n') 49 | 50 | ReleaseSemaphore(modulecache) 51 | 52 | EXCEPT DO 53 | 54 | SELECT exception 55 | CASE "NOCA" ; PrintF('no cache available!\n') 56 | CASE "ASEM" ; PrintF('semaphore is blocked!\n') 57 | CASE "MCC" ; PrintF('modulecache is corrupt!\n') -> 1.8.0 58 | ENDSELECT 59 | 60 | ENDPROC 61 | 62 | 63 | -------------------------------------------------------------------------------- /libstubs.e: -------------------------------------------------------------------------------- 1 | -> ECX/libstubs.e 2 | 3 | /* ECX by Leif Salomonsson [ecx tele2 se] is Copyright (c) 2002-2008 */ 4 | /* Released under the ECX COMPILER LICENSE, See ECXCOMPILERLICENSE.TXT */ 5 | 6 | OPT MODULE, PREPROCESS 7 | 8 | -> libstubs.e extracted 2009 from initcode.e 9 | -> initcode.e. created module May 2008. code extracted from codegen.e and ecxmain.e 10 | 11 | -> 1.10.0 : removed library specific initcode. 12 | 13 | ->#define DBG_LIBSTUBS 14 | 15 | MODULE '*binary' 16 | MODULE '*opcodes68' 17 | MODULE '*opcodesppc' 18 | MODULE '*runtime' 19 | MODULE '*compiler' 20 | MODULE '*common' 21 | MODULE '*assembler' 22 | 23 | MODULE 'exec/lists' 24 | 25 | EXPORT DEF g_nrofentries, g_entrytable:PTR TO LONG 26 | EXPORT DEF g_codeptr:PTR TO LONG, g_codebuf, link_codesize 27 | EXPORT DEF g_gvarlist:PTR TO gvar 28 | EXPORT DEF link_globaldatasize 29 | EXPORT DEF g_databuf:PTR TO LONG, g_databufsize 30 | EXPORT DEF g_modulelist:PTR TO mlh 31 | EXPORT DEF g_objectlist:PTR TO object 32 | 33 | #define Put32(v) g_codeptr[]++ := v 34 | 35 | EXPORT PROC putEntries68K() 36 | DEF a, e:PTR TO entry, b, proc:PTR TO proc 37 | DEF stub:PTR TO genlab, par:PTR TO var 38 | /* make actual entries */ 39 | IF Odd(g_codeptr) THEN g_codeptr := g_codeptr + 1 40 | FOR a := 0 TO g_nrofentries-1 41 | e := g_entrytable[a] 42 | IF e.prochln 43 | proc := e.prochln.ident 44 | IF proc = NIL THEN reportErr('unknown identifier', e.prochln.name) 45 | IF proc.identID <> IDENT_LABEL THEN reportErr('not suitable for entry', e.prochln.name) 46 | IF proc.ltype <> LTYPE_PROC THEN reportErr('not suitable for entry', e.prochln.name) 47 | proc.referenced := 1 48 | putLabel(e.label) 49 | e.nrofargs := proc.nrofargs 50 | IF proc.cpu = 0 51 | libstub68k_68k(e, proc) 52 | ELSE 53 | libstub68k_ppc(e, proc) 54 | ENDIF 55 | ELSE -> EMPTY 56 | putLabel(e.label) 57 | moveqdx(0,0) 58 | rts_() 59 | ENDIF 60 | ENDFOR 61 | 62 | ENDPROC 63 | 64 | EXPORT PROC putEntriesPPC() 65 | DEF a, e:PTR TO entry, proc:PTR TO proc 66 | /* make actual entries */ 67 | FOR a := 0 TO g_nrofentries-1 68 | e := g_entrytable[a] 69 | putAlign(4) 70 | IF e.prochln 71 | proc := e.prochln.ident 72 | IF proc = NIL THEN reportErr('unknown identifier', e.prochln.name) 73 | IF proc.identID <> IDENT_LABEL THEN reportErr('not suitable for entry', e.prochln.name) 74 | IF proc.ltype <> LTYPE_PROC THEN reportErr('not suitable for entry', e.prochln.name) 75 | proc.referenced := 1 76 | putLabel(e.label) 77 | e.nrofargs := proc.nrofargs 78 | IF e.type = 0 -> 68k abi in ppc mode ? 79 | IF proc.cpu = 0 -> 68k->68k ? 80 | libstub68k_68k(e, proc) 81 | ELSE -> 68k->ppc 82 | libstub68k_ppc(e, proc) 83 | ENDIF 84 | ELSE 85 | IF proc.cpu = 1 86 | libstubppc_ppc(e, proc) 87 | ELSE 88 | libstubppc_68k(e, proc) 89 | ENDIF 90 | ENDIF 91 | ELSE -> EMPTY 92 | IF e.type = 1 -> ppc abi 93 | putLabel(e.label) 94 | ppcaddi(3,0,0) 95 | ppcbclr(20,0,0) 96 | ELSE -> 68k abi 97 | putLabel(e.label) 98 | moveqdx(0,0) 99 | rts_() 100 | ENDIF 101 | ENDIF 102 | ENDFOR 103 | 104 | ENDPROC 105 | 106 | PROC libstubppc_ppc(e:PTR TO entry, proc:PTR TO proc) 107 | DEF a, endstub:PTR TO genlab, t, par:PTR TO var 108 | 109 | FOR t := 0 TO proc.nrofargs-1 -> v48 110 | par := proc.argarray[t] 111 | e.regs[t].rtype := par.rtype 112 | e.regs[t].rnum := par.rnum 113 | ENDFOR 114 | SELECT 20 OF proc.mret.ros[0] -> 2.0 115 | CASE RX ; e.return := 0 116 | CASE FPX ; e.return := 1 117 | CASE VX ; e.return := 2 118 | CASE X2R ; e.return := 3 119 | ENDSELECT 120 | ppcstwu(1,1,-64) 121 | ppcmfspr(0,8) 122 | ppcstw(0,1,68) 123 | ppcstw(13,1,60) 124 | ppclwz(13,e.basernum,PRIVBASE_ENV) -> changed 1.10.0 125 | FOR t := 0 TO proc.nrofargs-1 -> v48 126 | par := proc.argarray[t] 127 | IF par.rtype = PPCARGRTYPE_STACKRX 128 | ppclwz(0,1,par.rnum+64) 129 | ppcstw(0,1,par.rnum) 130 | ELSEIF par.rtype = PPCARGRTYPE_STACKRX2 -> 2.0 131 | ppclfd(0,1,par.rnum+64) 132 | ppcstfd(0,1,par.rnum) 133 | ENDIF 134 | ENDFOR 135 | ppcblab(proc,0,1) 136 | ppclwz(0,1,68) 137 | ppclwz(13,1,60) 138 | ppcmtspr(0,8) 139 | ppcaddi(1,1,64) 140 | ppcbclr(20,0,0) 141 | 142 | ENDPROC 143 | 144 | PROC libstubppc_68k(e:PTR TO entry, proc:PTR TO proc) 145 | DEF a, endstub:PTR TO genlab 146 | ppcstwu(1, 1, -16) 147 | ppcmfspr(0,8) 148 | ppcstw(0,1,20) 149 | FOR a := 0 TO proc.nrofargs-1 150 | ppcstw(e.regs[a].rnum, 2, a*4) 151 | ENDFOR 152 | ppclwz(0, e.basernum, PRIVBASE_ENV) 153 | ppcstw(0, 2, 48) -> a4 154 | -> do the twist 155 | endstub := newLabel() 156 | ppcblab(endstub,0,1) -> skip 68k stubcode 157 | -> stub: from regs to stack as params for procedure 158 | FOR a := 0 TO proc.nrofargs-1 DO movedxaxpd(SIZE_L,a,7) 159 | bsrlab(proc) 160 | leaaxpofsax(7,proc.nrofargs*4,7) 161 | rts_() 162 | putAlign(4) -> align 4 163 | putLabel(endstub) 164 | ppcmfspr(3,8) -> to r3 165 | ppclwz(0,2,104) -> emulcalldirect68k to r0 166 | ppcmtspr(0,9) -> ctr 167 | ppcbcctr(20,0,1) -> bctrl 168 | ppclwz(0,1,20) 169 | ppcmtspr(0,8) 170 | ppcaddi(1,1,16) 171 | ppcbclr(20,0,0) 172 | 173 | ENDPROC 174 | 175 | PROC libstub68k_68k(e:PTR TO entry, proc:PTR TO proc) 176 | DEF b 177 | 178 | -> save regs.. 179 | movemregsaxpd(SIZE_L, %0011111100111110, 7) 180 | -> get a4 from libbase pointed to by A6 181 | moveaxpofsax(SIZE_L,6,PRIVBASE_ENV,4) -> changed 1.10.0 182 | -> push regs as proc-params 183 | FOR b := 0 TO proc.nrofargs-1 184 | IF e.regs[b].rtype = 1 185 | moveaxaxpd(SIZE_L,e.regs[b].rnum,7) 186 | ELSEIF e.regs[b].rtype = 0 187 | movedxaxpd(SIZE_L,e.regs[b].rnum,7) 188 | ENDIF 189 | ENDFOR 190 | -> call proc 191 | bsrlab(proc) 192 | -> cleanup stack 193 | IF proc.nrofargs THEN leaaxpofsax(7,proc.nrofargs*4,7) 194 | -> restore regs 195 | movemaxpiregs(SIZE_L,7, %0111110011111100) 196 | -> return 197 | rts_() 198 | 199 | ENDPROC 200 | 201 | PROC libstub68k_ppc(e:PTR TO entry, proc:PTR TO proc) 202 | DEF b, stub:PTR TO genlab, par:PTR TO var 203 | 204 | stub := newLabel() 205 | Put32($FF000000) -> TRAP_LIB 206 | putReloc(stub) 207 | putAlign(4) 208 | putLabel(stub) 209 | ppcstwu(1,1,-64) 210 | ppcmfspr(0,8) 211 | ppclwz(12,2,56) -> bas 212 | ppcstw(13,1,60) 213 | ppcstw(0,1,68) 214 | ppclwz(13,12,PRIVBASE_ENV) -> changed 1.10.0 215 | FOR b := 0 TO proc.nrofargs-1 216 | par := proc.argarray[b] 217 | IF par.rtype = 0 218 | IF e.regs[b].rtype = 0 219 | ppclwz(par.rnum, 2, e.regs[b].rnum*4) 220 | ELSE 221 | ppclwz(par.rnum, 2, e.regs[b].rnum*4+32) 222 | ENDIF 223 | ELSEIF par.rtype = 1 224 | IF e.regs[b].rtype = 0 225 | ppclwz(0, 2, e.regs[b].rnum*4) 226 | ppcstw(0, 1, par.rnum) 227 | ELSE 228 | ppclwz(0, 2, e.regs[b].rnum*4+32) 229 | ppcstw(0, 1, par.rnum) 230 | ENDIF 231 | ELSE 232 | reportErr('procedure is not suitable as entry', proc.name) 233 | ENDIF 234 | ENDFOR 235 | ppcblab(proc,0,1) 236 | ppclwz(0,1,68) 237 | ppclwz(13,1,60) 238 | ppcmtspr(0,8) 239 | ppcaddi(1,1,64) 240 | ppcbclr(20,0,0) 241 | 242 | ENDPROC 243 | -------------------------------------------------------------------------------- /make68kifuncs.script: -------------------------------------------------------------------------------- 1 | vasmm68k_mot -o eec:ec68kifuncs.o -Fhunk -m68020 -m68882 ec68kifuncs.asm 2 | -------------------------------------------------------------------------------- /makedist.script: -------------------------------------------------------------------------------- 1 | 2 | SET EECNAME EEC-1_0 3 | 4 | IF EXISTS RAM:$EECNAME 5 | DELETE RAM:$EECNAME ALL 6 | ENDIF 7 | 8 | IF EXISTS RAM:$EECNAME.lha 9 | DELETE RAM:$EECNAME.lha 10 | ENDIF 11 | 12 | MAKEDIR RAM:$EECNAME 13 | 14 | CD RAM:$EECNAME 15 | MAKEDIR docs 16 | MAKEDIR bin 17 | MAKEDIR modules 18 | MAKEDIR tools 19 | MAKEDIR source 20 | COPY EEC:eec.readme eec.readme 21 | 22 | CD RAM:$EECNAME/BIN 23 | COPY EEC:eec.020 EEC.020 24 | COPY EEC:EEC.mos EEC.mos 25 | COPY EEC:EEC.os4 EEC.os4 26 | COPY EEC:diself DisELF 27 | COPY EEC:viewmodule ViewModule 28 | COPY EEC:emptycache EmptyCache 29 | COPY EEC:viewcache ViewCache 30 | COPY EEC:modulefromfd ModuleFromFD 31 | COPY EEC:modulefromproto ModuleFromProto 32 | COPY EEC:modulefromproto.readme ModuleFromProto.readme 33 | COPY EEC:trackhit TrackHit 34 | COPY EEC:dishunk DisHunk 35 | COPY EEC:ceemodule CeeModule 36 | COPY EEC:makelibmod MakeLibMod 37 | 38 | CD RAM:$EECNAME/DOCS 39 | COPY EEC:EEC.guide EEC.guide 40 | 41 | CD RAM:$EECNAME/MODULES 42 | COPY EEC:modules/#? "" all 43 | DELETE #?.~(m) #?/#?.~(m) #?/#?/#?.~(m) #?/#?/#?/#?.~(m) 44 | DELETE amigaos4/makelibmods.script 45 | DELETE morphos/makelibmods.script 46 | 47 | CD RAM:$EECNAME/SOURCE 48 | MAKEDIR modules 49 | COPY EEC:modules/#? modules/ all 50 | DELETE modules/~(#?.e) modules/#?/~(#?.e) modules/#?/#?/~(#?.e) modules/#?/#?/#?/~(#?.e) 51 | 52 | COPY EEC:Source/#? "" all 53 | DELETE #?.m #?/#?.m #?/#?/#?.m #?/#?/#?/#?.m 54 | DELETE ~(#?.#?) #?/~(#?.#?) #?/#?/~(#?.#?) #?/#?/#?/~(#?.#?) 55 | 56 | CD RAM: 57 | LHA a -r $EECNAME.lha $EECNAME 58 | COPY $EECNAME.lha media:upload/$EECNAME.lha 59 | COPY EEC:EEC.readme media:upload/$EECNAME.readme 60 | 61 | DELETE $EECNAME ALL 62 | 63 | ECHO $EECNAME.lha DONE 64 | 65 | UNSET EECNAME 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /makeeec.script: -------------------------------------------------------------------------------- 1 | .K target/A,define/K,more/K 2 | 3 | ;; NOTE: A special version of EC is *required* to compile eec.020. 4 | set specialec testec 5 | delete #?.m 6 | flushcache 7 | emptycache 8 | 9 | set target 10 | 11 | if EQ MORPHOS 12 | set ename eec.mos 13 | set ec eec.020 showargs morphos opti define "STACKSIZE 262144;" 14 | endif 15 | 16 | if EQ AMIGAOS4 17 | set ename eec.os4 18 | set ec eec.020 showargs amigaos4 opti define "STACKSIZE 262144;" 19 | endif 20 | 21 | if EQ AMIGAOS 22 | set ename eec.aos 23 | set ec eec.020 showargs opti define "" amigaos 24 | endif 25 | 26 | if EQ EC 27 | set ec $specialec addbuf=900 errline large ignorecache 28 | ;set ec ec addbuf=900 opti large errline 29 | endif 30 | 31 | if EQ EVO 32 | set ec evo showfname legacy addbuf=900 errline large ignorecache 33 | set target EC 34 | endif 35 | 36 | echo target: 37 | echo ec: $ec 38 | 39 | $ec binary.e 40 | $ec eecelf.e 41 | $ec runtime.e 42 | $ec support.e 43 | $ec compiler.e 44 | $ec common.e 45 | $ec opcodes68.e 46 | $ec opcodesppc.e 47 | $ec assembler.e 48 | $ec libstubs.e 49 | $ec inline68.e 50 | $ec inlineppc.e 51 | $ec codegen.e 52 | $ec ppcgen.e 53 | $ec 020gen.e 54 | $ec ecmodtrans.e 55 | echo building main 56 | if $target EQ EC 57 | $ec eecmain.e 58 | delete eec.020 59 | rename eecmain eec.020 60 | else 61 | $ec eecmain exename $ename 62 | endif 63 | 64 | 65 | -------------------------------------------------------------------------------- /makeppcifuncs.script: -------------------------------------------------------------------------------- 1 | vasmppc_std -Fhunk -big -many -o ppcifuncs.o ppcifuncs.asm 2 | -------------------------------------------------------------------------------- /makeppcifuncs_os4.script: -------------------------------------------------------------------------------- 1 | vasmppc_std -Fhunk -big -many -D_AMIGAOS4_ -o ppcifuncs_os4.o ppcifuncs.asm 2 | -------------------------------------------------------------------------------- /makesrcdist.script: -------------------------------------------------------------------------------- 1 | 2 | SET EECNAME EEC-1.0.0 3 | SET EDIR EEC: 4 | 5 | SET DSTDIR media:upload 6 | 7 | SET SRCDIR ${EECNAME}-src 8 | 9 | SET ARCH ${SRCDIR}.lha 10 | 11 | SET README ${SRCDIR}.readme 12 | 13 | CD RAM: 14 | 15 | IF EXISTS $SRCDIR 16 | DELETE $SRCDIR ALL 17 | ENDIF 18 | 19 | IF EXISTS $ARCH.lha 20 | DELETE $ARCH.lha 21 | ENDIF 22 | 23 | MAKEDIR $SRCDIR 24 | 25 | ; COMPILER (ECX LICENSE, ZLIB, OTHER) 26 | 27 | COPY ${EDIR}eecmain.e $SRCDIR/ ; ECX LICENSE 28 | COPY ${EDIR}compiler.e $SRCDIR/ ; ECX LICENSE 29 | COPY ${EDIR}codegen.e $SRCDIR/ ; ECX LICENSE 30 | COPY ${EDIR}assembler.e $SRCDIR/ ; ECX LICENSE 31 | COPY ${EDIR}common.e $SRCDIR/ ; ECX LICENSE 32 | COPY ${EDIR}support.e $SRCDIR/ ; ECX LICENSE 33 | COPY ${EDIR}inline68.e $SRCDIR/ ; ECX LICENSE 34 | COPY ${EDIR}inlineppc.e $SRCDIR/ ; ECX LICENSE 35 | COPY ${EDIR}ecmodtrans.e $SRCDIR/ ; ECX LICENSE 36 | COPY ${EDIR}m68gen.e $SRCDIR/ ; ECX LICENSE 37 | COPY ${EDIR}ppcgen.e $SRCDIR/ ; ECX LICENSE 38 | COPY ${EDIR}libstubs.e $SRCDIR/ ; ECX LICENSE 39 | COPY ${EDIR}runtime.e $SRCDIR/ ; ECX LICENSE 40 | 41 | COPY ${EDIR}opcodes68.e $SRCDIR/ ; ZLIB LICENSE 42 | COPY ${EDIR}opcodesppc.e $SRCDIR/ ; ZLIB LICENSE 43 | 44 | COPY ${EDIR}eecelf.e $SRCDIR/ ; OWN LICENSE 45 | COPY ${EDIR}binary.e $SRCDIR/ ; OWN LICENSE 46 | 47 | ; STARTUPS AND INTERNAL FUNCS (ZLIB/LIBPNG LICENSE) 48 | 49 | COPY ${EDIR}startup_morphos.e $SRCDIR/ 50 | COPY ${EDIR}startup_amigaos.e $SRCDIR/ 51 | COPY ${EDIR}startup_amigaos4.e $SRCDIR/ 52 | COPY ${EDIR}multilibraryX.e $SRCDIR/ 53 | COPY ${EDIR}ppcifuncs.asm $SRCDIR/ 54 | COPY ${EDIR}ec68kifuncs.asm $SRCDIR/ 55 | 56 | ; MISC (ZLIB/LIBPNG LICENSE) 57 | 58 | COPY ${EDIR}ppcdisasm.e $SRCDIR/ 59 | 60 | ; TOOLS (ECX TOOLS LICENSE) 61 | 62 | COPY ${EDIR}emptycache.e $SRCDIR/ 63 | COPY ${EDIR}viewcache.e $SRCDIR/ 64 | COPY ${EDIR}viewmodule.e $SRCDIR/ 65 | COPY ${EDIR}dumpmod.e $SRCDIR/ 66 | COPY ${EDIR}diself.e $SRCDIR/ 67 | COPY ${EDIR}dishunk.e $SRCDIR/ 68 | COPY ${EDIR}trackhit.e $SRCDIR/ 69 | ;COPY ${EDIR}catchhit.e $SRCDIR/ 70 | COPY ${EDIR}modulefromfd.e $SRCDIR/ 71 | COPY ${EDIR}modulefromproto.e $SRCDIR/ 72 | COPY ${EDIR}ceemodule.e $SRCDIR/ 73 | COPY ${EDIR}makelibmod.e $SRCDIR/ 74 | 75 | ; LICENSE TEXTS 76 | 77 | COPY ${EDIR}CompilerLicense.md $SRCDIR/ 78 | COPY ${EDIR}ToolLicense.md $SRCDIR/ 79 | 80 | ; README 81 | 82 | COPY ${EDIR}eecsrc.readme $SRCDIR/$README 83 | 84 | ; SCRIPTS 85 | 86 | COPY ${EDIR}makesrcdist.script $SRCDIR/ 87 | COPY ${EDIR}makedist.script $SRCDIR/ 88 | COPY ${EDIR}makestartups.script $SRCDIR/ 89 | COPY ${EDIR}makeeec.script $SRCDIR/ 90 | 91 | ; MAKE ARCHIVE 92 | 93 | LHA a -r $ARCH $SRCDIR/#?.#? 94 | 95 | COPY $ARCH $DSTDIR/ 96 | COPY ${EDIR}EECsrc.readme $DSTDIR/$README 97 | 98 | ; DELETE FILES 99 | 100 | DELETE $SRCDIR ALL 101 | DELETE $ARCH 102 | 103 | UNSET DSTDIR 104 | UNSET SRCDIR 105 | UNSET EDIR 106 | UNSET EECNAME 107 | UNSET ARCH 108 | UNSET README 109 | 110 | ECHO ALL DONE 111 | 112 | 113 | -------------------------------------------------------------------------------- /makestartups.script: -------------------------------------------------------------------------------- 1 | .KEY arg 2 | 3 | set ec eec.020 4 | set dir ecxmodules:eec/ 5 | ;set opts QUIET SHOWFNAME 6 | set opts SHOWFNAME IGNORECACHE 7 | 8 | delete ${dir}#?.m 9 | 10 | copy ecxmodules:ecx/target#? ecxmodules:eec/ 11 | 12 | $ec amigaos runtime.e ddir ecxmodules:amigaos/ define "_AMIGAOS;" $opts 13 | $ec morphos runtime.e ddir ecxmodules:morphos/ define "_MORPHOS;" $opts 14 | $ec amigaos4 runtime.e ddir ecxmodules:amigaos4/ define "_AMIGAOS4;" $opts 15 | 16 | $ec amigaos startup_amigaos.e ddir $dir define "" $opts 17 | $ec amigaos startup_amigaos.e ddir $dir define "MINSTARTUP;" $opts 18 | $ec morphos startup_morphos.e ddir $dir define "" $opts 19 | $ec morphos startup_morphos.e ddir $dir define "MINSTARTUP;" $opts 20 | $ec amigaos4 startup_amigaos4.e ddir $dir define "" $opts 21 | $ec amigaos4 startup_amigaos4.e ddir $dir define "MINSTARTUP;" $opts 22 | 23 | $ec amigaos multilibraryX.e ddir $dir define "CODE_AMIGAOS;" $opts 24 | $ec morphos multilibraryX.e ddir $dir define "CODE_MORPHOS;" $opts 25 | -------------------------------------------------------------------------------- /multilibraryx.e: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | (The zlib/libpng License) 4 | 5 | Copyright (c) 2007 Leif Salomonsson 6 | 7 | This software is provided 'as-is', without any express or implied warranty. 8 | In no event will the authors be held liable for any damages arising from 9 | the use of this software. 10 | 11 | Permission is granted to anyone to use this software for any purpose, 12 | including commercial applications, and to alter it and redistribute it 13 | freely, subject to the following restrictions: 14 | 15 | 1. The origin of this software must not be misrepresented; you must not 16 | claim that you wrote the original software. If you use this software 17 | in a product, an acknowledgment in the product documentation would be 18 | appreciated but is not required. 19 | 20 | 2. Altered source versions must be plainly marked as such, and must not be 21 | misrepresented as being the original software. 22 | 23 | 3. This notice may not be removed or altered from any source distribution. 24 | 25 | */ 26 | 27 | -> Feb 2007 28 | 29 | -> NOTE: Being startupcode, WE CAN NOT have inline lists.. 30 | -> Maybe this will change though.. 31 | 32 | -> May 2007: now returns same base if task already has openlibrary us. 33 | 34 | -> 2008 sometime, added support for MorphOS2 query() function and resident.tags. 35 | 36 | -> May 2008: made query() function take additional parameter: utilitybase 37 | -> as we are not guarantied to have global environment in this function. 38 | -> this also means we open utilitybase in init close it in expunge. store it in 39 | -> publicbase. 40 | 41 | -> June 2008: libraries now uses same environment layout as executables. 42 | -> also changed the libinfo structure, no more relocs in it. 43 | -> Environment is now allocated separately and stuffed into 44 | -> privbase.environment. 45 | 46 | OPT MODULE, PREPROCESS 47 | 48 | #ifdef DEBUG 49 | #define DEBUGF(str,...) DebugF(str,...) 50 | #else 51 | #define DEBUGF(str,...) 52 | #endif 53 | 54 | 55 | ->#define CODE_MORPHOS 56 | ->#define CODE_AMIGAOS 57 | 58 | 59 | #ifdef CODE_MORPHOS 60 | OPT MORPHOS 61 | #define RTFLAGS RTF_PPC 62 | #define GLOBREG R13 63 | #define USE_DOUBLE_LIBS 1 64 | #define PUBLICFUNCARRAY PTR libopen_gate, libclose_gate, libexpunge_gate, libext_gate, -1 65 | PROC_RTINIT_HEAD MACRO PROC rtinit(dum,seglist,execbase:PTR TO execbase) 66 | PROC_LIBOPEN_HEAD MACRO 67 | PROC libopen() 68 | DEF pubbase:PTR TO publicbase, version, eh:PTR TO emulhandle, globregsave 69 | eh := R2 70 | pubbase := eh.an[6] 71 | version := eh.dn[0] 72 | ENDM 73 | SETUPGLOBREG MACRO 74 | LWZ GLOBREG, \1 75 | LWZ GLOBREG, GLOBREG, PRIVBASE_ENV 76 | ENDM 77 | SAVEGLOBREG MACRO STW GLOBREG, globregsave 78 | LOADGLOBREG MACRO LWZ GLOBREG, globregsave 79 | PROC_LIBCLOSE_HEAD MACRO 80 | PROC libclose() 81 | DEF eh:PTR TO emulhandle, privbase:PTR TO privatebase, globregsave 82 | eh := R2 83 | privbase := eh.an[6] 84 | ENDM 85 | PROC_LIBEXPUNGE_HEAD MACRO 86 | PROC libexpunge() 87 | DEF eh:PTR TO emulhandle, pubbase:PTR TO publicbase 88 | eh := R2 89 | pubbase := eh.an[6] 90 | ENDM 91 | PROC_LIBEXT_HEAD MACRO 92 | PROC libext() 93 | DEF eh:PTR TO emulhandle, pubbase:PTR TO publicbase 94 | DEF data, attr 95 | ->DEF privbase:PTR TO privatebase 96 | eh := R2 97 | pubbase := eh.an[6] 98 | data := eh.an[0] 99 | attr := eh.dn[0] 100 | ENDM 101 | RUNPROTECT MACRO 102 | ADDI R3, R0, -1 103 | BLR 104 | ENDM 105 | #define LIBS_VERSION 50 106 | #define MATHLIBS_VERSION 37 107 | OPT MODNAME = 'multilibrary_morphos' 108 | #define CACHECLEARU NOP 109 | MODULE 'morphos/exec' 110 | MODULE 'morphos/exec/resident' 111 | MODULE 'morphos/emul/emulinterface' 112 | MODULE 'powerpc/simple' 113 | #define ALLOCVEC(size,flags) AllocVecAligned(size,flags,16,16) 114 | #endif 115 | 116 | #ifdef CODE_AMIGAOS 117 | OPT AMIGAOS 118 | #define USE_SINGLE_LIBS 1 119 | #define RTFLAGS NIL 120 | #define GLOBREG A4 121 | #define PUBLICFUNCARRAY PTR libopen, libclose, libexpunge, libext, -1 122 | PROC_RTINIT_HEAD MACRO 123 | PROC rtinit() 124 | DEF seglist, execbase:PTR TO execbase 125 | MOVE.L D0, seglist 126 | MOVE.L A6, execbase 127 | ENDM 128 | PROC_LIBOPEN_HEAD MACRO 129 | PROC libopen() 130 | DEF pubbase:PTR TO publicbase, version, globregsave 131 | MOVE.L A6, pubbase 132 | MOVE.L D0, version 133 | ENDM 134 | SETUPGLOBREG MACRO 135 | MOVE.L \1, GLOBREG 136 | MOVE.L PRIVBASE_ENV(GLOBREG), GLOBREG 137 | ENDM 138 | SAVEGLOBREG MACRO MOVE.L GLOBREG, globregsave 139 | LOADGLOBREG MACRO MOVE.L globregsave, GLOBREG 140 | PROC_LIBCLOSE_HEAD MACRO 141 | PROC libclose() 142 | DEF privbase:PTR TO privatebase, globregsave 143 | MOVE.L A6, privbase 144 | ENDM 145 | PROC_LIBEXPUNGE_HEAD MACRO 146 | PROC libexpunge() 147 | DEF pubbase:PTR TO publicbase 148 | MOVE.L A6, pubbase 149 | ENDM 150 | PROC_LIBEXT_HEAD MACRO 151 | PROC libext() 152 | DEF privbase:PTR TO privatebase, pubbase:PTR TO publicbase 153 | DEF data, attr 154 | MOVE.L A6, privbase 155 | MOVE.L A0, data 156 | MOVE.L D0, attr 157 | ENDM 158 | RUNPROTECT MACRO 159 | MOVE.L #-1, D0 160 | RTS 161 | ENDM 162 | #define LIBS_VERSION 39 163 | #define MATHLIBS_VERSION 37 164 | OPT MODNAME = 'multilibrary_amigaos' 165 | #define CACHECLEARU CacheClearU() 166 | MODULE 'exec/resident' 167 | #define ALLOCVEC(size,flags) AllocVec(size,flags) 168 | #endif 169 | 170 | 171 | MODULE 'morphos/exec/libraries' 172 | MODULE 'exec/memory' 173 | MODULE 'runtime' 174 | MODULE 'exec/nodes' 175 | MODULE 'exec/lists' 176 | MODULE 'exec/execbase' 177 | 178 | CONST INITFLAGS = LIBF_SUMUSED OR LIBF_CHANGED 179 | CONST ALLOCMEMFLAGS = MEMF_CLEAR OR MEMF_PUBLIC 180 | 181 | EXPORT ___startup: 182 | RUNPROTECT 183 | 184 | EXPORT ___libtag: 185 | WORD RTC_MATCHWORD 186 | PTR ___libtag 187 | PTR endskip 188 | CHAR RTFLAGS /* might get or-patched with RTF_EXTENDED later */, 189 | 0 /* version patched later */, 190 | NT_LIBRARY, 191 | 0 192 | PTR NIL -> namestr # (14) 193 | PTR NIL -> idstr # (18) 194 | PTR rtinit 195 | WORD 0 -> v53: revision patched later 196 | PTR 0 -> v53: tags. for mos extended resident struct 197 | 198 | EXPORT ___startinfo: 199 | LONG 0 -> rwsize 200 | LONG 0 -> initofs 201 | LONG 0 -> stacksize 202 | LONG 0 -> mainofs 203 | LONG 0 -> osversion 204 | LONG 0 -> functabofs 205 | LONG 0 -> closeofs 206 | LONG 0 -> queryofs 207 | 208 | publicfunctions: 209 | PUBLICFUNCARRAY 210 | 211 | 212 | PROC_RTINIT_HEAD 213 | DEF lib:PTR TO publicbase 214 | DEF libinfo:PTR TO libinfo 215 | DEF libtag:PTR TO libtag 216 | 217 | DEBUGF('LIB_rtinit\n') 218 | 219 | libtag := {___libtag} 220 | libinfo := {___startinfo} 221 | IF libinfo.osversion > execbase.lib.version THEN RETURN NIL 222 | 223 | lib := MakeLibrary({publicfunctions}, NIL, NIL, SIZEOF publicbase, seglist) 224 | IF lib = NIL THEN RETURN NIL 225 | 226 | lib.seglist := seglist 227 | lib.version := libtag.version 228 | lib.revision := libtag.revision 229 | lib.flags := INITFLAGS 230 | IF libinfo.queryofs 231 | lib.flags OR= LIBF_QUERYINFO -> v53 232 | lib.utilitybase := OpenLibrary('utility.library', 39) -> 1.10.0 233 | IF lib.utilitybase = NIL THEN RETURN NIL 234 | ELSE 235 | lib.utilitybase := NIL 236 | ENDIF 237 | lib.ln.name := libtag.name 238 | lib.idstring := libtag.idstring 239 | lib.ln.type := NT_LIBRARY 240 | 241 | lib.userlist.head := lib.userlist + 4 242 | lib.userlist.tail := NIL 243 | lib.userlist.tailpred := lib.userlist 244 | lib.pubbaseid := "PUBL" 245 | 246 | AddLibrary(lib) 247 | 248 | DEBUGF('LIB_rtinit DONE (lib=$\h, ver=\d, rev=\d, flags=$\h, name=\s, idstr=\s, osver=\d)\n', 249 | lib, lib.version, lib.revision, lib.flags, lib.ln.name, lib.idstring, libinfo.osversion) 250 | 251 | ENDPROC lib 252 | 253 | PROC thistask() 254 | DEF execbase 255 | execbase := Long(4) 256 | ENDPROC FindTask(NIL) 257 | 258 | 259 | PROC_LIBOPEN_HEAD 260 | DEF privbase:PTR TO privatebase 261 | DEF libinfo:PTR TO libinfo, libtag:PTR TO libtag 262 | DEF ifunc(PTR), mfunc(), r, task 263 | 264 | DEBUGF('LIB_open lib=$\h, ver=\d\n', pubbase, version) 265 | 266 | SAVEGLOBREG 267 | 268 | libinfo := {___startinfo} 269 | libtag := {___libtag} 270 | pubbase.opencnt++ 271 | pubbase.flags := pubbase.flags AND Not(LIBF_DELEXP) 272 | 273 | task := thistask() 274 | 275 | privbase := pubbase.userlist.head 276 | WHILE privbase.ln.succ 277 | EXIT privbase.usertask = task 278 | privbase := privbase.ln.succ 279 | ENDWHILE 280 | 281 | IF privbase.ln.succ 282 | 283 | DEBUGF('LIB_open reused privbase = $\h, task = $\h\n', privbase, task) 284 | privbase.usecount++ 285 | 286 | RETURN privbase 287 | 288 | ENDIF 289 | 290 | privbase := makePrivateBase(libinfo.functabofs + libinfo, libinfo.rwsize + libinfo.stacksize) 291 | IF privbase = NIL THEN RETURN NIL 292 | privbase.ln.name := libtag.name 293 | privbase.idstring := libtag.idstring 294 | privbase.version := version -> version _requested_! 295 | privbase.publicbase := pubbase 296 | privbase.opencnt := pubbase.opencnt -> 1.6 297 | privbase.usecount := 1 298 | privbase.usertask := task 299 | 300 | DEBUGF('LIB_open created privbase = $\h, task = $\h, libinfo.initofs = $\h\n', 301 | privbase, task, libinfo.initofs) 302 | 303 | -> call init (sets up GLOBREG) 304 | ifunc := libinfo.initofs + libinfo 305 | r := ifunc(privbase.envmem) 306 | ___stackbottom := r 307 | 308 | DEBUGF('LIB_open globreg = $\h\n', GLOBREG) 309 | 310 | privbase.environment := GLOBREG 311 | 312 | DEBUGF('LIB_open done calling init, ___stackbottom = $\h\n', ___stackbottom) 313 | 314 | execbase := Long(4) 315 | 316 | AddTail(pubbase.userlist, privbase) 317 | 318 | DEBUGF('LIB_open done adding private base to list\n') 319 | 320 | dosbase := OpenLibrary('dos.library', LIBS_VERSION) 321 | IF dosbase = NIL THEN JUMP libopen_error 322 | intuitionbase := OpenLibrary('intuition.library', LIBS_VERSION) 323 | IF intuitionbase = NIL THEN JUMP libopen_error 324 | gfxbase := OpenLibrary('graphics.library', LIBS_VERSION) 325 | IF gfxbase = NIL THEN JUMP libopen_error 326 | #ifdef USE_SINGLE_LIBS 327 | ___mathieeesingbasbase := OpenLibrary('mathieeesingbas.library', MATHLIBS_VERSION) 328 | IF ___mathieeesingbasbase = NIL THEN JUMP libopen_error 329 | ___mathieeesingtransbase := OpenLibrary('mathieeesingtrans.library', MATHLIBS_VERSION) 330 | IF ___mathieeesingtransbase = NIL THEN JUMP libopen_error 331 | #endif 332 | #ifdef USE_DOUBLE_LIBS 333 | ___mathieeedoubbasbase := OpenLibrary('mathieeedoubbas.library', MATHLIBS_VERSION) 334 | IF ___mathieeedoubbasbase = NIL THEN JUMP libopen_error 335 | ___mathieeedoubtransbase := OpenLibrary('mathieeedoubtrans.library', MATHLIBS_VERSION) 336 | IF ___mathieeedoubtransbase = NIL THEN JUMP libopen_error 337 | #endif 338 | 339 | DEBUGF('LIB_open opened libs ok\n') 340 | 341 | librarybase := privbase 342 | 343 | ___mempool := CreatePool(ALLOCMEMFLAGS, 4096, 256) 344 | IF ___mempool = NIL THEN JUMP libopen_error 345 | 346 | -> call main() 347 | mfunc := libinfo.mainofs 348 | IF mfunc 349 | mfunc += libinfo 350 | r := mfunc() 351 | IF r = FALSE THEN JUMP libopen_error 352 | ENDIF 353 | 354 | DEBUGF('LIB_open done calling main()\n') 355 | 356 | LOADGLOBREG 357 | 358 | RETURN privbase 359 | 360 | libopen_error: 361 | 362 | cleanupInstance(privbase) 363 | freePrivbase(privbase) 364 | 365 | LOADGLOBREG 366 | 367 | ENDPROC FALSE 368 | 369 | PROC freePrivbase(base:PTR TO privatebase) 370 | DEBUGF('freePrivbase($\h)\n', base) 371 | FreeMem(base-base.negsize, base.negsize + base.possize) 372 | ENDPROC 373 | 374 | 375 | PROC cleanupInstance(base:PTR TO privatebase) 376 | DEF mem:PTR TO memnode, next 377 | DEBUGF('cleanUpInstance($\h)\n', base) 378 | CloseLibrary(dosbase) 379 | CloseLibrary(intuitionbase) 380 | CloseLibrary(gfxbase) 381 | #ifdef USE_SINGLE_LIBS 382 | CloseLibrary(___mathieeesingbasbase) 383 | CloseLibrary(___mathieeesingtransbase) 384 | #endif 385 | #ifdef USE_DOUBLE_LIBS 386 | CloseLibrary(___mathieeedoubbasbase) 387 | CloseLibrary(___mathieeedoubtransbase) 388 | #endif 389 | 390 | IF ___mempool THEN DeletePool(___mempool) 391 | 392 | mem := ___memlist 393 | WHILE mem 394 | next := mem.next 395 | FreeMem(mem, mem.size) 396 | mem := next 397 | ENDWHILE 398 | 399 | IF base.envmem THEN FreeVec(base.envmem) -> 1.10.0 400 | 401 | ENDPROC 402 | 403 | PROC_LIBCLOSE_HEAD 404 | DEF func(), pubbase:PTR TO publicbase 405 | DEF libinfo:PTR TO libinfo 406 | 407 | -> 1.10.0 valid base check 408 | IF privbase.privbaseid <> "PRIV" THEN RETURN NIL 409 | 410 | DEBUGF('LIB_close privbase=$\h, usecount=\d\n', privbase, privbase.usecount) 411 | 412 | pubbase := privbase.publicbase 413 | 414 | IF privbase.usecount > 1 415 | pubbase.opencnt-- 416 | privbase.usecount-- 417 | RETURN NIL 418 | ENDIF 419 | 420 | SAVEGLOBREG 421 | SETUPGLOBREG privbase 422 | 423 | libinfo := {___startinfo} 424 | 425 | func := libinfo.closeofs 426 | IF func 427 | func += libinfo 428 | func() 429 | ENDIF 430 | 431 | cleanupInstance(privbase) 432 | 433 | Remove(privbase) 434 | 435 | freePrivbase(privbase) 436 | 437 | IF pubbase.opencnt-- = 0 438 | IF pubbase.flags AND LIBF_DELEXP 439 | LOADGLOBREG 440 | DEBUGF('LIB_close calling expunge, we want to go home\n') 441 | RETURN expunge(pubbase) 442 | ENDIF 443 | ENDIF 444 | 445 | LOADGLOBREG 446 | 447 | DEBUGF('LIB_close DONE\n') 448 | 449 | ENDPROC NIL 450 | 451 | PROC_LIBEXPUNGE_HEAD 452 | DEBUGF('LIB_expunge pubbase=$\h\n', pubbase) 453 | ENDPROC expunge(pubbase) 454 | 455 | PROC expunge(base:PTR TO publicbase) 456 | DEF execbase, seglist 457 | 458 | IF base.opencnt > 0 459 | base.flags OR= LIBF_DELEXP 460 | RETURN NIL 461 | ENDIF 462 | seglist := base.seglist 463 | execbase := Long(4) 464 | IF base.utilitybase THEN CloseLibrary(base.utilitybase) -> 1.10.0 465 | Remove(base) 466 | FreeMem(base - base.negsize, base.negsize + base.possize) 467 | 468 | DEBUGF('expunge DONE\n') 469 | 470 | ENDPROC seglist 471 | 472 | 473 | 474 | PROC makePrivateBase(functab, datasize) 475 | DEF lib:PTR TO privatebase, e:PTR TO libentry, e2:PTR TO libentry, negsize=4*SIZEOF libentry 476 | DEF execbase, a 477 | execbase := Long(4) 478 | e := functab 479 | DEBUGF('makePrivateLibrary($\h,\d) computing negsize\n', functab,datasize) 480 | WHILE e.inst <> -1 DO e++ 481 | negsize := negsize + e - functab + 3 AND -4 482 | DEBUGF('makePrivateLibrary() allocating mem (negsize=\d)\n', negsize) 483 | lib := AllocMem(SIZEOF privatebase + negsize, ALLOCMEMFLAGS) 484 | IF lib = NIL THEN RETURN NIL 485 | lib := lib + negsize 486 | DEBUGF('makePrivateLibrary() constructing functable (lib=$\h)\n', lib) 487 | 488 | e2 := lib 489 | 490 | e := {vectable} 491 | FOR a := 1 TO 4 492 | e2-- 493 | e2.inst := e.inst 494 | e2.addr := e.addr 495 | e++ 496 | ENDFOR 497 | 498 | e := functab 499 | WHILE e.inst <> -1 500 | e2-- 501 | e2.inst := e.inst 502 | e2.addr := e.addr 503 | e++ 504 | ENDWHILE 505 | 506 | lib.negsize := negsize 507 | 508 | -> 1.10.0 some stuff changed 509 | lib.possize := SIZEOF privatebase 510 | lib.envmem := AllocVec(datasize, ALLOCMEMFLAGS) 511 | IF lib.envmem = NIL 512 | freePrivbase(lib) 513 | RETURN NIL 514 | ENDIF 515 | 516 | lib.ln.type := NT_LIBRARY 517 | lib.flags := LIBF_SUMUSED OR LIBF_CHANGED 518 | lib.privbaseid := "PRIV" 519 | SumLibrary(lib) -> 1.6.0 520 | CACHECLEARU 521 | DEBUGF('makePrivateLibrary() DONE\n') 522 | ENDPROC lib 523 | 524 | -> May 2008: setups no global environment as we might be called without OpenLibrary() ! 525 | -> we also pass pubbase.utilitybase as third arg. 526 | -> we might get called with both public AND private libbase! 527 | PROC_LIBEXT_HEAD 528 | DEF info:PTR TO libinfo, func(PTR,LONG,PTR)(PTR), r=NIL 529 | info := {___startinfo} 530 | func := info.queryofs 531 | IF func 532 | func += info 533 | IF pubbase.pubbaseid <> "PUBL" -> 1.10.0 534 | pubbase := pubbase::privatebase.publicbase 535 | ENDIF 536 | r := func(data,attr,pubbase.utilitybase) 537 | ENDIF 538 | ENDPROC r 539 | 540 | endskip: 541 | 542 | FLOAT 0.0 -> ensures longword align :) 543 | 544 | #ifdef CODE_MORPHOS 545 | 546 | libopen_gate: 547 | WORD TRAP_LIB, 0 548 | PTR libopen 549 | libclose_gate: 550 | WORD TRAP_LIB, 0 551 | PTR libclose 552 | libexpunge_gate: 553 | WORD TRAP_LIB, 0 554 | PTR libexpunge 555 | libext_gate: 556 | WORD TRAP_LIB, 0 557 | PTR libext 558 | 559 | vectable: 560 | WORD JUMP68 ; PTR libopen_gate 561 | WORD JUMP68 ; PTR libclose_gate 562 | WORD JUMP68 ; PTR libexpunge_gate 563 | WORD JUMP68 ; PTR libext_gate 564 | 565 | #endif /* CODE_MORPHOS */ 566 | 567 | #ifdef CODE_AMIGAOS 568 | 569 | vectable: 570 | WORD JUMP68 ; PTR libopen 571 | WORD JUMP68 ; PTR libclose 572 | WORD JUMP68 ; PTR libexpunge 573 | WORD JUMP68 ; PTR libext 574 | 575 | #endif /* CODE_AMIGAOS */ 576 | 577 | 578 | 579 | 580 | 581 | -------------------------------------------------------------------------------- /opcodesppc.e: -------------------------------------------------------------------------------- 1 | OPT MODULE 2 | 3 | -> ECX/opcodesppc.e 4 | 5 | /* ECX by Leif Salomonsson [ecx tele2 se] is Copyright (c) 2002-2009 */ 6 | /* Released under the ECX COMPILER LICENSE, See ECXCOMPILERLICENSE.TXT */ 7 | 8 | 9 | -> moved ppc opcode stuff into this new module 2009 10 | 11 | EXPORT DEF g_codeptr:PTR TO LONG 12 | 13 | /************************************************************** 14 | *************************************************************** 15 | ******************** PPC OPCODES ****************************** 16 | *************************************************************** 17 | **************************************************************/ 18 | 19 | 20 | PROC i6_5_5_5_10_1(a,b,c,d,e,f) 21 | g_codeptr[]++ := Shl(Shl(Shl(Shl(Shl(a,5) OR b,5) OR c,5) OR d,10) OR e,1) OR f 22 | ENDPROC 23 | 24 | PROC i6_5_5_5_5_5_1(a,b,c,d,e,f,g) 25 | g_codeptr[]++ := Shl(Shl(Shl(Shl(Shl(Shl(a,5) OR b,5) OR c,5) OR d,5) OR e,5) OR f,1) OR g 26 | ENDPROC 27 | 28 | PROC i6_5_5_5_1_9_1(a,b,c,d,e,f,g) 29 | g_codeptr[]++ := Shl(Shl(Shl(Shl(Shl(Shl(a,5) OR b,5) OR c,5) OR d,1) OR e,9) OR f,1) OR g 30 | ENDPROC 31 | 32 | PROC i6_5_5_16(a,b,c,d) 33 | g_codeptr[]++ := Shl(Shl(Shl(a,5) OR b,5) OR c,16) OR (d AND $FFFF) 34 | ENDPROC 35 | 36 | PROC i6_5_10_10_1(a,b,c,d,e) 37 | g_codeptr[]++ := Shl(Shl(Shl(Shl(a,5) OR b,10) OR c,10) OR d,1) OR e 38 | ENDPROC 39 | 40 | PROC i6_10_5_10_1(a,b,c,d,e) 41 | g_codeptr[]++ := Shl(Shl(Shl(Shl(a,10) OR b,5) OR c,10) OR d,1) OR e 42 | ENDPROC 43 | 44 | PROC i6_24_1_1(a,b,c,d) 45 | g_codeptr[]++ := Shl(Shl(Shl(a,24) OR (b AND $FFFFFF),1) OR c,1) OR d 46 | ENDPROC 47 | 48 | PROC i6_5_5_14_1_1(a,b,c,d,e,f) 49 | g_codeptr[]++ := Shl(Shl(Shl(Shl(Shl(a,5) OR b,5) OR c,14) OR (d AND $3FFF),1) OR e,1) OR f 50 | ENDPROC 51 | 52 | PROC i6_5_5_5_5_6(a,b,c,d,e,f) -> v48 53 | g_codeptr[]++ := Shl(Shl(Shl(Shl(Shl(a,5) OR b,5) OR c,5) OR d,5) OR e,6) OR f 54 | ENDPROC 55 | 56 | PROC i6_5_5_5_11(a,b,c,d,e) -> v48 57 | g_codeptr[]++ := Shl(Shl(Shl(Shl(a,5) OR b,5) OR c,5) OR d,11) OR e 58 | ENDPROC 59 | 60 | PROC i6_5_5_5_1_10(a,b,c,d,e,f) -> v48 61 | g_codeptr[]++ := Shl(Shl(Shl(Shl(Shl(a,5) OR b,5) OR c,5) OR d,1) OR e,10) OR f 62 | ENDPROC 63 | 64 | ->-------------------------------------------------------------- 65 | 66 | EXPORT PROC ppcadd(d,a,b,oe,rc) IS i6_5_5_5_1_9_1(31,d,a,b,oe,266,rc) 67 | EXPORT PROC ppcaddc(d,a,b,oe,rc) IS i6_5_5_5_1_9_1(31,d,a,b,oe,10,rc) 68 | EXPORT PROC ppcadde(d,a,b,oe,rc) IS i6_5_5_5_1_9_1(31,d,a,b,oe,138,rc) 69 | EXPORT PROC ppcaddi(d,a,simm) IS i6_5_5_16(14,d,a,simm) 70 | EXPORT PROC ppcaddic(d,a,simm) IS i6_5_5_16(12,d,a,simm) 71 | EXPORT PROC ppcaddic_(d,a,simm) IS i6_5_5_16(13,d,a,simm) 72 | EXPORT PROC ppcaddis(d,a,simm) IS i6_5_5_16(15,d,a,simm) 73 | EXPORT PROC ppcaddme(d,a,oe,rc) IS i6_5_5_5_1_9_1(31,d,a,NIL,oe,234,rc) 74 | EXPORT PROC ppcaddze(d,a,oe,rc) IS i6_5_5_5_1_9_1(31,d,a,NIL,oe,202,rc) 75 | EXPORT PROC ppcand(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,28,rc) 76 | EXPORT PROC ppcandc(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,60,rc) 77 | EXPORT PROC ppcandi_(s,a,uimm) IS i6_5_5_16(28,s,a,uimm) 78 | EXPORT PROC ppcandis_(s,a,uimm) IS i6_5_5_16(29,s,a,uimm) 79 | EXPORT PROC ppcb(li,aa,lk) IS i6_24_1_1(18,li,aa,lk) 80 | EXPORT PROC ppcbc(bo,bl,bd,aa,lk) IS i6_5_5_14_1_1(16,bo,bl,bd,aa,lk) 81 | EXPORT PROC ppcbcctr(bo,bl,lk) IS i6_5_5_5_10_1(19,bo,bl,NIL,528,lk) 82 | EXPORT PROC ppcbclr(bo,bl,lk) IS i6_5_5_5_10_1(19,bo,bl,NIL,16,lk) 83 | EXPORT PROC ppccmp(crf,l,a,b) IS i6_5_5_5_10_1(31,Shl(crf,2) OR l,a,b,NIL,NIL) 84 | EXPORT PROC ppccmpi(crf,l,a,simm) IS i6_5_5_16(11,Shl(crf,2) OR l,a,simm) 85 | EXPORT PROC ppccmpl(crf,l,a,b) IS i6_5_5_5_10_1(31,Shl(crf,2) OR l,a,b,32,NIL) 86 | EXPORT PROC ppccmpli(crf,l,a,uimm) IS i6_5_5_16(10,Shl(crf,2) OR l,a,uimm) 87 | EXPORT PROC ppccntlzd(s,a,rc) IS i6_5_5_5_10_1(31,s,a,NIL,58,rc) 88 | EXPORT PROC ppccntlzw(s,a,rc) IS i6_5_5_5_10_1(31,s,a,NIL,26,rc) 89 | EXPORT PROC ppccrand(crbD,crbA,crbB) IS i6_5_5_5_10_1(19,crbD,crbA,crbB,257,0) 90 | EXPORT PROC ppccrandc(crbD,crbA,crbB) IS i6_5_5_5_10_1(19,crbD,crbA,crbB,129,0) 91 | EXPORT PROC ppccreqv(crbD,crbA,crbB) IS i6_5_5_5_10_1(19,crbD,crbA,crbB,289,0) 92 | EXPORT PROC ppccrnand(crbD,crbA,crbB) IS i6_5_5_5_10_1(19,crbD,crbA,crbB,225,0) 93 | EXPORT PROC ppccrnor(crbD,crbA,crbB) IS i6_5_5_5_10_1(19,crbD,crbA,crbB,33,0) 94 | EXPORT PROC ppccror(crbD,crbA,crbB) IS i6_5_5_5_10_1(19,crbD,crbA,crbB,449,0) 95 | EXPORT PROC ppccrorc(crbD,crbA,crbB) IS i6_5_5_5_10_1(19,crbD,crbA,crbB,417,0) 96 | EXPORT PROC ppccrxor(crbD,crbA,crbB) IS i6_5_5_5_10_1(19,crbD,crbA,crbB,193,0) 97 | EXPORT PROC ppcdcba(a,b) IS i6_5_5_5_10_1(31,NIL,a,b,758,0) 98 | EXPORT PROC ppcdcbf(a,b) IS i6_5_5_5_10_1(31,NIL,a,b,86,0) 99 | EXPORT PROC ppcdcbi(a,b) IS i6_5_5_5_10_1(31,NIL,a,b,470,0) 100 | EXPORT PROC ppcdcbst(a,b) IS i6_5_5_5_10_1(31,NIL,a,b,54,0) 101 | EXPORT PROC ppcdcbt(a,b) IS i6_5_5_5_10_1(31,NIL,a,b,278,0) 102 | EXPORT PROC ppcdcbtst(a,b) IS i6_5_5_5_10_1(31,NIL,a,b,246,0) 103 | EXPORT PROC ppcdcbz(a,b) IS i6_5_5_5_10_1(31,NIL,a,b,1014,0) 104 | EXPORT PROC ppcdivd(d,a,b,oe,rc) IS i6_5_5_5_1_9_1(31,d,a,b,oe,489,rc) 105 | EXPORT PROC ppcdivdu(d,a,b,oe,rc) IS i6_5_5_5_1_9_1(31,d,a,b,oe,457,rc) 106 | EXPORT PROC ppcdivw(d,a,b,oe,rc) IS i6_5_5_5_1_9_1(31,d,a,b,oe,491,rc) 107 | EXPORT PROC ppcdivwu(d,a,b,oe,rc) IS i6_5_5_5_1_9_1(31,d,a,b,oe,459,rc) 108 | EXPORT PROC ppceciwx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,310,0) 109 | EXPORT PROC ppcecowx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,438,0) 110 | EXPORT PROC ppceieio() IS i6_5_5_5_10_1(31,NIL,NIL,NIL,854,0) 111 | EXPORT PROC ppceqv(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,284,rc) 112 | EXPORT PROC ppcextsb(s,a,rc) IS i6_5_5_5_10_1(31,s,a,NIL,954,rc) 113 | EXPORT PROC ppcextsh(s,a,rc) IS i6_5_5_5_10_1(31,s,a,NIL,922,rc) 114 | EXPORT PROC ppcextsw(s,a,rc) IS i6_5_5_5_10_1(31,s,a,NIL,986,rc) 115 | EXPORT PROC ppcfabs(d,b,rc) IS i6_5_5_5_10_1(63,d,NIL,b,264,rc) 116 | EXPORT PROC ppcfadd(d,a,b,rc) IS i6_5_5_5_10_1(63,d,a,b,21,rc) 117 | EXPORT PROC ppcfadds(d,a,b,rc) IS i6_5_5_5_10_1(59,d,a,b,21,rc) 118 | EXPORT PROC ppcfcfid(d,b,rc) IS i6_5_5_5_10_1(63,d,NIL,b,846,rc) 119 | EXPORT PROC ppcfcmpo(crfD,a,b) IS i6_5_5_5_10_1(63,Shl(crfD,2),a,b,32,0) 120 | EXPORT PROC ppcfcmpu(crfD,a,b) IS i6_5_5_5_10_1(63,Shl(crfD,2),a,b,0,0) 121 | EXPORT PROC ppcfctid(d,b,rc) IS i6_5_5_5_10_1(63,d,NIL,b,814,rc) 122 | EXPORT PROC ppcfctidz(d,b,rc) IS i6_5_5_5_10_1(63,d,NIL,b,815,rc) 123 | EXPORT PROC ppcfctiw(d,b,rc) IS i6_5_5_5_10_1(63,d,NIL,b,14,rc) 124 | EXPORT PROC ppcfctiwz(d,b,rc) IS i6_5_5_5_10_1(63,d,NIL,b,15,rc) 125 | EXPORT PROC ppcfdiv(d,a,b,rc) IS i6_5_5_5_10_1(63,d,a,b,18,rc) 126 | EXPORT PROC ppcfdivs(d,a,b,rc) IS i6_5_5_5_10_1(59,d,a,b,18,rc) 127 | EXPORT PROC ppcfmadd(d,a,b,c,rc) IS i6_5_5_5_5_5_1(63,d,a,b,c,29,rc) 128 | EXPORT PROC ppcfmadds(d,a,b,c,rc) IS i6_5_5_5_5_5_1(59,d,a,b,c,29,rc) 129 | EXPORT PROC ppcfmr(d,b,rc) IS i6_5_5_5_10_1(63,d,NIL,b,72,rc) 130 | EXPORT PROC ppcfmsub(d,a,b,c,rc) IS i6_5_5_5_5_5_1(63,d,a,b,c,28,rc) 131 | EXPORT PROC ppcfmsubs(d,a,b,c,rc) IS i6_5_5_5_5_5_1(59,d,a,b,c,28,rc) 132 | EXPORT PROC ppcfmul(d,a,c,rc) IS i6_5_5_5_5_5_1(63,d,a,NIL,c,25,rc) 133 | EXPORT PROC ppcfmuls(d,a,c,rc) IS i6_5_5_5_5_5_1(59,d,a,NIL,c,25,rc) 134 | EXPORT PROC ppcfnabs(d,b,rc) IS i6_5_5_5_10_1(63,d,NIL,b,136,rc) 135 | EXPORT PROC ppcfneg(d,b,rc) IS i6_5_5_5_10_1(63,d,NIL,b,40,rc) 136 | EXPORT PROC ppcfnmadd(d,a,b,c,rc) IS i6_5_5_5_5_5_1(63,d,a,b,c,31,rc) 137 | EXPORT PROC ppcfnmadds(d,a,b,c,rc) IS i6_5_5_5_5_5_1(59,d,a,b,c,31,rc) 138 | EXPORT PROC ppcfnmsub(d,a,b,c,rc) IS i6_5_5_5_5_5_1(63,d,a,b,c,39,rc) 139 | EXPORT PROC ppcfnmsubs(d,a,b,c,rc) IS i6_5_5_5_5_5_1(59,d,a,b,c,39,rc) 140 | EXPORT PROC ppcfres(d,b,rc) IS i6_5_5_5_5_5_1(59,d,NIL,b,NIL,24,rc) 141 | EXPORT PROC ppcfrsp(d,b,rc) IS i6_5_5_5_10_1(63,d,NIL,b,12,rc) 142 | EXPORT PROC ppcfrsqrte(d,b,rc) IS i6_5_5_5_5_5_1(63,d,NIL,b,NIL,26,rc) 143 | EXPORT PROC ppcfsel(d,a,b,c,rc) IS i6_5_5_5_5_5_1(63,d,a,b,c,23,rc) 144 | EXPORT PROC ppcfsqrt(d,b,rc) IS i6_5_5_5_5_5_1(63,d,NIL,b,NIL,22,rc) 145 | EXPORT PROC ppcfsqrts(d,b,rc) IS i6_5_5_5_5_5_1(59,d,NIL,b,NIL,22,rc) 146 | EXPORT PROC ppcfsub(d,a,b,rc) IS i6_5_5_5_5_5_1(63,d,a,b,NIL,20,rc) 147 | EXPORT PROC ppcfsubs(d,a,b,rc) IS i6_5_5_5_5_5_1(59,d,a,b,NIL,20,rc) 148 | EXPORT PROC ppcicbi(a,b) IS i6_5_5_5_10_1(31,NIL,a,b,982,0) 149 | EXPORT PROC ppcisync() IS i6_5_5_5_10_1(19,NIL,NIL,NIL,150,0) 150 | EXPORT PROC ppclbz(d,a,disp) IS i6_5_5_16(34,d,a,disp) 151 | EXPORT PROC ppclbzu(d,a,disp) IS i6_5_5_16(35,d,a,disp) 152 | EXPORT PROC ppclbzux(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,119,0) 153 | EXPORT PROC ppclbzx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,87,0) 154 | EXPORT PROC ppcld(d,a,ds) IS i6_5_5_16(58,d,a,Shl(ds,2)) 155 | EXPORT PROC ppcldarx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,84,0) 156 | EXPORT PROC ppcldu(d,a,ds) IS i6_5_5_16(58,d,a,Shl(ds,2) OR 1) 157 | EXPORT PROC ppcldux(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,53,0) 158 | EXPORT PROC ppcldx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,21,0) 159 | EXPORT PROC ppclfd(d,a,disp) IS i6_5_5_16(50,d,a,disp) 160 | EXPORT PROC ppclfdu(d,a,disp) IS i6_5_5_16(51,d,a,disp) 161 | EXPORT PROC ppclfdux(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,631,0) 162 | EXPORT PROC ppclfdx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,599,0) 163 | EXPORT PROC ppclfs(d,a,disp) IS i6_5_5_16(48,d,a,disp) 164 | EXPORT PROC ppclfsu(d,a,disp) IS i6_5_5_16(49,d,a,disp) 165 | EXPORT PROC ppclfsux(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,567,0) 166 | EXPORT PROC ppclfsx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,535,0) 167 | EXPORT PROC ppclha(d,a,disp) IS i6_5_5_16(42,d,a,disp) 168 | EXPORT PROC ppclhau(d,a,disp) IS i6_5_5_16(43,d,a,disp) 169 | EXPORT PROC ppclhaux(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,375,0) 170 | EXPORT PROC ppclhax(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,343,0) 171 | EXPORT PROC ppclhbrx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,790,0) 172 | EXPORT PROC ppclhz(d,a,disp) IS i6_5_5_16(40,d,a,disp) 173 | EXPORT PROC ppclhzu(d,a,disp) IS i6_5_5_16(41,d,a,disp) 174 | EXPORT PROC ppclhzux(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,311,0) 175 | EXPORT PROC ppclhzx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,279,0) 176 | EXPORT PROC ppclmw(d,a,disp) IS i6_5_5_16(46,d,a,disp) 177 | EXPORT PROC ppclswi(d,a,nb) IS i6_5_5_5_10_1(31,d,a,nb,597,0) 178 | EXPORT PROC ppclswx(d,a,nb) IS i6_5_5_5_10_1(31,d,a,nb,533,0) 179 | EXPORT PROC ppclwa(d,a,ds) IS i6_5_5_16(58,d,a,Shl(ds,2)) 180 | EXPORT PROC ppclwarx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,20,0) 181 | EXPORT PROC ppclwaux(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,373,0) 182 | EXPORT PROC ppclwax(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,341,0) 183 | EXPORT PROC ppclwbrx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,534,0) 184 | EXPORT PROC ppclwz(d,a,disp) IS i6_5_5_16(32,d,a,disp) 185 | EXPORT PROC ppclwzu(d,a,disp) IS i6_5_5_16(33,d,a,disp) 186 | EXPORT PROC ppclwzux(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,55,0) 187 | EXPORT PROC ppclwzx(d,a,b) IS i6_5_5_5_10_1(31,d,a,b,23,0) 188 | EXPORT PROC ppcmcrf(crfD,crfS) IS i6_5_5_5_10_1(19,Shl(crfD,2),Shl(crfS,2),NIL,NIL,0) 189 | EXPORT PROC ppcmcrfs(crfD,crfS) IS i6_5_5_5_10_1(63,Shl(crfD,2),Shl(crfS,2),NIL,64,0) 190 | EXPORT PROC ppcmcrxr(crfD) IS i6_5_5_5_10_1(31,Shl(crfD,2),NIL,NIL,512,0) 191 | EXPORT PROC ppcmfcr(d) IS i6_5_5_5_10_1(31,d,NIL,NIL,19,0) 192 | EXPORT PROC ppcmffs(d,rc) IS i6_5_5_5_10_1(63,d,NIL,NIL,583,rc) 193 | EXPORT PROC ppcmfmsr(d) IS i6_5_5_5_10_1(31,d,NIL,NIL,83,0) 194 | EXPORT PROC ppcmfspr(d,spr) IS i6_5_10_10_1(31,d,Shl(spr,5),339,0) 195 | EXPORT PROC ppcmfsr(d,sr) IS i6_5_5_5_10_1(31,d,sr,NIL,595,0) 196 | EXPORT PROC ppcmfsrin(d,b) IS i6_5_5_5_10_1(31,d,NIL,b,659,0) 197 | EXPORT PROC ppcmftb(d,tbr) IS i6_5_10_10_1(31,d,tbr,371,0) 198 | EXPORT PROC ppcmtcrf(s,crm) IS i6_5_10_10_1(31,s,Shl(crm,1),144,0) 199 | EXPORT PROC ppcmtfsb0(crbD,rc) IS i6_5_5_5_10_1(63,crbD,NIL,NIL,70,rc) 200 | EXPORT PROC ppcmtfsb1(crbD,rc) IS i6_5_5_5_10_1(63,crbD,NIL,NIL,38,rc) 201 | EXPORT PROC ppcmtfsf(fm,b,rc) IS i6_10_5_10_1(63,Shl(fm,1),b,711,rc) 202 | EXPORT PROC ppcmtfsfi(crfD,imm,rc) IS i6_5_5_5_10_1(63,Shl(crfD,2),NIL,Shl(imm,1),134,rc) 203 | EXPORT PROC ppcmtmsr(s) IS i6_5_5_5_10_1(31,s,NIL,NIL,146,0) 204 | EXPORT PROC ppcmtspr(s,spr) IS i6_5_10_10_1(31,s,Shl(spr,5),467,0) 205 | EXPORT PROC ppcmtsr(s,sr) IS i6_5_5_5_10_1(31,s,sr,NIL,210,0) 206 | EXPORT PROC ppcmtsrin(s,b) IS i6_5_5_5_10_1(31,s,NIL,b,242,0) 207 | EXPORT PROC ppcmulhd(d,a,b,rc) IS i6_5_5_5_10_1(31,d,a,b,73,rc) 208 | EXPORT PROC ppcmulhdu(d,a,b,rc) IS i6_5_5_5_10_1(31,d,a,b,9,rc) 209 | EXPORT PROC ppcmulhw(d,a,b,rc) IS i6_5_5_5_10_1(31,d,a,b,75,rc) 210 | EXPORT PROC ppcmulhwu(d,a,b,rc) IS i6_5_5_5_10_1(31,d,a,b,11,rc) 211 | EXPORT PROC ppcmulld(d,a,b,oe,rc) IS i6_5_5_5_10_1(31,d,a,b,Shl(oe,9) OR 233,rc) 212 | EXPORT PROC ppcmulli(d,a,simm) IS i6_5_5_16(7,d,a,simm) 213 | EXPORT PROC ppcmullw(d,a,b,oe,rc) IS i6_5_5_5_10_1(31,d,a,b,Shl(oe,9) OR 235,rc) 214 | EXPORT PROC ppcnand(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,476,rc) 215 | EXPORT PROC ppcneg(d,a,oe,rc) IS i6_5_5_5_10_1(31,d,a,NIL,Shl(oe,9) OR 104,rc) 216 | EXPORT PROC ppcnor(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,124,rc) 217 | EXPORT PROC ppcor(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,444,rc) 218 | EXPORT PROC ppcorc(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,412,rc) 219 | EXPORT PROC ppcori(s,a,uimm) IS i6_5_5_16(24,s,a,uimm) 220 | EXPORT PROC ppcoris(s,a,uimm) IS i6_5_5_16(25,s,a,uimm) 221 | EXPORT PROC ppcrfi() IS i6_5_5_5_10_1(19,NIL,NIL,NIL,50,0) 222 | EXPORT PROC ppcrldcl(s,a,b,mb,rc) IS i6_5_5_5_10_1(30,s,a,b,Shl(mb,4) OR 8,rc) 223 | EXPORT PROC ppcrldcr(s,a,b,me,rc) IS i6_5_5_5_10_1(30,s,a,b,Shl(me,4) OR 9,rc) 224 | EXPORT PROC ppcrldic(s,a,sh,mb,rc) IS i6_5_5_5_10_1(30,s,a,sh,Shl(Shl(mb,3) OR 2,1) OR sh,rc) 225 | EXPORT PROC ppcrldicl(s,a,sh,mb,rc) IS i6_5_5_5_10_1(30,s,a,sh,Shl(Shl(mb,3) OR 0,1) OR sh,rc) 226 | EXPORT PROC ppcrldicr(s,a,sh,me,rc) IS i6_5_5_5_10_1(30,s,a,sh,Shl(Shl(me,3) OR 1,1) OR sh,rc) 227 | EXPORT PROC ppcrldimi(s,a,sh,mb,rc) IS i6_5_5_5_10_1(30,s,a,sh,Shl(Shl(mb,3) OR 3,1) OR sh,rc) 228 | EXPORT PROC ppcrlwimi(s,a,sh,mb,me,rc) IS i6_5_5_5_10_1(20,s,a,sh,Shl(mb,5) OR me,rc) 229 | EXPORT PROC ppcrlwinm(s,a,sh,mb,me,rc) IS i6_5_5_5_10_1(21,s,a,sh,Shl(mb,5) OR me,rc) 230 | EXPORT PROC ppcrlwnm(s,a,b,mb,me,rc) IS i6_5_5_5_10_1(23,s,a,b,Shl(mb,5) OR me,rc) 231 | EXPORT PROC ppcsc() IS i6_5_5_16(17,NIL,NIL,2) 232 | EXPORT PROC ppcslbia() IS i6_5_5_5_10_1(31,NIL,NIL,NIL,498,0) 233 | EXPORT PROC ppcslbie(b) IS i6_5_5_5_10_1(31,NIL,NIL,b,434,0) 234 | EXPORT PROC ppcsld(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,27,rc) 235 | EXPORT PROC ppcslw(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,24,rc) 236 | EXPORT PROC ppcsrad(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,794,rc) 237 | EXPORT PROC ppcsradi(s,a,sh,rc) IS i6_5_5_5_10_1(31,s,a,sh,Shl(413,1) OR sh,rc) 238 | EXPORT PROC ppcsraw(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,792,rc) 239 | EXPORT PROC ppcsrawi(s,a,sh,rc) IS i6_5_5_5_10_1(31,s,a,sh,824,rc) 240 | EXPORT PROC ppcsrd(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,539,rc) 241 | EXPORT PROC ppcsrw(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,536,rc) 242 | EXPORT PROC ppcstb(s,a,disp) IS i6_5_5_16(38,s,a,disp) 243 | EXPORT PROC ppcstbu(s,a,disp) IS i6_5_5_16(39,s,a,disp) 244 | EXPORT PROC ppcstbux(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,247,0) 245 | EXPORT PROC ppcstbx(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,215,0) 246 | EXPORT PROC ppcstd(s,a,ds) IS i6_5_5_16(62,s,a,Shl(ds,2)) 247 | EXPORT PROC ppcstdcx_(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,214,1) 248 | EXPORT PROC ppcstdu(s,a,ds) IS i6_5_5_16(62,s,a,Shl(ds,2) OR 1) 249 | EXPORT PROC ppcstdux(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,181,0) 250 | EXPORT PROC ppcstdx(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,149,0) 251 | EXPORT PROC ppcstfd(s,a,disp) IS i6_5_5_16(54,s,a,disp) 252 | EXPORT PROC ppcstfdu(s,a,disp) IS i6_5_5_16(55,s,a,disp) 253 | EXPORT PROC ppcstfdux(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,759,0) 254 | EXPORT PROC ppcstfdx(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,727,0) 255 | EXPORT PROC ppcstfiwx(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,983,0) 256 | EXPORT PROC ppcstfs(s,a,disp) IS i6_5_5_16(52,s,a,disp) 257 | EXPORT PROC ppcstfsu(s,a,disp) IS i6_5_5_16(53,s,a,disp) 258 | EXPORT PROC ppcstfsux(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,695,0) 259 | EXPORT PROC ppcstfsx(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,663,0) 260 | EXPORT PROC ppcsth(s,a,disp) IS i6_5_5_16(44,s,a,disp) 261 | EXPORT PROC ppcsthbrx(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,918,0) 262 | EXPORT PROC ppcsthu(s,a,disp) IS i6_5_5_16(45,s,a,disp) 263 | EXPORT PROC ppcsthux(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,439,0) 264 | EXPORT PROC ppcsthx(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,407,0) 265 | EXPORT PROC ppcstmw(s,a,disp) IS i6_5_5_16(47,s,a,disp) 266 | EXPORT PROC ppcstswi(s,a,nb) IS i6_5_5_5_10_1(31,s,a,nb,725,0) 267 | EXPORT PROC ppcstswx(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,661,0) 268 | EXPORT PROC ppcstw(s,a,disp) IS i6_5_5_16(36,s,a,disp) 269 | EXPORT PROC ppcstwbrx(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,662,0) 270 | EXPORT PROC ppcstwcx_(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,150,1) 271 | EXPORT PROC ppcstwu(s,a,disp) IS i6_5_5_16(37,s,a,disp) 272 | EXPORT PROC ppcstwux(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,183,0) 273 | EXPORT PROC ppcstwx(s,a,b) IS i6_5_5_5_10_1(31,s,a,b,151,0) 274 | EXPORT PROC ppcsubf(d,a,b,oe,rc) IS i6_5_5_5_10_1(31,d,a,b,Shl(oe,9) OR 40,rc) 275 | EXPORT PROC ppcsubfc(d,a,b,oe,rc) IS i6_5_5_5_10_1(31,d,a,b,Shl(oe,9) OR 8,rc) 276 | EXPORT PROC ppcsubfe(d,a,b,oe,rc) IS i6_5_5_5_10_1(31,d,a,b,Shl(oe,9) OR 136,rc) 277 | EXPORT PROC ppcsubfic(d,a,simm) IS i6_5_5_16(8,d,a,simm) 278 | EXPORT PROC ppcsubfme(d,a,oe,rc) IS i6_5_5_5_10_1(31,d,a,NIL,Shl(oe,9) OR 232,rc) 279 | EXPORT PROC ppcsubfze(d,a,oe,rc) IS i6_5_5_5_10_1(31,d,a,NIL,Shl(oe,9) OR 200,rc) 280 | EXPORT PROC ppcsync() IS i6_5_5_5_10_1(31,NIL,NIL,NIL,598,0) 281 | EXPORT PROC ppctd(to,a,b) IS i6_5_5_5_10_1(31,to,a,b,68,0) 282 | EXPORT PROC ppctdi(to,a,simm) IS i6_5_5_16(2,to,a,simm) 283 | EXPORT PROC ppctlbia() IS i6_5_5_5_10_1(31,NIL,NIL,NIL,370,0) 284 | EXPORT PROC ppctlbie(b) IS i6_5_5_5_10_1(31,NIL,NIL,b,306,0) 285 | EXPORT PROC ppctlbsync() IS i6_5_5_5_10_1(31,NIL,NIL,NIL,566,0) 286 | EXPORT PROC ppctw(to,a,b) IS i6_5_5_5_10_1(31,to,a,b,4,0) 287 | EXPORT PROC ppctwi(to,a,simm) IS i6_5_5_16(3,to,a,simm) 288 | EXPORT PROC ppcxor(s,a,b,rc) IS i6_5_5_5_10_1(31,s,a,b,316,rc) 289 | EXPORT PROC ppcxori(s,a,uimm) IS i6_5_5_16(26,s,a,uimm) 290 | EXPORT PROC ppcxoris(s,a,uimm) IS i6_5_5_16(27,s,a,uimm) 291 | 292 | -> Altivec -------------------------------------------------------------------------------- /ppcifuncs.asm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EEC-Developers/eec/a21d06122679be69ff8f660b339bd9eacd8c6ad5/ppcifuncs.asm -------------------------------------------------------------------------------- /runtime.e: -------------------------------------------------------------------------------- 1 | 2 | -> ECX/runtime.e 3 | 4 | /* ECX by Leif Salomonsson [ecx tele2 se] is Copyright (c) 2002-2008 */ 5 | /* Released under the ECX COMPILER LICENSE, See ECXCOMPILERLICENSE.TXT */ 6 | 7 | OPT MODULE 8 | OPT EXPORT 9 | 10 | OPT DIR = 'emodules:' 11 | 12 | MODULE 'exec/libraries' 13 | MODULE 'exec/resident' 14 | MODULE 'exec/lists' 15 | MODULE 'exec/nodes' 16 | 17 | 18 | CONST JUMP68 = $4EF9 19 | 20 | 21 | CONST FRAMEPPC_OLDFRAME = 0, 22 | FRAMEPPC_LINKREG = 4, 23 | SIZEOF_FRAMEPPC = 8, 24 | 25 | ES_OLDSTRUCT = 0, 26 | ES_STACKPOINTER = 4, 27 | ES_EXCEPTCODE = 8, 28 | ES_OLDEXCEPTION = 12 -> 2.2.3 29 | 30 | CONST SIZEOF_ES = 16 31 | 32 | 33 | OBJECT memnode 34 | next:LONG 35 | size:LONG 36 | ENDOBJECT 37 | 38 | OBJECT libentry 39 | inst:INT 40 | addr:LONG 41 | ENDOBJECT 42 | 43 | OBJECT publicbase OF lib 44 | pad2:INT 45 | userlist:mlh -> 1.6.0 46 | pubbaseid:LONG -> 1.10.0 "PUBL" 47 | seglist:LONG 48 | utilitybase:LONG -> 1.10.0 49 | ENDOBJECT 50 | 51 | OBJECT privatebase OF lib 52 | dummy1:INT 53 | dummy2:LONG 54 | dummy3:LONG 55 | dummy4:LONG 56 | privbaseid:LONG -> "PRIV" -> 1.10.0 57 | environment:LONG -> 1.10.0 58 | envmem:LONG -> 1.10.0 59 | publicbase:PTR TO publicbase 60 | usertask:LONG -> 1.6.0 61 | usecount:LONG 62 | ENDOBJECT 63 | 64 | CONST PRIVBASE_ENV = 52 65 | 66 | OBJECT startinfo 67 | rwsize:LONG 68 | initofs:LONG 69 | stacksize:LONG 70 | mainofs:LONG 71 | osversion:LONG -> 1.6 72 | ENDOBJECT 73 | 74 | OBJECT libtag OF rt 75 | -> morphos extensions 76 | revision:INT 77 | tags:LONG 78 | ENDOBJECT 79 | 80 | OBJECT libinfo OF startinfo -> 1.10.0, lets inherit 81 | functabofs:PTR TO libentry -> 1.6 82 | closeofs:LONG 83 | queryofs:LONG -> v53 84 | ENDOBJECT 85 | 86 | ->CONST SIZEOF_privatebase = 60 87 | 88 | 89 | CONST JUMPSTARTSIZE = 8 -> 1.5.4 90 | 91 | 92 | -> classes 93 | CONST OBJECT_CLASSINFO = -4, 94 | CLASSINFO_SIZE = -4, 95 | CLASSINFO_NAME = -8 96 | 97 | /* library */ 98 | 99 | CONST LN_TYPE=8, LN_PRI=9, LN_NAME=10 100 | CONST LIB_FLAGS=14, LIB_VERSION=20, LIB_REVISION=22, LIB_IDSTRING=24 101 | 102 | 103 | CONST PV_cleanupstack = -4, /* ec comp */ 104 | IV_stdout = -8, /* ec comp */ 105 | IV_conout = -12, /* ec comp */ 106 | IV_stdrast = -16, /* ec comp */ 107 | PV_memlist = -20, /* ec comp */ 108 | PV_exit68k = -24, /* 68k cleanupcode */ 109 | PV_clireturnval = -28, /* ec */ 110 | IV_arg = -32, /* ec comp */ 111 | IV_wbmessage = -36, /* ec comp */ 112 | IV_execbase = -40, /* ec comp */ 113 | IV_dosbase = -44, /* ec comp */ 114 | IV_intuitionbase = -48, /* ec comp */ 115 | IV_gfxbase = -52, /* ec comp */ 116 | PV_mathieeesingbasbase = -56, /* ec comp */ 117 | PV_mathieeesingtransbase = -60, /* ec comp */ 118 | PV_stackbottom = -64, /* ec comp, the startaddress of stack */-> AllocVec:ed 119 | PV_codequal = -68, /* [code:INT,qualifier:INT] intui support */ 120 | PV_iaddress = -72, /* intui support */ 121 | PV_code_return = -76, /* 68k exceptions */ 122 | PV_stack_return = -80, /* 68k exceptions */ 123 | IV_exception = -84, /* ec comp */ 124 | PV_saveda5 = -88, /* 68k exceptions */ 125 | IV_stdin = -92, /* ec comp */ 126 | IV_exceptioninfo = -96, /* ec comp */ 127 | PV_currchunk = -100, /* FastNew() ("chopmem") */ 128 | PV_chunkleft = -104, /* FastNew() ("chopleft") */ 129 | PV_cellsmem = -108, /* ec cells */ 130 | PV_freecells = -112, /* ec cells */ 131 | PV_chunksize = -116, /* ec cells */ 132 | 133 | /****** END, EC GLOBALS ******/ 134 | 135 | PV_mempool = -120, /* mempool for String(),List(),DisposeLink() */ 136 | PV_utillib = -124, /* CreativE "utilitybase" variable (NOT USED, KEEP NIL)*/ 137 | PV_cleanupframe = -128, /* 1.6.0: 68k CleanUp() startup A5 */ 138 | PV_rwdata = -132, -> V46: points to AllocVec:ed rwdata 139 | 140 | /* v45: own librarybase in library mode */ 141 | IV_librarybase = -136, 142 | 143 | -> powerpc globals 144 | PV_randseed = -140, -> Rnd() 145 | PV_ppccleanup = -144, -> adr of cleanupcode, used by CleanUp() 146 | PV_exceptstruct = -148, -> ppc exceptionhandling 147 | 148 | -> ppc list-quote function globals 149 | PV_argsave0 = -152, -> ppc quote+list functions.. 150 | PV_argsave1 = -156, 151 | PV_argsave2 = -160, 152 | PV_argsave3 = -164, 153 | PV_argsave4 = -168, 154 | PV_argsave5 = -172, 155 | PV_argsave6 = -176, 156 | PV_argsave7 = -180, 157 | 158 | PV_initcode = -184, -> 1.10.0, startup sets it to initcode 159 | PV_unused100 = -188, 160 | PV_unused101 = -192, 161 | 162 | -> ppc str_fmt 163 | PV_ppc_str_fmt_old = -196, -> backwards compab as of 1.5.4 164 | 165 | -> ppc double float support 166 | PV_mathieeedoubbasbase = -200, 167 | PV_mathieeedoubtransbase = -204, 168 | 169 | /* OS4 support */ 170 | IV_execiface = -208, 171 | IV_dosiface = -212, 172 | IV_gfxiface = -216, 173 | IV_intuitioniface = -220, 174 | PV_mathieeedoubbasiface = -224, 175 | PV_mathieeedoubtransiface = -228, 176 | PV_mathieeesingbasiface = -232, 177 | PV_mathieeesingtransiface = -236, 178 | 179 | 180 | -> memtable for fastnew 181 | PV_memtable = -512, -> table compatible with EC. (260 bytes) 182 | 183 | IVARSSIZE = 512 184 | 185 | 186 | 187 | ->CONST ENVOFFSET = SIZEOF_privatebase + IVARSSIZE 188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /startup_amigaos.e: -------------------------------------------------------------------------------- 1 | 2 | 3 | -> Feb 2007 4 | 5 | -> Startupcode in E! 6 | -> FINALLY.. 7 | 8 | -> NOTE: WE CAN NOT have inline lists.. 9 | -> Maybe this will change though.. 10 | 11 | -> October 2008: splitted out amigaos 12 | 13 | OPT MODULE, PREPROCESS 14 | 15 | ->#define MINSTARTUP 16 | 17 | #ifdef DEBUG 18 | #define DEBUGF(str,...) DebugF(str,...) 19 | #else 20 | #define DEBUGF(str,...) 21 | #endif 22 | 23 | #define MEMFLAGS MEMF_CLEAR OR MEMF_PUBLIC 24 | 25 | #define USE_SINGLE_LIBS 1 26 | #ifdef MINSTARTUP 27 | OPT MODNAME = 'minstartup_amigaos' 28 | #else 29 | OPT MODNAME = 'startup_amigaos' 30 | #endif 31 | OPT AMIGAOS 32 | #define REG_ARG A0 33 | #define REG_ARGLEN D0 34 | #define GLOBREG A4 35 | SAVEREGISTERS MACRO NOP 36 | LOADREGISTERS MACRO NOP 37 | SAVESTACKRETURN MACRO 38 | MOVE.L A7, ___cleanupstack 39 | MOVE.L A5, ___cleanupframe 40 | ENDM 41 | LOADSTACKRETURN MACRO 42 | MOVE.L ___cleanupstack, A7 43 | MOVE.L ___cleanupframe, A5 44 | ENDM 45 | #define LIBS_VERSION 39 46 | MODULE 'exec/tasks' 47 | #define SHELLSTACKBOT process.task.splower 48 | #define STACKREG A7 49 | SETUPEXEC MACRO 50 | execbase := Long(4) 51 | ENDM 52 | 53 | MODULE 'exec/execbase' 54 | MODULE 'dos/dosextens' 55 | MODULE 'dos/dos' 56 | MODULE 'exec/memory' 57 | MODULE 'runtime' 58 | MODULE 'exec/libraries' 59 | 60 | EXPORT ___startinfo: 61 | LONG 0 -> rwsize 62 | LONG 0 -> initofs 63 | LONG 0 -> stacksize 64 | LONG 0 -> mainofs 65 | LONG 0 -> osversion 66 | 67 | EXPORT PROC ___startup() 68 | DEF _arg, _arglen, si:PTR TO startinfo, execbase:PTR TO execbase 69 | DEF sss:stackswapstruct 70 | DEF rwmem=NIL:PTR TO LONG, ifunc(PTR), mfunc(), r=20, stackmem=NIL 71 | DEF mem:PTR TO memnode, next 72 | DEF process:PTR TO process 73 | 74 | SAVEREGISTERS 75 | 76 | _arg := REG_ARG 77 | _arglen := REG_ARGLEN 78 | 79 | SETUPEXEC 80 | 81 | si := {___startinfo} 82 | 83 | -> check osversion 84 | IF si.osversion > execbase.lib.version THEN JUMP endpart 85 | 86 | rwmem := AllocVec(si.rwsize, MEMFLAGS) 87 | IF rwmem = NIL THEN JUMP endpart 88 | 89 | ifunc := si + si.initofs 90 | DEBUGF('startup: calling init $\h\n', ifunc) 91 | 92 | ifunc(rwmem) 93 | 94 | /* WE NOW HAVE ACCESS TO globals ! */ 95 | 96 | DEBUGF('startup: globreg=$\h\n', GLOBREG) 97 | 98 | ___initcode := ifunc -> 1.10.0, save for stuff like newEnvironment() 99 | 100 | ___rwdatasize := si.rwsize -> 2.0 101 | 102 | -> we cannot reach global execbase as its defined locally, so we do it like this 103 | PutLong(GLOBREG + OFFSETOF ___internalglobs.execbase, execbase) 104 | 105 | ___rwdata := rwmem 106 | 107 | process := FindTask(NIL) 108 | 109 | DEBUGF('startup: allocating stack \d bytes\n', si.stacksize) 110 | 111 | stackmem := AllocVec(si.stacksize, MEMFLAGS) 112 | IF stackmem = NIL THEN JUMP endpart 113 | ___stackbottom := stackmem 114 | -> init stack swap struct 115 | sss.lower := ___stackbottom 116 | sss.upper := ___stackbottom + si.stacksize 117 | sss.pointer := sss.upper 118 | ___stackswapstruct := sss -> fix 119 | StackSwap(sss) 120 | 121 | 122 | -> create pool 123 | ___mempool := CreatePool(NIL, 4096, 256) 124 | IF ___mempool = NIL THEN JUMP endpart 125 | 126 | DEBUGF('startup: ___mempool = $\h\n', ___mempool) 127 | 128 | #ifndef MINSTARTUP 129 | 130 | -> check for wbstartup, or arg 131 | IF process.cli = NIL 132 | WaitPort(process.msgport) 133 | wbmessage := GetMsg(process.msgport) 134 | arg := '' 135 | ELSE -> no wbstartup 136 | arg := _arg 137 | arg[_arglen-1] := NIL 138 | ENDIF 139 | 140 | DEBUGF('startup: arg done\n') 141 | 142 | dosbase := OpenLibrary('dos.library', LIBS_VERSION) 143 | intuitionbase := OpenLibrary('intuition.library', LIBS_VERSION) 144 | gfxbase := OpenLibrary('graphics.library', LIBS_VERSION) 145 | 146 | stdout := Output() 147 | stdin := Input() 148 | 149 | DEBUGF('input output done\n') 150 | 151 | 152 | #else /* MINSTARTUP */ 153 | 154 | arg := _arg 155 | 156 | #endif /* MINSTARTUP */ 157 | 158 | -> keep using 37 as version for these ! 159 | #ifdef USE_DOUBLE_LIBS 160 | -> ppc code uses double precision libs 161 | ___mathieeedoubbasbase := OpenLibrary('mathieeedoubbas.library', 37) 162 | ___mathieeedoubtransbase := OpenLibrary('mathieeedoubtrans.library', 37) 163 | #endif 164 | 165 | #ifdef USE_SINGLE_LIBS 166 | -> 68k code uses single precision libs 167 | ___mathieeesingbasbase := OpenLibrary('mathieeesingbas.library', 37) 168 | ___mathieeesingtransbase := OpenLibrary('mathieeesingtrans.library', 37) 169 | #endif 170 | 171 | SAVESTACKRETURN 172 | 173 | ___exit68k := {exitcode} 174 | 175 | mfunc := si + si.mainofs 176 | 177 | DEBUGF('startup: calling main $\h\n', mfunc) 178 | 179 | ___clireturnval := mfunc() 180 | 181 | exitcode: 182 | LOADSTACKRETURN 183 | endpart: 184 | 185 | IF rwmem 186 | IF ___stackswapstruct THEN StackSwap(___stackswapstruct) 187 | ENDIF 188 | IF stackmem THEN FreeVec(stackmem) 189 | 190 | IF rwmem 191 | 192 | -> free user memory [ New(), NewR(), NewM(), NEW, FastNew() ] 193 | mem := ___memlist 194 | WHILE mem 195 | next := mem.next 196 | FreeMem(mem, mem.size) 197 | mem := next 198 | ENDWHILE 199 | 200 | IF ___mempool THEN DeletePool(___mempool) 201 | 202 | #ifdef USE_SINGLE_LIBS 203 | CloseLibrary(___mathieeesingbasbase) 204 | CloseLibrary(___mathieeesingtransbase) 205 | #endif 206 | 207 | #ifdef USE_DOUBLE_LIBS 208 | CloseLibrary(___mathieeedoubbasbase) 209 | CloseLibrary(___mathieeedoubtransbase) 210 | #endif 211 | 212 | #ifndef MINSTARTUP 213 | 214 | IF conout 215 | Read(conout,0,0) -> what ? 216 | Close(conout) 217 | ENDIF 218 | 219 | CloseLibrary(dosbase) 220 | CloseLibrary(intuitionbase) 221 | CloseLibrary(gfxbase) 222 | 223 | IF wbmessage 224 | Forbid() -> we dont want to be unloadseged until we are done 225 | ReplyMsg(wbmessage) 226 | ENDIF 227 | 228 | #endif /* MINSTARTUP */ 229 | 230 | r := ___clireturnval 231 | 232 | FreeVec(rwmem) 233 | 234 | /* GLOBAL ENV IS NOW GONE */ 235 | 236 | ENDIF 237 | 238 | 239 | LOADREGISTERS 240 | 241 | ENDPROC r 242 | 243 | -------------------------------------------------------------------------------- /startup_amigaos4.e: -------------------------------------------------------------------------------- 1 | 2 | 3 | -> October 2008: splitted opt amigaos4 4 | 5 | OPT MODULE, PREPROCESS, AMIGAOS4 6 | 7 | ->#define MINSTARTUP 8 | 9 | ->#define DEBUG 10 | 11 | #ifdef DEBUG 12 | #define DEBUGF(str,...) DebugF(str,...,0) 13 | #else 14 | #define DEBUGF(str,...) 15 | #endif 16 | 17 | #define MEMFLAGS MEMF_CLEAR OR MEMF_SHARED 18 | 19 | 20 | 21 | #ifdef MINSTARTUP 22 | OPT MODNAME = 'minstartup_amigaos4' 23 | #else 24 | OPT MODNAME = 'startup_amigaos4' 25 | #endif 26 | 27 | #define REG_ARG R3 28 | #define REG_ARGLEN R4 29 | #define REG_EXEC R5 30 | #define GLOBREG R13 31 | #define USE_DOUBLE_LIBS 1 32 | SAVEREGISTERS MACRO STMW R13, regsave 33 | LOADREGISTERS MACRO LMW R13, regsave 34 | #define LIBS_VERSION 50 35 | MODULE 'exec/tasks' 36 | 37 | MODULE 'exec/execbase' 38 | MODULE 'dos/dosextens' 39 | MODULE 'dos/dos' 40 | MODULE 'exec/memory' 41 | MODULE 'powerpc/simple' 42 | MODULE 'runtime' 43 | MODULE 'exec/libraries' 44 | 45 | EXPORT ___startinfo: 46 | LONG 0 -> rwsize 47 | LONG 0 -> initofs 48 | LONG 0 -> stacksize 49 | LONG 0 -> mainofs 50 | LONG 0 -> osversion 51 | 52 | EXPORT PROC ___startup(_arg, _arglen, execbase:PTR TO execbase) 53 | DEF si:PTR TO startinfo 54 | DEF sss:stackswapstruct 55 | DEF rwmem=NIL:PTR TO LONG, ifunc(PTR), r=20, stackmem=NIL 56 | DEF mem:PTR TO memnode, next 57 | DEF process:PTR TO process 58 | DEF regsave[32]:ARRAY OF LONG 59 | DEF execiface 60 | 61 | SAVEREGISTERS 62 | 63 | execiface := execbase.maininterface 64 | 65 | si := {___startinfo} 66 | 67 | -> check osversion 68 | IF si.osversion > execbase.lib.version THEN RETURN 20 69 | 70 | rwmem := AllocVec(si.rwsize, MEMFLAGS) 71 | IF rwmem = NIL THEN RETURN 20 72 | 73 | ifunc := si + si.initofs 74 | ifunc(rwmem) 75 | 76 | /* WE NOW HAVE ACCESS TO globals ! */ 77 | 78 | ___initcode := ifunc -> 1.10.0, save for stuff like newEnvironment() 79 | 80 | ___rwdatasize := si.rwsize -> 2.0 81 | 82 | -> we cannot reach global execbase as its defined locally, so we do it like this 83 | PutLong(GLOBREG + OFFSETOF ___internalglobs.execbase, execbase) 84 | 85 | -> same with execiface 86 | PutLong(GLOBREG + OFFSETOF ___internalglobs.execiface, execiface) 87 | 88 | DEBUGF('startup: globreg=$\h\n', GLOBREG) 89 | 90 | ___rwdata := rwmem 91 | 92 | process := FindTask(NIL) 93 | 94 | DEBUGF('startup: allocating stack \d bytes\n', si.stacksize) 95 | 96 | stackmem := AllocVec(si.stacksize, MEMFLAGS) 97 | IF stackmem = NIL THEN JUMP endpart 98 | ___stackbottom := stackmem 99 | -> init stack swap struct 100 | sss.lower := ___stackbottom 101 | sss.upper := ___stackbottom + si.stacksize 102 | sss.pointer := sss.upper - 16 103 | ___stackswapstruct := sss -> fix 104 | 105 | 106 | -> create pool 107 | ___mempool := CreatePool(NIL, 4096, 256) 108 | IF ___mempool = NIL THEN JUMP endpart 109 | 110 | DEBUGF('startup: created mempool $\h\n', ___mempool) 111 | 112 | #ifndef MINSTARTUP 113 | 114 | -> check for wbstartup, or arg 115 | IF process.cli = NIL 116 | WaitPort(process.msgport) 117 | wbmessage := GetMsg(process.msgport) 118 | arg := '' 119 | ELSE -> no wbstartup 120 | arg := _arg 121 | arg[_arglen-1] := NIL 122 | ENDIF 123 | 124 | DEBUGF('startup: done with arg\n') 125 | 126 | dosbase := OpenLibrary('dos.library', LIBS_VERSION) 127 | intuitionbase := OpenLibrary('intuition.library', LIBS_VERSION) 128 | gfxbase := OpenLibrary('graphics.library', LIBS_VERSION) 129 | 130 | dosiface := GetInterface(dosbase, 'main', 1, NIL) 131 | intuitioniface := GetInterface(intuitionbase, 'main', 1, NIL) 132 | gfxiface := GetInterface(gfxbase, 'main', 1, NIL) 133 | 134 | stdout := Output() 135 | stdin := Input() 136 | 137 | DEBUGF('startup: input/output done\n') 138 | 139 | 140 | #else /* MINSTARTUP */ 141 | 142 | arg := _arg 143 | 144 | #endif /* MINSTARTUP */ 145 | 146 | #ifdef USE_DOUBLE_LIBS 147 | -> ppc code uses double precision libs 148 | ___mathieeedoubbasbase := OpenLibrary('mathieeedoubbas.library', LIBS_VERSION) 149 | ___mathieeedoubtransbase := OpenLibrary('mathieeedoubtrans.library', LIBS_VERSION) 150 | ___mathieeedoubbasiface := GetInterface(___mathieeedoubbasbase, 'main', 1, NIL) 151 | ___mathieeedoubtransiface := GetInterface(___mathieeedoubtransbase, 'main', 1, NIL) 152 | #endif 153 | 154 | #ifdef USE_SINGLE_LIBS 155 | -> 68k code uses single precision libs 156 | ___mathieeesingbasbase := OpenLibrary('mathieeesingbas.library', LIBS_VERSION) 157 | ___mathieeesingtransbase := OpenLibrary('mathieeesingtrans.library', LIBS_VERSION) 158 | ___mathieeesingbasiface := GetInterface(___mathieeesingbasbase, 'main', 1, NIL) 159 | ___mathieeesingtransiface := GetInterface(___mathieeesingtransbase, 'main', 1, NIL) 160 | #endif 161 | 162 | ___os4main := si + si.mainofs 163 | 164 | safeCallMainSwapped() 165 | 166 | endpart: 167 | 168 | DEBUGF('startup: finnishing up\n') 169 | 170 | IF stackmem THEN FreeVec(stackmem) 171 | 172 | IF rwmem 173 | 174 | -> free user memory [ New(), NewR(), NewM(), NEW, FastNew() ] 175 | mem := ___memlist 176 | WHILE mem 177 | next := mem.next 178 | FreeMem(mem, mem.size) 179 | mem := next 180 | ENDWHILE 181 | 182 | IF ___mempool THEN DeletePool(___mempool) 183 | 184 | #ifdef USE_SINGLE_LIBS 185 | DropInterface(___mathieeesingbasiface) 186 | DropInterface(___mathieeesingtransiface) 187 | CloseLibrary(___mathieeesingbasbase) 188 | CloseLibrary(___mathieeesingtransbase) 189 | #endif 190 | 191 | #ifdef USE_DOUBLE_LIBS 192 | DropInterface(___mathieeedoubbasiface) 193 | DropInterface(___mathieeedoubtransiface) 194 | CloseLibrary(___mathieeedoubbasbase) 195 | CloseLibrary(___mathieeedoubtransbase) 196 | #endif 197 | 198 | #ifndef MINSTARTUP 199 | 200 | IF conout 201 | Read(conout,0,0) -> what ? 202 | Close(conout) 203 | ENDIF 204 | 205 | DropInterface(dosiface) 206 | DropInterface(intuitioniface) 207 | DropInterface(gfxiface) 208 | 209 | CloseLibrary(dosbase) 210 | CloseLibrary(intuitionbase) 211 | CloseLibrary(gfxbase) 212 | 213 | IF wbmessage 214 | Forbid() -> we dont want to be unloadseged until we are done 215 | ReplyMsg(wbmessage) 216 | ENDIF 217 | 218 | #endif /* MINSTARTUP */ 219 | 220 | r := ___clireturnval 221 | 222 | FreeVec(rwmem) 223 | 224 | /* GLOBAL ENV IS NOW GONE */ 225 | 226 | ENDIF 227 | 228 | 229 | LOADREGISTERS 230 | 231 | ENDPROC r 232 | 233 | PROC safeCallMain() 234 | 235 | DEBUGF('startup: safeCallMain()\n') 236 | 237 | STW R1, ___cleanupstack 238 | 239 | ___ppccleanup := {exitcode} 240 | 241 | ___clireturnval := ___os4main() 242 | 243 | exitcode: 244 | LWZ R1, ___cleanupstack 245 | 246 | DEBUGF('startup: safeCallMain DONE\n') 247 | 248 | ENDPROC 249 | 250 | PROC safeCallMainSwapped() 251 | DEBUGF('startup: safeCallMainSwapped()\n') 252 | 253 | StackSwap(___stackswapstruct) 254 | 255 | safeCallMain() 256 | 257 | -> danger! we have no access to local execiface until after stackswap()! 258 | -> so we will have to do it with asm 259 | LWZ R4, ___stackswapstruct 260 | LWZ R3, .execiface(R13:___internalglobs) 261 | LWZ R0, StackSwap(R3) 262 | MTCTR R0 263 | BCTRL 264 | 265 | DEBUGF('startup: safeCallMainSwapped() DONE\n') 266 | 267 | ENDPROC 268 | 269 | -------------------------------------------------------------------------------- /startup_morphos.e: -------------------------------------------------------------------------------- 1 | 2 | -> Feb 2007 3 | 4 | -> Startupcode in E! 5 | -> FINALLY.. 6 | 7 | -> NOTE: WE CAN NOT have inline lists.. 8 | -> Maybe this will change though.. 9 | 10 | -> TODO: make 68k exitcode (in PPC mode) point to stubcode. 11 | 12 | -> October 2008: splitted out morphos version 13 | 14 | OPT MODULE, PREPROCESS 15 | 16 | 17 | ->#define MINSTARTUP 18 | 19 | #ifdef DEBUG 20 | #define DEBUGF(str,...) DebugF(str,...) 21 | #else 22 | #define DEBUGF(str,...) 23 | #endif 24 | 25 | #define MEMFLAGS MEMF_CLEAR OR MEMF_PUBLIC 26 | 27 | #ifdef MINSTARTUP 28 | OPT MODNAME = 'minstartup_morphos' 29 | #else 30 | OPT MODNAME = 'startup_morphos' 31 | #define USE_SINGLE_LIBS 1 32 | #endif 33 | OPT MORPHOS 34 | #define REG_ARG R3 35 | #define REG_ARGLEN R4 36 | #define GLOBREG R13 37 | #define USE_NEW_STACKSWAP 1 38 | #define USE_ETASK_MEMPOOL 1 39 | #define USE_DOUBLE_LIBS 1 40 | SAVEREGISTERS MACRO STMW R13, regsave 41 | LOADREGISTERS MACRO LMW R13, regsave 42 | SAVESTACKRETURN MACRO NOP 43 | LOADSTACKRETURN MACRO NOP 44 | #define USE_PPC_STUB 1 45 | #define LIBS_VERSION 50 46 | MODULE 'exec/tasks' 47 | #define SHELLSTACKBOT process.task.etask.ppcsplower 48 | #define STACKREG R1 49 | SETUPEXEC MACRO 50 | execbase := Long(4) 51 | ENDM 52 | 53 | 54 | MODULE 'exec/execbase' 55 | MODULE 'dos/dosextens' 56 | MODULE 'dos/dos' 57 | MODULE 'exec/memory' 58 | MODULE 'powerpc/simple' 59 | MODULE 'runtime' 60 | MODULE 'exec/libraries' 61 | 62 | EXPORT ___startinfo: 63 | LONG 0 -> rwsize 64 | LONG 0 -> initofs 65 | LONG 0 -> stacksize 66 | LONG 0 -> mainofs 67 | LONG 0 -> osversion 68 | 69 | EXPORT PROC ___startup() 70 | DEF _arg, _arglen, si:PTR TO startinfo, execbase:PTR TO execbase 71 | DEF sss:stackswapstruct 72 | DEF rwmem=NIL:PTR TO LONG, ifunc(PTR), mfunc(), r=20, stackmem=NIL 73 | DEF mem:PTR TO memnode, next 74 | DEF process:PTR TO process 75 | DEF ssargs[10]:ARRAY OF LONG 76 | DEF regsave[32]:ARRAY OF LONG 77 | 78 | SAVEREGISTERS 79 | 80 | _arg := REG_ARG 81 | _arglen := REG_ARGLEN 82 | 83 | SETUPEXEC 84 | 85 | si := {___startinfo} 86 | 87 | -> check osversion 88 | IF si.osversion > execbase.lib.version THEN JUMP endpart 89 | 90 | rwmem := AllocVec(si.rwsize, MEMFLAGS) 91 | IF rwmem = NIL THEN JUMP endpart 92 | 93 | ifunc := si + si.initofs 94 | ifunc(rwmem) 95 | 96 | /* WE NOW HAVE ACCESS TO globals ! */ 97 | 98 | DEBUGF('startup: globreg=$\h\n', GLOBREG) 99 | 100 | ___initcode := ifunc -> 1.10.0, save for stuff like newEnvironment() 101 | 102 | ___rwdatasize := si.rwsize -> 2.0 103 | 104 | -> we cannot reach global execbase as its defined locally, so we do it like this 105 | PutLong(GLOBREG + OFFSETOF ___internalglobs.execbase, execbase) 106 | 107 | ___rwdata := rwmem 108 | 109 | process := FindTask(NIL) 110 | 111 | DEBUGF('startup: allocating stack \d bytes\n', si.stacksize) 112 | 113 | stackmem := AllocVec(si.stacksize, MEMFLAGS) 114 | IF stackmem = NIL THEN JUMP endpart 115 | ___stackbottom := stackmem 116 | -> init stack swap struct 117 | sss.lower := ___stackbottom 118 | sss.upper := ___stackbottom + si.stacksize 119 | sss.pointer := sss.upper 120 | ___stackswapstruct := sss -> fix 121 | 122 | 123 | -> get pool from tc.etask.mempool 124 | ___mempool := process.task.etask.mempool 125 | 126 | #ifndef MINSTARTUP 127 | 128 | -> check for wbstartup, or arg 129 | IF process.cli = NIL 130 | WaitPort(process.msgport) 131 | wbmessage := GetMsg(process.msgport) 132 | arg := '' 133 | ELSE -> no wbstartup 134 | arg := _arg 135 | arg[_arglen-1] := NIL 136 | ENDIF 137 | 138 | dosbase := OpenLibrary('dos.library', LIBS_VERSION) 139 | intuitionbase := OpenLibrary('intuition.library', LIBS_VERSION) 140 | gfxbase := OpenLibrary('graphics.library', LIBS_VERSION) 141 | 142 | stdout := Output() 143 | stdin := Input() 144 | 145 | 146 | #else /* MINSTARTUP */ 147 | 148 | arg := _arg 149 | 150 | #endif /* MINSTARTUP */ 151 | 152 | #ifdef USE_DOUBLE_LIBS 153 | -> ppc code uses double precision libs 154 | ___mathieeedoubbasbase := OpenLibrary('mathieeedoubbas.library', LIBS_VERSION) 155 | ___mathieeedoubtransbase := OpenLibrary('mathieeedoubtrans.library', LIBS_VERSION) 156 | #endif 157 | 158 | #ifdef USE_SINGLE_LIBS 159 | -> 68k code uses single precision libs 160 | ___mathieeesingbasbase := OpenLibrary('mathieeesingbas.library', LIBS_VERSION) 161 | ___mathieeesingtransbase := OpenLibrary('mathieeesingtrans.library', LIBS_VERSION) 162 | #endif 163 | 164 | mfunc := si + si.mainofs 165 | 166 | ssargs[0] := mfunc 167 | ssargs[1] := GLOBREG 168 | ___clireturnval := NewPPCStackSwap(sss, {stub}, ssargs) 169 | 170 | 171 | endpart: 172 | 173 | IF stackmem THEN FreeVec(stackmem) 174 | 175 | IF rwmem 176 | 177 | -> free user memory [ New(), NewR(), NewM(), NEW, FastNew() ] 178 | mem := ___memlist 179 | WHILE mem 180 | next := mem.next 181 | FreeMem(mem, mem.size) 182 | mem := next 183 | ENDWHILE 184 | 185 | #ifdef USE_SINGLE_LIBS 186 | CloseLibrary(___mathieeesingbasbase) 187 | CloseLibrary(___mathieeesingtransbase) 188 | #endif 189 | 190 | #ifdef USE_DOUBLE_LIBS 191 | CloseLibrary(___mathieeedoubbasbase) 192 | CloseLibrary(___mathieeedoubtransbase) 193 | #endif 194 | 195 | #ifndef MINSTARTUP 196 | 197 | IF conout 198 | Read(conout,0,0) -> what ? 199 | Close(conout) 200 | ENDIF 201 | 202 | CloseLibrary(dosbase) 203 | CloseLibrary(intuitionbase) 204 | CloseLibrary(gfxbase) 205 | 206 | IF wbmessage 207 | Forbid() -> we dont want to be unloadseged until we are done 208 | ReplyMsg(wbmessage) 209 | ENDIF 210 | 211 | #endif /* MINSTARTUP */ 212 | 213 | r := ___clireturnval 214 | 215 | FreeVec(rwmem) 216 | 217 | /* GLOBAL ENV IS NOW GONE */ 218 | 219 | ENDIF 220 | 221 | 222 | LOADREGISTERS 223 | 224 | ENDPROC r 225 | 226 | PROC stub(mainaddres, globalreg) 227 | DEF regs[32]:ARRAY OF LONG 228 | STMW R13, regs 229 | OR R13, R4, R4 230 | STW R1, ___cleanupstack 231 | MTCTR R3 232 | LA R5, exitcodeppc 233 | STW R5, ___ppccleanup 234 | BCTRL 235 | exitcodeppc: 236 | LWZ R1, ___cleanupstack 237 | LMW R13, regs 238 | ENDPROC R3 239 | -------------------------------------------------------------------------------- /support.e: -------------------------------------------------------------------------------- 1 | 2 | -> ECX/support.e 3 | 4 | /* ECX by Leif Salomonsson [ecx tele2 se] is Copyright (c) 2002-2008 */ 5 | /* Released under the ECX COMPILER LICENSE, See ECXCOMPILERLICENSE.TXT */ 6 | 7 | 8 | OPT MODULE 9 | OPT PREPROCESS 10 | 11 | MODULE 'utility' -> v55 12 | MODULE 'utility/date' -> v55 13 | MODULE 'dos/datetime' -> 1.8.0 14 | MODULE 'dos/dos' 15 | 16 | DEF utilitybase 17 | 18 | #ifndef ECX_VERSION 19 | 20 | MODULE 'mathieeedoubtrans' 21 | 22 | DEF mathieeedoubtransbase 23 | 24 | EXPORT PROC initSupport() 25 | mathieeedoubtransbase := OpenLibrary('mathieeedoubtrans.library', 37) 26 | IF mathieeedoubtransbase = NIL THEN Throw("LIB", 'mathieeedoubtrans.library') 27 | 28 | utilitybase := OpenLibrary('utility.library', 39) 29 | IF utilitybase = NIL THEN Throw("LIB", 'utility.library') 30 | ENDPROC 31 | 32 | EXPORT PROC endSupport() 33 | IF utilitybase THEN CloseLibrary(utilitybase) -> v55 34 | IF mathieeedoubtransbase THEN CloseLibrary(mathieeedoubtransbase) 35 | ENDPROC 36 | 37 | EXPORT PROC singToDoub(sing) 38 | DEF x, y 39 | x, y := IeeeDPFieee(sing) 40 | ENDPROC x, y 41 | 42 | #endif /* ECX_VERSION */ 43 | 44 | 45 | #ifdef ECX_VERSION 46 | 47 | #ifdef __AMIGAOS4__ 48 | DEF utilityiface 49 | #endif 50 | 51 | EXPORT PROC initSupport() 52 | utilitybase := OpenLibrary('utility.library', 39) 53 | IF utilitybase = NIL THEN Throw("LIB", 'utility.library') 54 | #ifdef __AMIGAOS4__ 55 | utilityiface := GetInterface(utilitybase, 'main', 1, NIL) 56 | IF utilityiface = NIL THEN Throw("LIB", 'utility.library->interface') 57 | #endif 58 | ENDPROC 59 | 60 | EXPORT PROC endSupport() 61 | #ifdef __AMIGAOS4__ 62 | IF utilityiface THEN DropInterface(utilityiface) 63 | #endif 64 | IF utilitybase THEN CloseLibrary(utilitybase) -> v55 65 | ENDPROC 66 | 67 | EXPORT PROC singToDoub(sing) 68 | DEF d:DOUBLE 69 | d := sing 70 | ENDPROC Long({d}), Long({d}+4) -> fixed 1.8.2 71 | 72 | #endif /* ECX_VERSION */ 73 | 74 | EXPORT PROC writeNewExeFile(buf,size, name) HANDLE 75 | DEF fh=NIL 76 | 77 | fh := Open(name, NEWFILE) 78 | IF fh = NIL THEN Raise("OPEN") 79 | 80 | IF Write(fh, buf, size) <> size THEN Raise("WRIT") 81 | 82 | EXCEPT DO 83 | 84 | IF fh THEN Close(fh) 85 | 86 | IF exception 87 | RETURN NIL 88 | ELSE 89 | -> os4's JXFS does not set e bit by default 90 | SetProtection(name, NIL) 91 | ENDIF 92 | ENDPROC size 93 | 94 | EXPORT PROC writeNewFile(buf,size, name) HANDLE 95 | DEF fh=NIL 96 | 97 | fh := Open(name, NEWFILE) 98 | IF fh = NIL THEN Raise("OPEN") 99 | 100 | IF Write(fh, buf, size) <> size THEN Raise("WRIT") 101 | 102 | EXCEPT DO 103 | 104 | IF fh THEN Close(fh) 105 | 106 | IF exception THEN RETURN NIL 107 | 108 | ENDPROC size 109 | 110 | 111 | -> 2.0 112 | EXPORT PROC makeVersiondateStr(estr) 113 | DEF dt:datetime, s 114 | DEF buf[100]:ARRAY 115 | 116 | DateStamp(dt) 117 | dt.flags := NIL 118 | dt.strday := NIL 119 | dt.strdate := buf+2 120 | dt.strtime := NIL 121 | buf[0] := "'" 122 | buf[1] := "(" 123 | 124 | dt.format := FORMAT_CDN 125 | IF DateToStr(dt) 126 | s := buf 127 | s := s + InStr(s, '-') 128 | s[]++ := "." 129 | s := s + InStr(s, '-') 130 | s[]++ := "." 131 | s[3] := s[1] 132 | s[2] := s[0] 133 | s[0] := "2" 134 | s[1] := "0" 135 | s[4] := ")" 136 | s[5] := "'" 137 | s[6] := NIL 138 | StrCopy(estr, buf) 139 | ELSE 140 | SetStr(estr, 0) 141 | ENDIF 142 | 143 | ENDPROC 144 | 145 | EXPORT PROC makeDateStr(estr) 146 | 147 | DEF dt:datetime, s 148 | DEF buf[100]:ARRAY 149 | 150 | DateStamp(dt) 151 | dt.flags := NIL 152 | dt.strday := NIL 153 | dt.strdate := buf+1 154 | dt.strtime := NIL 155 | buf[0] := "'" 156 | 157 | dt.format := FORMAT_DOS 158 | IF DateToStr(dt) 159 | s := buf 160 | s := s + InStr(s, '-') + 1 161 | s := s + InStr(s, '-') + 1 162 | s[3] := s[1] 163 | s[2] := s[0] 164 | s[0] := "2" 165 | s[1] := "0" 166 | s[4] := "'" 167 | s[5] := NIL 168 | StrCopy(estr, buf) 169 | ELSE 170 | SetStr(estr, 0) 171 | ENDIF 172 | 173 | ENDPROC 174 | 175 | EXPORT PROC makeTimeStr(estr) 176 | DEF secs 177 | DEF cd:clockdata 178 | 179 | secs := getSeconds() 180 | 181 | Amiga2Date(secs, cd) 182 | 183 | StringF(estr, '\a\z\d[2]:\z\d[2]:\z\d[2]\a', cd.hour, cd.min, cd.sec) 184 | 185 | ENDPROC 186 | 187 | PROC getSeconds() 188 | DEF seconds,now:datestamp 189 | DateStamp(now) -> datestamp datum 190 | seconds := Mul(now.days, 86400) + Mul(now.minute, 60) + Div(now.tick, TICKS_PER_SECOND) 191 | ENDPROC seconds 192 | -------------------------------------------------------------------------------- /viewcache.e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EEC-Developers/eec/a21d06122679be69ff8f660b339bd9eacd8c6ad5/viewcache.e --------------------------------------------------------------------------------