├── DAsmJit.inc ├── README.md ├── DAsmJit.pas ├── LICENSE.md ├── DAsmJit_Lock.pas ├── DAsmJit_VirtualMemory.pas ├── DAsmJit_CpuInfo.pas ├── DAsmJit_Logger.pas ├── DAsmJit_MemoryManager.pas ├── DAsmJit_Util.pas └── DAsmJit_Defs.pas /DAsmJit.inc: -------------------------------------------------------------------------------- 1 | {$IFDEF FPC} 2 | {$MODE DELPHI} 3 | {$H+} 4 | {$ELSE} 5 | {$DEFINE MSWINDOWS} 6 | {$ENDIF} 7 | 8 | {$IFDEF MSWINDOWS} 9 | {$DEFINE ASMJIT_WINDOWS} 10 | {$ELSE} 11 | {$DEFINE ASMJIT_POSIX} 12 | {$ENDIF} 13 | 14 | // [DAsmJit - Architecture] 15 | {$IFDEF CPUX64} 16 | {$DEFINE ASMJIT_X64} // x86-64 17 | {$ELSE} 18 | {$DEFINE ASMJIT_X86} 19 | {$ENDIF} 20 | 21 | {.$DEFINE ASMJIT_DEBUG_INSTRUCTION_MAP} 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DAsmJit 2 | ------- 3 | 4 | Pascal port of AsmJit: complete x86/x64 JIT and Remote Assembler for C++ 5 | 6 | Ported by Nielsie95 with a couple of fixes from others, see https://villavu.com/forum/showthread.php?t=56493 7 | 8 | * [AsmJit Official Repository](https://github.com/asmjit/asmjit) 9 | * [Permissive ZLIB license](./LICENSE.md) 10 | 11 | Note: as this is an older port of AsmJit, it doesn't support new instruction sets published after 2010 (like AVX) -------------------------------------------------------------------------------- /DAsmJit.pas: -------------------------------------------------------------------------------- 1 | unit DAsmJit; 2 | 3 | {$I DAsmJit.inc} 4 | 5 | interface 6 | 7 | type 8 | //Defined in Delphi 9 | PInt8 = ^Int8; 10 | Int8 = ShortInt; 11 | 12 | PUInt8 = ^UInt8; 13 | UInt8 = Byte; 14 | 15 | PInt16 = ^Int16; 16 | Int16 = SmallInt; 17 | 18 | PUInt16 = ^UInt16; 19 | UInt16 = Word; 20 | 21 | PInt32 = ^Int32; 22 | Int32 = LongInt; 23 | 24 | PUInt32 = ^UInt32; 25 | UInt32 = LongWord; 26 | 27 | //PInt64 = ^Int64; 28 | //Int64 = Int64; 29 | 30 | PUInt64 = ^UInt64; 31 | //UInt64 = UInt64; 32 | 33 | {$IFDEF ASMJIT_X86} 34 | SysInt = Int32; 35 | SysUInt = UInt32; 36 | {$ELSE} 37 | SysInt = Int64; 38 | SysUInt = UInt64; 39 | {$ENDIF} 40 | 41 | PSysInt = ^SysInt; 42 | PSysUInt = ^SysUInt; 43 | 44 | {$IFNDEF FPC} 45 | PtrInt = Integer; 46 | PtrUInt = Cardinal; 47 | 48 | const 49 | LineEnding = #13#10; 50 | {$ENDIF} 51 | 52 | implementation 53 | 54 | end. 55 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2017, Petr Kobalicek 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /DAsmJit_Lock.pas: -------------------------------------------------------------------------------- 1 | unit DAsmJit_Lock; 2 | 3 | {$I DAsmJit.inc} 4 | 5 | interface 6 | 7 | {$IFDEF ASMJIT_WINDOWS} 8 | uses 9 | Windows; 10 | {$ENDIF} 11 | 12 | type 13 | {$IFDEF ASMJIT_WINDOWS} 14 | TLockHandle = TRTLCriticalSection; 15 | {$ELSE} 16 | TLockHandle = pthread_mutex_t; 17 | {$ENDIF} 18 | 19 | TLock = class 20 | protected 21 | FHandle: TLockHandle; 22 | public 23 | constructor Create; 24 | destructor Destroy; override; 25 | 26 | procedure DAsmJit_Lock; 27 | procedure UnLock; 28 | 29 | property Handle: TLockHandle read FHandle; 30 | end; 31 | 32 | TAutoLock = class 33 | protected 34 | FTarget: TLock; 35 | FOwnTarget: Boolean; 36 | public 37 | constructor Create(Target: TLock = nil); 38 | destructor Destroy; override; 39 | end; 40 | 41 | implementation 42 | 43 | constructor TLock.Create; 44 | begin 45 | inherited; 46 | 47 | {$IFDEF ASMJIT_WINDOWS} 48 | InitializeCriticalSection(FHandle); 49 | {$ENDIF} 50 | end; 51 | 52 | destructor TLock.Destroy; 53 | begin 54 | {$IFDEF ASMJIT_WINDOWS} 55 | DeleteCriticalSection(FHandle); 56 | {$ENDIF} 57 | 58 | inherited; 59 | end; 60 | 61 | procedure TLock.DAsmJit_Lock; 62 | begin 63 | {$IFDEF ASMJIT_WINDOWS} 64 | EnterCriticalSection(FHandle); 65 | {$ENDIF} 66 | end; 67 | 68 | procedure TLock.UnLock; 69 | begin 70 | {$IFDEF ASMJIT_WINDOWS} 71 | LeaveCriticalSection(FHandle); 72 | {$ENDIF} 73 | end; 74 | 75 | constructor TAutoLock.Create(Target: TLock = nil); 76 | begin 77 | inherited Create; 78 | 79 | if (Target = nil) then 80 | begin 81 | FTarget := TLock.Create; 82 | FOwnTarget := True; 83 | end 84 | else 85 | begin 86 | FTarget := Target; 87 | FOwnTarget := False; 88 | end; 89 | 90 | FTarget.DAsmJit_Lock; 91 | end; 92 | 93 | destructor TAutoLock.Destroy; 94 | begin 95 | FTarget.UnLock; 96 | 97 | if (FOwnTarget) then 98 | FTarget.Free; 99 | 100 | inherited; 101 | end; 102 | 103 | end. 104 | -------------------------------------------------------------------------------- /DAsmJit_VirtualMemory.pas: -------------------------------------------------------------------------------- 1 | unit DAsmJit_VirtualMemory; 2 | 3 | {$I DAsmJit.inc} 4 | 5 | interface 6 | 7 | uses 8 | {$IFDEF ASMJIT_WINDOWS}Windows,{$ENDIF} DAsmJit; 9 | 10 | type 11 | TVirtualMemory = class 12 | class function Alloc(Length: SysUInt; Allocated: PSysUInt; canExecute: Boolean): Pointer; 13 | class procedure FreeAddress(Addr: Pointer; Length: SysUInt); 14 | class function Alignment: SysUInt; 15 | class function PageSize: SysUInt; 16 | end; 17 | 18 | implementation 19 | 20 | type 21 | TVirtualMemoryLocal = class 22 | public 23 | Alignment: SysUInt; 24 | pageSize: SysUInt; 25 | 26 | constructor Create; 27 | end; 28 | 29 | var 30 | vm: TVirtualMemoryLocal; 31 | 32 | function isAligned(Base, Alignment: SysUInt): Boolean; 33 | begin 34 | Result := (Base mod Alignment) = 0; 35 | end; 36 | 37 | function roundUp(Base, pageSize: SysUInt): SysUInt; 38 | var 39 | over: SysUInt; 40 | begin 41 | over := Base mod pageSize; 42 | if (over > 0) then 43 | Result := Base + (pageSize - over) 44 | else 45 | Result := Base; 46 | end; 47 | 48 | function roundUpToPowerOf2(Base: SysUInt): SysUInt; 49 | begin 50 | Dec(Base); 51 | 52 | Base := Base or (Base shr 1); 53 | Base := Base or (Base shr 2); 54 | Base := Base or (Base shr 4); 55 | Base := Base or (Base shr 8); 56 | Base := Base or (Base shr 16); 57 | 58 | {$IFDEF ASMJIT_X64} 59 | Base := Base or (Base shr 32); 60 | {$ENDIF} 61 | 62 | Result := Base + 1; 63 | end; 64 | 65 | constructor TVirtualMemoryLocal.Create; 66 | {$IFDEF ASMJIT_WINDOWS} 67 | var 68 | Info: TSystemInfo; 69 | {$ENDIF} 70 | begin 71 | inherited; 72 | 73 | {$IFDEF ASMJIT_WINDOWS} 74 | GetSystemInfo(Info); 75 | Alignment := Info.dwAllocationGranularity; 76 | pageSize := roundUpToPowerOf2(Info.dwPageSize); 77 | {$ELSE} 78 | Alignment := getpagesize; 79 | pageSize := Alignment; 80 | {$ENDIF} 81 | end; 82 | 83 | class function TVirtualMemory.Alloc(Length: SysUInt; Allocated: PSysUInt; canExecute: Boolean): Pointer; 84 | var 85 | mSize: SysUInt; 86 | Protect: Integer; 87 | mBase: Pointer; 88 | {$IFDEF ASMJIT_WINDOWS} 89 | mProt: Pointer; 90 | {$ENDIF ASMJIT_WINDOWS} 91 | begin 92 | mSize := RoundUp(Length, vm.pageSize); 93 | 94 | {$IFDEF ASMJIT_WINDOWS} 95 | if canExecute then 96 | Protect := PAGE_EXECUTE_READWRITE 97 | else 98 | Protect := PAGE_READWRITE; 99 | mBase := VirtualAlloc(nil, mSize, MEM_COMMIT or MEM_RESERVE, Protect); 100 | mProt := nil; 101 | VirtualProtect(mBase, mSize, PAGE_EXECUTE, mProt); 102 | {$ELSE} 103 | Protect := PROT_READ or PROT_WRITE; 104 | if canExecute then 105 | Protect := Protect or PROT_EXEC; 106 | mBase := mmap(nil, mSize, Protection, MAP_PRIVATE or MAP_ANONYMOUS, -1, 0); 107 | {$ENDIF} 108 | 109 | {$IFDEF ASMJIT_WINDOWS} 110 | if (mBase = nil) then 111 | {$ELSE} 112 | if (mBase = MAP_FAILED) then 113 | {$ENDIF} 114 | begin 115 | Result := nil; 116 | Exit; 117 | end; 118 | 119 | {$IFDEF ASMJIT_WINDOWS} 120 | Assert(isAligned(SysUInt(mBase), vm.Alignment)); 121 | {$ENDIF} 122 | 123 | if (Allocated <> nil) then 124 | Allocated^ := mSize; 125 | Result := mBase; 126 | end; 127 | 128 | class procedure TVirtualMemory.FreeAddress(Addr: Pointer; Length: SysUInt); 129 | begin 130 | {$IFDEF ASMJIT_WINDOWS} 131 | VirtualFree(Addr, 0, MEM_RELEASE); 132 | {$ELSE} 133 | munmap(Addr, Length); 134 | {$ENDIF} 135 | end; 136 | 137 | class function TVirtualMemory.Alignment: SysUInt; 138 | begin 139 | Result := vm.Alignment; 140 | end; 141 | 142 | class function TVirtualMemory.PageSize: SysUInt; 143 | begin 144 | Result := vm.pageSize 145 | end; 146 | 147 | initialization 148 | vm := TVirtualMemoryLocal.Create; 149 | finalization 150 | vm.Free; 151 | 152 | end. 153 | -------------------------------------------------------------------------------- /DAsmJit_CpuInfo.pas: -------------------------------------------------------------------------------- 1 | unit DAsmJit_CpuInfo; 2 | 3 | {$I DAsmJit.inc} 4 | 5 | interface 6 | 7 | uses 8 | {$IFDEF ASMJIT_WINDOWS}Windows,{$ENDIF} DAsmJit; 9 | 10 | type 11 | PCpuId = ^ TCpuId; 12 | TCpuId = record 13 | case UInt32 of 14 | 0: (i: array[0..3] of UInt32); 15 | 1: (eax: UInt32; 16 | ebx: UInt32; 17 | ecx: UInt32; 18 | edx: UInt32;) 19 | end; 20 | 21 | const 22 | //TVendorID_E = ( 23 | Vendor_Unknown = 0; 24 | Vendor_INTEL = 1; 25 | Vendor_AMD = 2; 26 | Vendor_VIA = 3; 27 | //); 28 | 29 | type 30 | TX86ExtendedInfo = record 31 | ProcessorType: UInt32; 32 | BrandIndex: UInt32; 33 | clFlushCacheLineSize: UInt32; 34 | LogicalProcessors: UInt32; 35 | apicPhysicalId: UInt32; 36 | end; 37 | 38 | PCpuInfo = ^TCpuInfo; 39 | TCpuInfo = record 40 | Vendor: AnsiString; 41 | VendorId: UInt32; 42 | Family: UInt32; 43 | Model: UInt32; 44 | Stepping: UInt32; 45 | NumberOfProcessors: UInt32; 46 | Features: UInt32; 47 | Bugs: UInt32; 48 | x86ExtendedInfo: TX86ExtendedInfo; 49 | end; 50 | 51 | const 52 | //TFeature_E = ( 53 | Feature_RDTSC = SysUInt(1) shl 0; 54 | Feature_RDTSCP = SysUInt(1) shl 1; 55 | Feature_CMOV = SysUInt(1) shl 2; 56 | Feature_CMPXCHG8B = SysUInt(1) shl 3; 57 | Feature_CMPXCHG16B = SysUInt(1) shl 4; 58 | Feature_CLFLUSH = SysUInt(1) shl 5; 59 | Feature_PREFETCH = SysUInt(1) shl 6; 60 | Feature_LAHF_SAHF = SysUInt(1) shl 7; 61 | Feature_FXSR = SysUInt(1) shl 8; 62 | Feature_FFXSR = SysUInt(1) shl 9; 63 | Feature_MMX = SysUInt(1) shl 10; 64 | Feature_MMXExt = SysUInt(1) shl 11; 65 | Feature_3dNow = SysUInt(1) shl 12; 66 | Feature_3dNowExt = SysUInt(1) shl 13; 67 | Feature_SSE = SysUInt(1) shl 14; 68 | Feature_MSSE = SysUInt(1) shl 15; 69 | Feature_SSE2 = SysUInt(1) shl 16; 70 | Feature_SSE3 = SysUInt(1) shl 17; 71 | Feature_SSSE3 = SysUInt(1) shl 18; 72 | Feature_SSE4_A = SysUInt(1) shl 19; 73 | Feature_SSE4_1 = SysUInt(1) shl 20; 74 | Feature_SSE4_2 = SysUInt(1) shl 21; 75 | Feature_SSE5 = SysUInt(1) shl 22; 76 | Feature_MotitorMWait = SysUInt(1) shl 23; 77 | Feature_POPCNT = SysUInt(1) shl 24; 78 | Feature_LZCNT = SysUInt(1) shl 25; 79 | Feature_MultiThreading = SysUInt(1) shl 29; 80 | Feature_ExecuteDisableBit = SysUInt(1) shl 30; 81 | Feature_64Bit = SysUInt(1) shl 31; 82 | //); 83 | 84 | //const 85 | Bug_AmdLockMB = SysUInt(1) shl 0; 86 | 87 | var 88 | getCpuInfo: TCpuInfo; 89 | 90 | procedure cpuId(varIn: NativeUInt; varOut: PCpuId); 91 | procedure detectCpuInfo(i: PCpuInfo); 92 | 93 | implementation 94 | 95 | type 96 | TVendorInfo = record 97 | id: UInt32; 98 | Text: AnsiString; 99 | end; 100 | 101 | const 102 | VendorInfo: array[0..3] of TVendorInfo = ( 103 | (id: Vendor_INTEL; Text: 'GenuineIntel'), 104 | (id: Vendor_AMD; Text: 'AMDisbetter!'), 105 | (id: Vendor_AMD; Text: 'AuthenticAMD'), 106 | (id: Vendor_VIA; Text: 'VIA'#0'VIA'#0'VIA'#0) 107 | ); 108 | 109 | function detectNumberOfProcessors: UInt32; 110 | var 111 | {$IFDEF ASMJIT_WINDOWS} 112 | Info: TSystemInfo; 113 | {$ELSE} 114 | res: SysUInt; 115 | {$ENDIF} 116 | begin 117 | {$IFDEF ASMJIT_WINDOWS} 118 | GetSystemInfo(Info); 119 | Result := Info.dwNumberOfProcessors; 120 | {$ELSE} 121 | Result := sysconf(_SC_NPROCESSORS_ONLN); 122 | if (Result = -1) then Result := 1; 123 | {$ENDIF} 124 | end; 125 | 126 | procedure cpuId(varIn: NativeUInt; varOut: PCpuId); assembler; {$asmmode intel} 127 | asm 128 | {$IFDEF ASMJIT_X64} 129 | 130 | //x64 131 | push rax 132 | push rbx 133 | push rcx 134 | push rdx 135 | push rdi 136 | mov rax, varIn 137 | mov rdi, varOut 138 | cpuid 139 | mov dword64 ptr[rdi + 0], rax 140 | mov dword64 ptr[rdi + 4], rbx 141 | mov dword64 ptr[rdi + 8], rcx 142 | mov dword64 ptr[rdi + 12], rdx 143 | pop rdi 144 | pop rdx 145 | pop rcx 146 | pop rbx 147 | pop rax 148 | 149 | {$ELSE} 150 | 151 | //x86 152 | push eax 153 | push ebx 154 | push ecx 155 | push edx 156 | push edi 157 | mov eax, varIn 158 | mov edi, varOut 159 | cpuid 160 | mov dword ptr[edi + 0], eax 161 | mov dword ptr[edi + 4], ebx 162 | mov dword ptr[edi + 8], ecx 163 | mov dword ptr[edi + 12], edx 164 | pop edi 165 | pop edx 166 | pop ecx 167 | pop ebx 168 | pop eax 169 | 170 | {$ENDIF} 171 | end; 172 | 173 | procedure detectCpuInfo(i: PCpuInfo); 174 | 175 | function Min(a, b: SysUInt): SysUInt; 176 | begin 177 | if (b < a) then 178 | Result := b 179 | else 180 | Result := a; 181 | end; 182 | 183 | var 184 | a{, exIds}: SysUInt; 185 | idOut: TCpuId; 186 | v: PAnsiChar; 187 | begin 188 | FillChar(i^, SizeOf(TCpuInfo), 0); 189 | i.Vendor := 'Unknown'; 190 | i.NumberOfProcessors := detectNumberOfProcessors; 191 | 192 | cpuId(0, @idOut); 193 | 194 | GetMem(v, 12 * SizeOf(AnsiChar)); 195 | FillChar(v^, 12 * SizeOf(AnsiChar), 0); 196 | Move(idOut.ebx, v^, 4); 197 | Inc(v, 4); 198 | Move(idOut.edx, v^, 4); 199 | Inc(v, 4); 200 | Move(idOut.ecx, v^, 4); 201 | Dec(v, 8); 202 | i.Vendor := v; 203 | FreeMem(v); 204 | 205 | for a := 0 to 2 do 206 | if (i.Vendor = VendorInfo[a].Text) then 207 | begin 208 | i.vendorId := VendorInfo[a].id; 209 | Break; 210 | end; 211 | 212 | cpuId(1, @idOut); 213 | 214 | i.family := (idOut.eax shr 8) and $0F; 215 | i.model := (idOut.eax shr 4) and $0F; 216 | i.stepping := (idOut.eax ) and $0F; 217 | 218 | if (i.family = $0F) then 219 | begin 220 | Inc(i.family, ((idOut.eax shr 20) and $FF)); 221 | Inc(i.model, ((idOut.eax shr 16) and $0F) shl 4); 222 | end; 223 | 224 | i.x86ExtendedInfo.processorType := ((idOut.eax shr 12) and $03); 225 | i.x86ExtendedInfo.brandIndex := ((idOut.ebx ) and $FF); 226 | i.x86ExtendedInfo.clFlushCacheLineSize := ((idOut.ebx shr 8) and $FF) * 8; 227 | i.x86ExtendedInfo.logicalProcessors := ((idOut.ebx shr 16) and $FF); 228 | i.x86ExtendedInfo.apicPhysicalId := ((idOut.ebx shr 24) and $FF); 229 | 230 | if ((idOut.ecx and SysUInt($00000001)) > 0) then i.features := i.Features or Feature_SSE3; 231 | if ((idOut.ecx and SysUInt($00000008)) > 0) then i.features := i.features or Feature_MotitorMWait; 232 | if ((idOut.ecx and SysUInt($00000200)) > 0) then i.features := i.features or Feature_SSSE3; 233 | if ((idOut.ecx and SysUInt($00002000)) > 0) then i.features := i.features or Feature_CMPXCHG16B; 234 | if ((idOut.ecx and SysUInt($00080000)) > 0) then i.features := i.features or Feature_SSE4_1; 235 | if ((idOut.ecx and SysUInt($00100000)) > 0) then i.features := i.features or Feature_SSE4_2; 236 | if ((idOut.ecx and SysUInt($00800000)) > 0) then i.features := i.features or Feature_POPCNT; 237 | 238 | if ((idOut.edx and SysUInt($00000010)) > 0) then i.features := i.features or Feature_RDTSC; 239 | if ((idOut.edx and SysUInt($00000100)) > 0) then i.features := i.features or Feature_CMPXCHG8B; 240 | if ((idOut.edx and SysUInt($00008000)) > 0) then i.features := i.features or Feature_CMOV; 241 | if ((idOut.edx and SysUInt($00800000)) > 0) then i.features := i.features or Feature_MMX; 242 | if ((idOut.edx and SysUInt($01000000)) > 0) then i.features := i.features or Feature_FXSR; 243 | if ((idOut.edx and SysUInt($02000000)) > 0) then i.features := i.features or Feature_SSE or Feature_MMXExt; 244 | if ((idOut.edx and SysUInt($04000000)) > 0) then i.features := i.features or Feature_SSE or Feature_SSE2; 245 | if ((idOut.edx and SysUInt($10000000)) > 0) then i.features := i.features or Feature_MultiThreading; 246 | 247 | if ((i.vendorId = Vendor_AMD) and ((idOut.edx and SysUInt($10000000)) > 0)) then 248 | if (i.numberOfProcessors = 1) then i.numberOfProcessors := 2; 249 | 250 | if ((i.vendorId = Vendor_AMD) and (i.family = 15) and (i.model >= 32) and (i.model <= 63)) then 251 | i.bugs := i.bugs or Bug_AmdLockMB; 252 | 253 | cpuid($80000000, @idOut); 254 | //exIds := Min(idOut.eax - 1, $80000001); 255 | 256 | //for a := UInt32($80000001) to exIds do 257 | begin 258 | cpuid($80000001, @idOut); 259 | 260 | //case a of 261 | // $80000001: 262 | begin 263 | if ((idOut.ecx and SysUInt($00000001)) > 0) then i.features := i.Features or Feature_LAHF_SAHF; 264 | if ((idOut.ecx and SysUInt($00000020)) > 0) then i.features := i.features or Feature_LZCNT; 265 | if ((idOut.ecx and SysUInt($00000040)) > 0) then i.features := i.features or Feature_SSE4_A; 266 | if ((idOut.ecx and SysUInt($00000080)) > 0) then i.features := i.features or Feature_MSSE; 267 | if ((idOut.ecx and SysUInt($00000100)) > 0) then i.features := i.features or Feature_PREFETCH; 268 | if ((idOut.ecx and SysUInt($00000800)) > 0) then i.features := i.features or Feature_SSE5; 269 | 270 | if ((idOut.edx and SysUInt($00100000)) > 0) then i.features := i.features or Feature_ExecuteDisableBit; 271 | if ((idOut.edx and SysUInt($00200000)) > 0) then i.features := i.features or Feature_FFXSR; 272 | if ((idOut.edx and SysUInt($00400000)) > 0) then i.features := i.features or Feature_MMXExt; 273 | if ((idOut.edx and SysUInt($08000000)) > 0) then i.features := i.features or Feature_RDTSCP; 274 | if ((idOut.edx and SysUInt($20000000)) > 0) then i.features := i.features or Feature_64Bit; 275 | if ((idOut.edx and SysUInt($40000000)) > 0) then i.features := i.features or Feature_3dNowExt or Feature_MMXExt; 276 | if ((idOut.edx and SysUInt($80000000)) > 0) then i.features := i.features or Feature_3dNow; 277 | end; 278 | // end; 279 | end; 280 | end; 281 | 282 | initialization 283 | detectCpuInfo(@getCpuInfo); 284 | finalization 285 | end. 286 | -------------------------------------------------------------------------------- /DAsmJit_Logger.pas: -------------------------------------------------------------------------------- 1 | unit DAsmJit_Logger; 2 | 3 | {$I DAsmJit.inc} 4 | 5 | interface 6 | 7 | uses 8 | DAsmJit, Classes, DAsmJit_Serializer, DAsmJit_Defs; 9 | 10 | type 11 | TLogger = class(TCustomLogger) 12 | protected 13 | //FEnabled: Boolean; 14 | FHaveStream: Boolean; 15 | public 16 | constructor Create; virtual; 17 | 18 | procedure log(buf: string); override; 19 | procedure logInstruction(code: UInt32; o1, o2, o3: POperand; inlineComment: string = ''); virtual; 20 | procedure logAlign(m: SysInt); override; 21 | procedure logLabel(Lbl: TLabel); virtual; 22 | procedure logFormat(fmt: string; args: array of const); override; 23 | 24 | class function dumpInstruction(code: UInt32): string; 25 | class function dumpOperand(op: POperand): string; 26 | class function dumpRegister(typ, index: UInt8): string; 27 | class function dumpLabel(Lbl: TLabel): string; 28 | 29 | //property Enabled: Boolean read FEnabled write FEnabled; 30 | end; 31 | 32 | TStreamLogger = class(TLogger) 33 | protected 34 | FStream: TStream; 35 | 36 | procedure SetStream(Stream: TStream); 37 | public 38 | constructor Create(Stream: TStream = nil); reintroduce; 39 | 40 | procedure log(buf: string); override; 41 | property Stream: TStream read FStream write SetStream; 42 | end; 43 | 44 | TLoggerCallback = procedure(buf: string) of object; 45 | TCallbackLogger = class(TLogger) 46 | protected 47 | cb: TLoggerCallback; 48 | public 49 | constructor Create(CallBack: TLoggerCallback = nil); reintroduce; 50 | 51 | procedure log(buf: string); override; 52 | property Callback: TLoggerCallback read cb write cb; 53 | end; 54 | 55 | implementation 56 | 57 | uses 58 | SysUtils; 59 | 60 | const 61 | instructionName: array[0..577] of pchar = ( 62 | 'adc', 63 | 'add', 64 | 'addpd', 65 | 'addps', 66 | 'addsd', 67 | 'addss', 68 | 'addsubpd', 69 | 'addsubps', 70 | 'amd_prefetch', 71 | 'amd_prefetchw', 72 | 'and', 73 | 'andnpd', 74 | 'andnps', 75 | 'andpd', 76 | 'andps', 77 | 'blendpd', 78 | 'blendps', 79 | 'blendvpd', 80 | 'blendvps', 81 | 'bsf', 82 | 'bsr', 83 | 'bswap', 84 | 'bt', 85 | 'btc', 86 | 'btr', 87 | 'bts', 88 | 'call', 89 | 'cbw', 90 | 'cdqe', 91 | 'clc', 92 | 'cld', 93 | 'clflush', 94 | 'cmc', 95 | 'cmova', 96 | 'cmovae', 97 | 'cmovb', 98 | 'cmovbe', 99 | 'cmovc', 100 | 'cmove', 101 | 'cmovg', 102 | 'cmovge', 103 | 'cmovl', 104 | 'cmovle', 105 | 'cmovna', 106 | 'cmovnae', 107 | 'cmovnb', 108 | 'cmovnbe', 109 | 'cmovnc', 110 | 'cmovne', 111 | 'cmovng', 112 | 'cmovnge', 113 | 'cmovnl', 114 | 'cmovnle', 115 | 'cmovno', 116 | 'cmovnp', 117 | 'cmovns', 118 | 'cmovnz', 119 | 'cmovo', 120 | 'cmovp', 121 | 'cmovpe', 122 | 'cmovpo', 123 | 'cmovs', 124 | 'cmovz', 125 | 'cmp', 126 | 'cmppd', 127 | 'cmpps', 128 | 'cmpsd', 129 | 'cmpss', 130 | 'cmpxchg', 131 | 'cmpxchg16b', 132 | 'cmpxchg8b', 133 | 'comisd', 134 | 'comiss', 135 | 'cpuid', 136 | 'crc32', 137 | 'cvtdq2pd', 138 | 'cvtdq2ps', 139 | 'cvtpd2dq', 140 | 'cvtpd2pi', 141 | 'cvtpd2ps', 142 | 'cvtpi2pd', 143 | 'cvtpi2ps', 144 | 'cvtps2dq', 145 | 'cvtps2pd', 146 | 'cvtps2pi', 147 | 'cvtsd2si', 148 | 'cvtsd2ss', 149 | 'cvtsi2sd', 150 | 'cvtsi2ss', 151 | 'cvtss2sd', 152 | 'cvtss2si', 153 | 'cvttpd2dq', 154 | 'cvttpd2pi', 155 | 'cvttps2dq', 156 | 'cvttps2pi', 157 | 'cvttsd2si', 158 | 'cvttss2si', 159 | 'cwde', 160 | 'daa', 161 | 'das', 162 | 'dec', 163 | 'div', 164 | 'divpd', 165 | 'divps', 166 | 'divsd', 167 | 'divss', 168 | 'dppd', 169 | 'dpps', 170 | 'emms', 171 | 'enter', 172 | 'extractps', 173 | 'f2xm1', 174 | 'fabs', 175 | 'fadd', 176 | 'faddp', 177 | 'fbld', 178 | 'fbstp', 179 | 'fchs', 180 | 'fclex', 181 | 'fcmovb', 182 | 'fcmovbe', 183 | 'fcmove', 184 | 'fcmovnb', 185 | 'fcmovnbe', 186 | 'fcmovne', 187 | 'fcmovnu', 188 | 'fcmovu', 189 | 'fcom', 190 | 'fcomi', 191 | 'fcomip', 192 | 'fcomp', 193 | 'fcompp', 194 | 'fcos', 195 | 'fdecstp', 196 | 'fdiv', 197 | 'fdivp', 198 | 'fdivr', 199 | 'fdivrp', 200 | 'femms', 201 | 'ffree', 202 | 'fiadd', 203 | 'ficom', 204 | 'ficomp', 205 | 'fidiv', 206 | 'fidivr', 207 | 'fild', 208 | 'fimul', 209 | 'fincstp', 210 | 'finit', 211 | 'fist', 212 | 'fistp', 213 | 'fisttp', 214 | 'fisub', 215 | 'fisubr', 216 | 'fld', 217 | 'fld1', 218 | 'fldcw', 219 | 'fldenv', 220 | 'fldl2e', 221 | 'fldl2t', 222 | 'fldlg2', 223 | 'fldln2', 224 | 'fldpi', 225 | 'fldz', 226 | 'fmul', 227 | 'fmulp', 228 | 'fnclex', 229 | 'fninit', 230 | 'fnop', 231 | 'fnsave', 232 | 'fnstcw', 233 | 'fnstenv', 234 | 'fnstsw', 235 | 'fpatan', 236 | 'fprem', 237 | 'fprem1', 238 | 'fptan', 239 | 'frndint', 240 | 'frstor', 241 | 'fsave', 242 | 'fscale', 243 | 'fsin', 244 | 'fsincos', 245 | 'fsqrt', 246 | 'fst', 247 | 'fstcw', 248 | 'fstenv', 249 | 'fstp', 250 | 'fstsw', 251 | 'fsub', 252 | 'fsubp', 253 | 'fsubr', 254 | 'fsubrp', 255 | 'ftst', 256 | 'fucom', 257 | 'fucomi', 258 | 'fucomip', 259 | 'fucomp', 260 | 'fucompp', 261 | 'fwait', 262 | 'fxam', 263 | 'fxch', 264 | 'fxrstor', 265 | 'fxsave', 266 | 'fxtract', 267 | 'fyl2x', 268 | 'fyl2xp1', 269 | 'haddpd', 270 | 'haddps', 271 | 'hsubpd', 272 | 'hsubps', 273 | 'idiv', 274 | 'imul', 275 | 'inc', 276 | 'int3', 277 | 'ja', 278 | 'jae', 279 | 'jb', 280 | 'jbe', 281 | 'jc', 282 | 'je', 283 | 'jg', 284 | 'jge', 285 | 'jl', 286 | 'jle', 287 | 'jna', 288 | 'jnae', 289 | 'jnb', 290 | 'jnbe', 291 | 'jnc', 292 | 'jne', 293 | 'jng', 294 | 'jnge', 295 | 'jnl', 296 | 'jnle', 297 | 'jno', 298 | 'jnp', 299 | 'jns', 300 | 'jnz', 301 | 'jo', 302 | 'jp', 303 | 'jpe', 304 | 'jpo', 305 | 'js', 306 | 'jz', 307 | 'jmp', 308 | 'ja short', 309 | 'jae short', 310 | 'jb short', 311 | 'jbe short', 312 | 'jc short', 313 | 'je short', 314 | 'jg short', 315 | 'jge short', 316 | 'jl short', 317 | 'jle short', 318 | 'jna short', 319 | 'jnae short', 320 | 'jnb short', 321 | 'jnbe short', 322 | 'jnc short', 323 | 'jne short', 324 | 'jng short', 325 | 'jnge short', 326 | 'jnl short', 327 | 'jnle short', 328 | 'jno short', 329 | 'jnp short', 330 | 'jns short', 331 | 'jnz short', 332 | 'jo short', 333 | 'jp short', 334 | 'jpe short', 335 | 'jpo short', 336 | 'js short', 337 | 'jz short', 338 | 'jmp short', 339 | 'lddqu', 340 | 'ldmxcsr', 341 | 'lea', 342 | 'leave', 343 | 'lfence', 344 | 'DAsmJit_Lock', 345 | 'maskmovdqu', 346 | 'maskmovq', 347 | 'maxpd', 348 | 'maxps', 349 | 'maxsd', 350 | 'maxss', 351 | 'mfence', 352 | 'minpd', 353 | 'minps', 354 | 'minsd', 355 | 'minss', 356 | 'monitor', 357 | 'mov', 358 | 'movapd', 359 | 'movaps', 360 | 'movbe', 361 | 'movd', 362 | 'movddup', 363 | 'movdq2q', 364 | 'movdqa', 365 | 'movdqu', 366 | 'movhlps', 367 | 'movhpd', 368 | 'movhps', 369 | 'movlhps', 370 | 'movlpd', 371 | 'movlps', 372 | 'movmskpd', 373 | 'movmskps', 374 | 'movntdq', 375 | 'movntdqa', 376 | 'movnti', 377 | 'movntpd', 378 | 'movntps', 379 | 'movntq', 380 | 'movq', 381 | 'movq2dq', 382 | 'movsd', 383 | 'movshdup', 384 | 'movsldup', 385 | 'movss', 386 | 'movsx', 387 | 'movsxd', 388 | 'movupd', 389 | 'movups', 390 | 'movzx', 391 | 'mov', 392 | 'mpsadbw', 393 | 'mul', 394 | 'mulpd', 395 | 'mulps', 396 | 'mulsd', 397 | 'mulss', 398 | 'mwait', 399 | 'neg', 400 | 'nop', 401 | 'not', 402 | 'or', 403 | 'orpd', 404 | 'orps', 405 | 'pabsb', 406 | 'pabsd', 407 | 'pabsw', 408 | 'packssdw', 409 | 'packsswb', 410 | 'packusdw', 411 | 'packuswb', 412 | 'paddb', 413 | 'paddd', 414 | 'paddq', 415 | 'paddsb', 416 | 'paddsw', 417 | 'paddusb', 418 | 'paddusw', 419 | 'paddw', 420 | 'palignr', 421 | 'pand', 422 | 'pandn', 423 | 'pause', 424 | 'pavgb', 425 | 'pavgw', 426 | 'pblendvb', 427 | 'pblendw', 428 | 'pcmpeqb', 429 | 'pcmpeqd', 430 | 'pcmpeqq', 431 | 'pcmpeqw', 432 | 'pcmpestri', 433 | 'pcmpestrm', 434 | 'pcmpgtb', 435 | 'pcmpgtd', 436 | 'pcmpgtq', 437 | 'pcmpgtw', 438 | 'pcmpistri', 439 | 'pcmpistrm', 440 | 'pextrb', 441 | 'pextrd', 442 | 'pextrq', 443 | 'pextrw', 444 | 'pf2id', 445 | 'pf2iw', 446 | 'pfacc', 447 | 'pfadd', 448 | 'pfcmpeq', 449 | 'pfcmpge', 450 | 'pfcmpgt', 451 | 'pfmax', 452 | 'pfmin', 453 | 'pfmul', 454 | 'pfnacc', 455 | 'pfpnacc', 456 | 'pfrcp', 457 | 'pfrcpit1', 458 | 'pfrcpit2', 459 | 'pfrsqit1', 460 | 'pfrsqrt', 461 | 'pfsub', 462 | 'pfsubr', 463 | 'phaddd', 464 | 'phaddsw', 465 | 'phaddw', 466 | 'phminposuw', 467 | 'phsubd', 468 | 'phsubsw', 469 | 'phsubw', 470 | 'pi2fd', 471 | 'pi2fw', 472 | 'pinsrb', 473 | 'pinsrd', 474 | 'pinsrq', 475 | 'pinsrw', 476 | 'pmaddubsw', 477 | 'pmaddwd', 478 | 'pmaxsb', 479 | 'pmaxsd', 480 | 'pmaxsw', 481 | 'pmaxub', 482 | 'pmaxud', 483 | 'pmaxuw', 484 | 'pminsb', 485 | 'pminsd', 486 | 'pminsw', 487 | 'pminub', 488 | 'pminud', 489 | 'pminuw', 490 | 'pmovmskb', 491 | 'pmovsxbd', 492 | 'pmovsxbq', 493 | 'pmovsxbw', 494 | 'pmovsxdq', 495 | 'pmovsxwd', 496 | 'pmovsxwq', 497 | 'pmovzxbd', 498 | 'pmovzxbq', 499 | 'pmovzxbw', 500 | 'pmovzxdq', 501 | 'pmovzxwd', 502 | 'pmovzxwq', 503 | 'pmuldq', 504 | 'pmulhrsw', 505 | 'pmulhuw', 506 | 'pmulhw', 507 | 'pmulld', 508 | 'pmullw', 509 | 'pmuludq', 510 | 'pop', 511 | 'popad', 512 | 'popcnt', 513 | 'popfd', 514 | 'popfq', 515 | 'por', 516 | 'prefetch', 517 | 'psadbw', 518 | 'pshufb', 519 | 'pshufd', 520 | 'pshufw', 521 | 'pshufhw', 522 | 'pshuflw', 523 | 'psignb', 524 | 'psignd', 525 | 'psignw', 526 | 'pslld', 527 | 'pslldq', 528 | 'psllq', 529 | 'psllw', 530 | 'psrad', 531 | 'psraw', 532 | 'psrld', 533 | 'psrldq', 534 | 'psrlq', 535 | 'psrlw', 536 | 'psubb', 537 | 'psubd', 538 | 'psubq', 539 | 'psubsb', 540 | 'psubsw', 541 | 'psubusb', 542 | 'psubusw', 543 | 'psubw', 544 | 'pswapd', 545 | 'ptest', 546 | 'punpckhbw', 547 | 'punpckhdq', 548 | 'punpckhqdq', 549 | 'punpckhwd', 550 | 'punpcklbw', 551 | 'punpckldq', 552 | 'punpcklqdq', 553 | 'punpcklwd', 554 | 'push', 555 | 'pushad', 556 | 'pushfd', 557 | 'pushfq', 558 | 'pxor', 559 | 'rcl', 560 | 'rcpps', 561 | 'rcpss', 562 | 'rcr', 563 | 'rdtsc', 564 | 'rdtscp', 565 | 'ret', 566 | 'rol', 567 | 'ror', 568 | 'roundpd', 569 | 'roundps', 570 | 'roundsd', 571 | 'roundss', 572 | 'rsqrtps', 573 | 'rsqrtss', 574 | 'sahf', 575 | 'sal', 576 | 'sar', 577 | 'sbb', 578 | 'seta', 579 | 'setae', 580 | 'setb', 581 | 'setbe', 582 | 'setc', 583 | 'sete', 584 | 'setg', 585 | 'setge', 586 | 'setl', 587 | 'setle', 588 | 'setna', 589 | 'setnae', 590 | 'setnb', 591 | 'setnbe', 592 | 'setnc', 593 | 'setne', 594 | 'setng', 595 | 'setnge', 596 | 'setnl', 597 | 'setnle', 598 | 'setno', 599 | 'setnp', 600 | 'setns', 601 | 'setnz', 602 | 'seto', 603 | 'setp', 604 | 'setpe', 605 | 'setpo', 606 | 'sets', 607 | 'setz', 608 | 'sfence', 609 | 'shl', 610 | 'shld', 611 | 'shr', 612 | 'shrd', 613 | 'shufpd', 614 | 'shufps', 615 | 'sqrtpd', 616 | 'sqrtps', 617 | 'sqrtsd', 618 | 'sqrtss', 619 | 'stc', 620 | 'std', 621 | 'stmxcsr', 622 | 'sub', 623 | 'subpd', 624 | 'subps', 625 | 'subsd', 626 | 'subss', 627 | 'test', 628 | 'ucomisd', 629 | 'ucomiss', 630 | 'ud2', 631 | 'unpckhpd', 632 | 'unpckhps', 633 | 'unpcklpd', 634 | 'unpcklps', 635 | 'xadd', 636 | 'xchg', 637 | 'xor', 638 | 'xorpd', 639 | 'xorps'); 640 | 641 | operandSize: array[0..16] of string = ( 642 | '', 643 | 'byte ptr ', 644 | 'word ptr ', 645 | '', 646 | 'dword ptr ', 647 | '', 648 | '', 649 | '', 650 | 'qword ptr ', 651 | '', 652 | 'tword ptr ', 653 | '', 654 | '', 655 | '', 656 | '', 657 | '', 658 | 'dqword ptr '); 659 | 660 | segmentName: array[0..6] of string = ( 661 | ' ', 662 | 'cs:', 663 | 'ss:', 664 | 'ds:', 665 | 'es:', 666 | 'fs:', 667 | 'gs:'); 668 | 669 | function myutoa(i: SysUInt; base: SysUInt = 10): string; 670 | const 671 | Letters = '0123456789ABCDEF'; 672 | var 673 | b: SysInt; 674 | begin 675 | Result := ''; 676 | repeat 677 | b := i mod Base; 678 | Result := letters[Int8(b + 1)] + Result; 679 | i := i div Base; 680 | until (i <= 0); 681 | end; 682 | 683 | function myitoa(i: SysInt; Base: SysUInt = 10): string; 684 | begin 685 | Result := ''; 686 | if (i < 0) then 687 | begin 688 | Result := Result + '-'; 689 | i := -i; 690 | end; 691 | 692 | Result := Result + myutoa(SysUInt(i), Base); 693 | end; 694 | 695 | constructor TLogger.Create; 696 | begin 697 | inherited; 698 | 699 | FEnabled := True; 700 | FHaveStream := True; 701 | end; 702 | 703 | procedure TLogger.logInstruction(Code: UInt32; o1, o2, o3: POperand; inlineComment: string); 704 | var 705 | buf: string; 706 | currentLength, commentLength, alignBy: SysUInt; 707 | begin 708 | if ((not FEnabled) or (not FHaveStream)) then Exit; 709 | 710 | Buf := dumpInstruction(Code); 711 | 712 | if (o1 <> nil) and (not o1.isNone) then begin Buf := Buf + ' '; Buf := Buf + dumpOperand(o1); end; 713 | if (o2 <> nil) and (not o2.isNone) then begin Buf := Buf + ', ';Buf := Buf + dumpOperand(o2); end; 714 | if (o3 <> nil) and (not o3.isNone) then begin Buf := Buf + ', ';Buf := Buf + dumpOperand(o3); end; 715 | 716 | if (inlineComment <> '') then 717 | begin 718 | currentLength := Length(buf); 719 | commentLength := Length(inlineComment); 720 | if (commentLength > 255) then 721 | commentLength := 255; 722 | alignBy := 40; 723 | 724 | if (currentLength >= alignBy) then 725 | alignBy := 0 726 | else 727 | alignBy := alignBy - currentLength; 728 | 729 | Buf := Buf + StringOfChar(' ', alignBy) + '; ' + Copy(inlineComment, 1, commentLength); 730 | end; 731 | 732 | Buf := Buf + LineEnding; 733 | log(buf); 734 | end; 735 | 736 | procedure TLogger.logAlign(m: SysInt); 737 | begin 738 | if ((not FEnabled) or (not FHaveStream)) then Exit; 739 | 740 | logFormat('.align %d' + LineEnding, [Int32(m)]); 741 | end; 742 | 743 | procedure TLogger.logLabel(Lbl: TLabel); 744 | begin 745 | if ((not FEnabled) or (not FHaveStream)) then Exit; 746 | 747 | log(dumpLabel(Lbl) + ':' + LineEnding); 748 | end; 749 | 750 | procedure TLogger.logFormat(fmt: string; Args: array of const); 751 | begin 752 | if ((not FEnabled) or (not FHaveStream)) then Exit; 753 | log(Format(fmt, Args)); 754 | end; 755 | 756 | procedure TLogger.log(buf: string); 757 | begin 758 | end; 759 | 760 | class function TLogger.dumpInstruction(Code: UInt32): string; 761 | begin 762 | Assert(Code < _INST_COUNT); 763 | Result := instructionName[code - 1]; 764 | end; 765 | 766 | class function TLogger.dumpOperand(op: POperand): string; 767 | const 768 | onetwofoureight = '1248'; 769 | var 770 | reg: TBaseReg; 771 | isAbsolute: Boolean; 772 | mem: TMem; 773 | begin 774 | Result := ''; 775 | if (op.isReg) then 776 | begin 777 | reg := TBaseReg(op^); 778 | Result := dumpRegister(reg.typ, reg.index); 779 | Exit; 780 | end 781 | else if (op.isMem) then 782 | begin 783 | isAbsolute := False; 784 | mem := TMem(op^); 785 | 786 | if (op.size <= 16) then 787 | Result := operandSize[op.size]; 788 | 789 | Result := Result + segmentName[mem.segmentPrefix] + '['; 790 | 791 | if (mem.hasBase) then 792 | Result := Result + dumpRegister(REG_GPN, mem.base) 793 | else if (mem.hasLabel) then 794 | Result := Result + dumpLabel(mem.u._mem.Lbl^) 795 | else 796 | begin 797 | isAbsolute := True; 798 | Result := Result + myutoa(SysUInt(mem.u._mem.target), 16); 799 | end; 800 | 801 | if (mem.hasIndex) then 802 | begin 803 | Result := Result + ' + ' + dumpRegister(REG_GPN, mem.index); 804 | 805 | if (mem.shift > 0) then 806 | Result := Result + ' * ' + onetwofoureight[(mem.shift and 3) + 1]; 807 | end; 808 | 809 | if ((mem.displacement > 0) and (not isAbsolute)) then 810 | begin 811 | if (mem.displacement < 0) then 812 | Result := Result + '-' 813 | else 814 | Result := Result + '+'; 815 | Result := Result + myitoa(mem.displacement); 816 | end; 817 | 818 | Result := Result + ']'; 819 | Exit; 820 | end 821 | else if (op.isImm) then 822 | Result := myitoa(SysInt(TImmediate(op^).value)) 823 | else if (op.isLabel) then 824 | Result := dumpLabel(TLabel(op^)) 825 | else 826 | Result := 'none'; 827 | end; 828 | 829 | class function TLogger.dumpRegister(typ, index: UInt8): string; 830 | const 831 | regs1: array[0..7] of string = ('al', 'cl', 'dl', 'bl', 'ah', 'ch', 'dh', 'bh'); 832 | regs2: array[0..7] of string = ('ax', 'cx', 'dx', 'bx', 'sp', 'bp', 'si', 'di'); 833 | begin 834 | Result := ''; 835 | case typ of 836 | REG_GPB: 837 | if (index < 8) then 838 | Result := regs1[index] 839 | else 840 | Result := Format('r%ub', [UInt32(index)]); 841 | REG_GPW: 842 | if (index < 8) then 843 | Result := regs2[index] 844 | else 845 | Result := Format('r%uw', [UInt32(index)]); 846 | REG_GPD: 847 | if (index < 8) then 848 | Result := Format('e%s', [regs2[index]]) 849 | else 850 | Result := Format('r%ud', [UInt32(index)]); 851 | REG_GPQ: 852 | if (index < 8) then 853 | Result := Format('r%s', [regs2[index]]) 854 | else 855 | Result := Format('r%u', [UInt32(index)]); 856 | REG_X87: 857 | Result := Format('st%u', [UInt32(index)]); 858 | REG_MM: 859 | Result := Format('mmu%u', [UInt32(index)]); 860 | REG_XMM: 861 | Result := Format('xmm%u', [UInt32(index)]); 862 | end; 863 | end; 864 | 865 | class function TLogger.dumpLabel(Lbl: TLabel): string; 866 | begin 867 | Result := 'L'; 868 | 869 | if (Lbl.labelId > 0) then 870 | Result := Result + myutoa(Lbl.labelId) 871 | else 872 | Result := Result + 'x'; 873 | end; 874 | 875 | constructor TStreamLogger.Create(Stream: TStream = nil); 876 | begin 877 | inherited Create; 878 | 879 | SetStream(Stream); 880 | end; 881 | 882 | procedure TStreamLogger.log(buf: string); 883 | begin 884 | if ((not FEnabled) or (not FHaveStream)) then Exit; 885 | 886 | FStream.Write(Buf, Length(Buf)); 887 | end; 888 | 889 | procedure TStreamLogger.SetStream(Stream: TStream); 890 | begin 891 | FStream := Stream; 892 | FHaveStream := (Stream <> nil); 893 | end; 894 | 895 | constructor TCallBackLogger.Create(CallBack: TLoggerCallback = nil); 896 | begin 897 | inherited Create; 898 | 899 | cb := CallBack; 900 | end; 901 | 902 | procedure TCallBackLogger.log(buf: string); 903 | begin 904 | if ((not FEnabled) or (@cb = nil)) then 905 | Exit; 906 | 907 | cb(buf); 908 | end; 909 | 910 | end. 911 | -------------------------------------------------------------------------------- /DAsmJit_MemoryManager.pas: -------------------------------------------------------------------------------- 1 | unit DAsmJit_MemoryManager; 2 | 3 | {$I DAsmJit.inc} 4 | 5 | interface 6 | 7 | uses 8 | DAsmJit, DAsmJit_Lock, DAsmJit_VirtualMemory; 9 | 10 | const 11 | //MEMORY_ALLOC_TYPE_E = ( 12 | MEMORY_ALLOC_FREEABLE = 0; 13 | MEMORY_ALLOC_PERNAMENT = 1; 14 | //); 15 | 16 | //TNODE_COLOR_E = ( 17 | NODE_BLACK = 0; 18 | NODE_RED = 1; 19 | //); 20 | 21 | BITS_PER_ENTITY = SizeOf(SysUInt) * 8; 22 | 23 | type 24 | TMemoryManager = class 25 | public 26 | function Alloc(Size: SysUInt; Typ: UInt32 = MEMORY_ALLOC_FREEABLE): Pointer; virtual; abstract; 27 | function FreeAddress(Address: Pointer): Boolean; virtual; abstract; 28 | function Used: SysUInt; virtual; abstract; 29 | function Allocated: SysUInt; virtual; abstract; 30 | class function Global: TMemoryManager; 31 | end; 32 | 33 | TDefaultMemoryManager = class(TMemoryManager) 34 | protected 35 | Fd: Pointer; 36 | public 37 | constructor Create; 38 | destructor Destroy; override; 39 | 40 | function Alloc(Size: SysUInt; Typ: UInt32 = MEMORY_ALLOC_FREEABLE): Pointer; override; 41 | function FreeAddress(Address: Pointer): Boolean; override; 42 | function Used: SysUInt; override; 43 | function Allocated: SysUInt; override; 44 | end; 45 | 46 | PM_Node = ^TM_Node; 47 | TM_Node = record 48 | prev: PM_Node; 49 | next: PM_Node; 50 | nlLeft: PM_Node; 51 | nlRight: PM_Node; 52 | nlColor: UInt32; 53 | mem: PUInt8; 54 | size: SysUInt; 55 | blocks: SysUInt; 56 | density: SysUInt; 57 | used: SysUInt; 58 | largestBlock: SysUInt; 59 | baUsed: PSysUInt; 60 | baCont: PSysUInt; 61 | end; 62 | 63 | PM_PernamentNode = ^TM_PernamentNode; 64 | TM_PernamentNode = record 65 | mem: PUInt8; 66 | size: SysUInt; 67 | used: SysUInt; 68 | prev: PM_PernamentNode; 69 | end; 70 | 71 | function M_Node_Remain(r: TM_Node): SysUInt; 72 | function M_PernamentNode_Available(r: TM_PernamentNode): SysUInt; 73 | 74 | implementation 75 | 76 | type 77 | TMemoryManagerPrivate = class 78 | protected 79 | FLock: TLock; 80 | FNewChunkSize: SysUInt; 81 | FNewChunkDensity: SysUInt; 82 | FAllocated: SysUInt; 83 | FUsed: SysUInt; 84 | FFirst: PM_Node; 85 | FLast: PM_Node; 86 | FOptimal: PM_Node; 87 | FRoot: PM_Node; 88 | FPernament: PM_PernamentNode; 89 | public 90 | constructor Create; 91 | 92 | class function CreateNode(Size, Density: SysUInt): PM_Node; 93 | function AllocPernament(vSize: SysUInt): Pointer; 94 | function AllocFreeable(vSize: SysUInt): Pointer; 95 | function FreeAddress(Address: Pointer): Boolean; 96 | class function nlIsRed(n: PM_Node): Boolean; 97 | class function nlRotateLeft(n: PM_Node): PM_Node; 98 | class function nlRotateRight(n: PM_Node): PM_Node; 99 | class procedure nlFlipColor(n: PM_Node); 100 | class function nlMoveRedLeft(h: PM_Node): PM_Node; 101 | class function nlMoveRedRight(h: PM_Node): PM_Node; 102 | class function nlFixUp(h: PM_Node): PM_Node; 103 | procedure nlInsertNode(n: PM_Node); 104 | function nlInsertNode_(h, n: PM_Node): PM_Node; 105 | procedure nlRemoveNode(n: PM_Node); 106 | function nlRemoveNode_(h, n: PM_Node): PM_Node; 107 | function nlRemoveMin(h: PM_Node): PM_Node; 108 | function nlFindPtr(Mem: PUInt8): PM_Node; 109 | end; 110 | 111 | procedure _SetBit(buf: PSysUInt; Index: SysUInt); 112 | var 113 | i, j: SysUInt; 114 | begin 115 | i := index div (SizeOf(SysUInt) * 8); 116 | j := index mod (SizeOf(SysUInt) * 8); 117 | 118 | Inc(Buf, i); 119 | Buf^ := Buf^ or SysUInt(1) shl j; 120 | end; 121 | 122 | procedure _ClearBit(buf: PSysUInt; index: SysUInt); 123 | var 124 | i, j: SysUInt; 125 | begin 126 | i := index div (SizeOf(SysUInt) * 8); 127 | j := index mod (SizeOf(SysUInt) * 8); 128 | 129 | Inc(Buf, i); 130 | Buf^ := Buf^ and (not (SysUInt(1) shl j)); 131 | end; 132 | 133 | procedure _SetBits(buf: PSysUInt; index, len: SysUInt); 134 | var 135 | i, j, c: SysUInt; 136 | begin 137 | if (len = 0) then Exit; 138 | 139 | i := index div (SizeOf(SysUInt) * 8); 140 | j := index mod (SizeOf(SysUInt) * 8); 141 | c := (SizeOf(SysUInt) * 8) - j; 142 | 143 | Inc(Buf, i); 144 | 145 | if (c > len) then 146 | begin 147 | buf^ := buf^ or ((SysUInt(-1)) shr ((SizeOf(SysUInt) * 8) - len)) shl j; 148 | Exit; 149 | end 150 | else 151 | begin 152 | buf^ := buf^ or ((SysUInt(-1)) shr ((SizeOf(SysUInt) * 8) - c)) shl j; 153 | Inc(Buf); 154 | Dec(len, c); 155 | end; 156 | 157 | while (len >= (SizeOf(SysUInt) * 8)) do 158 | begin 159 | buf^ := SysUInt(-1); 160 | Inc(buf); 161 | Dec(len, SizeOf(SysUInt) * 8); 162 | end; 163 | 164 | if (len > 0) then 165 | buf^ := buf^ or ((SysUInt(-1)) shr ((SizeOf(SysUInt) * 8) - len)); 166 | end; 167 | 168 | procedure _ClearBits(buf: PSysUInt; index, len: SysUInt); 169 | var 170 | i, j, c: SysUInt; 171 | begin 172 | if (len = 0) then Exit; 173 | 174 | i := index div (SizeOf(SysUInt) * 8); 175 | j := index mod (SizeOf(SysUInt) * 8); 176 | c := (SizeOf(SysUInt) * 8) - j; 177 | 178 | Inc(Buf, i); 179 | 180 | if (c > len) then 181 | begin 182 | buf^ := buf^ and (not (((SysUInt(-1)) shr ((SizeOf(SysUInt) * 8) - len)) shl j)); 183 | Exit; 184 | end 185 | else 186 | begin 187 | buf^ := buf^ and (not (((SysUInt(-1)) shr ((SizeOf(SysUInt) * 8) - c)) shl j)); 188 | Inc(Buf); 189 | Dec(len, c); 190 | end; 191 | 192 | while (len >= (SizeOf(SysUInt) * 8)) do 193 | begin 194 | buf^ := SysUInt(-1); 195 | Inc(buf); 196 | Dec(len, SizeOf(SysUInt) * 8); 197 | end; 198 | 199 | if (len > 0) then 200 | buf^ := buf^ and ((SysUInt(-1)) shr len); 201 | end; 202 | 203 | function M_Node_Remain(r: TM_Node): SysUInt; 204 | begin 205 | Result := r.Size - r.Used; 206 | end; 207 | 208 | function M_PernamentNode_Available(r: TM_PernamentNode): SysUInt; 209 | begin 210 | Result := r.Size - r.Used; 211 | end; 212 | 213 | constructor TMemoryManagerPrivate.Create; 214 | begin 215 | inherited; 216 | 217 | FNewChunkSize := 65536; 218 | FNewChunkDensity := 64; 219 | FAllocated := 0; 220 | FUsed := 0; 221 | FRoot := nil; 222 | FFirst := nil; 223 | FOptimal := nil; 224 | FPernament := nil; 225 | end; 226 | 227 | class function TMemoryManagerPrivate.createNode(Size, Density: SysUInt): PM_Node; 228 | var 229 | vSize, Blocks, baSize, memSize: SysUInt; 230 | vMem: PUInt8; 231 | Node: PM_Node; 232 | begin 233 | vMem := PUInt8(TVirtualMemory.alloc(Size, @vSize, True)); 234 | 235 | if (vmem = nil) then 236 | begin 237 | Result := nil; 238 | Exit; 239 | end; 240 | 241 | blocks := (vSize div Density); 242 | basize := (((blocks + 7) shr 3) + SizeOf(SysUInt) - 1) and (not SysUInt(SizeOf(SysUInt)-1)); 243 | memSize := SizeOf(TM_Node) + (baSize * 2); 244 | 245 | GetMem(Node, memSize); 246 | 247 | if (Node = nil) then 248 | begin 249 | TVirtualMemory.FreeAddress(vMem, vSize); 250 | Result := nil; 251 | Exit; 252 | end; 253 | 254 | FillChar(Node^, memSize, 0); 255 | 256 | Node.nlColor := NODE_RED; 257 | Node.mem := vMem; 258 | 259 | Node.Size := vSize; 260 | Node.Blocks := Blocks; 261 | Node.Density := Density; 262 | Node.LargestBlock := vSize; 263 | Node.baUsed := PSysUInt( PtrUInt(PUInt8(Node)) + SizeOf(TM_Node) ); 264 | Node.baCont := PSysUInt( PtrUInt(PUInt8(Node.baUsed)) + basize ); 265 | 266 | Result := Node; 267 | end; 268 | 269 | function TMemoryManagerPrivate.allocPernament(vSize: SysUInt): Pointer; 270 | const 271 | pernamentAlignment: SysUInt = 32; 272 | pernamentNodeSize: SysUInt = 32768; 273 | var 274 | over, alignedSize, nodeSize: SysUInt; 275 | Locked: TAutoLock; 276 | node: PM_PernamentNode; 277 | Res: PUInt8; 278 | begin 279 | over := vsize mod pernamentAlignment; 280 | if (over > 0) then over := pernamentAlignment - over; 281 | alignedSize := vsize + over; 282 | 283 | locked := TAutoLock.Create(FLock); 284 | try 285 | node := FPernament; 286 | 287 | while ((node <> nil) and (alignedSize > M_PernamentNode_Available(node^))) do node := node.prev; 288 | 289 | if (node = nil) then 290 | begin 291 | nodeSize := pernamentNodeSize; 292 | if (vsize > nodeSize) then nodeSize := vsize; 293 | 294 | //GetMem(Node, SizeOf(TM_PernamentNode)); 295 | New(node); 296 | if (node = nil) then 297 | begin 298 | Result := nil; 299 | Exit; 300 | end; 301 | 302 | node.mem := PUInt8(TVirtualMemory.alloc(nodeSize, @node.size, True)); 303 | if (node.mem = nil) then 304 | begin 305 | FreeMem(node); 306 | Result := nil; 307 | Exit; 308 | end; 309 | 310 | node.used := 0; 311 | node.prev := FPernament; 312 | FPernament := node; 313 | end; 314 | 315 | Res := PUInt8(PtrUInt(node.mem) + node.used); 316 | node.used := node.used + alignedSize; 317 | FUsed := FUsed + alignedSize; 318 | 319 | Result := Pointer(Res); 320 | finally 321 | locked.Free; 322 | end; 323 | end; 324 | 325 | function TMemoryManagerPrivate.allocFreeable(vSize: SysUInt): Pointer; 326 | var 327 | i, Need, minVSize, uBits, Bit, Blocks, Cont, maxCont, j, Max, chunkSize, u: SysUInt; 328 | Locked: TAutoLock; 329 | Node, Next: PM_Node; 330 | up: PSysUInt; 331 | Res: PUInt8; 332 | label 333 | found; 334 | begin 335 | vSize := (vSize + 31) and (not SysUInt(31)); 336 | if (vsize = 0) then 337 | begin 338 | Result := nil; 339 | Exit; 340 | end; 341 | 342 | locked := TAutoLock.Create(FLock); 343 | try 344 | Node := FOptimal; 345 | 346 | minVSize := FNewChunkSize; 347 | 348 | while (node <> nil) do 349 | begin 350 | if ((M_Node_Remain(node^) < vsize) or 351 | ((node.largestBlock < vsize) and (node.largestBlock <> 0))) then 352 | begin 353 | Next := node.next; 354 | if ((M_Node_Remain(node^) < minVSize) and (node = FOptimal) and (Next <> nil)) then FOptimal := Next; 355 | Node := Next; 356 | Continue; 357 | end; 358 | 359 | up := node.baUsed; 360 | blocks := node.blocks; 361 | cont := 0; 362 | maxCont := 0; 363 | 364 | need := (vsize + node.density - 1) div node.density; 365 | i := 0; 366 | 367 | while (i < blocks) do 368 | begin 369 | ubits := up^; 370 | Inc(up); 371 | 372 | if (ubits = SysUInt(-1)) then 373 | begin 374 | if (cont > maxCont) then maxCont := cont; 375 | cont := 0; 376 | 377 | Inc(i, BITS_PER_ENTITY); 378 | Continue; 379 | end; 380 | 381 | max := BITS_PER_ENTITY; 382 | if (i + max > blocks) then max := blocks - i; 383 | 384 | 385 | bit := 1; 386 | for j := 1 to max do 387 | begin 388 | if ((ubits and bit) = 0) then 389 | begin 390 | Inc(cont); 391 | if (cont = need) then 392 | begin 393 | Inc(i, j); 394 | Dec(i, cont); 395 | goto found; 396 | end; 397 | Continue; 398 | end; 399 | 400 | if (cont > maxCont) then maxCont := cont; 401 | cont := 0; 402 | bit := bit shl 1; 403 | end; 404 | 405 | Inc(i, BITS_PER_ENTITY); 406 | end; 407 | 408 | node.largestBlock := maxCont * node.density; 409 | node := node.next; 410 | end; 411 | 412 | chunkSize := FNewChunkSize; 413 | if (chunkSize < vsize) then 414 | chunkSize := vsize; 415 | 416 | node := createNode(chunkSize, FNewChunkDensity); 417 | if (node = nil) then 418 | begin 419 | Result := nil; 420 | Exit; 421 | end; 422 | 423 | node.prev := FLast; 424 | 425 | if (FFirst = nil) then 426 | begin 427 | FFirst := node; 428 | FLast := node; 429 | FOptimal := node; 430 | end 431 | else 432 | begin 433 | node.prev := FLast; 434 | FLast.next := node; 435 | FLast := node; 436 | end; 437 | 438 | nlInsertNode(node); 439 | 440 | i := 0; 441 | need := (vsize + node.density - 1) div node.density; 442 | 443 | FAllocated := FAllocated + node.size; 444 | 445 | found: 446 | _SetBits(node.baUsed, i, need); 447 | _SetBits(node.baCont, i, need-1); 448 | 449 | u := need * node.density; 450 | Inc(node.used, u); 451 | node.largestBlock := 0; 452 | Inc(FUsed, u); 453 | 454 | Res := PUInt8(PtrUInt(node.mem) + (i * node.density)); 455 | Assert((PtrUInt(Res) >= PtrUInt(node.mem)) and (PtrUInt(Res) < (PtrUInt(node.mem) + node.size))); 456 | Result := Res; 457 | finally 458 | locked.Free; 459 | end; 460 | end; 461 | 462 | function TMemoryManagerPrivate.FreeAddress(Address: Pointer): Boolean; 463 | var 464 | locked: TAutoLock; 465 | node, cur, next, prev: PM_Node; 466 | offset, bitPos, i, j, uBits, cBits, bit, cont: SysUInt; 467 | up, cp: PSysUInt; 468 | Stop: Boolean; 469 | begin 470 | if (address = nil) then 471 | begin 472 | Result := True; 473 | Exit; 474 | end; 475 | 476 | locked := TAutoLock.Create(FLock); 477 | try 478 | node := nlFindPtr(PUInt8(Address)); 479 | if (node = nil) then 480 | begin 481 | Result := False; 482 | Exit; 483 | end; 484 | 485 | offset := SysUInt(PtrUInt(address) - PtrUInt(node.mem)); 486 | bitpos := offset div node.density; 487 | i := (bitpos div BITS_PER_ENTITY); 488 | j := (bitpos mod BITS_PER_ENTITY); 489 | 490 | up := PSysUInt(PtrUInt(node.baUsed) + i); 491 | cp := PSysUInt(PtrUInt(node.baCont) + i); 492 | ubits := up^; 493 | cbits := cp^; 494 | bit := SysUInt(1) shl j; 495 | cont := 0; 496 | 497 | while True do 498 | begin 499 | Stop := (cbits and bit) = 0; 500 | ubits := ubits and not bit; 501 | cbits := cbits and not bit; 502 | 503 | Inc(j); 504 | bit := bit shl 1; 505 | Inc(cont); 506 | 507 | if (Stop or (j = BITS_PER_ENTITY)) then 508 | begin 509 | up^ := ubits; 510 | cp^ := cbits; 511 | 512 | if (Stop) then 513 | Break; 514 | 515 | Inc(up); 516 | Inc(cp); 517 | ubits := up^; 518 | cbits := cp^; 519 | 520 | j := 0; 521 | bit := 1; 522 | end; 523 | end; 524 | 525 | if (node.used = node.size) then 526 | begin 527 | cur := FOptimal; 528 | 529 | repeat 530 | cur := cur.prev; 531 | if (cur = node) then 532 | begin 533 | FOptimal := node; 534 | Break; 535 | end; 536 | until (cur = nil); 537 | end; 538 | 539 | cont := cont * node.density; 540 | if (node.largestBlock < cont) then 541 | node.largestBlock := cont; 542 | Dec(node.used, cont); 543 | Dec(FUsed, cont); 544 | 545 | if (node.used = 0) then 546 | begin 547 | Dec(FAllocated, node.size); 548 | nlRemoveNode(node); 549 | TVirtualMemory.FreeAddress(node.mem, node.size); 550 | 551 | next := node.next; 552 | prev := node.prev; 553 | 554 | if (prev <> nil) then 555 | prev.next := next 556 | else 557 | FFirst := next; 558 | if (next <> nil) then 559 | next.prev := prev 560 | else 561 | FLast := prev; 562 | if (FOptimal = node) then 563 | if (prev <> nil) then 564 | FOptimal := prev 565 | else 566 | FOptimal := next; 567 | 568 | FreeMem(node); 569 | end; 570 | 571 | Result := True; 572 | finally 573 | locked.Free; 574 | end; 575 | end; 576 | 577 | class function TMemoryManagerPrivate.nlIsRed(n: PM_Node): Boolean; 578 | begin 579 | Result := (n <> nil) and (n.nlColor = NODE_RED); 580 | end; 581 | 582 | class function TMemoryManagerPrivate.nlRotateLeft(n: PM_Node): PM_Node; 583 | var 584 | x: PM_Node; 585 | begin 586 | x := n.nlRight; 587 | n.nlRight := x.nlLeft; 588 | x.nlLeft := n; 589 | x.nlColor := x.nlLeft.nlColor; 590 | x.nlLeft.nlColor := NODE_RED; 591 | Result := x; 592 | end; 593 | 594 | class function TMemoryManagerPrivate.nlRotateRight(n: PM_Node): PM_Node; 595 | var 596 | x: PM_Node; 597 | begin 598 | x := n.nlLeft; 599 | n.nlLeft := x.nlRight; 600 | x.nlRight := n; 601 | x.nlColor := x.nlRight.nlColor; 602 | x.nlRight.nlColor := NODE_RED; 603 | Result := x; 604 | end; 605 | 606 | class procedure TMemoryManagerPrivate.nlFlipColor(n: PM_Node); 607 | begin 608 | n.nlColor := not n.nlColor; 609 | n.nlLeft.nlColor := not n.nlLeft.nlColor; 610 | n.nlRight.nlColor := not n.nlRight.nlColor; 611 | end; 612 | 613 | class function TMemoryManagerPrivate.nlMoveRedLeft(h: PM_Node): PM_Node; 614 | begin 615 | nlFlipColor(h); 616 | if (nlIsRed(h.nlRight.nlLeft)) then 617 | begin 618 | h.nlRight := nlRotateRight(h.nlRight); 619 | h := nlRotateLeft(h); 620 | nlFlipColor(h); 621 | end; 622 | Result := h; 623 | end; 624 | 625 | class function TMemoryManagerPrivate.nlMoveRedRight(h: PM_Node): PM_Node; 626 | begin 627 | nlFlipColor(h); 628 | if (nlIsRed(h.nlLeft.nlLeft)) then 629 | begin 630 | h := nlRotateRight(h); 631 | nlFlipColor(h); 632 | end; 633 | Result := h; 634 | end; 635 | 636 | class function TMemoryManagerPrivate.nlFixUp(h: PM_Node): PM_Node; 637 | begin 638 | if (nlIsRed(h.nlRight)) then 639 | h := nlRotateLeft(h); 640 | if (nlIsRed(h.nlLeft) and nlIsRed(h.nlLeft.nlLeft)) then 641 | h := nlRotateRight(h); 642 | if (nlIsRed(h.nlLeft) and nlIsRed(h.nlRight)) then 643 | nlFlipColor(h); 644 | 645 | Result := h; 646 | end; 647 | 648 | procedure TMemoryManagerPrivate.nlInsertNode(n: PM_Node); 649 | begin 650 | FRoot := nlInsertNode_(FRoot, n); 651 | end; 652 | 653 | function TMemoryManagerPrivate.nlInsertNode_(h, n: PM_Node): PM_Node; 654 | begin 655 | if (h = nil) then 656 | begin 657 | Result := n; 658 | Exit; 659 | end; 660 | 661 | if (nlIsRed(h.nlLeft) and nlIsRed(h.nlRight)) then nlFlipColor(h); 662 | 663 | if (PtrUInt(n.mem) < PtrUInt(h.mem)) then 664 | h.nlLeft := nlInsertNode_(h.nlLeft, n) 665 | else 666 | h.nlRight := nlInsertNode_(h.nlRight, n); 667 | 668 | if (nlIsRed(h.nlRight) and not nlIsRed(h.nlLeft)) then h := nlRotateLeft(h); 669 | if (nlIsRed(h.nlLeft) and nlIsRed(h.nlLeft.nlLeft)) then h := nlRotateRight(h); 670 | 671 | Result := h; 672 | end; 673 | 674 | procedure TMemoryManagerPrivate.nlRemoveNode(n: PM_Node); 675 | begin 676 | FRoot := nlRemoveNode_(FRoot, n); 677 | if (FRoot <> nil) then FRoot.nlColor := NODE_BLACK; 678 | 679 | Assert(nlFindPtr(n.mem) = nil); 680 | end; 681 | 682 | function findParent(root, n: PM_Node): PM_Node; 683 | var 684 | Parent, Cur: PM_Node; 685 | Mem, curMem, curEnd: PUInt8; 686 | begin 687 | parent := nil; 688 | cur := root; 689 | mem := n.mem; 690 | 691 | while (cur <> nil) do 692 | begin 693 | curMem := cur.mem; 694 | if (PtrUInt(mem) < PtrUInt(curMem)) then 695 | begin 696 | parent := cur; 697 | cur := cur.nlLeft; 698 | Continue; 699 | end 700 | else 701 | begin 702 | curEnd := PUInt8(PtrUInt(curMem) + cur.size); 703 | if (PtrUInt(mem) >= PtrUInt(curEnd)) then 704 | begin 705 | parent := cur; 706 | cur := cur.nlRight; 707 | Continue; 708 | end; 709 | Result := Parent; 710 | Exit; 711 | end; 712 | end; 713 | 714 | Result := nil; 715 | end; 716 | 717 | function TMemoryManagerPrivate.nlRemoveNode_(h, n: PM_Node): PM_Node; 718 | var 719 | _l, _r: PM_Node; 720 | begin 721 | if (PtrUInt(n.mem) < PtrUInt(h.mem)) then 722 | begin 723 | if ((not nlIsRed(h.nlLeft)) and (not nlIsRed(h.nlLeft.nlLeft))) then 724 | h := nlMoveRedLeft(h); 725 | h.nlLeft := nlRemoveNode_(h.nlLeft, n); 726 | end 727 | else 728 | begin 729 | if (nlIsRed(h.nlLeft)) then 730 | h := nlRotateRight(h); 731 | if ((h = n) and (h.nlRight = nil)) then 732 | begin 733 | Result := nil; 734 | Exit; 735 | end; 736 | if ((not nlIsRed(h.nlRight)) and (not nlIsRed(h.nlRight.nlLeft))) then 737 | h := nlMoveRedRight(h); 738 | if (h = n) then 739 | begin 740 | h := n.nlRight; 741 | while (h.nlLeft <> nil) do h := h.nlLeft; 742 | 743 | _l := n.nlLeft; 744 | _r := nlRemoveMin(n.nlRight); 745 | 746 | h.nlLeft := _l; 747 | h.nlRight := _r; 748 | h.nlColor := n.nlColor; 749 | end 750 | else 751 | h.nlRight := nlRemoveNode_(h.nlRight, n); 752 | end; 753 | 754 | Result := nlFixUp(h); 755 | end; 756 | 757 | function TMemoryManagerPrivate.nlRemoveMin(h: PM_Node): PM_Node; 758 | begin 759 | if (h.nlLeft = nil) then 760 | begin 761 | Result := nil; 762 | Exit; 763 | end; 764 | if ((not nlIsRed(h.nlLeft)) and (not nlIsRed(h.nlLeft.nlLeft))) then 765 | h := nlMoveRedLeft(h); 766 | h.nlLeft := nlRemoveMin(h.nlLeft); 767 | Result := nlFixUp(h); 768 | end; 769 | 770 | function TMemoryManagerPrivate.nlFindPtr(mem: PUInt8): PM_Node; 771 | var 772 | curMem, curEnd: PUInt8; 773 | cur: PM_Node; 774 | begin 775 | cur := FRoot; 776 | 777 | while (cur <> nil) do 778 | begin 779 | curMem := cur.mem; 780 | if (PtrUInt(mem) < PtrUInt(curMem)) then 781 | begin 782 | cur := cur.nlLeft; 783 | Continue; 784 | end 785 | else 786 | begin 787 | curEnd := PUInt8(PtrUInt(curMem) + cur.size); 788 | if (PtrUInt(mem) >= PtrUInt(curEnd)) then 789 | begin 790 | cur := cur.nlRight; 791 | Continue; 792 | end; 793 | Result := cur; 794 | Exit; 795 | end; 796 | end; 797 | 798 | Result := nil; 799 | end; 800 | 801 | {$J+} 802 | class function TMemoryManager.Global: TMemoryManager; 803 | const 804 | memmgr: Pointer = nil; 805 | begin 806 | if (memmgr = nil) then 807 | memmgr := TDefaultMemoryManager.Create; 808 | Result := memmgr; 809 | end; 810 | 811 | constructor TDefaultMemoryManager.Create; 812 | begin 813 | inherited; 814 | 815 | Fd := TMemoryManagerPrivate.Create; 816 | end; 817 | 818 | destructor TDefaultMemoryManager.Destroy; 819 | begin 820 | TMemoryManagerPrivate(Fd).Free; 821 | inherited; 822 | end; 823 | 824 | function TDefaultMemoryManager.Alloc(Size: SysUInt; Typ: UInt32 = MEMORY_ALLOC_FREEABLE): Pointer; 825 | begin 826 | if (Typ = MEMORY_ALLOC_PERNAMENT) then 827 | Result := TMemoryManagerPrivate(Fd).AllocPernament(Size) 828 | else 829 | Result := TMemoryManagerPrivate(Fd).AllocFreeable(Size); 830 | end; 831 | 832 | function TDefaultMemoryManager.FreeAddress(Address: Pointer): Boolean; 833 | begin 834 | Result := TMemoryManagerPrivate(Fd).FreeAddress(Address); 835 | end; 836 | 837 | function TDefaultMemoryManager.Used: SysUInt; 838 | begin 839 | Result := TMemoryManagerPrivate(Fd).FUsed; 840 | end; 841 | 842 | function TDefaultMemoryManager.Allocated: SysUInt; 843 | begin 844 | Result := TMemoryManagerPrivate(Fd).FAllocated; 845 | end; 846 | 847 | initialization 848 | finalization 849 | TMemoryManager.Global.Free; 850 | 851 | end. 852 | -------------------------------------------------------------------------------- /DAsmJit_Util.pas: -------------------------------------------------------------------------------- 1 | unit DAsmJit_Util; 2 | 3 | {$I DAsmJit.inc} 4 | 5 | interface 6 | 7 | uses 8 | DAsmJit; 9 | 10 | type 11 | _DontInitialize = record end; 12 | _Initialize = record end; 13 | 14 | var 15 | _Init: _Initialize; 16 | _DontInit: _DontInitialize; 17 | 18 | type 19 | TI32FPUnion = record 20 | case Integer of 21 | 0: (i: Int32); 22 | 1: (f: Single); 23 | end; 24 | 25 | TI64FPUnion = record 26 | case Integer of 27 | 0: (i: Int64); 28 | 1: (f: Double); 29 | end; 30 | 31 | TMMData = record 32 | case Integer of 33 | 0: (sb: array[0..7] of Int8); 34 | 1: (ub: array[0..7] of UInt8); 35 | 2: (sw: array[0..3] of Int16); 36 | 3: (uw: array[0..3] of UInt16); 37 | 4: (sd: array[0..1] of Int32); 38 | 5: (ud: array[0..1] of UInt32); 39 | 6: (sq: array[0..0] of Int64); 40 | 7: (uq: array[0..0] of UInt64); 41 | 8: (sf: array[0..1] of Single); 42 | end; 43 | 44 | TXMMData = record 45 | case Integer of 46 | 0: (sb: array[0..15] of Int8); 47 | 1: (ub: array[0..15] of UInt8); 48 | 2: (sw: array[0..7] of Int16); 49 | 3: (uw: array[0..7] of UInt16); 50 | 4: (sd: array[0..3] of Int32); 51 | 5: (ud: array[0..3] of UInt32); 52 | 6: (sq: array[0..1] of Int64); 53 | 7: (uq: array[0..1] of UInt64); 54 | 8: (sf: array[0..3] of Single); 55 | 9: (df: array[0..1] of Double); 56 | end; 57 | 58 | TBuffer = class 59 | protected 60 | FData: PUInt8; 61 | FCur: PUInt8; 62 | FMax: PUInt8; 63 | FCapacity: SysInt; 64 | FGrowThreshold: SysInt; 65 | public 66 | constructor Create(growThreshold: SysInt = 16); 67 | destructor Destroy; override; 68 | 69 | function offset: SysInt; 70 | function ensureSpace: Boolean; 71 | function toOffset(o: SysInt): SysInt; 72 | function realloc(t: SysInt): Boolean; 73 | function grow: Boolean; 74 | procedure clear; 75 | procedure DoFree; 76 | function take: PUInt8; 77 | procedure emitByte(x: UInt8); 78 | procedure emitWord(x: UInt16); 79 | procedure emitDWord(x: UInt32); 80 | procedure emitQWord(x: UInt64); 81 | procedure emitSysInt(x: SysInt); 82 | procedure emitSysUInt(x: SysUInt); 83 | procedure emitData(ptr: Pointer; len: SysUInt); 84 | 85 | function getByteAt(pos: SysInt): UInt8; 86 | function getWordAt(pos: SysInt): UInt16; 87 | function getDWordAt(pos: SysInt): UInt32; 88 | function getQWordAt(pos: SysInt): UInt64; 89 | procedure setByteAt(pos: SysInt; x: UInt8); 90 | procedure setWordAt(pos: SysInt; x: UInt16); 91 | procedure setDWordAt(pos: SysInt; x: UInt32); 92 | procedure setQWordAt(pos: SysInt; x: UInt64); 93 | 94 | property Data: PUInt8 read FData; 95 | property Cur: PUInt8 read FCur; 96 | property Maximum: PUInt8 read FMax; 97 | property Capacity: SysInt read FCapacity; 98 | property GrowThreshold: SysInt read FGrowThreshold; 99 | end; 100 | 101 | TPodVector = class 102 | protected 103 | FData: Pointer; 104 | FLength: SysUInt; 105 | FCapacity: SysUInt; 106 | 107 | function GetIndex(Index: SysUInt): Pointer; 108 | procedure SetIndex(Index: SysUInt; Val: Pointer); 109 | function _grow: Boolean; 110 | function _realloc(t: SysUInt): Boolean; 111 | public 112 | constructor Create; 113 | destructor Destroy; override; 114 | 115 | procedure clear; 116 | procedure DoFree; 117 | function prepend(Item: Pointer): Boolean; 118 | function insert(index: SysUInt; Item: Pointer): Boolean; 119 | function append(Item: Pointer): Boolean; 120 | function indexOf(Val: Pointer): SysUInt; 121 | procedure removeAt(i: SysUInt); 122 | procedure swap(Other: TPodVector); 123 | 124 | property Data: Pointer read FData; 125 | property Length: SysUInt read FLength; 126 | property Capacity: SysUInt read FCapacity; 127 | property Items[Index: SysUInt]: Pointer read GetIndex write SetIndex; default; 128 | end; 129 | 130 | (*PChunk = ^TChunk; 131 | TChunk = record 132 | Prev: PChunk; 133 | Pos: SysUInt; 134 | Size: SysUInt; 135 | Data: array[0..0] of UInt8; 136 | function Remain: SysUInt; 137 | end; 138 | 139 | TZone = class 140 | protected 141 | FChunks: PChunk; 142 | FTotal: SysUInt; 143 | FChunkSize: SysUInt; 144 | public 145 | constructor Create(ChunkSize: SysUInt); 146 | destructor Destroy; override; 147 | 148 | function alloc(size: SysUInt): Pointer; 149 | procedure clear; 150 | procedure freeAll; 151 | 152 | property Total: SysUInt read FTotal; 153 | property ChunkSize: SysUInt read FChunkSize; 154 | end;*) 155 | 156 | procedure MMData_set_sb(var r: TMMData; x0, x1, x2, x3, x4, x5, x6, x7: Int8); 157 | procedure MMData_set_ub(var r: TMMData; x0, x1, x2, x3, x4, x5, x6, x7: UInt8); 158 | procedure MMData_set_sw(var r: TMMData; x0, x1, x2, x3: Int16); 159 | procedure MMData_set_uw(var r: TMMData; x0, x1, x2, x3: UInt16); 160 | procedure MMData_set_sd(var r: TMMData; x0, x1: Int32); 161 | procedure MMData_set_ud(var r: TMMData; x0, x1: UInt32); 162 | procedure MMData_set_sq(var r: TMMData; x0: Int64); 163 | procedure MMData_set_uq(var r: TMMData; x0: UInt64); 164 | procedure MMData_set_sf(var r: TMMData; x0, x1: Single); 165 | 166 | procedure XMMData_set_sb(var r: TXMMData; x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15: Int8); 167 | procedure XMMData_set_ub(var r: TXMMData; x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15: UInt8); 168 | procedure XMMData_set_sw(var r: TXMMData; x0, x1, x2, x3, x4, x5, x6, x7: Int16); 169 | procedure XMMData_set_uw(var r: TXMMData; x0, x1, x2, x3, x4, x5, x6, x7: UInt16); 170 | procedure XMMData_set_sd(var r: TXMMData; x0, x1, x2, x3: Int32); 171 | procedure XMMData_set_ud(var r: TXMMData; x0, x1, x2, x3: UInt32); 172 | procedure XMMData_set_sq(var r: TXMMData; x0, x1: Int64); 173 | procedure XMMData_set_uq(var r: TXMMData; x0, x1: UInt64); 174 | procedure XMMData_set_sf(var r: TXMMData; x0, x1, x2, x3: Single); 175 | procedure XMMData_set_df(var r: TXMMData; x0, x1: Single); 176 | 177 | function isInt8(x: SysInt): Boolean; inline; 178 | function isUInt8(x: SysInt): Boolean; inline; 179 | function isInt16(x: SysInt): Boolean; inline; 180 | function isUInt16(x: SysInt): Boolean; inline; 181 | function isInt32(x: SysInt): Boolean; inline; 182 | function isUInt32(x: SysInt): Boolean; inline; 183 | 184 | function int32AsFloat(i: Int32): Single; inline; 185 | function floatAsInt32(f: Single): Int32; inline; 186 | function int64AsDouble(i: Int64): Double; inline; 187 | function doubleAsInt32(f: Double): Int64; inline; 188 | 189 | implementation 190 | 191 | function isInt8(x: SysInt): Boolean; inline; 192 | begin 193 | Result := (x >= -128) and (x <= 127); 194 | end; 195 | 196 | function isUInt8(x: SysInt): Boolean; inline; 197 | begin 198 | Result := (x >= 0) and (x <= 255); 199 | end; 200 | 201 | function isInt16(x: SysInt): Boolean; inline; 202 | begin 203 | Result := (x >= -32768) and (x <= 32767); 204 | end; 205 | 206 | function isUInt16(x: SysInt): Boolean; inline; 207 | begin 208 | Result := (x >= 0) and (x <= 65535); 209 | end; 210 | 211 | function isInt32(x: SysInt): Boolean; inline; 212 | begin 213 | {$IFDEF ASMJIT_X86} 214 | Result := True; 215 | {$ELSE} 216 | Result := (x >= Int64(-2147483648)) and (x <= Int64(2147483647)); 217 | {$ENDIF} 218 | end; 219 | 220 | function isUInt32(x: SysInt): Boolean; inline; 221 | begin 222 | {$IFDEF ASMJIT_X86} 223 | Result := (x >= 0); 224 | {$ELSE} 225 | Result := (x >= 0) and (x <= Int64(4294967295)); 226 | {$ENDIF} 227 | end; 228 | 229 | function int32AsFloat(i: Int32): Single; inline; 230 | var 231 | u: TI32FPUnion; 232 | begin 233 | u.i := i; 234 | Result := u.f; 235 | end; 236 | 237 | function floatAsInt32(f: Single): Int32; inline; 238 | var 239 | u: TI32FPUnion; 240 | begin 241 | u.f := f; 242 | Result := u.i; 243 | end; 244 | 245 | function int64AsDouble(i: Int64): Double; inline; 246 | var 247 | u: TI64FPUnion; 248 | begin 249 | u.i := i; 250 | Result := u.f; 251 | end; 252 | 253 | function doubleAsInt32(f: Double): Int64; inline; 254 | var 255 | u: TI64FPUnion; 256 | begin 257 | u.f := f; 258 | Result := u.i; 259 | end; 260 | 261 | procedure MMData_set_sb(var r: TMMData; x0, x1, x2, x3, x4, x5, x6, x7: Int8); 262 | begin 263 | with r do begin 264 | sb[0] := x0; sb[1] := x1; sb[2] := x2; sb[3] := x3; sb[4] := x4; sb[5] := x5; sb[6] := x6; sb[7] := x7; 265 | end; 266 | end; 267 | 268 | procedure MMData_set_ub(var r: TMMData; x0, x1, x2, x3, x4, x5, x6, x7: UInt8); 269 | begin 270 | with r do begin 271 | ub[0] := x0; ub[1] := x1; ub[2] := x2; ub[3] := x3; ub[4] := x4; ub[5] := x5; ub[6] := x6; ub[7] := x7; 272 | end; 273 | end; 274 | 275 | procedure MMData_set_sw(var r: TMMData; x0, x1, x2, x3: Int16); 276 | begin 277 | with r do begin 278 | sw[0] := x0; sw[1] := x1; sw[2] := x2; sw[3] := x3; 279 | end; 280 | end; 281 | 282 | procedure MMData_set_uw(var r: TMMData; x0, x1, x2, x3: UInt16); 283 | begin 284 | with r do begin 285 | uw[0] := x0; uw[1] := x1; uw[2] := x2; uw[3] := x3; 286 | end; 287 | end; 288 | 289 | procedure MMData_set_sd(var r: TMMData; x0, x1: Int32); 290 | begin 291 | with r do begin 292 | sd[0] := x0; sd[1] := x1; 293 | end; 294 | end; 295 | 296 | procedure MMData_set_ud(var r: TMMData; x0, x1: UInt32); 297 | begin 298 | with r do begin 299 | ud[0] := x0; ud[1] := x1; 300 | end; 301 | end; 302 | 303 | procedure MMData_set_sq(var r: TMMData; x0: Int64); 304 | begin 305 | with r do begin 306 | sq[0] := x0; 307 | end; 308 | end; 309 | 310 | procedure MMData_set_uq(var r: TMMData; x0: UInt64); 311 | begin 312 | with r do begin 313 | uq[0] := x0; 314 | end; 315 | end; 316 | 317 | procedure MMData_set_sf(var r: TMMData; x0, x1: Single); 318 | begin 319 | with r do begin 320 | sf[0] := x0; sf[1] := x1; 321 | end; 322 | end; 323 | 324 | procedure XMMData_set_sb(var r: TXMMData; x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15: Int8); 325 | begin 326 | with r do begin 327 | sb[0] := x0; sb[1] := x1; sb[2] := x2; sb[3] := x3; sb[4] := x4; sb[5] := x5; sb[6] := x6; sb[7] := x7; 328 | sb[8] := x8; sb[9] := x9; sb[10] := x10; sb[11] := x11; sb[12] := x12; sb[13] := x13; sb[14] := x14; sb[15] := x15; 329 | end; 330 | end; 331 | 332 | procedure XMMData_set_ub(var r: TXMMData; x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15: UInt8); 333 | begin 334 | with r do begin 335 | ub[0] := x0; ub[1] := x1; ub[2] := x2; ub[3] := x3; ub[4] := x4; ub[5] := x5; ub[6] := x6; ub[7] := x7; 336 | ub[8] := x8; ub[9] := x9; ub[10] := x10; ub[11] := x11; ub[12] := x12; ub[13] := x13; ub[14] := x14; ub[15] := x15; 337 | end; 338 | end; 339 | 340 | procedure XMMData_set_sw(var r: TXMMData; x0, x1, x2, x3, x4, x5, x6, x7: Int16); 341 | begin 342 | with r do begin 343 | sw[0] := x0; sw[1] := x1; sw[2] := x2; sw[3] := x3; sw[4] := x4; sw[5] := x5; sw[6] := x6; sw[7] := x7; 344 | end; 345 | end; 346 | 347 | procedure XMMData_set_uw(var r: TXMMData; x0, x1, x2, x3, x4, x5, x6, x7: UInt16); 348 | begin 349 | with r do begin 350 | uw[0] := x0; uw[1] := x1; uw[2] := x2; uw[3] := x3; uw[4] := x4; uw[5] := x5; uw[6] := x6; uw[7] := x7; 351 | end; 352 | end; 353 | 354 | procedure XMMData_set_sd(var r: TXMMData; x0, x1, x2, x3: Int32); 355 | begin 356 | with r do begin 357 | sd[0] := x0; sd[1] := x1; sd[2] := x2; sd[3] := x3; 358 | end; 359 | end; 360 | 361 | procedure XMMData_set_ud(var r: TXMMData; x0, x1, x2, x3: UInt32); 362 | begin 363 | with r do begin 364 | ud[0] := x0; ud[1] := x1; ud[2] := x2; ud[3] := x3; 365 | end; 366 | end; 367 | 368 | procedure XMMData_set_sq(var r: TXMMData; x0, x1: Int64); 369 | begin 370 | with r do begin 371 | sq[0] := x0; sq[1] := x1; 372 | end; 373 | end; 374 | 375 | procedure XMMData_set_uq(var r: TXMMData; x0, x1: UInt64); 376 | begin 377 | with r do begin 378 | uq[0] := x0; uq[1] := x1; 379 | end; 380 | end; 381 | 382 | procedure XMMData_set_sf(var r: TXMMData; x0, x1, x2, x3: Single); 383 | begin 384 | with r do begin 385 | sf[0] := x0; sf[1] := x1; sf[2] := x2; sf[3] := x3; 386 | end; 387 | end; 388 | 389 | procedure XMMData_set_df(var r: TXMMData; x0, x1: Single); 390 | begin 391 | with r do begin 392 | df[0] := x0; df[1] := x1; 393 | end; 394 | end; 395 | 396 | constructor TBuffer.Create(GrowThreshold: SysInt = 16); 397 | begin 398 | inherited Create; 399 | 400 | FGrowThreshold := GrowThreshold; 401 | FData := nil; 402 | FCur := nil; 403 | FMax := nil; 404 | FCapacity := 0; 405 | end; 406 | 407 | destructor TBuffer.Destroy; 408 | begin 409 | if (FData <> nil) then 410 | FreeMem(FData); 411 | 412 | inherited; 413 | end; 414 | 415 | {function TBuffer.data: PUInt8; 416 | begin 417 | Result := FData; 418 | end; 419 | 420 | function TBuffer.cur: PUInt8; 421 | begin 422 | Result := FCur; 423 | end; 424 | 425 | function TBuffer.Maximum: PUInt8; 426 | begin 427 | Result := FMax; 428 | end; 429 | 430 | function TBuffer.capacity: SysInt; 431 | begin 432 | Result := FCapacity; 433 | end; 434 | 435 | function TBuffer.GrowThreshold: SysInt; 436 | begin 437 | Result := FGrowThreshold; 438 | end;} 439 | 440 | function TBuffer.offset: SysInt; 441 | begin 442 | Result := SysInt(PtrInt(FCur) - PtrInt(FData)); 443 | end; 444 | 445 | function TBuffer.ensureSpace: Boolean; 446 | begin 447 | if (PtrInt(FCur) >= PtrInt(FMax)) then 448 | Result := Grow 449 | else 450 | Result := True; 451 | end; 452 | 453 | function TBuffer.toOffset(o: SysInt): SysInt; 454 | var 455 | Prev: SysInt; 456 | begin 457 | Assert(o < FCapacity); 458 | 459 | prev := SysInt(PtrInt(FCur) - PtrInt(FData)); 460 | FCur := PUInt8(PtrInt(FData) + o); 461 | Result := Prev; 462 | end; 463 | 464 | procedure TBuffer.emitByte(x: UInt8); 465 | begin 466 | FCur^ := x; 467 | Inc(FCur); 468 | end; 469 | 470 | procedure TBuffer.emitWord(x: UInt16); 471 | begin 472 | PUInt16(FCur)^ := x; 473 | Inc(FCur, 2); 474 | end; 475 | 476 | procedure TBuffer.emitDWord(x: UInt32); 477 | begin 478 | PUInt32(FCur)^ := x; 479 | Inc(FCur, 4); 480 | end; 481 | 482 | procedure TBuffer.emitQWord(x: UInt64); 483 | begin 484 | PUInt64(FCur)^ := x; 485 | Inc(FCur, 8); 486 | end; 487 | 488 | procedure TBuffer.emitSysInt(x: SysInt); 489 | begin 490 | PSysInt(FCur)^ := x; 491 | Inc(FCur, SizeOf(SysInt)); 492 | end; 493 | 494 | procedure TBuffer.emitSysUInt(x: SysUInt); 495 | begin 496 | PSysUInt(FCur)^ := x; 497 | Inc(FCur, SizeOf(SysUInt)); 498 | end; 499 | 500 | function TBuffer.getByteAt(pos: SysInt): UInt8; 501 | begin 502 | Result := PUInt8(PtrInt(FData) + pos)^; 503 | end; 504 | 505 | function TBuffer.getWordAt(pos: SysInt): UInt16; 506 | begin 507 | Result := PUInt16(PtrInt(FData) + pos)^; 508 | end; 509 | 510 | function TBuffer.getDWordAt(pos: SysInt): UInt32; 511 | begin 512 | Result := PUInt32(PtrInt(FData) + pos)^; 513 | end; 514 | 515 | function TBuffer.getQWordAt(pos: SysInt): UInt64; 516 | begin 517 | Result := PUInt64(PtrInt(FData) + pos)^; 518 | end; 519 | 520 | procedure TBuffer.setByteAt(pos: SysInt; x: UInt8); 521 | begin 522 | PUInt8(PtrInt(FData) + pos)^ := x; 523 | end; 524 | 525 | procedure TBuffer.setWordAt(pos: SysInt; x: UInt16); 526 | begin 527 | PUInt16(PtrInt(FData) + pos)^ := x; 528 | end; 529 | 530 | procedure TBuffer.setDWordAt(pos: SysInt; x: UInt32); 531 | begin 532 | PUInt32(PtrInt(FData) + pos)^ := x; 533 | end; 534 | 535 | procedure TBuffer.setQWordAt(pos: SysInt; x: UInt64); 536 | begin 537 | PUInt64(PtrInt(FData) + pos)^ := x; 538 | end; 539 | 540 | procedure TBuffer.emitData(Ptr: Pointer; Len: SysUInt); 541 | var 542 | max: SysInt; 543 | begin 544 | max := capacity - offset; 545 | if (SysUInt(max) < Len) and (not realloc(SysUInt(offset) + Len)) then 546 | Exit; 547 | 548 | Move(Ptr^, FCur^, Len); 549 | Inc(FCur, Len); 550 | end; 551 | 552 | function TBuffer.realloc(t: SysInt): Boolean; 553 | var 554 | len: SysInt; 555 | begin 556 | if (capacity < t) then 557 | begin 558 | len := offset(); 559 | 560 | if (FData <> nil) then 561 | ReallocMem(FData, t) 562 | else 563 | GetMem(FData, t); 564 | if (FData = nil) then 565 | begin 566 | Result := False; 567 | Exit; 568 | end; 569 | 570 | FCur := PUInt8(PtrInt(FData) + len); 571 | FMax := PUInt8(PtrInt(FData) + t); 572 | if (t >= FGrowThreshold) then 573 | FMax := PUInt8(PtrInt(FMax) - FGrowThreshold) 574 | else 575 | FMax := PUInt8(PtrInt(FMax) - t); 576 | 577 | FCapacity := t; 578 | end; 579 | 580 | Result := True; 581 | end; 582 | 583 | function TBuffer.grow: Boolean; 584 | var 585 | t: SysInt; 586 | begin 587 | t := FCapacity; 588 | 589 | if (t < 512) then 590 | t := 1024 591 | else if (t > 65536) then 592 | t := t + 65536 593 | else 594 | t := t shl 1; 595 | 596 | Result := realloc(t); 597 | end; 598 | 599 | procedure TBuffer.clear; 600 | begin 601 | FCur := FData; 602 | end; 603 | 604 | procedure TBuffer.DoFree; 605 | begin 606 | if (FData = nil) then Exit; 607 | FreeMem(FData); 608 | 609 | FData := nil; 610 | FCur := nil; 611 | FMax := nil; 612 | FCapacity := 0; 613 | end; 614 | 615 | function TBuffer.take: PUInt8; 616 | var 617 | data: PUInt8; 618 | begin 619 | data := FData; 620 | 621 | FData := nil; 622 | FCur := nil; 623 | FMax := nil; 624 | FCapacity := 0; 625 | 626 | Result := data; 627 | end; 628 | 629 | constructor TPodVector.Create; 630 | begin 631 | inherited Create; 632 | 633 | FData := nil; 634 | FLength := 0; 635 | FCapacity := 0; 636 | end; 637 | 638 | destructor TPodVector.Destroy; 639 | begin 640 | if (FData <> nil) then 641 | FreeMem(FData); 642 | 643 | inherited Destroy; 644 | end; 645 | 646 | function TPodVector.GetIndex(Index: SysUInt): Pointer; 647 | begin 648 | Assert(Index < FLength); 649 | Result := PPointer(PtrUInt(FData) + (Index * SizeOf(Pointer)))^; 650 | end; 651 | 652 | procedure TPodVector.SetIndex(Index: SysUInt; Val: Pointer); 653 | begin 654 | Assert(Index < FLength); 655 | PPointer(PtrUInt(FData) + (Index * SizeOf(Pointer)))^ := Val; 656 | end; 657 | 658 | {function TPodVector.data: Pointer; 659 | begin 660 | Result := FData; 661 | end; 662 | 663 | function TPodVector.length: SysUInt; 664 | begin 665 | Result := FLength; 666 | end; 667 | 668 | function TPodVector.capacity: SysUInt; 669 | begin 670 | Result := FCapacity; 671 | end;} 672 | 673 | procedure TPodVector.clear; 674 | begin 675 | FLength := 0; 676 | end; 677 | 678 | procedure TPodVector.DoFree; 679 | begin 680 | if (FData <> nil) then 681 | begin 682 | FreeMem(FData); 683 | FData := nil; 684 | FLength := 0; 685 | FCapacity := 0; 686 | end; 687 | end; 688 | 689 | function TPodVector.prepend(Item: Pointer): Boolean; 690 | var 691 | dst: Pointer; 692 | begin 693 | if ((FLength = FCapacity) and (not _Grow)) then 694 | begin 695 | Result := False; 696 | Exit; 697 | end; 698 | 699 | dst := Pointer(PtrInt(FData) + SizeOf(Pointer)); 700 | Move(FData^, dst^, SizeOf(Pointer) * FLength); 701 | PPointer(FData)^ := Item; 702 | 703 | Inc(FLength); 704 | Result := True; 705 | end; 706 | 707 | function TPodVector.insert(Index: SysUInt; Item: Pointer): Boolean; 708 | var 709 | src, dst: Pointer; 710 | begin 711 | Assert(index <= FLength); 712 | if ((FLength = FCapacity) and (not _grow)) then 713 | begin 714 | Result := False; 715 | Exit; 716 | end; 717 | 718 | src := Pointer(PtrUInt(FData) + (index * SizeOf(Pointer))); 719 | dst := Pointer(PtrUInt(FData) + ((index + 1) * SizeOf(Pointer))); 720 | Move(src^, dst^, (FLength - index) * SizeOf(Pointer)); 721 | PPointer(src)^ := Item; 722 | 723 | Inc(FLength); 724 | Result := True; 725 | end; 726 | 727 | function TPodVector.append(Item: Pointer): Boolean; 728 | var 729 | dst: Pointer; 730 | begin 731 | if ((FLength = FCapacity) and (not _grow)) then 732 | begin 733 | Result := False; 734 | Exit; 735 | end; 736 | 737 | dst := Pointer(PtrUInt(FData) + (FLength * SizeOf(Pointer))); 738 | PPointer(dst)^ := Item; 739 | 740 | Inc(FLength); 741 | Result := True; 742 | end; 743 | 744 | function TPodVector.indexOf(Val: Pointer): SysUInt; 745 | var 746 | i: SysUInt; 747 | begin 748 | if (FLength > 0) then 749 | begin 750 | for i := 0 to FLength - 1 do 751 | if (Val = GetIndex(i)) then 752 | begin 753 | Result := i; 754 | Exit; 755 | end; 756 | end; 757 | Result := SysUInt(-1); 758 | end; 759 | 760 | procedure TPodVector.removeAt(i: SysUInt); 761 | var 762 | src, dst: Pointer; 763 | begin 764 | Assert(i < FLength); 765 | 766 | src := Pointer(PtrUInt(FData) + ((i + 1) * SizeOf(Pointer))); 767 | dst := Pointer(PtrUInt(FData) + (i * SizeOf(Pointer))); 768 | Dec(FLength); 769 | Move(src^, dst^, (FLength - i) * SizeOf(Pointer)); 770 | end; 771 | 772 | procedure TPodVector.swap(Other: TPodVector); 773 | var 774 | _tmp_data: Pointer; 775 | _tmp_length, _tmp_capacity: SysUInt; 776 | begin 777 | _tmp_data := FData; 778 | _tmp_length := FLength; 779 | _tmp_capacity := FCapacity; 780 | 781 | FData := other.FData; 782 | FLength := other.FLength; 783 | FCapacity := other.FCapacity; 784 | 785 | other.FData := _tmp_data; 786 | other.FLength := _tmp_length; 787 | other.FCapacity := _tmp_capacity; 788 | end; 789 | 790 | function TPodVector._grow: Boolean; 791 | begin 792 | if FCapacity < 16 then 793 | Result := _realloc(16) 794 | else 795 | Result := _realloc(FCapacity shl 1); 796 | end; 797 | 798 | function TPodVector._realloc(t: SysUInt): Boolean; 799 | begin 800 | Assert(t >= FLength); 801 | 802 | if (FData <> nil) then 803 | ReallocMem(FData, t * SizeOf(Pointer)) 804 | else 805 | GetMem(FData, t * SizeOf(Pointer)); 806 | 807 | if (FData = nil) then 808 | begin 809 | Result := False; 810 | Exit; 811 | end; 812 | 813 | FCapacity := t; 814 | Result := True; 815 | end; 816 | 817 | (*function TChunk.remain: SysUInt; 818 | begin 819 | Result := Size - Pos; 820 | end; 821 | 822 | constructor TZone.Create(ChunkSize: SysUInt); 823 | begin 824 | inherited Create; 825 | 826 | FChunks := nil; 827 | FTotal := 0; 828 | FChunkSize := ChunkSize; 829 | end; 830 | 831 | destructor TZone.Destroy; 832 | begin 833 | FreeAll; 834 | 835 | inherited; 836 | end; 837 | 838 | {function TZone.Total: SysUInt; 839 | begin 840 | Result := FTotal; 841 | end; 842 | 843 | function TZone.chunkSize: SysUInt; 844 | begin 845 | Result := FChunkSize; 846 | end;} 847 | 848 | function TZone.alloc(Size: SysUInt): Pointer; 849 | var 850 | cur: PChunk; 851 | chSize: SysUInt; 852 | p: PUInt8; 853 | begin 854 | Size := (Size + SizeOf(SysInt) - 1) and (not (SizeOf(SysInt) - 1)); 855 | cur := FChunks; 856 | 857 | if ((cur = nil) or (cur.remain < Size)) then 858 | begin 859 | chSize := FChunkSize; 860 | if (chSize < size) then 861 | chSize := Size; 862 | 863 | GetMem(Cur, SizeOf(TChunk) - SizeOf(Pointer) + chSize); 864 | if (cur = nil) then 865 | begin 866 | Result := nil; 867 | Exit; 868 | end; 869 | 870 | FillChar(Cur^, SizeOf(TChunk) - SizeOf(Pointer) + chSize, 0); 871 | 872 | cur.prev := FChunks; 873 | cur.pos := 0; 874 | cur.size := FChunkSize; 875 | FChunks := cur; 876 | end; 877 | 878 | {$R-} 879 | p := PUInt8(@cur.data[cur.pos]); 880 | {$R+} 881 | cur.pos := cur.pos + size; 882 | FTotal := FTotal + size; 883 | Result := p; 884 | end; 885 | 886 | procedure TZone.clear; 887 | var 888 | cur, prev: PChunk; 889 | begin 890 | cur := FChunks; 891 | if (cur = nil) then Exit; 892 | 893 | repeat 894 | prev := cur.prev; 895 | if (prev <> nil) then 896 | FreeMem(cur); 897 | cur := prev; 898 | until(cur = nil); 899 | 900 | FChunks := prev; 901 | FChunks.pos := 0; 902 | FTotal := 0; 903 | end; 904 | 905 | procedure TZone.freeAll; 906 | var 907 | cur, prev: PChunk; 908 | begin 909 | cur := FChunks; 910 | if (cur = nil) then Exit; 911 | 912 | repeat 913 | prev := cur.prev; 914 | FreeMem(cur); 915 | Cur := prev; 916 | until(cur = nil); 917 | 918 | FChunks := nil; 919 | FTotal := 0; 920 | end;*) 921 | 922 | end. 923 | -------------------------------------------------------------------------------- /DAsmJit_Defs.pas: -------------------------------------------------------------------------------- 1 | unit DAsmJit_Defs; 2 | 3 | {$I DAsmJit.inc} 4 | 5 | interface 6 | 7 | uses 8 | DAsmJit; 9 | 10 | type 11 | TCustomLogger = class(TObject) 12 | protected 13 | FEnabled: Boolean; 14 | public 15 | procedure log(buf: string); virtual; abstract; 16 | procedure logAlign(m: SysInt); virtual; abstract; 17 | procedure logFormat(fmt: string; args: array of const); virtual; abstract; 18 | 19 | property Enabled: Boolean read FEnabled write FEnabled; 20 | end; 21 | 22 | const 23 | //TERROR_CODE_E = ( 24 | ERROR_NONE = 0; 25 | ERROR_NO_HEAP_MEMORY = 1; 26 | ERROR_NO_VIRTUAL_MEMORY = 2; 27 | ERROR_UNKNOWN_INSTRUCTION = 3; 28 | ERROR_ILLEGAL_INSTRUCTION = 4; 29 | ERROR_ILLEGAL_ADDRESING = 5; 30 | ERROR_ILLEGAL_SHORT_JUMP = 6; 31 | _ERROR_COUNT = 7; 32 | //); 33 | 34 | //TOP_E = ( 35 | OP_NONE = 0; 36 | OP_REG = 1; 37 | OP_MEM = 2; 38 | OP_IMM = 3; 39 | OP_LABEL = 4; 40 | OP_VAR = 5; 41 | //); 42 | 43 | //TSIZE_E = ( 44 | SIZE_BYTE = 1; 45 | SIZE_WORD = 2; 46 | SIZE_DWORD = 4; 47 | SIZE_QWORD = 8; 48 | SIZE_TWORD = 10; 49 | SIZE_DQWORD = 16; 50 | //); 51 | 52 | //TRELOC_MODE_E = ( 53 | RELOC_NONE = 0; 54 | RELOC_OVERWRITE = 1; 55 | //); 56 | 57 | //TLABEL_STATE_E = ( 58 | LABEL_STATE_UNUSED = 0; 59 | LABEL_STATE_LINKED = 1; 60 | LABEL_STATE_BOUND = 2; 61 | //); 62 | 63 | //TPROPERTY_E = ( 64 | PROPERTY_OPTIMIZE_ALIGN = 0; 65 | PROPERTY_X86_FORCE_REX = 1; 66 | PROPERTY_X86_JCC_HINTS = 2; 67 | //); 68 | 69 | //TRID_E = ( 70 | RID_EAX = 0; 71 | RID_ECX = 1; 72 | RID_EDX = 2; 73 | RID_EBX = 3; 74 | RID_ESP = 4; 75 | RID_EBP = 5; 76 | RID_ESI = 6; 77 | RID_EDI = 7; 78 | //); 79 | 80 | //TSEGMENT_E = ( 81 | SEGMENT_NONE = 0; 82 | SEGMENT_CS = 1; 83 | SEGMENT_SS = 2; 84 | SEGMENT_DS = 3; 85 | SEGMENT_ES = 4; 86 | SEGMENT_FS = 5; 87 | SEGMENT_GS = 6; 88 | _SEGMENT_END = 7; 89 | //); 90 | 91 | //TPREFETCH_HINT_E = ( 92 | PREFETCH_T0 = 1; 93 | PREFETCH_T1 = 2; 94 | PREFETCH_T2 = 3; 95 | PREFETCH_NTA = 0; 96 | //); 97 | 98 | //TSCALE_E = ( 99 | TIMES_1 = 0; 100 | TIMES_2 = 1; 101 | TIMES_4 = 2; 102 | TIMES_8 = 3; 103 | //); 104 | 105 | //THINT_E = ( 106 | HINT_NONE = 0; 107 | HINT_TAKEN = 1; 108 | HINT_NOT_TAKEN = 2; 109 | //); 110 | 111 | //THINT_BYTE_VALUE_E = ( 112 | HINT_BYTE_VALUE_TAKEN = $3E; 113 | HINT_BYTE_VALUE_NOT_TAKEN = $2E; 114 | //); 115 | 116 | //TFP_STATUS_E = ( 117 | FP_C0 = $100; 118 | FP_C1 = $200; 119 | FP_C2 = $400; 120 | FP_C3 = $4000; 121 | FP_CC_MASK = $4500; 122 | //); 123 | 124 | //const 125 | REGTYPE_MASK = $F0; 126 | REGCODE_MASK = $0F; 127 | REG_GPB = $00; 128 | REG_GPW = $10; 129 | REG_GPD = $20; 130 | REG_GPQ = $30; 131 | {$IFDEF ASMJIT_X86} 132 | REG_GPN = REG_GPD; 133 | {$ELSE} 134 | REG_GPN = REG_GPQ; 135 | {$ENDIF} 136 | REG_X87 = $50; 137 | REG_MM = $60; 138 | REG_XMM = $70; 139 | REG_AL = REG_GPB ; REG_CL = 1; REG_DL = 2; REG_BL = 3; REG_AH = 4; REG_CH = 5; REG_DH = 6; REG_BH = 7; 140 | {$IFDEF ASMJIT_X64} 141 | REG_R8B = 8 ; REG_R9B = 9; REG_R10B = 10; REG_R11B = 11; REG_R12B = 12; REG_R13B = 13; REG_R14B = 14; REG_R15B = 15; 142 | {$ENDIF} 143 | REG_AX = REG_GPW ; REG_CX = 17; REG_DX = 18; REG_BX = 19; REG_SP = 20; REG_BP = 21; REG_SI = 22; REG_DI = 23; 144 | {$IFDEF ASMJIT_X64} 145 | REG_R8W = 24 ; REG_R9W = 25; REG_R10W = 26; REG_R11W = 27; REG_R12W = 28; REG_R13W = 29; REG_R14W = 30; REG_R15W = 31; 146 | {$ENDIF} 147 | REG_EAX = REG_GPD ; REG_ECX = 33; REG_EDX = 34; REG_EBX = 35; REG_ESP = 36; REG_EBP = 37; REG_ESI = 38; REG_EDI = 39; 148 | {$IFDEF ASMJIT_X64} 149 | REG_R8D = 40 ; REG_R9D = 41; REG_R10D = 42; REG_R11D = 43; REG_R12D = 44; REG_R13D = 45; REG_R14D = 46; REG_R15D = 47; 150 | REG_RAX = REG_GPQ ; REG_RCX = 49; REG_RDX = 50; REG_RBX = 51; REG_RSP = 52; REG_RBP = 53; REG_RSI = 54; REG_RDI = 55; 151 | REG_R8 = 56 ; REG_R9 = 57; REG_R10 = 58; REG_R11 = 59; REG_R12 = 60; REG_R13 = 61; REG_R14 = 62; REG_R15 = 63; 152 | {$ENDIF} 153 | REG_MM0 = REG_MM ; REG_MM1 = 97; REG_MM2 = 98; REG_MM3 = 99; REG_MM4 = 100; REG_MM5 = 101; REG_MM6 = 102; REG_MM7 = 103; 154 | REG_XMM0 = REG_XMM ; REG_XMM1 =113; REG_XMM2 =114; REG_XMM3 =115; REG_XMM4 = 116; REG_XMM5 =117; REG_XMM6 =118; REG_XMM7 =119; 155 | {$IFDEF ASMJIT_X64} 156 | REG_XMM8 = 120 ; REG_XMM9 =121; REG_XMM10=122; REG_XMM11=123; REG_XMM12=124; REG_XMM13= 125; REG_XMM14=126; REG_XMM15=127; 157 | {$ENDIF} 158 | {$IFDEF ASMJIT_X86} 159 | REG_NAX = REG_GPD ; REG_NCX = 33; REG_NDX = 34; REG_NBX = 35; REG_NSP = 36; REG_NBP = 37; REG_NSI = 38; REG_NDI = 39; 160 | {$ELSE} 161 | REG_NAX = REG_GPQ ; REG_NCX = 49; REG_NDX = 50; REG_NBX = 51; REG_NSP = 52; REG_NBP = 53; REG_NSI = 54; REG_NDI = 55; 162 | {$ENDIF} 163 | NO_REG = $FF; 164 | 165 | {$IFDEF ASMJIT_X86} 166 | NUM_REGS = 8; 167 | {$ELSE} 168 | NUM_REGS = 16; 169 | {$ENDIF} 170 | 171 | C_NO_CONDITION = -1; 172 | 173 | C_A = $7; 174 | C_AE = $3; 175 | C_B = $2; 176 | C_BE = $6; 177 | C_C = $2; 178 | C_E = $4; 179 | C_G = $F; 180 | C_GE = $D; 181 | C_L = $C; 182 | C_LE = $E; 183 | C_NA = $6; 184 | C_NAE = $2; 185 | C_NB = $3; 186 | C_NBE = $7; 187 | C_NC = $3; 188 | C_NE = $5; 189 | C_NG = $E; 190 | C_NGE = $C; 191 | C_NL = $D; 192 | C_NLE = $F; 193 | C_NO = $1; 194 | C_NP = $B; 195 | C_NS = $9; 196 | C_NZ = $5; 197 | C_O = $0; 198 | C_P = $A; 199 | C_PE = $A; 200 | C_PO = $B; 201 | C_S = $8; 202 | C_Z = $4; 203 | 204 | C_OVERFLOW = $0; 205 | C_NO_OVERFLOW = $1; 206 | C_BELOW = $2; 207 | C_ABOVE_EQUAL = $3; 208 | C_EQUAL = $4; 209 | C_NOT_EQUAL = $5; 210 | C_BELOW_EQUAL = $6; 211 | C_ABOVE = $7; 212 | C_SIGN = $8; 213 | C_NOT_SIGN = $9; 214 | C_PARITY_EVEN = $A; 215 | C_PARITY_ODD = $B; 216 | C_LESS = $C; 217 | C_GREATER_EQUAL = $D; 218 | C_LESS_EQUAL = $E; 219 | C_GREATER = $F; 220 | 221 | C_ZERO = $4; 222 | C_NOT_ZERO = $5; 223 | C_NEGATIVE = $8; 224 | C_POSITIVE = $9; 225 | 226 | C_FP_UNORDERED = 16; 227 | C_FP_NOT_UNORDERED = 17; 228 | 229 | FP_CW_INVOPEX_MASK = $001; 230 | FP_CW_DENOPEX_MASK = $002; 231 | FP_CW_ZERODIV_MASK = $004; 232 | FP_CW_OVFEX_MASK = $008; 233 | FP_CW_UNDFEX_MASK = $010; 234 | FP_CW_PRECEX_MASK = $020; 235 | FP_CW_PRECC_MASK = $300; 236 | FP_CW_ROUNDC_MASK = $C00; 237 | 238 | FP_CW_PREC_SINGLE = $000; 239 | FP_CW_PREC_DOUBLE = $200; 240 | FP_CW_PREC_EXTENDED = $300; 241 | 242 | FP_CW_ROUND_NEAREST = $000; 243 | FP_CW_ROUND_DOWN = $400; 244 | FP_CW_ROUND_UP = $800; 245 | FP_CW_ROUND_TOZERO = $C00; 246 | 247 | INST_ADC = 001; 248 | INST_ADD = 002; 249 | INST_ADDPD = 003; 250 | INST_ADDPS = 004; 251 | INST_ADDSD = 005; 252 | INST_ADDSS = 006; 253 | INST_ADDSUBPD = 007; 254 | INST_ADDSUBPS = 008; 255 | INST_AMD_PREFETCH = 009; 256 | INST_AMD_PREFETCHW = 010; 257 | INST_AND = 011; 258 | INST_ANDNPD = 012; 259 | INST_ANDNPS = 013; 260 | INST_ANDPD = 014; 261 | INST_ANDPS = 015; 262 | INST_BLENDPD = 016; 263 | INST_BLENDPS = 017; 264 | INST_BLENDVPD = 018; 265 | INST_BLENDVPS = 019; 266 | INST_BSF = 020; 267 | INST_BSR = 021; 268 | INST_BSWAP = 022; 269 | INST_BT = 023; 270 | INST_BTC = 024; 271 | INST_BTR = 025; 272 | INST_BTS = 026; 273 | INST_CALL = 027; 274 | INST_CBW = 028; 275 | INST_CDQE = 029; 276 | INST_CLC = 030; 277 | INST_CLD = 031; 278 | INST_CLFLUSH = 032; 279 | INST_CMC = 033; 280 | INST_CMOV = 034; 281 | INST_CMOVA = INST_CMOV; 282 | INST_CMOVAE = 035; 283 | INST_CMOVB = 036; 284 | INST_CMOVBE = 037; 285 | INST_CMOVC = 038; 286 | INST_CMOVE = 039; 287 | INST_CMOVG = 040; 288 | INST_CMOVGE = 041; 289 | INST_CMOVL = 042; 290 | INST_CMOVLE = 043; 291 | INST_CMOVNA = 044; 292 | INST_CMOVNAE = 045; 293 | INST_CMOVNB = 046; 294 | INST_CMOVNBE = 047; 295 | INST_CMOVNC = 048; 296 | INST_CMOVNE = 049; 297 | INST_CMOVNG = 050; 298 | INST_CMOVNGE = 051; 299 | INST_CMOVNL = 052; 300 | INST_CMOVNLE = 053; 301 | INST_CMOVNO = 054; 302 | INST_CMOVNP = 055; 303 | INST_CMOVNS = 056; 304 | INST_CMOVNZ = 057; 305 | INST_CMOVO = 058; 306 | INST_CMOVP = 059; 307 | INST_CMOVPE = 060; 308 | INST_CMOVPO = 061; 309 | INST_CMOVS = 062; 310 | INST_CMOVZ = 063; 311 | 312 | INST_CMP = 064; 313 | INST_CMPPD = 065; 314 | INST_CMPPS = 066; 315 | INST_CMPSD = 067; 316 | INST_CMPSS = 068; 317 | INST_CMPXCHG = 069; 318 | INST_CMPXCHG16B = 070; 319 | INST_CMPXCHG8B = 071; 320 | INST_COMISD = 072; 321 | INST_COMISS = 073; 322 | INST_CPUID = 074; 323 | INST_CRC32 = 075; 324 | INST_CVTDQ2PD = 076; 325 | INST_CVTDQ2PS = 077; 326 | INST_CVTPD2DQ = 078; 327 | INST_CVTPD2PI = 079; 328 | INST_CVTPD2PS = 080; 329 | INST_CVTPI2PD = 081; 330 | INST_CVTPI2PS = 082; 331 | INST_CVTPS2DQ = 083; 332 | INST_CVTPS2PD = 084; 333 | INST_CVTPS2PI = 085; 334 | INST_CVTSD2SI = 086; 335 | INST_CVTSD2SS = 087; 336 | INST_CVTSI2SD = 088; 337 | INST_CVTSI2SS = 089; 338 | INST_CVTSS2SD = 090; 339 | INST_CVTSS2SI = 091; 340 | INST_CVTTPD2DQ = 092; 341 | INST_CVTTPD2PI = 093; 342 | INST_CVTTPS2DQ = 094; 343 | INST_CVTTPS2PI = 095; 344 | INST_CVTTSD2SI = 096; 345 | INST_CVTTSS2SI = 097; 346 | INST_CWDE = 098; 347 | INST_DAA = 099; 348 | INST_DAS = 100; 349 | INST_DEC = 101; 350 | INST_DIV = 102; 351 | INST_DIVPD = 103; 352 | INST_DIVPS = 104; 353 | INST_DIVSD = 105; 354 | INST_DIVSS = 106; 355 | INST_DPPD = 107; 356 | INST_DPPS = 108; 357 | INST_EMMS = 109; 358 | INST_ENTER = 110; 359 | INST_EXTRACTPS = 111; 360 | INST_F2XM1 = 112; 361 | INST_FABS = 113; 362 | INST_FADD = 114; 363 | INST_FADDP = 115; 364 | INST_FBLD = 116; 365 | INST_FBSTP = 117; 366 | INST_FCHS = 118; 367 | INST_FCLEX = 119; 368 | INST_FCMOVB = 120; 369 | INST_FCMOVBE = 121; 370 | INST_FCMOVE = 122; 371 | INST_FCMOVNB = 123; 372 | INST_FCMOVNBE = 124; 373 | INST_FCMOVNE = 125; 374 | INST_FCMOVNU = 126; 375 | INST_FCMOVU = 127; 376 | INST_FCOM = 128; 377 | INST_FCOMI = 129; 378 | INST_FCOMIP = 130; 379 | INST_FCOMP = 131; 380 | INST_FCOMPP = 132; 381 | INST_FCOS = 133; 382 | INST_FDECSTP = 134; 383 | INST_FDIV = 135; 384 | INST_FDIVP = 136; 385 | INST_FDIVR = 137; 386 | INST_FDIVRP = 138; 387 | INST_FEMMS = 139; 388 | INST_FFREE = 140; 389 | INST_FIADD = 141; 390 | INST_FICOM = 142; 391 | INST_FICOMP = 143; 392 | INST_FIDIV = 144; 393 | INST_FIDIVR = 145; 394 | INST_FILD = 146; 395 | INST_FIMUL = 147; 396 | INST_FINCSTP = 148; 397 | INST_FINIT = 149; 398 | INST_FIST = 150; 399 | INST_FISTP = 151; 400 | INST_FISTTP = 152; 401 | INST_FISUB = 153; 402 | INST_FISUBR = 154; 403 | INST_FLD = 155; 404 | INST_FLD1 = 156; 405 | INST_FLDCW = 157; 406 | INST_FLDENV = 158; 407 | INST_FLDL2E = 159; 408 | INST_FLDL2T = 160; 409 | INST_FLDLG2 = 161; 410 | INST_FLDLN2 = 162; 411 | INST_FLDPI = 163; 412 | INST_FLDZ = 164; 413 | INST_FMUL = 165; 414 | INST_FMULP = 166; 415 | INST_FNCLEX = 167; 416 | INST_FNINIT = 168; 417 | INST_FNOP = 169; 418 | INST_FNSAVE = 170; 419 | INST_FNSTCW = 171; 420 | INST_FNSTENV = 172; 421 | INST_FNSTSW = 173; 422 | INST_FPATAN = 174; 423 | INST_FPREM = 175; 424 | INST_FPREM1 = 176; 425 | INST_FPTAN = 177; 426 | INST_FRNDINT = 178; 427 | INST_FRSTOR = 179; 428 | INST_FSAVE = 180; 429 | INST_FSCALE = 181; 430 | INST_FSIN = 182; 431 | INST_FSINCOS = 183; 432 | INST_FSQRT = 184; 433 | INST_FST = 185; 434 | INST_FSTCW = 186; 435 | INST_FSTENV = 187; 436 | INST_FSTP = 188; 437 | INST_FSTSW = 189; 438 | INST_FSUB = 190; 439 | INST_FSUBP = 191; 440 | INST_FSUBR = 192; 441 | INST_FSUBRP = 193; 442 | INST_FTST = 194; 443 | INST_FUCOM = 195; 444 | INST_FUCOMI = 196; 445 | INST_FUCOMIP = 197; 446 | INST_FUCOMP = 198; 447 | INST_FUCOMPP = 199; 448 | INST_FWAIT = 200; 449 | INST_FXAM = 201; 450 | INST_FXCH = 202; 451 | INST_FXRSTOR = 203; 452 | INST_FXSAVE = 204; 453 | INST_FXTRACT = 205; 454 | INST_FYL2X = 206; 455 | INST_FYL2XP1 = 207; 456 | INST_HADDPD = 208; 457 | INST_HADDPS = 209; 458 | INST_HSUBPD = 210; 459 | INST_HSUBPS = 211; 460 | INST_IDIV = 212; 461 | INST_IMUL = 213; 462 | INST_INC = 214; 463 | INST_INT3 = 215; 464 | 465 | INST_J = 216; 466 | INST_JA = INST_J; 467 | INST_JAE = 217; 468 | INST_JB = 218; 469 | INST_JBE = 219; 470 | INST_JC = 220; 471 | INST_JE = 221; 472 | INST_JG = 222; 473 | INST_JGE = 223; 474 | INST_JL = 224; 475 | INST_JLE = 225; 476 | INST_JNA = 226; 477 | INST_JNAE = 227; 478 | INST_JNB = 228; 479 | INST_JNBE = 229; 480 | INST_JNC = 230; 481 | INST_JNE = 231; 482 | INST_JNG = 232; 483 | INST_JNGE = 233; 484 | INST_JNL = 234; 485 | INST_JNLE = 235; 486 | INST_JNO = 236; 487 | INST_JNP = 237; 488 | INST_JNS = 238; 489 | INST_JNZ = 239; 490 | INST_JO = 240; 491 | INST_JP = 241; 492 | INST_JPE = 242; 493 | INST_JPO = 243; 494 | INST_JS = 244; 495 | INST_JZ = 245; 496 | INST_JMP = 246; 497 | 498 | INST_J_SHORT = 247; 499 | INST_JA_SHORT = INST_J_SHORT; 500 | INST_JAE_SHORT = 248; 501 | INST_JB_SHORT = 249; 502 | INST_JBE_SHORT = 250; 503 | INST_JC_SHORT = 251; 504 | INST_JE_SHORT = 252; 505 | INST_JG_SHORT = 253; 506 | INST_JGE_SHORT = 254; 507 | INST_JL_SHORT = 255; 508 | INST_JLE_SHORT = 256; 509 | INST_JNA_SHORT = 257; 510 | INST_JNAE_SHORT = 258; 511 | INST_JNB_SHORT = 259; 512 | INST_JNBE_SHORT = 260; 513 | INST_JNC_SHORT = 261; 514 | INST_JNE_SHORT = 262; 515 | INST_JNG_SHORT = 263; 516 | INST_JNGE_SHORT = 264; 517 | INST_JNL_SHORT = 265; 518 | INST_JNLE_SHORT = 266; 519 | INST_JNO_SHORT = 267; 520 | INST_JNP_SHORT = 268; 521 | INST_JNS_SHORT = 269; 522 | INST_JNZ_SHORT = 270; 523 | INST_JO_SHORT = 271; 524 | INST_JP_SHORT = 272; 525 | INST_JPE_SHORT = 273; 526 | INST_JPO_SHORT = 274; 527 | INST_JS_SHORT = 275; 528 | INST_JZ_SHORT = 276; 529 | INST_JMP_SHORT = 277; 530 | 531 | INST_LDDQU = 278; 532 | INST_LDMXCSR = 279; 533 | INST_LEA = 280; 534 | INST_LEAVE = 281; 535 | INST_LFENCE = 282; 536 | INST_LOCK = 283; 537 | INST_MASKMOVDQU = 284; 538 | INST_MASKMOVQ = 285; 539 | INST_MAXPD = 286; 540 | INST_MAXPS = 287; 541 | INST_MAXSD = 288; 542 | INST_MAXSS = 289; 543 | INST_MFENCE = 290; 544 | INST_MINPD = 291; 545 | INST_MINPS = 292; 546 | INST_MINSD = 293; 547 | INST_MINSS = 294; 548 | INST_MONITOR = 295; 549 | INST_MOV = 296; 550 | INST_MOVAPD = 297; 551 | INST_MOVAPS = 298; 552 | INST_MOVBE = 299; 553 | INST_MOVD = 300; 554 | INST_MOVDDUP = 301; 555 | INST_MOVDQ2Q = 302; 556 | INST_MOVDQA = 303; 557 | INST_MOVDQU = 304; 558 | INST_MOVHLPS = 305; 559 | INST_MOVHPD = 306; 560 | INST_MOVHPS = 307; 561 | INST_MOVLHPS = 308; 562 | INST_MOVLPD = 309; 563 | INST_MOVLPS = 310; 564 | INST_MOVMSKPD = 311; 565 | INST_MOVMSKPS = 312; 566 | INST_MOVNTDQ = 313; 567 | INST_MOVNTDQA = 314; 568 | INST_MOVNTI = 315; 569 | INST_MOVNTPD = 316; 570 | INST_MOVNTPS = 317; 571 | INST_MOVNTQ = 318; 572 | INST_MOVQ = 319; 573 | INST_MOVQ2DQ = 320; 574 | INST_MOVSD = 321; 575 | INST_MOVSHDUP = 322; 576 | INST_MOVSLDUP = 323; 577 | INST_MOVSS = 324; 578 | INST_MOVSX = 325; 579 | INST_MOVSXD = 326; 580 | INST_MOVUPD = 327; 581 | INST_MOVUPS = 328; 582 | INST_MOVZX = 329; 583 | INST_MOV_PTR = 330; 584 | INST_MPSADBW = 331; 585 | INST_MUL = 332; 586 | INST_MULPD = 333; 587 | INST_MULPS = 334; 588 | INST_MULSD = 335; 589 | INST_MULSS = 336; 590 | INST_MWAIT = 337; 591 | INST_NEG = 338; 592 | INST_NOP = 339; 593 | INST_NOT = 340; 594 | INST_OR = 341; 595 | INST_ORPD = 342; 596 | INST_ORPS = 343; 597 | INST_PABSB = 344; 598 | INST_PABSD = 345; 599 | INST_PABSW = 346; 600 | INST_PACKSSDW = 347; 601 | INST_PACKSSWB = 348; 602 | INST_PACKUSDW = 349; 603 | INST_PACKUSWB = 350; 604 | INST_PADDB = 351; 605 | INST_PADDD = 352; 606 | INST_PADDQ = 353; 607 | INST_PADDSB = 354; 608 | INST_PADDSW = 355; 609 | INST_PADDUSB = 356; 610 | INST_PADDUSW = 357; 611 | INST_PADDW = 358; 612 | INST_PALIGNR = 359; 613 | INST_PAND = 360; 614 | INST_PANDN = 361; 615 | INST_PAUSE = 362; 616 | INST_PAVGB = 363; 617 | INST_PAVGW = 364; 618 | INST_PBLENDVB = 365; 619 | INST_PBLENDW = 366; 620 | INST_PCMPEQB = 367; 621 | INST_PCMPEQD = 368; 622 | INST_PCMPEQQ = 369; 623 | INST_PCMPEQW = 370; 624 | INST_PCMPESTRI = 371; 625 | INST_PCMPESTRM = 372; 626 | INST_PCMPGTB = 373; 627 | INST_PCMPGTD = 374; 628 | INST_PCMPGTQ = 375; 629 | INST_PCMPGTW = 376; 630 | INST_PCMPISTRI = 377; 631 | INST_PCMPISTRM = 378; 632 | INST_PEXTRB = 379; 633 | INST_PEXTRD = 380; 634 | INST_PEXTRQ = 381; 635 | INST_PEXTRW = 382; 636 | INST_PF2ID = 383; 637 | INST_PF2IW = 384; 638 | INST_PFACC = 385; 639 | INST_PFADD = 386; 640 | INST_PFCMPEQ = 387; 641 | INST_PFCMPGE = 388; 642 | INST_PFCMPGT = 389; 643 | INST_PFMAX = 390; 644 | INST_PFMIN = 391; 645 | INST_PFMUL = 392; 646 | INST_PFNACC = 393; 647 | INST_PFPNACC = 394; 648 | INST_PFRCP = 395; 649 | INST_PFRCPIT1 = 396; 650 | INST_PFRCPIT2 = 397; 651 | INST_PFRSQIT1 = 398; 652 | INST_PFRSQRT = 399; 653 | INST_PFSUB = 400; 654 | INST_PFSUBR = 401; 655 | INST_PHADDD = 402; 656 | INST_PHADDSW = 403; 657 | INST_PHADDW = 404; 658 | INST_PHMINPOSUW = 405; 659 | INST_PHSUBD = 406; 660 | INST_PHSUBSW = 407; 661 | INST_PHSUBW = 408; 662 | INST_PI2FD = 409; 663 | INST_PI2FW = 410; 664 | INST_PINSRB = 411; 665 | INST_PINSRD = 412; 666 | INST_PINSRQ = 413; 667 | INST_PINSRW = 414; 668 | INST_PMADDUBSW = 415; 669 | INST_PMADDWD = 416; 670 | INST_PMAXSB = 417; 671 | INST_PMAXSD = 418; 672 | INST_PMAXSW = 419; 673 | INST_PMAXUB = 420; 674 | INST_PMAXUD = 421; 675 | INST_PMAXUW = 422; 676 | INST_PMINSB = 423; 677 | INST_PMINSD = 424; 678 | INST_PMINSW = 425; 679 | INST_PMINUB = 426; 680 | INST_PMINUD = 427; 681 | INST_PMINUW = 428; 682 | INST_PMOVMSKB = 429; 683 | INST_PMOVSXBD = 430; 684 | INST_PMOVSXBQ = 431; 685 | INST_PMOVSXBW = 432; 686 | INST_PMOVSXDQ = 433; 687 | INST_PMOVSXWD = 434; 688 | INST_PMOVSXWQ = 435; 689 | INST_PMOVZXBD = 436; 690 | INST_PMOVZXBQ = 437; 691 | INST_PMOVZXBW = 438; 692 | INST_PMOVZXDQ = 439; 693 | INST_PMOVZXWD = 440; 694 | INST_PMOVZXWQ = 441; 695 | INST_PMULDQ = 442; 696 | INST_PMULHRSW = 443; 697 | INST_PMULHUW = 444; 698 | INST_PMULHW = 445; 699 | INST_PMULLD = 446; 700 | INST_PMULLW = 447; 701 | INST_PMULUDQ = 448; 702 | INST_POP = 449; 703 | INST_POPAD = 450; 704 | INST_POPCNT = 451; 705 | INST_POPFD = 452; 706 | INST_POPFQ = 453; 707 | INST_POR = 454; 708 | INST_PREFETCH = 455; 709 | INST_PSADBW = 456; 710 | INST_PSHUFB = 457; 711 | INST_PSHUFD = 458; 712 | INST_PSHUFW = 459; 713 | INST_PSHUFHW = 460; 714 | INST_PSHUFLW = 461; 715 | INST_PSIGNB = 462; 716 | INST_PSIGND = 463; 717 | INST_PSIGNW = 464; 718 | INST_PSLLD = 465; 719 | INST_PSLLDQ = 466; 720 | INST_PSLLQ = 467; 721 | INST_PSLLW = 468; 722 | INST_PSRAD = 469; 723 | INST_PSRAW = 470; 724 | INST_PSRLD = 471; 725 | INST_PSRLDQ = 472; 726 | INST_PSRLQ = 473; 727 | INST_PSRLW = 474; 728 | INST_PSUBB = 475; 729 | INST_PSUBD = 476; 730 | INST_PSUBQ = 477; 731 | INST_PSUBSB = 478; 732 | INST_PSUBSW = 479; 733 | INST_PSUBUSB = 480; 734 | INST_PSUBUSW = 481; 735 | INST_PSUBW = 482; 736 | INST_PSWAPD = 483; 737 | INST_PTEST = 484; 738 | INST_PUNPCKHBW = 485; 739 | INST_PUNPCKHDQ = 486; 740 | INST_PUNPCKHQDQ = 487; 741 | INST_PUNPCKHWD = 488; 742 | INST_PUNPCKLBW = 489; 743 | INST_PUNPCKLDQ = 490; 744 | INST_PUNPCKLQDQ = 491; 745 | INST_PUNPCKLWD = 492; 746 | INST_PUSH = 493; 747 | INST_PUSHAD = 494; 748 | INST_PUSHFD = 495; 749 | INST_PUSHFQ = 496; 750 | INST_PXOR = 497; 751 | INST_RCL = 498; 752 | INST_RCPPS = 499; 753 | INST_RCPSS = 500; 754 | INST_RCR = 501; 755 | INST_RDTSC = 502; 756 | INST_RDTSCP = 503; 757 | INST_RET = 504; 758 | INST_ROL = 505; 759 | INST_ROR = 506; 760 | INST_ROUNDPD = 507; 761 | INST_ROUNDPS = 508; 762 | INST_ROUNDSD = 509; 763 | INST_ROUNDSS = 510; 764 | INST_RSQRTPS = 511; 765 | INST_RSQRTSS = 512; 766 | INST_SAHF = 513; 767 | INST_SAL = 514; 768 | INST_SAR = 515; 769 | INST_SBB = 516; 770 | INST_SET = 517; 771 | INST_SETA=INST_SET; 772 | INST_SETAE = 518; 773 | INST_SETB = 519; 774 | INST_SETBE = 520; 775 | INST_SETC = 521; 776 | INST_SETE = 522; 777 | INST_SETG = 523; 778 | INST_SETGE = 524; 779 | INST_SETL = 525; 780 | INST_SETLE = 526; 781 | INST_SETNA = 527; 782 | INST_SETNAE = 528; 783 | INST_SETNB = 529; 784 | INST_SETNBE = 530; 785 | INST_SETNC = 531; 786 | INST_SETNE = 532; 787 | INST_SETNG = 533; 788 | INST_SETNGE = 534; 789 | INST_SETNL = 535; 790 | INST_SETNLE = 536; 791 | INST_SETNO = 537; 792 | INST_SETNP = 538; 793 | INST_SETNS = 539; 794 | INST_SETNZ = 540; 795 | INST_SETO = 541; 796 | INST_SETP = 542; 797 | INST_SETPE = 543; 798 | INST_SETPO = 544; 799 | INST_SETS = 545; 800 | INST_SETZ = 546; 801 | INST_SFENCE = 547; 802 | INST_SHL = 548; 803 | INST_SHLD = 549; 804 | INST_SHR = 550; 805 | INST_SHRD = 551; 806 | INST_SHUFPD = 552; 807 | INST_SHUFPS = 553; 808 | INST_SQRTPD = 554; 809 | INST_SQRTPS = 555; 810 | INST_SQRTSD = 556; 811 | INST_SQRTSS = 557; 812 | INST_STC = 558; 813 | INST_STD = 559; 814 | INST_STMXCSR = 560; 815 | INST_SUB = 561; 816 | INST_SUBPD = 562; 817 | INST_SUBPS = 563; 818 | INST_SUBSD = 564; 819 | INST_SUBSS = 565; 820 | INST_TEST = 566; 821 | INST_UCOMISD = 567; 822 | INST_UCOMISS = 568; 823 | INST_UD2 = 569; 824 | INST_UNPCKHPD = 570; 825 | INST_UNPCKHPS = 571; 826 | INST_UNPCKLPD = 572; 827 | INST_UNPCKLPS = 573; 828 | INST_XADD = 574; 829 | INST_XCHG = 575; 830 | INST_XOR = 576; 831 | INST_XORPD = 577; 832 | INST_XORPS = 578; 833 | 834 | _INST_COUNT = 579; 835 | 836 | function errorCodeToString(Error: UInt32): string; 837 | 838 | implementation 839 | 840 | function errorCodeToString(Error: UInt32): string; 841 | const 842 | errorMessage: array[0..7] of string = ( 843 | 'No error', 844 | 'No heap memory', 845 | 'No virtual memory', 846 | 'Unknown instruction', 847 | 'Illegal instruction', 848 | 'Illegal addressing', 849 | 'Illegal short jump', 850 | 'Unknown error' 851 | ); 852 | begin 853 | if (Error > _ERROR_COUNT) then 854 | Error := _ERROR_COUNT; 855 | 856 | Result := errorMessage[Error]; 857 | end; 858 | 859 | end. 860 | --------------------------------------------------------------------------------