Preparation C code for c2rust conversion
This commit is contained in:
parent
26fc44a61f
commit
6de0bb374b
23 changed files with 908 additions and 564 deletions
0
src/native/all.c
Normal file
0
src/native/all.c
Normal file
|
|
@ -1,4 +1,3 @@
|
|||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
|
|
|||
|
|
@ -1,32 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG true
|
||||
#endif
|
||||
|
||||
/**
|
||||
* How many cycles the CPU does at a time before running hardware timers
|
||||
*/
|
||||
#define LOOP_COUNTER 20011
|
||||
//#define LOOP_COUNTER 20011
|
||||
|
||||
#define TSC_RATE (50 * 1000)
|
||||
//#define TSC_RATE (50 * 1000)
|
||||
|
||||
#define CPU_LOG_VERBOSE false
|
||||
#define ENABLE_ACPI false
|
||||
|
||||
#define USE_A20 false
|
||||
|
||||
#define CHECK_TLB_INVARIANTS 0
|
||||
|
||||
#define ENABLE_JIT 1
|
||||
|
||||
#define CHECK_CPU_EXCEPTIONS 0
|
||||
|
||||
#define ENABLE_PROFILER 0
|
||||
#define ENABLE_PROFILER_OPSTATS 0
|
||||
#define ENABLE_PROFILER_SAFE_READ_WRITE 0
|
||||
#define ENABLE_PROFILER 1
|
||||
#define ENABLE_PROFILER_OPSTATS 1
|
||||
#define ENABLE_PROFILER_SAFE_READ_WRITE 1
|
||||
|
||||
// Note: needs to be enabled here and in config.js
|
||||
#define DUMP_UNCOMPILED_ASSEMBLY 0
|
||||
|
||||
#define LOG_PAGE_FAULTS 0
|
||||
//#define LOG_PAGE_FAULTS 0
|
||||
|
|
|
|||
|
|
@ -1,151 +1,150 @@
|
|||
#pragma once
|
||||
|
||||
#define FLAG_CARRY 1
|
||||
#define FLAG_PARITY 4
|
||||
#define FLAG_ADJUST 16
|
||||
#define FLAG_ZERO 64
|
||||
#define FLAG_SIGN 128
|
||||
#define FLAG_TRAP 256
|
||||
#define FLAG_INTERRUPT 512
|
||||
#define FLAG_DIRECTION 1024
|
||||
#define FLAG_OVERFLOW 2048
|
||||
#define FLAG_IOPL (1 << 12 | 1 << 13)
|
||||
#define FLAG_NT (1 << 14)
|
||||
#define FLAG_RF (1 << 16)
|
||||
#define FLAG_VM (1 << 17)
|
||||
#define FLAG_AC (1 << 18)
|
||||
#define FLAG_VIF (1 << 19)
|
||||
#define FLAG_VIP (1 << 20)
|
||||
#define FLAG_ID (1 << 21)
|
||||
#define FLAGS_DEFAULT (1 << 1)
|
||||
#include <stdint.h>
|
||||
|
||||
#define FLAGS_MASK ( \
|
||||
FLAG_CARRY | FLAG_PARITY | FLAG_ADJUST | FLAG_ZERO | FLAG_SIGN | FLAG_TRAP | FLAG_INTERRUPT | \
|
||||
FLAG_DIRECTION | FLAG_OVERFLOW | FLAG_IOPL | FLAG_NT | FLAG_RF | FLAG_VM | FLAG_AC | \
|
||||
FLAG_VIF | FLAG_VIP | FLAG_ID)
|
||||
extern const int32_t FLAG_CARRY;
|
||||
extern const int32_t FLAG_PARITY;
|
||||
extern const int32_t FLAG_ADJUST;
|
||||
extern const int32_t FLAG_ZERO;
|
||||
extern const int32_t FLAG_SIGN;
|
||||
extern const int32_t FLAG_TRAP;
|
||||
extern const int32_t FLAG_INTERRUPT;
|
||||
extern const int32_t FLAG_DIRECTION;
|
||||
extern const int32_t FLAG_OVERFLOW;
|
||||
extern const int32_t FLAG_IOPL;
|
||||
extern const int32_t FLAG_NT;
|
||||
extern const int32_t FLAG_RF;
|
||||
extern const int32_t FLAG_VM;
|
||||
extern const int32_t FLAG_AC;
|
||||
extern const int32_t FLAG_VIF;
|
||||
extern const int32_t FLAG_VIP;
|
||||
extern const int32_t FLAG_ID;
|
||||
extern const int32_t FLAGS_DEFAULT;
|
||||
|
||||
#define FLAGS_ALL (FLAG_CARRY | FLAG_PARITY | FLAG_ADJUST | FLAG_ZERO | FLAG_SIGN | FLAG_OVERFLOW)
|
||||
extern const int32_t FLAGS_MASK;
|
||||
|
||||
#define OPSIZE_8 7
|
||||
#define OPSIZE_16 15
|
||||
#define OPSIZE_32 31
|
||||
extern const int32_t FLAGS_ALL;
|
||||
|
||||
#define EAX 0
|
||||
#define ECX 1
|
||||
#define EDX 2
|
||||
#define EBX 3
|
||||
#define ESP 4
|
||||
#define EBP 5
|
||||
#define ESI 6
|
||||
#define EDI 7
|
||||
extern const int32_t OPSIZE_8;
|
||||
extern const int32_t OPSIZE_16;
|
||||
extern const int32_t OPSIZE_32;
|
||||
|
||||
#define AX 0
|
||||
#define CX 2
|
||||
#define DX 4
|
||||
#define BX 6
|
||||
#define SP 8
|
||||
#define BP 10
|
||||
#define SI 12
|
||||
#define DI 14
|
||||
extern const int32_t EAX;
|
||||
extern const int32_t ECX;
|
||||
extern const int32_t EDX;
|
||||
extern const int32_t EBX;
|
||||
extern const int32_t ESP;
|
||||
extern const int32_t EBP;
|
||||
extern const int32_t ESI;
|
||||
extern const int32_t EDI;
|
||||
|
||||
#define AL 0
|
||||
#define CL 4
|
||||
#define DL 8
|
||||
#define BL 12
|
||||
#define AH 1
|
||||
#define CH 5
|
||||
#define DH 9
|
||||
#define BH 13
|
||||
extern const int32_t AX;
|
||||
extern const int32_t CX;
|
||||
extern const int32_t DX;
|
||||
extern const int32_t BX;
|
||||
extern const int32_t SP;
|
||||
extern const int32_t BP;
|
||||
extern const int32_t SI;
|
||||
extern const int32_t DI;
|
||||
|
||||
#define ES 0
|
||||
#define CS 1
|
||||
#define SS 2
|
||||
#define DS 3
|
||||
#define FS 4
|
||||
#define GS 5
|
||||
extern const int32_t AL;
|
||||
extern const int32_t CL;
|
||||
extern const int32_t DL;
|
||||
extern const int32_t BL;
|
||||
extern const int32_t AH;
|
||||
extern const int32_t CH;
|
||||
extern const int32_t DH;
|
||||
extern const int32_t BH;
|
||||
|
||||
#define TR 6
|
||||
#define LDTR 7
|
||||
extern const int32_t ES;
|
||||
extern const int32_t CS;
|
||||
extern const int32_t SS;
|
||||
extern const int32_t DS;
|
||||
extern const int32_t FS;
|
||||
extern const int32_t GS;
|
||||
|
||||
extern const int32_t TR;
|
||||
extern const int32_t LDTR;
|
||||
|
||||
|
||||
#define PAGE_TABLE_PRESENT_MASK (1 << 0)
|
||||
#define PAGE_TABLE_RW_MASK (1 << 1)
|
||||
#define PAGE_TABLE_USER_MASK (1 << 2)
|
||||
#define PAGE_TABLE_ACCESSED_MASK (1 << 5)
|
||||
#define PAGE_TABLE_DIRTY_MASK (1 << 6)
|
||||
#define PAGE_TABLE_PSE_MASK (1 << 7)
|
||||
#define PAGE_TABLE_GLOBAL_MASK (1 << 8)
|
||||
extern const int32_t PAGE_TABLE_PRESENT_MASK;
|
||||
extern const int32_t PAGE_TABLE_RW_MASK;
|
||||
extern const int32_t PAGE_TABLE_USER_MASK;
|
||||
extern const int32_t PAGE_TABLE_ACCESSED_MASK;
|
||||
extern const int32_t PAGE_TABLE_DIRTY_MASK;
|
||||
extern const int32_t PAGE_TABLE_PSE_MASK;
|
||||
extern const int32_t PAGE_TABLE_GLOBAL_MASK;
|
||||
|
||||
#define MMAP_BLOCK_BITS 17
|
||||
#define MMAP_BLOCK_SIZE = (1 << MMAP_BLOCK_BITS)
|
||||
extern const int32_t MMAP_BLOCK_BITS;
|
||||
extern const int32_t MMAP_BLOCK_SIZE;
|
||||
|
||||
#define CR0_PE 1
|
||||
#define CR0_MP (1 << 1)
|
||||
#define CR0_EM (1 << 2)
|
||||
#define CR0_TS (1 << 3)
|
||||
#define CR0_ET (1 << 4)
|
||||
#define CR0_WP (1 << 16)
|
||||
#define CR0_NW (1 << 29)
|
||||
#define CR0_CD (1 << 30)
|
||||
#define CR0_PG (1 << 31)
|
||||
extern const int32_t CR0_PE;
|
||||
extern const int32_t CR0_MP;
|
||||
extern const int32_t CR0_EM;
|
||||
extern const int32_t CR0_TS;
|
||||
extern const int32_t CR0_ET;
|
||||
extern const int32_t CR0_WP;
|
||||
extern const int32_t CR0_NW;
|
||||
extern const int32_t CR0_CD;
|
||||
extern const int32_t CR0_PG;
|
||||
|
||||
#define CR4_VME (1)
|
||||
#define CR4_PVI (1 << 1)
|
||||
#define CR4_TSD (1 << 2)
|
||||
#define CR4_PSE (1 << 4)
|
||||
#define CR4_DE (1 << 3)
|
||||
#define CR4_PAE (1 << 5)
|
||||
#define CR4_PGE (1 << 7)
|
||||
extern const int32_t CR4_VME;
|
||||
extern const int32_t CR4_PVI;
|
||||
extern const int32_t CR4_TSD;
|
||||
extern const int32_t CR4_PSE;
|
||||
extern const int32_t CR4_DE;
|
||||
extern const int32_t CR4_PAE;
|
||||
extern const int32_t CR4_PGE;
|
||||
|
||||
|
||||
#define IA32_SYSENTER_CS 0x174
|
||||
#define IA32_SYSENTER_ESP 0x175
|
||||
#define IA32_SYSENTER_EIP 0x176
|
||||
extern const int32_t IA32_SYSENTER_CS;
|
||||
extern const int32_t IA32_SYSENTER_ESP;
|
||||
extern const int32_t IA32_SYSENTER_EIP;
|
||||
|
||||
#define IA32_TIME_STAMP_COUNTER 0x10
|
||||
#define IA32_PLATFORM_ID 0x17
|
||||
#define IA32_APIC_BASE_MSR 0x1B
|
||||
#define IA32_BIOS_SIGN_ID 0x8B
|
||||
#define MSR_PLATFORM_INFO 0xCE
|
||||
#define MSR_MISC_FEATURE_ENABLES 0x140
|
||||
#define IA32_MISC_ENABLE 0x1A0
|
||||
#define IA32_RTIT_CTL 0x570
|
||||
#define MSR_SMI_COUNT 0x34
|
||||
#define IA32_MCG_CAP 0x179
|
||||
#define IA32_KERNEL_GS_BASE 0xC0000101
|
||||
#define MSR_PKG_C2_RESIDENCY 0x60D
|
||||
extern const int32_t IA32_TIME_STAMP_COUNTER;
|
||||
extern const int32_t IA32_PLATFORM_ID;
|
||||
extern const int32_t IA32_APIC_BASE_MSR;
|
||||
extern const int32_t IA32_BIOS_SIGN_ID;
|
||||
extern const int32_t MSR_PLATFORM_INFO;
|
||||
extern const int32_t MSR_MISC_FEATURE_ENABLES;
|
||||
extern const int32_t IA32_MISC_ENABLE;
|
||||
extern const int32_t IA32_RTIT_CTL;
|
||||
extern const int32_t MSR_SMI_COUNT;
|
||||
extern const int32_t IA32_MCG_CAP;
|
||||
extern const int32_t IA32_KERNEL_GS_BASE;
|
||||
extern const int32_t MSR_PKG_C2_RESIDENCY;
|
||||
|
||||
#define IA32_APIC_BASE_BSP (1 << 8)
|
||||
#define IA32_APIC_BASE_EXTD (1 << 10)
|
||||
#define IA32_APIC_BASE_EN (1 << 11)
|
||||
extern const int32_t IA32_APIC_BASE_BSP;
|
||||
extern const int32_t IA32_APIC_BASE_EXTD;
|
||||
extern const int32_t IA32_APIC_BASE_EN;
|
||||
|
||||
|
||||
// Note: Duplicated in apic.js
|
||||
#define APIC_ADDRESS ((int32_t)0xFEE00000)
|
||||
extern const int32_t APIC_ADDRESS;
|
||||
|
||||
|
||||
// Segment prefixes must not collide with reg_*s variables
|
||||
// _ZERO is a special zero offset segment
|
||||
#define SEG_PREFIX_NONE (-1)
|
||||
#define SEG_PREFIX_ZERO 7
|
||||
extern const int32_t SEG_PREFIX_NONE;
|
||||
extern const int32_t SEG_PREFIX_ZERO;
|
||||
|
||||
#define PREFIX_MASK_REP 0b11000
|
||||
#define PREFIX_REPZ 0b01000
|
||||
#define PREFIX_REPNZ 0b10000
|
||||
extern const int32_t PREFIX_MASK_REP;
|
||||
extern const int32_t PREFIX_REPZ;
|
||||
extern const int32_t PREFIX_REPNZ;
|
||||
|
||||
#define PREFIX_MASK_SEGMENT 0b111
|
||||
#define PREFIX_MASK_OPSIZE 0b100000
|
||||
#define PREFIX_MASK_ADDRSIZE 0b1000000
|
||||
extern const int32_t PREFIX_MASK_SEGMENT;
|
||||
extern const int32_t PREFIX_MASK_OPSIZE;
|
||||
extern const int32_t PREFIX_MASK_ADDRSIZE;
|
||||
|
||||
// aliases
|
||||
#define PREFIX_F2 PREFIX_REPNZ
|
||||
#define PREFIX_F3 PREFIX_REPZ
|
||||
#define PREFIX_66 PREFIX_MASK_OPSIZE
|
||||
extern const int32_t PREFIX_F2;
|
||||
extern const int32_t PREFIX_F3;
|
||||
extern const int32_t PREFIX_66;
|
||||
|
||||
#define LOG_CPU 0x000002
|
||||
extern const int32_t LOG_CPU;
|
||||
|
||||
#define A20_MASK (~(1 << 20))
|
||||
#define A20_MASK16 (~(1 << (20 - 1)))
|
||||
#define A20_MASK32 (~(1 << (20 - 2)))
|
||||
extern const int32_t A20_MASK;
|
||||
extern const int32_t A20_MASK16;
|
||||
extern const int32_t A20_MASK32;
|
||||
|
||||
#define MXCSR_MASK (0xFFFF & ~(1 << 6))
|
||||
extern const int32_t MXCSR_MASK;
|
||||
|
|
|
|||
253
src/native/cpu.c
253
src/native/cpu.c
|
|
@ -1,4 +1,3 @@
|
|||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -17,16 +16,198 @@
|
|||
#include "rust_imports.h"
|
||||
#include "shared.h"
|
||||
|
||||
const int32_t FLAG_CARRY = 1;
|
||||
const int32_t FLAG_PARITY = 4;
|
||||
const int32_t FLAG_ADJUST = 16;
|
||||
const int32_t FLAG_ZERO = 64;
|
||||
const int32_t FLAG_SIGN = 128;
|
||||
const int32_t FLAG_TRAP = 256;
|
||||
const int32_t FLAG_INTERRUPT = 512;
|
||||
const int32_t FLAG_DIRECTION = 1024;
|
||||
const int32_t FLAG_OVERFLOW = 2048;
|
||||
const int32_t FLAG_IOPL = (1 << 12 | 1 << 13);
|
||||
const int32_t FLAG_NT = (1 << 14);
|
||||
const int32_t FLAG_RF = (1 << 16);
|
||||
const int32_t FLAG_VM = (1 << 17);
|
||||
const int32_t FLAG_AC = (1 << 18);
|
||||
const int32_t FLAG_VIF = (1 << 19);
|
||||
const int32_t FLAG_VIP = (1 << 20);
|
||||
const int32_t FLAG_ID = (1 << 21);
|
||||
const int32_t FLAGS_DEFAULT = (1 << 1);
|
||||
|
||||
const int32_t FLAGS_MASK = (
|
||||
FLAG_CARRY | FLAG_PARITY | FLAG_ADJUST | FLAG_ZERO | FLAG_SIGN | FLAG_TRAP | FLAG_INTERRUPT |
|
||||
FLAG_DIRECTION | FLAG_OVERFLOW | FLAG_IOPL | FLAG_NT | FLAG_RF | FLAG_VM | FLAG_AC |
|
||||
FLAG_VIF | FLAG_VIP | FLAG_ID);
|
||||
|
||||
const int32_t FLAGS_ALL = (FLAG_CARRY | FLAG_PARITY | FLAG_ADJUST | FLAG_ZERO | FLAG_SIGN | FLAG_OVERFLOW);
|
||||
|
||||
const int32_t OPSIZE_8 = 7;
|
||||
const int32_t OPSIZE_16 = 15;
|
||||
const int32_t OPSIZE_32 = 31;
|
||||
|
||||
const int32_t EAX = 0;
|
||||
const int32_t ECX = 1;
|
||||
const int32_t EDX = 2;
|
||||
const int32_t EBX = 3;
|
||||
const int32_t ESP = 4;
|
||||
const int32_t EBP = 5;
|
||||
const int32_t ESI = 6;
|
||||
const int32_t EDI = 7;
|
||||
|
||||
const int32_t AX = 0;
|
||||
const int32_t CX = 2;
|
||||
const int32_t DX = 4;
|
||||
const int32_t BX = 6;
|
||||
const int32_t SP = 8;
|
||||
const int32_t BP = 10;
|
||||
const int32_t SI = 12;
|
||||
const int32_t DI = 14;
|
||||
|
||||
const int32_t AL = 0;
|
||||
const int32_t CL = 4;
|
||||
const int32_t DL = 8;
|
||||
const int32_t BL = 12;
|
||||
const int32_t AH = 1;
|
||||
const int32_t CH = 5;
|
||||
const int32_t DH = 9;
|
||||
const int32_t BH = 13;
|
||||
|
||||
const int32_t ES = 0;
|
||||
const int32_t CS = 1;
|
||||
const int32_t SS = 2;
|
||||
const int32_t DS = 3;
|
||||
const int32_t FS = 4;
|
||||
const int32_t GS = 5;
|
||||
|
||||
const int32_t TR = 6;
|
||||
const int32_t LDTR = 7;
|
||||
|
||||
|
||||
const int32_t PAGE_TABLE_PRESENT_MASK = (1 << 0);
|
||||
const int32_t PAGE_TABLE_RW_MASK = (1 << 1);
|
||||
const int32_t PAGE_TABLE_USER_MASK = (1 << 2);
|
||||
const int32_t PAGE_TABLE_ACCESSED_MASK = (1 << 5);
|
||||
const int32_t PAGE_TABLE_DIRTY_MASK = (1 << 6);
|
||||
const int32_t PAGE_TABLE_PSE_MASK = (1 << 7);
|
||||
const int32_t PAGE_TABLE_GLOBAL_MASK = (1 << 8);
|
||||
|
||||
const int32_t MMAP_BLOCK_BITS = 17;
|
||||
const int32_t MMAP_BLOCK_SIZE = (1 << MMAP_BLOCK_BITS);
|
||||
|
||||
const int32_t CR0_PE = 1;
|
||||
const int32_t CR0_MP = (1 << 1);
|
||||
const int32_t CR0_EM = (1 << 2);
|
||||
const int32_t CR0_TS = (1 << 3);
|
||||
const int32_t CR0_ET = (1 << 4);
|
||||
const int32_t CR0_WP = (1 << 16);
|
||||
const int32_t CR0_NW = (1 << 29);
|
||||
const int32_t CR0_CD = (1 << 30);
|
||||
const int32_t CR0_PG = (1 << 31);
|
||||
|
||||
const int32_t CR4_VME = (1);
|
||||
const int32_t CR4_PVI = (1 << 1);
|
||||
const int32_t CR4_TSD = (1 << 2);
|
||||
const int32_t CR4_PSE = (1 << 4);
|
||||
const int32_t CR4_DE = (1 << 3);
|
||||
const int32_t CR4_PAE = (1 << 5);
|
||||
const int32_t CR4_PGE = (1 << 7);
|
||||
|
||||
|
||||
const int32_t IA32_SYSENTER_CS = 0x174;
|
||||
const int32_t IA32_SYSENTER_ESP = 0x175;
|
||||
const int32_t IA32_SYSENTER_EIP = 0x176;
|
||||
|
||||
const int32_t IA32_TIME_STAMP_COUNTER = 0x10;
|
||||
const int32_t IA32_PLATFORM_ID = 0x17;
|
||||
const int32_t IA32_APIC_BASE_MSR = 0x1B;
|
||||
const int32_t IA32_BIOS_SIGN_ID = 0x8B;
|
||||
const int32_t MSR_PLATFORM_INFO = 0xCE;
|
||||
const int32_t MSR_MISC_FEATURE_ENABLES = 0x140;
|
||||
const int32_t IA32_MISC_ENABLE = 0x1A0;
|
||||
const int32_t IA32_RTIT_CTL = 0x570;
|
||||
const int32_t MSR_SMI_COUNT = 0x34;
|
||||
const int32_t IA32_MCG_CAP = 0x179;
|
||||
const int32_t IA32_KERNEL_GS_BASE = 0xC0000101;
|
||||
const int32_t MSR_PKG_C2_RESIDENCY = 0x60D;
|
||||
|
||||
const int32_t IA32_APIC_BASE_BSP = (1 << 8);
|
||||
const int32_t IA32_APIC_BASE_EXTD = (1 << 10);
|
||||
const int32_t IA32_APIC_BASE_EN = (1 << 11);
|
||||
|
||||
|
||||
// Note: Duplicated in apic.js
|
||||
const int32_t APIC_ADDRESS = ((int32_t)0xFEE00000);
|
||||
|
||||
|
||||
// Segment prefixes must not collide with reg_*s variables
|
||||
// _ZERO is a special zero offset segment
|
||||
const int32_t SEG_PREFIX_NONE = (-1);
|
||||
const int32_t SEG_PREFIX_ZERO = 7;
|
||||
|
||||
const int32_t PREFIX_MASK_REP = 0b11000;
|
||||
const int32_t PREFIX_REPZ = 0b01000;
|
||||
const int32_t PREFIX_REPNZ = 0b10000;
|
||||
|
||||
const int32_t PREFIX_MASK_SEGMENT = 0b111;
|
||||
const int32_t PREFIX_MASK_OPSIZE = 0b100000;
|
||||
const int32_t PREFIX_MASK_ADDRSIZE = 0b1000000;
|
||||
|
||||
// aliases
|
||||
const int32_t PREFIX_F2 = PREFIX_REPNZ;
|
||||
const int32_t PREFIX_F3 = PREFIX_REPZ;
|
||||
const int32_t PREFIX_66 = PREFIX_MASK_OPSIZE;
|
||||
|
||||
const int32_t LOG_CPU = 0x000002;
|
||||
|
||||
const int32_t A20_MASK = (~(1 << 20));
|
||||
const int32_t A20_MASK16 = (~(1 << (20 - 1)));
|
||||
const int32_t A20_MASK32 = (~(1 << (20 - 2)));
|
||||
|
||||
const int32_t MXCSR_MASK = (0xFFFF & ~(1 << 6));
|
||||
|
||||
const int32_t CPU_EXCEPTION_DE = 0; // Divide Error
|
||||
const int32_t CPU_EXCEPTION_DB = 1; // Debug Exception
|
||||
const int32_t CPU_EXCEPTION_NMI = 2; // NMI Interrupt
|
||||
const int32_t CPU_EXCEPTION_BP = 3; // Breakpoint
|
||||
const int32_t CPU_EXCEPTION_OF = 4; // Overflow
|
||||
const int32_t CPU_EXCEPTION_BR = 5; // BOUND Range Exceeded
|
||||
const int32_t CPU_EXCEPTION_UD = 6; // Invalid Opcode
|
||||
const int32_t CPU_EXCEPTION_NM = 7; // Device Not Available
|
||||
const int32_t CPU_EXCEPTION_DF = 8; // Double Fault
|
||||
const int32_t CPU_EXCEPTION_TS = 10; // Invalid TSS
|
||||
const int32_t CPU_EXCEPTION_NP = 11; // Segment Not Present
|
||||
const int32_t CPU_EXCEPTION_SS = 12; // Stack-Segment Fault
|
||||
const int32_t CPU_EXCEPTION_GP = 13; // General Protection
|
||||
const int32_t CPU_EXCEPTION_PF = 14; // Page Fault
|
||||
const int32_t CPU_EXCEPTION_MF = 16; // x87 FPU Floating-Point Error
|
||||
const int32_t CPU_EXCEPTION_AC = 17; // Alignment Check
|
||||
const int32_t CPU_EXCEPTION_MC = 18; // Machine Check Abort
|
||||
const int32_t CPU_EXCEPTION_XM = 19; // SIMD Floating-Point Exception
|
||||
const int32_t CPU_EXCEPTION_VE = 20; // Virtualization Exception
|
||||
|
||||
const int32_t LOOP_COUNTER = 20011;
|
||||
const double_t TSC_RATE = (50 * 1000);
|
||||
|
||||
const bool CHECK_TLB_INVARIANTS = false;
|
||||
|
||||
const int32_t TLB_VALID = (1 << 0);
|
||||
const int32_t TLB_READONLY = (1 << 1);
|
||||
const int32_t TLB_NO_USER = (1 << 2);
|
||||
const int32_t TLB_IN_MAPPED_RANGE = (1 << 3);
|
||||
const int32_t TLB_GLOBAL = (1 << 4);
|
||||
const int32_t TLB_HAS_CODE = (1 << 5);
|
||||
|
||||
#if DEBUG
|
||||
bool must_not_fault = false;
|
||||
#endif
|
||||
|
||||
#if CHECK_CPU_EXCEPTIONS
|
||||
#if 1
|
||||
int32_t current_cpu_exception = -1;
|
||||
void assert_no_cpu_exception() {
|
||||
if(current_cpu_exception != -1)
|
||||
{
|
||||
dbg_log("Expected no cpu exception, got %d", current_cpu_exception);
|
||||
dbg_log1("Expected no cpu exception, got %d", current_cpu_exception);
|
||||
dbg_trace();
|
||||
assert(false);
|
||||
}
|
||||
|
|
@ -43,6 +224,7 @@ uint64_t tsc_offset = 0;
|
|||
|
||||
bool jit_block_boundary = false;
|
||||
|
||||
const int32_t VALID_TLB_ENTRY_MAX = 10000;
|
||||
int32_t valid_tlb_entries[VALID_TLB_ENTRY_MAX] = {0};
|
||||
int32_t valid_tlb_entries_count = 0;
|
||||
|
||||
|
|
@ -111,9 +293,9 @@ void update_eflags(int32_t new_flags)
|
|||
|
||||
void trigger_pagefault(bool write, bool user, bool present)
|
||||
{
|
||||
if(LOG_PAGE_FAULTS)
|
||||
if(false)
|
||||
{
|
||||
dbg_log("page fault w=%d u=%d p=%d eip=%x cr2=%x",
|
||||
dbg_log5("page fault w=%d u=%d p=%d eip=%x cr2=%x",
|
||||
write, user, present, *previous_ip, cr[2]);
|
||||
dbg_trace();
|
||||
}
|
||||
|
|
@ -296,20 +478,21 @@ int32_t do_page_translation(int32_t addr, bool for_writing, bool user)
|
|||
}
|
||||
else
|
||||
{
|
||||
#if CHECK_TLB_INVARIANTS
|
||||
bool found = false;
|
||||
|
||||
for(int32_t i = 0; i < valid_tlb_entries_count; i++)
|
||||
if(CHECK_TLB_INVARIANTS)
|
||||
{
|
||||
if(valid_tlb_entries[i] == page)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool found = false;
|
||||
|
||||
assert(found);
|
||||
#endif
|
||||
for(int32_t i = 0; i < valid_tlb_entries_count; i++)
|
||||
{
|
||||
if(valid_tlb_entries[i] == page)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(found);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_in_mapped_range = in_mapped_range(high);
|
||||
|
|
@ -356,7 +539,8 @@ void tlb_set_has_code(uint32_t physical_page, bool has_code)
|
|||
|
||||
void check_tlb_invariants(void)
|
||||
{
|
||||
#if CHECK_TLB_INVARIANTS
|
||||
if(!CHECK_TLB_INVARIANTS) return;
|
||||
|
||||
for(int32_t i = 0; i < valid_tlb_entries_count; i++)
|
||||
{
|
||||
int32_t page = valid_tlb_entries[i];
|
||||
|
|
@ -381,7 +565,6 @@ void check_tlb_invariants(void)
|
|||
// problem when clearing code from a page)
|
||||
dbg_assert(!entry_has_code || has_code);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t get_valid_tlb_entries_count(void)
|
||||
|
|
@ -704,7 +887,7 @@ bool same_page(int32_t addr1, int32_t addr2)
|
|||
void cycle_internal()
|
||||
{
|
||||
profiler_stat_increment(S_CYCLE_INTERNAL);
|
||||
#if ENABLE_JIT
|
||||
if(true) {
|
||||
|
||||
*previous_ip = *instruction_pointer;
|
||||
uint32_t phys_addr = get_phys_eip();
|
||||
|
|
@ -722,7 +905,7 @@ void cycle_internal()
|
|||
|
||||
uint16_t wasm_table_index = entry & 0xFFFF;
|
||||
uint16_t initial_state = entry >> 16;
|
||||
call_indirect1(wasm_table_index, initial_state);
|
||||
call_indirect1((uint32_t)wasm_table_index + 0x100, initial_state);
|
||||
|
||||
clear_current_cpu_exception();
|
||||
|
||||
|
|
@ -751,7 +934,9 @@ void cycle_internal()
|
|||
profiler_stat_increment_by(S_RUN_INTERPRETED_STEPS, *timestamp_counter - initial_tsc);
|
||||
}
|
||||
|
||||
#else
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use non-JIT mode */
|
||||
previous_ip[0] = instruction_pointer[0];
|
||||
|
||||
|
|
@ -764,7 +949,7 @@ void cycle_internal()
|
|||
#endif
|
||||
|
||||
run_instruction(opcode | !!*is_32 << 8);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void run_prefix_instruction()
|
||||
|
|
@ -806,7 +991,7 @@ void raise_exception(int32_t interrupt_nr)
|
|||
#if DEBUG
|
||||
if(must_not_fault)
|
||||
{
|
||||
dbg_log("Unexpected fault: 0x%x", interrupt_nr);
|
||||
dbg_log1("Unexpected fault: 0x%x", interrupt_nr);
|
||||
dbg_trace();
|
||||
assert(false);
|
||||
}
|
||||
|
|
@ -827,7 +1012,7 @@ void raise_exception_with_code(int32_t interrupt_nr, int32_t error_code)
|
|||
#if DEBUG
|
||||
if(must_not_fault)
|
||||
{
|
||||
dbg_log("Unexpected fault: 0x%x with code 0x%x", interrupt_nr, error_code);
|
||||
dbg_log2("Unexpected fault: 0x%x with code 0x%x", interrupt_nr, error_code);
|
||||
dbg_trace();
|
||||
assert(false);
|
||||
}
|
||||
|
|
@ -1467,12 +1652,13 @@ void clear_tlb()
|
|||
|
||||
valid_tlb_entries_count = global_page_offset;
|
||||
|
||||
#if CHECK_TLB_INVARIANTS
|
||||
for(int32_t i = 0; i < 0x100000; i++)
|
||||
if(CHECK_TLB_INVARIANTS)
|
||||
{
|
||||
assert(tlb_data[i] == 0 || (tlb_data[i] & TLB_GLOBAL));
|
||||
for(int32_t i = 0; i < 0x100000; i++)
|
||||
{
|
||||
assert(tlb_data[i] == 0 || (tlb_data[i] & TLB_GLOBAL));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void full_clear_tlb()
|
||||
|
|
@ -1491,12 +1677,13 @@ void full_clear_tlb()
|
|||
|
||||
valid_tlb_entries_count = 0;
|
||||
|
||||
#if CHECK_TLB_INVARIANTS
|
||||
for(int32_t i = 0; i < 0x100000; i++)
|
||||
if(CHECK_TLB_INVARIANTS)
|
||||
{
|
||||
assert(tlb_data[i] == 0);
|
||||
for(int32_t i = 0; i < 0x100000; i++)
|
||||
{
|
||||
assert(tlb_data[i] == 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void invlpg(int32_t addr)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -21,7 +20,7 @@ union reg128 {
|
|||
float_t f32[4];
|
||||
double_t f64[2];
|
||||
};
|
||||
_Static_assert(sizeof(union reg128) == 16, "reg128 is 16 bytes");
|
||||
//_Static_assert(sizeof(union reg128) == 16, "reg128 is 16 bytes");
|
||||
|
||||
union reg64 {
|
||||
int8_t i8[8];
|
||||
|
|
@ -35,7 +34,7 @@ union reg64 {
|
|||
float_t f32[2];
|
||||
double f64[1];
|
||||
};
|
||||
_Static_assert(sizeof(union reg64) == 8, "reg64 is 8 bytes");
|
||||
//_Static_assert(sizeof(union reg64) == 8, "reg64 is 8 bytes");
|
||||
|
||||
typedef uint8_t cached_state_flags;
|
||||
|
||||
|
|
@ -43,36 +42,36 @@ typedef uint8_t cached_state_flags;
|
|||
// state-altering, etc.)
|
||||
extern bool jit_block_boundary;
|
||||
|
||||
#define VALID_TLB_ENTRY_MAX 10000
|
||||
int32_t valid_tlb_entries[VALID_TLB_ENTRY_MAX];
|
||||
int32_t valid_tlb_entries_count;
|
||||
extern const int32_t VALID_TLB_ENTRY_MAX;
|
||||
extern int32_t valid_tlb_entries[10000];
|
||||
extern int32_t valid_tlb_entries_count;
|
||||
|
||||
#define TLB_VALID (1 << 0)
|
||||
#define TLB_READONLY (1 << 1)
|
||||
#define TLB_NO_USER (1 << 2)
|
||||
#define TLB_IN_MAPPED_RANGE (1 << 3)
|
||||
#define TLB_GLOBAL (1 << 4)
|
||||
#define TLB_HAS_CODE (1 << 5)
|
||||
extern const int32_t TLB_VALID;
|
||||
extern const int32_t TLB_READONLY;
|
||||
extern const int32_t TLB_NO_USER;
|
||||
extern const int32_t TLB_IN_MAPPED_RANGE;
|
||||
extern const int32_t TLB_GLOBAL;
|
||||
extern const int32_t TLB_HAS_CODE;
|
||||
|
||||
static const int32_t CPU_EXCEPTION_DE = 0; // Divide Error
|
||||
static const int32_t CPU_EXCEPTION_DB = 1; // Debug Exception
|
||||
static const int32_t CPU_EXCEPTION_NMI = 2; // NMI Interrupt
|
||||
static const int32_t CPU_EXCEPTION_BP = 3; // Breakpoint
|
||||
static const int32_t CPU_EXCEPTION_OF = 4; // Overflow
|
||||
static const int32_t CPU_EXCEPTION_BR = 5; // BOUND Range Exceeded
|
||||
static const int32_t CPU_EXCEPTION_UD = 6; // Invalid Opcode
|
||||
static const int32_t CPU_EXCEPTION_NM = 7; // Device Not Available
|
||||
static const int32_t CPU_EXCEPTION_DF = 8; // Double Fault
|
||||
static const int32_t CPU_EXCEPTION_TS = 10; // Invalid TSS
|
||||
static const int32_t CPU_EXCEPTION_NP = 11; // Segment Not Present
|
||||
static const int32_t CPU_EXCEPTION_SS = 12; // Stack-Segment Fault
|
||||
static const int32_t CPU_EXCEPTION_GP = 13; // General Protection
|
||||
static const int32_t CPU_EXCEPTION_PF = 14; // Page Fault
|
||||
static const int32_t CPU_EXCEPTION_MF = 16; // x87 FPU Floating-Point Error
|
||||
static const int32_t CPU_EXCEPTION_AC = 17; // Alignment Check
|
||||
static const int32_t CPU_EXCEPTION_MC = 18; // Machine Check Abort
|
||||
static const int32_t CPU_EXCEPTION_XM = 19; // SIMD Floating-Point Exception
|
||||
static const int32_t CPU_EXCEPTION_VE = 20; // Virtualization Exception
|
||||
extern const int32_t CPU_EXCEPTION_DE; // Divide Error
|
||||
extern const int32_t CPU_EXCEPTION_DB; // Debug Exception
|
||||
extern const int32_t CPU_EXCEPTION_NMI; // NMI Interrupt
|
||||
extern const int32_t CPU_EXCEPTION_BP; // Breakpoint
|
||||
extern const int32_t CPU_EXCEPTION_OF; // Overflow
|
||||
extern const int32_t CPU_EXCEPTION_BR; // BOUND Range Exceeded
|
||||
extern const int32_t CPU_EXCEPTION_UD; // Invalid Opcode
|
||||
extern const int32_t CPU_EXCEPTION_NM; // Device Not Available
|
||||
extern const int32_t CPU_EXCEPTION_DF; // Double Fault
|
||||
extern const int32_t CPU_EXCEPTION_TS; // Invalid TSS
|
||||
extern const int32_t CPU_EXCEPTION_NP; // Segment Not Present
|
||||
extern const int32_t CPU_EXCEPTION_SS; // Stack-Segment Fault
|
||||
extern const int32_t CPU_EXCEPTION_GP; // General Protection
|
||||
extern const int32_t CPU_EXCEPTION_PF; // Page Fault
|
||||
extern const int32_t CPU_EXCEPTION_MF; // x87 FPU Floating-Point Error
|
||||
extern const int32_t CPU_EXCEPTION_AC; // Alignment Check
|
||||
extern const int32_t CPU_EXCEPTION_MC; // Machine Check Abort
|
||||
extern const int32_t CPU_EXCEPTION_XM; // SIMD Floating-Point Exception
|
||||
extern const int32_t CPU_EXCEPTION_VE; // Virtualization Exception
|
||||
|
||||
// defined in call-indirect.ll
|
||||
extern void call_indirect(int32_t index);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,29 @@
|
|||
#include "log.h"
|
||||
#include "misc_instr.h"
|
||||
|
||||
//#ifndef M_LOG2E
|
||||
const double_t M_LOG2E = 1.44269504088896340736;
|
||||
//#endif
|
||||
|
||||
//#ifndef M_LN2
|
||||
const double_t M_LN2 = 0.693147180559945309417;
|
||||
//#endif
|
||||
|
||||
//#ifndef M_LN10
|
||||
const double_t M_LN10 = 2.30258509299404568402;
|
||||
//#endif
|
||||
|
||||
//#ifndef M_PI
|
||||
const double_t M_PI = 3.14159265358979323846;
|
||||
//#endif
|
||||
|
||||
const int32_t FPU_C0 = 0x100;
|
||||
const int32_t FPU_C1 = 0x200;
|
||||
const int32_t FPU_C2 = 0x400;
|
||||
const int32_t FPU_C3 = 0x4000;
|
||||
const int32_t FPU_RESULT_FLAGS = (FPU_C0 | FPU_C1 | FPU_C2 | FPU_C3);
|
||||
const int32_t FPU_STACK_TOP = 0x3800;
|
||||
|
||||
// precision, round & infinity control
|
||||
const int32_t
|
||||
FPU_PC = 3 << 8,
|
||||
|
|
@ -253,7 +276,7 @@ void fpu_ftst(double_t x)
|
|||
{
|
||||
*fpu_status_word &= ~FPU_RESULT_FLAGS;
|
||||
|
||||
if(isnan(x))
|
||||
if(isnan_XXX(x))
|
||||
{
|
||||
*fpu_status_word |= FPU_C3 | FPU_C2 | FPU_C0;
|
||||
}
|
||||
|
|
@ -278,7 +301,7 @@ void fpu_fxam(double_t x)
|
|||
{
|
||||
*fpu_status_word |= FPU_C3 | FPU_C0;
|
||||
}
|
||||
else if(isnan(x))
|
||||
else if(isnan_XXX(x))
|
||||
{
|
||||
*fpu_status_word |= FPU_C0;
|
||||
}
|
||||
|
|
@ -326,7 +349,7 @@ int32_t fpu_load_tag_word()
|
|||
{
|
||||
tag_word |= 1 << (i << 1);
|
||||
}
|
||||
else if(!isfinite(value))
|
||||
else if(!isfinite_XXX(value))
|
||||
{
|
||||
tag_word |= 2 << (i << 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,28 +4,28 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef M_LOG2E
|
||||
#define M_LOG2E 1.44269504088896340736
|
||||
#endif
|
||||
//#ifndef M_LOG2E
|
||||
extern const double_t M_LOG2E;
|
||||
//#endif
|
||||
|
||||
#ifndef M_LN2
|
||||
#define M_LN2 0.693147180559945309417
|
||||
#endif
|
||||
//#ifndef M_LN2
|
||||
extern const double_t M_LN2;
|
||||
//#endif
|
||||
|
||||
#ifndef M_LN10
|
||||
#define M_LN10 2.30258509299404568402
|
||||
#endif
|
||||
//#ifndef M_LN10
|
||||
extern const double_t M_LN10;
|
||||
//#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
//#ifndef M_PI
|
||||
extern const double_t M_PI;
|
||||
//#endif
|
||||
|
||||
#define FPU_C0 0x100
|
||||
#define FPU_C1 0x200
|
||||
#define FPU_C2 0x400
|
||||
#define FPU_C3 0x4000
|
||||
#define FPU_RESULT_FLAGS (FPU_C0 | FPU_C1 | FPU_C2 | FPU_C3)
|
||||
#define FPU_STACK_TOP 0x3800
|
||||
extern const int32_t FPU_C0;
|
||||
extern const int32_t FPU_C1;
|
||||
extern const int32_t FPU_C2;
|
||||
extern const int32_t FPU_C3;
|
||||
extern const int32_t FPU_RESULT_FLAGS;
|
||||
extern const int32_t FPU_STACK_TOP;
|
||||
|
||||
double_t fpu_get_st0(void);
|
||||
double_t fpu_get_sti(int32_t i);
|
||||
|
|
|
|||
96
src/native/global_pointers.c
Normal file
96
src/native/global_pointers.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "const.h"
|
||||
#include "shared.h"
|
||||
|
||||
uint8_t* const reg8 = (uint8_t* const) 4;
|
||||
uint16_t* const reg16 = (uint16_t* const) 4;
|
||||
int8_t* const reg8s = (int8_t* const) 4;
|
||||
int16_t* const reg16s = (int16_t* const) 4;
|
||||
int32_t* const reg32s = (int32_t* const) 4;
|
||||
|
||||
int32_t* const last_op1 = (int32_t* const) 512;
|
||||
int32_t* const last_op2 = (int32_t* const) 516;
|
||||
int32_t* const last_op_size = (int32_t* const) 520;
|
||||
int32_t* const last_add_result = (int32_t* const) 524;
|
||||
int32_t* const last_result = (int32_t* const) 528;
|
||||
int32_t* const flags_changed = (int32_t* const) 532;
|
||||
int32_t* const flags = (int32_t* const) 536;
|
||||
|
||||
bool* const page_fault = (bool* const) 540;
|
||||
|
||||
// gap
|
||||
|
||||
bool* const a20_enabled = (bool* const) 552;
|
||||
int32_t* const instruction_pointer = (int32_t* const) 556;
|
||||
int32_t* const previous_ip = (int32_t* const) 560;
|
||||
|
||||
int32_t* const idtr_size = (int32_t* const) 564;
|
||||
int32_t* const idtr_offset = (int32_t* const) 568;
|
||||
int32_t* const gdtr_size = (int32_t* const) 572;
|
||||
int32_t* const gdtr_offset = (int32_t* const) 576;
|
||||
int32_t* const cr = (int32_t* const) 580; // length 32
|
||||
|
||||
uint8_t* const cpl = (uint8_t* const) 612;
|
||||
bool* const in_hlt = (bool* const) 616;
|
||||
int32_t* const last_virt_eip = (int32_t* const) 620;
|
||||
int32_t* const eip_phys = (int32_t* const) 624;
|
||||
int32_t* const last_virt_esp = (int32_t* const) 628;
|
||||
int32_t* const esp_phys = (int32_t* const) 632;
|
||||
int32_t* const sysenter_cs = (int32_t* const) 636;
|
||||
int32_t* const sysenter_esp = (int32_t* const) 640;
|
||||
int32_t* const sysenter_eip = (int32_t* const) 644;
|
||||
uint8_t* const prefixes = (uint8_t* const) 648;
|
||||
// gap
|
||||
uint32_t* const timestamp_counter = (uint32_t* const) 664;
|
||||
|
||||
uint16_t* const sreg = (uint16_t* const) 668;
|
||||
int32_t* const dreg = (int32_t* const) 684; // length 32
|
||||
int32_t* const fw_value = (int32_t* const) 720;
|
||||
bool* const segment_is_null = (bool* const) 724; // length 8
|
||||
int32_t* const segment_offsets = (int32_t* const) 736; // length 32
|
||||
uint32_t* const segment_limits = (uint32_t* const) 768; // length 32
|
||||
|
||||
bool* const protected_mode = (bool* const) 800;
|
||||
bool* const is_32 = (bool* const) 804;
|
||||
bool* const stack_size_32 = (bool* const) 808;
|
||||
uint32_t* const memory_size = (uint32_t* const) 812;
|
||||
int32_t* const fpu_stack_empty = (int32_t* const) 816;
|
||||
|
||||
// gap
|
||||
|
||||
int32_t* const mxcsr = (int32_t* const) 824;
|
||||
|
||||
union reg128* const reg_xmm = (union reg128* const) 828; // length 128
|
||||
|
||||
uint64_t* const current_tsc = (uint64_t* const) 956;
|
||||
|
||||
double_t* const fpu_st = (double_t* const) 968; // length 64
|
||||
uint8_t* const fpu_st8 = (uint8_t* const) 968;
|
||||
int32_t* const fpu_st32 = (int32_t* const) 968;
|
||||
|
||||
uint32_t* const fpu_stack_ptr = (uint32_t* const) 1032;
|
||||
int32_t* const fpu_control_word = (int32_t* const) 1036;
|
||||
int32_t* const fpu_status_word = (int32_t* const) 1040;
|
||||
int32_t* const fpu_opcode = (int32_t* const) 1044;
|
||||
int32_t* const fpu_ip = (int32_t* const) 1048;
|
||||
int32_t* const fpu_ip_selector = (int32_t* const) 1052;
|
||||
int32_t* const fpu_dp = (int32_t* const) 1056;
|
||||
int32_t* const fpu_dp_selector = (int32_t* const) 1060;
|
||||
|
||||
union reg64* const reg_mmx = (union reg64* const) 1064; // length 64
|
||||
|
||||
// gap
|
||||
|
||||
uint32_t* const opstats_buffer = (uint32_t* const) 0x1000; // length 0x400
|
||||
uint32_t* const opstats_buffer_0f = (uint32_t* const) 0x1400; // length 0x400
|
||||
|
||||
// gap
|
||||
|
||||
int32_t* const tlb_data = (int32_t* const) 0x400000; // length 0x100000*4
|
||||
|
||||
uint8_t* const mem8 = (uint8_t* const) 0x800000;
|
||||
uint16_t* const mem16 = (uint16_t* const) 0x800000;
|
||||
int32_t* const mem32s = (int32_t* const) 0x800000;
|
||||
|
|
@ -7,92 +7,92 @@
|
|||
#include "const.h"
|
||||
#include "shared.h"
|
||||
|
||||
static uint8_t* const reg8 = (uint8_t* const) 4;
|
||||
static uint16_t* const reg16 = (uint16_t* const) 4;
|
||||
static int8_t* const reg8s = (int8_t* const) 4;
|
||||
static int16_t* const reg16s = (int16_t* const) 4;
|
||||
static int32_t* const reg32s = (int32_t* const) 4;
|
||||
extern uint8_t* const reg8;
|
||||
extern uint16_t* const reg16;
|
||||
extern int8_t* const reg8s;
|
||||
extern int16_t* const reg16s;
|
||||
extern int32_t* const reg32s;
|
||||
|
||||
static int32_t* const last_op1 = (int32_t* const) 512;
|
||||
static int32_t* const last_op2 = (int32_t* const) 516;
|
||||
static int32_t* const last_op_size = (int32_t* const) 520;
|
||||
static int32_t* const last_add_result = (int32_t* const) 524;
|
||||
static int32_t* const last_result = (int32_t* const) 528;
|
||||
static int32_t* const flags_changed = (int32_t* const) 532;
|
||||
static int32_t* const flags = (int32_t* const) 536;
|
||||
extern int32_t* const last_op1;
|
||||
extern int32_t* const last_op2;
|
||||
extern int32_t* const last_op_size;
|
||||
extern int32_t* const last_add_result;
|
||||
extern int32_t* const last_result;
|
||||
extern int32_t* const flags_changed;
|
||||
extern int32_t* const flags;
|
||||
|
||||
static bool* const page_fault = (bool* const) 540;
|
||||
extern bool* const page_fault;
|
||||
|
||||
// gap
|
||||
|
||||
static bool* const a20_enabled = (bool* const) 552;
|
||||
static int32_t* const instruction_pointer = (int32_t* const) 556;
|
||||
static int32_t* const previous_ip = (int32_t* const) 560;
|
||||
extern bool* const a20_enabled;
|
||||
extern int32_t* const instruction_pointer;
|
||||
extern int32_t* const previous_ip;
|
||||
|
||||
static int32_t* const idtr_size = (int32_t* const) 564;
|
||||
static int32_t* const idtr_offset = (int32_t* const) 568;
|
||||
static int32_t* const gdtr_size = (int32_t* const) 572;
|
||||
static int32_t* const gdtr_offset = (int32_t* const) 576;
|
||||
static int32_t* const cr = (int32_t* const) 580; // length 32
|
||||
extern int32_t* const idtr_size;
|
||||
extern int32_t* const idtr_offset;
|
||||
extern int32_t* const gdtr_size;
|
||||
extern int32_t* const gdtr_offset;
|
||||
extern int32_t* const cr; // length 32
|
||||
|
||||
static uint8_t* const cpl = (uint8_t* const) 612;
|
||||
static bool* const in_hlt = (bool* const) 616;
|
||||
static int32_t* const last_virt_eip = (int32_t* const) 620;
|
||||
static int32_t* const eip_phys = (int32_t* const) 624;
|
||||
static int32_t* const last_virt_esp = (int32_t* const) 628;
|
||||
static int32_t* const esp_phys = (int32_t* const) 632;
|
||||
static int32_t* const sysenter_cs = (int32_t* const) 636;
|
||||
static int32_t* const sysenter_esp = (int32_t* const) 640;
|
||||
static int32_t* const sysenter_eip = (int32_t* const) 644;
|
||||
static uint8_t* const prefixes = (uint8_t* const) 648;
|
||||
extern uint8_t* const cpl;
|
||||
extern bool* const in_hlt;
|
||||
extern int32_t* const last_virt_eip;
|
||||
extern int32_t* const eip_phys;
|
||||
extern int32_t* const last_virt_esp;
|
||||
extern int32_t* const esp_phys;
|
||||
extern int32_t* const sysenter_cs;
|
||||
extern int32_t* const sysenter_esp;
|
||||
extern int32_t* const sysenter_eip;
|
||||
extern uint8_t* const prefixes;
|
||||
// gap
|
||||
static uint32_t* const timestamp_counter = (uint32_t* const) 664;
|
||||
extern uint32_t* const timestamp_counter;
|
||||
|
||||
static uint16_t* const sreg = (uint16_t* const) 668;
|
||||
static int32_t* const dreg = (int32_t* const) 684; // length 32
|
||||
static int32_t* const fw_value = (int32_t* const) 720;
|
||||
static bool* const segment_is_null = (bool* const) 724; // length 8
|
||||
static int32_t* const segment_offsets = (int32_t* const) 736; // length 32
|
||||
static uint32_t* const segment_limits = (uint32_t* const) 768; // length 32
|
||||
extern uint16_t* const sreg;
|
||||
extern int32_t* const dreg; // length 32
|
||||
extern int32_t* const fw_value;
|
||||
extern bool* const segment_is_null; // length 8
|
||||
extern int32_t* const segment_offsets; // length 32
|
||||
extern uint32_t* const segment_limits; // length 32
|
||||
|
||||
static bool* const protected_mode = (bool* const) 800;
|
||||
static bool* const is_32 = (bool* const) 804;
|
||||
static bool* const stack_size_32 = (bool* const) 808;
|
||||
static uint32_t* const memory_size = (uint32_t* const) 812;
|
||||
static int32_t* const fpu_stack_empty = (int32_t* const) 816;
|
||||
extern bool* const protected_mode;
|
||||
extern bool* const is_32;
|
||||
extern bool* const stack_size_32;
|
||||
extern uint32_t* const memory_size;
|
||||
extern int32_t* const fpu_stack_empty;
|
||||
|
||||
// gap
|
||||
|
||||
static int32_t* const mxcsr = (int32_t* const) 824;
|
||||
extern int32_t* const mxcsr;
|
||||
|
||||
static union reg128* const reg_xmm = (union reg128* const) 828; // length 128
|
||||
extern union reg128* const reg_xmm; // length 128
|
||||
|
||||
static uint64_t* const current_tsc = (uint64_t* const) 956;
|
||||
extern uint64_t* const current_tsc;
|
||||
|
||||
static double_t* const fpu_st = (double_t* const) 968; // length 64
|
||||
static uint8_t* const fpu_st8 = (uint8_t* const) 968;
|
||||
static int32_t* const fpu_st32 = (int32_t* const) 968;
|
||||
extern double_t* const fpu_st; // length 64
|
||||
extern uint8_t* const fpu_st8;
|
||||
extern int32_t* const fpu_st32;
|
||||
|
||||
static uint32_t* const fpu_stack_ptr = (uint32_t* const) 1032;
|
||||
static int32_t* const fpu_control_word = (int32_t* const) 1036;
|
||||
static int32_t* const fpu_status_word = (int32_t* const) 1040;
|
||||
static int32_t* const fpu_opcode = (int32_t* const) 1044;
|
||||
static int32_t* const fpu_ip = (int32_t* const) 1048;
|
||||
static int32_t* const fpu_ip_selector = (int32_t* const) 1052;
|
||||
static int32_t* const fpu_dp = (int32_t* const) 1056;
|
||||
static int32_t* const fpu_dp_selector = (int32_t* const) 1060;
|
||||
extern uint32_t* const fpu_stack_ptr;
|
||||
extern int32_t* const fpu_control_word;
|
||||
extern int32_t* const fpu_status_word;
|
||||
extern int32_t* const fpu_opcode;
|
||||
extern int32_t* const fpu_ip;
|
||||
extern int32_t* const fpu_ip_selector;
|
||||
extern int32_t* const fpu_dp;
|
||||
extern int32_t* const fpu_dp_selector;
|
||||
|
||||
static union reg64* const reg_mmx = (union reg64* const) 1064; // length 64
|
||||
extern union reg64* const reg_mmx; // length 64
|
||||
|
||||
// gap
|
||||
|
||||
static uint32_t* const opstats_buffer = (uint32_t* const) 0x1000; // length 0x400
|
||||
static uint32_t* const opstats_buffer_0f = (uint32_t* const) 0x1400; // length 0x400
|
||||
extern uint32_t* const opstats_buffer; // length 0x400
|
||||
extern uint32_t* const opstats_buffer_0f; // length 0x400
|
||||
|
||||
// gap
|
||||
|
||||
static int32_t* const tlb_data = (int32_t* const) 0x400000; // length 0x100000*4
|
||||
extern int32_t* const tlb_data; // length 0x100000*4
|
||||
|
||||
static uint8_t* const mem8 = (uint8_t* const) 0x800000;
|
||||
static uint16_t* const mem16 = (uint16_t* const) 0x800000;
|
||||
static int32_t* const mem32s = (int32_t* const) 0x800000;
|
||||
extern uint8_t* const mem8;
|
||||
extern uint16_t* const mem16;
|
||||
extern int32_t* const mem32s;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
@ -418,8 +416,8 @@ DEFINE_MODRM_INSTR_READ8(instr_8A, write_reg8(r, ___))
|
|||
DEFINE_MODRM_INSTR_READ16(instr16_8B, write_reg16(r, ___))
|
||||
DEFINE_MODRM_INSTR_READ32(instr32_8B, write_reg32(r, ___))
|
||||
|
||||
bool instr_8C_check_sreg(int32_t sreg) {
|
||||
if(sreg >= 6)
|
||||
bool instr_8C_check_sreg(int32_t seg) {
|
||||
if(seg >= 6)
|
||||
{
|
||||
dbg_log("mov sreg #ud");
|
||||
trigger_ud();
|
||||
|
|
@ -1039,7 +1037,7 @@ void instr_D9_4_reg(int32_t r)
|
|||
fpu_fxam(st0);
|
||||
break;
|
||||
default:
|
||||
dbg_log("%x", r);
|
||||
dbg_log1("%x", r);
|
||||
trigger_ud();
|
||||
}
|
||||
}
|
||||
|
|
@ -1653,9 +1651,9 @@ void instr32_FF_5_mem(int32_t addr)
|
|||
}
|
||||
DEFINE_MODRM_INSTR1_READ32(instr32_FF_6, push32(___))
|
||||
|
||||
void run_instruction(int32_t opcode)
|
||||
{
|
||||
#include "../../build/interpreter.c"
|
||||
}
|
||||
//void run_instruction(int32_t opcode)
|
||||
//{
|
||||
//#include "../../build/interpreter.c"
|
||||
//}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
|
|
|||
|
|
@ -3,75 +3,81 @@
|
|||
#include "cpu.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define SAFE_READ_WRITE8(addr, fun) \
|
||||
int32_t phys_addr = translate_address_write(addr); \
|
||||
int32_t ___ = read8(phys_addr); \
|
||||
write8(phys_addr, fun);
|
||||
extern void SAFE_READ_WRITE8();
|
||||
extern void SAFE_READ_WRITE16();
|
||||
extern void SAFE_READ_WRITE32();
|
||||
|
||||
#define SAFE_READ_WRITE16(addr, fun) \
|
||||
int32_t phys_addr = translate_address_write(addr); \
|
||||
if((phys_addr & 0xFFF) == 0xFFF) \
|
||||
{ \
|
||||
int32_t phys_addr_high = translate_address_write((addr) + 1); \
|
||||
int32_t ___ = virt_boundary_read16(phys_addr, phys_addr_high); \
|
||||
virt_boundary_write16(phys_addr, phys_addr_high, fun); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
int32_t ___ = read16(phys_addr); \
|
||||
write16(phys_addr, fun); \
|
||||
}
|
||||
extern int32_t ___;
|
||||
|
||||
#define SAFE_READ_WRITE32(addr, fun) \
|
||||
int32_t phys_addr = translate_address_write(addr); \
|
||||
if((phys_addr & 0xFFF) >= 0xFFD) \
|
||||
{ \
|
||||
int32_t phys_addr_high = translate_address_write((addr) + 3 & ~3) | ((addr) + 3) & 3; \
|
||||
int32_t ___ = virt_boundary_read32s(phys_addr, phys_addr_high); \
|
||||
virt_boundary_write32(phys_addr, phys_addr_high, fun); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
int32_t ___ = read32s(phys_addr); \
|
||||
write32(phys_addr, fun); \
|
||||
}
|
||||
//#define SAFE_READ_WRITE8(addr, fun) \
|
||||
// int32_t phys_addr = translate_address_write(addr); \
|
||||
// int32_t ___ = read8(phys_addr); \
|
||||
// write8(phys_addr, fun);
|
||||
//
|
||||
//#define SAFE_READ_WRITE16(addr, fun) \
|
||||
// int32_t phys_addr = translate_address_write(addr); \
|
||||
// if((phys_addr & 0xFFF) == 0xFFF) \
|
||||
// { \
|
||||
// int32_t phys_addr_high = translate_address_write((addr) + 1); \
|
||||
// int32_t ___ = virt_boundary_read16(phys_addr, phys_addr_high); \
|
||||
// virt_boundary_write16(phys_addr, phys_addr_high, fun); \
|
||||
// } \
|
||||
// else \
|
||||
// { \
|
||||
// int32_t ___ = read16(phys_addr); \
|
||||
// write16(phys_addr, fun); \
|
||||
// }
|
||||
//
|
||||
//#define SAFE_READ_WRITE32(addr, fun) \
|
||||
// int32_t phys_addr = translate_address_write(addr); \
|
||||
// if((phys_addr & 0xFFF) >= 0xFFD) \
|
||||
// { \
|
||||
// int32_t phys_addr_high = translate_address_write((addr) + 3 & ~3) | ((addr) + 3) & 3; \
|
||||
// int32_t ___ = virt_boundary_read32s(phys_addr, phys_addr_high); \
|
||||
// virt_boundary_write32(phys_addr, phys_addr_high, fun); \
|
||||
// } \
|
||||
// else \
|
||||
// { \
|
||||
// int32_t ___ = read32s(phys_addr); \
|
||||
// write32(phys_addr, fun); \
|
||||
// }
|
||||
|
||||
#define DEFINE_MODRM_INSTR1_READ_WRITE_8(name, fun) \
|
||||
void name ## _mem(int32_t addr) { SAFE_READ_WRITE8(addr, fun) } \
|
||||
void name ## _mem(int32_t addr) { SAFE_READ_WRITE8(addr, fun); } \
|
||||
void name ## _reg(int32_t r1) { int32_t ___ = read_reg8(r1); write_reg8(r1, fun); }
|
||||
|
||||
#define DEFINE_MODRM_INSTR1_READ_WRITE_16(name, fun) \
|
||||
void name ## _mem(int32_t addr) { SAFE_READ_WRITE16(addr, fun) } \
|
||||
void name ## _mem(int32_t addr) { SAFE_READ_WRITE16(addr, fun); } \
|
||||
void name ## _reg(int32_t r1) { int32_t ___ = read_reg16(r1); write_reg16(r1, fun); }
|
||||
|
||||
#define DEFINE_MODRM_INSTR1_READ_WRITE_32(name, fun) \
|
||||
void name ## _mem(int32_t addr) { SAFE_READ_WRITE32(addr, fun) } \
|
||||
void name ## _mem(int32_t addr) { SAFE_READ_WRITE32(addr, fun); } \
|
||||
void name ## _reg(int32_t r1) { int32_t ___ = read_reg32(r1); write_reg32(r1, fun); }
|
||||
|
||||
|
||||
#define DEFINE_MODRM_INSTR2_READ_WRITE_8(name, fun) \
|
||||
void name ## _mem(int32_t addr, int32_t imm) { SAFE_READ_WRITE8(addr, fun) } \
|
||||
void name ## _mem(int32_t addr, int32_t imm) { SAFE_READ_WRITE8(addr, fun); } \
|
||||
void name ## _reg(int32_t r1, int32_t imm) { int32_t ___ = read_reg8(r1); write_reg8(r1, fun); }
|
||||
|
||||
#define DEFINE_MODRM_INSTR2_READ_WRITE_16(name, fun) \
|
||||
void name ## _mem(int32_t addr, int32_t imm) { SAFE_READ_WRITE16(addr, fun) } \
|
||||
void name ## _mem(int32_t addr, int32_t imm) { SAFE_READ_WRITE16(addr, fun); } \
|
||||
void name ## _reg(int32_t r1, int32_t imm) { int32_t ___ = read_reg16(r1); write_reg16(r1, fun); }
|
||||
|
||||
#define DEFINE_MODRM_INSTR2_READ_WRITE_32(name, fun) \
|
||||
void name ## _mem(int32_t addr, int32_t imm) { SAFE_READ_WRITE32(addr, fun) } \
|
||||
void name ## _mem(int32_t addr, int32_t imm) { SAFE_READ_WRITE32(addr, fun); } \
|
||||
void name ## _reg(int32_t r1, int32_t imm) { int32_t ___ = read_reg32(r1); write_reg32(r1, fun); }
|
||||
|
||||
|
||||
#define DEFINE_MODRM_INSTR_READ_WRITE_8(name, fun) \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE8(addr, fun) } \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE8(addr, fun); } \
|
||||
void name ## _reg(int32_t r1, int32_t r) { int32_t ___ = read_reg8(r1); write_reg8(r1, fun); }
|
||||
|
||||
#define DEFINE_MODRM_INSTR_READ_WRITE_16(name, fun) \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE16(addr, fun) } \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE16(addr, fun); } \
|
||||
void name ## _reg(int32_t r1, int32_t r) { int32_t ___ = read_reg16(r1); write_reg16(r1, fun); }
|
||||
|
||||
#define DEFINE_MODRM_INSTR_READ_WRITE_32(name, fun) \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE32(addr, fun) } \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE32(addr, fun); } \
|
||||
void name ## _reg(int32_t r1, int32_t r) { int32_t ___ = read_reg32(r1); write_reg32(r1, fun); }
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -20,6 +19,9 @@
|
|||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
const bool CPU_LOG_VERBOSE = false;
|
||||
const bool ENABLE_ACPI = true;
|
||||
|
||||
bool apic_enabled = false;
|
||||
|
||||
void instr_0F00_0_mem(int32_t addr) {
|
||||
|
|
@ -460,7 +462,7 @@ void instr_0F20(int32_t r, int32_t creg) {
|
|||
write_reg32(r, cr[4]);
|
||||
break;
|
||||
default:
|
||||
dbg_log("%d", creg);
|
||||
dbg_log1("%d", creg);
|
||||
undefined_instruction();
|
||||
}
|
||||
}
|
||||
|
|
@ -511,7 +513,7 @@ void instr_0F22(int32_t r, int32_t creg) {
|
|||
break;
|
||||
|
||||
case 2:
|
||||
dbg_log("cr2 <- %x", data);
|
||||
dbg_log1("cr2 <- %x", data);
|
||||
cr[2] = data;
|
||||
break;
|
||||
|
||||
|
|
@ -526,7 +528,7 @@ void instr_0F22(int32_t r, int32_t creg) {
|
|||
break;
|
||||
|
||||
case 4:
|
||||
dbg_log("cr4 <- %d", cr[4]);
|
||||
dbg_log1("cr4 <- %d", cr[4]);
|
||||
|
||||
if(data & (1 << 11 | 1 << 12 | 1 << 15 | 1 << 16 | 1 << 19 | 0xFFC00000))
|
||||
{
|
||||
|
|
@ -551,7 +553,7 @@ void instr_0F22(int32_t r, int32_t creg) {
|
|||
break;
|
||||
|
||||
default:
|
||||
dbg_log("%d", creg);
|
||||
dbg_log1("%d", creg);
|
||||
undefined_instruction();
|
||||
}
|
||||
}
|
||||
|
|
@ -746,24 +748,25 @@ void instr_0F30() {
|
|||
|
||||
if(index != IA32_SYSENTER_ESP)
|
||||
{
|
||||
dbg_log("wrmsr ecx=%x data=%x:%x", index, high, low);
|
||||
dbg_log3("wrmsr ecx=%x data=%x:%x", index, high, low);
|
||||
}
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case IA32_SYSENTER_CS:
|
||||
if(index == IA32_SYSENTER_CS)
|
||||
{
|
||||
sysenter_cs[0] = low & 0xFFFF;
|
||||
break;
|
||||
|
||||
case IA32_SYSENTER_EIP:
|
||||
}
|
||||
else if(index == IA32_SYSENTER_EIP)
|
||||
{
|
||||
sysenter_eip[0] = low;
|
||||
break;
|
||||
|
||||
case IA32_SYSENTER_ESP:
|
||||
}
|
||||
else if(index == IA32_SYSENTER_ESP)
|
||||
{
|
||||
sysenter_esp[0] = low;
|
||||
break;
|
||||
|
||||
case IA32_APIC_BASE_MSR:
|
||||
}
|
||||
else if(index == IA32_APIC_BASE_MSR)
|
||||
{
|
||||
{
|
||||
dbg_assert_message(high == 0, "Changing APIC address (high 32 bits) not supported");
|
||||
int32_t address = low & ~(IA32_APIC_BASE_BSP | IA32_APIC_BASE_EXTD | IA32_APIC_BASE_EN);
|
||||
|
|
@ -771,35 +774,40 @@ void instr_0F30() {
|
|||
dbg_assert_message((low & IA32_APIC_BASE_EXTD) == 0, "x2apic not supported");
|
||||
apic_enabled = (low & IA32_APIC_BASE_EN) == IA32_APIC_BASE_EN;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA32_TIME_STAMP_COUNTER:
|
||||
}
|
||||
else if(index == IA32_TIME_STAMP_COUNTER)
|
||||
{
|
||||
set_tsc(low, high);
|
||||
break;
|
||||
|
||||
case IA32_BIOS_SIGN_ID:
|
||||
break;
|
||||
}
|
||||
else if(index == IA32_BIOS_SIGN_ID)
|
||||
{
|
||||
|
||||
case MSR_MISC_FEATURE_ENABLES:
|
||||
}
|
||||
else if(index == MSR_MISC_FEATURE_ENABLES)
|
||||
{
|
||||
// Linux 4, see: https://patchwork.kernel.org/patch/9528279/
|
||||
break;
|
||||
|
||||
case IA32_MISC_ENABLE: // Enable Misc. Processor Features
|
||||
break;
|
||||
}
|
||||
else if(index == IA32_MISC_ENABLE)
|
||||
{ // Enable Misc. Processor Features
|
||||
|
||||
case IA32_MCG_CAP:
|
||||
}
|
||||
else if(index == IA32_MCG_CAP)
|
||||
{
|
||||
// netbsd
|
||||
break;
|
||||
|
||||
case IA32_KERNEL_GS_BASE:
|
||||
}
|
||||
else if(index == IA32_KERNEL_GS_BASE)
|
||||
{
|
||||
// Only used in 64 bit mode (by SWAPGS), but set by kvm-unit-test
|
||||
dbg_log("GS Base written");
|
||||
break;
|
||||
|
||||
default:
|
||||
dbg_log("Unknown msr: %x", index);
|
||||
}
|
||||
else
|
||||
{
|
||||
dbg_log1("Unknown msr: %x", index);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void instr_0F31() {
|
||||
|
|
@ -830,37 +838,41 @@ void instr_0F32() {
|
|||
|
||||
int32_t index = reg32s[ECX];
|
||||
|
||||
dbg_log("rdmsr ecx=%x", index);
|
||||
dbg_log1("rdmsr ecx=%x", index);
|
||||
|
||||
int32_t low = 0;
|
||||
int32_t high = 0;
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case IA32_SYSENTER_CS:
|
||||
if(index == IA32_SYSENTER_CS)
|
||||
{
|
||||
low = sysenter_cs[0];
|
||||
break;
|
||||
|
||||
case IA32_SYSENTER_EIP:
|
||||
}
|
||||
else if(index == IA32_SYSENTER_EIP)
|
||||
{
|
||||
low = sysenter_eip[0];
|
||||
break;
|
||||
|
||||
case IA32_SYSENTER_ESP:
|
||||
}
|
||||
else if(index == IA32_SYSENTER_ESP)
|
||||
{
|
||||
low = sysenter_esp[0];
|
||||
break;
|
||||
|
||||
case IA32_TIME_STAMP_COUNTER:
|
||||
}
|
||||
else if(index == IA32_TIME_STAMP_COUNTER)
|
||||
{
|
||||
{
|
||||
uint64_t tsc = read_tsc();
|
||||
low = tsc;
|
||||
high = tsc >> 32;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA32_PLATFORM_ID:
|
||||
break;
|
||||
}
|
||||
else if(index == IA32_PLATFORM_ID)
|
||||
{
|
||||
|
||||
case IA32_APIC_BASE_MSR:
|
||||
}
|
||||
else if(index == IA32_APIC_BASE_MSR)
|
||||
{
|
||||
if(ENABLE_ACPI)
|
||||
{
|
||||
low = APIC_ADDRESS;
|
||||
|
|
@ -870,40 +882,48 @@ void instr_0F32() {
|
|||
low |= IA32_APIC_BASE_EN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IA32_BIOS_SIGN_ID:
|
||||
break;
|
||||
}
|
||||
else if(index == IA32_BIOS_SIGN_ID)
|
||||
{
|
||||
|
||||
case MSR_PLATFORM_INFO:
|
||||
}
|
||||
else if(index == MSR_PLATFORM_INFO)
|
||||
{
|
||||
low = 1 << 8;
|
||||
break;
|
||||
|
||||
case MSR_MISC_FEATURE_ENABLES:
|
||||
break;
|
||||
}
|
||||
else if(index == MSR_MISC_FEATURE_ENABLES)
|
||||
{
|
||||
|
||||
case IA32_MISC_ENABLE: // Enable Misc. Processor Features
|
||||
}
|
||||
else if(index == IA32_MISC_ENABLE)
|
||||
{ // Enable Misc. Processor Features
|
||||
low = 1 << 0; // fast string
|
||||
break;
|
||||
|
||||
case IA32_RTIT_CTL:
|
||||
}
|
||||
else if(index == IA32_RTIT_CTL)
|
||||
{
|
||||
// linux4
|
||||
break;
|
||||
|
||||
case MSR_SMI_COUNT:
|
||||
break;
|
||||
}
|
||||
else if(index == MSR_SMI_COUNT)
|
||||
{
|
||||
|
||||
case IA32_MCG_CAP:
|
||||
}
|
||||
else if(index == IA32_MCG_CAP)
|
||||
{
|
||||
// netbsd
|
||||
break;
|
||||
|
||||
case MSR_PKG_C2_RESIDENCY:
|
||||
break;
|
||||
|
||||
default:
|
||||
dbg_log("Unknown msr: %x", index);
|
||||
}
|
||||
else if(index == MSR_PKG_C2_RESIDENCY)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
dbg_log1("Unknown msr: %x", index);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
reg32s[EAX] = low;
|
||||
reg32s[EDX] = high;
|
||||
|
|
@ -2363,7 +2383,7 @@ void instr_0FAE_2_mem(int32_t addr) {
|
|||
int32_t new_mxcsr = safe_read32s(addr);
|
||||
if(new_mxcsr & ~MXCSR_MASK)
|
||||
{
|
||||
dbg_log("Invalid mxcsr bits: %x", (new_mxcsr & ~MXCSR_MASK));
|
||||
dbg_log1("Invalid mxcsr bits: %x", (new_mxcsr & ~MXCSR_MASK));
|
||||
assert(false);
|
||||
trigger_gp_non_raising(0);
|
||||
return;
|
||||
|
|
@ -3922,14 +3942,14 @@ void instr_0FFF() {
|
|||
trigger_ud();
|
||||
}
|
||||
|
||||
void run_instruction0f_16(int32_t opcode)
|
||||
{
|
||||
#include "../../build/interpreter0f_16.c"
|
||||
}
|
||||
//void run_instruction0f_16(int32_t opcode)
|
||||
//{
|
||||
//#include "../../build/interpreter0f_16.c"
|
||||
//}
|
||||
|
||||
void run_instruction0f_32(int32_t opcode)
|
||||
{
|
||||
#include "../../build/interpreter0f_32.c"
|
||||
}
|
||||
//void run_instruction0f_32(int32_t opcode)
|
||||
//{
|
||||
//#include "../../build/interpreter0f_32.c"
|
||||
//}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
|
|
|||
|
|
@ -16,24 +16,24 @@
|
|||
|
||||
|
||||
#define DEFINE_MODRM_INSTR_IMM_READ_WRITE_16(name, fun) \
|
||||
void name ## _mem(int32_t addr, int32_t r, int32_t imm) { SAFE_READ_WRITE16(addr, fun) } \
|
||||
void name ## _mem(int32_t addr, int32_t r, int32_t imm) { SAFE_READ_WRITE16(addr, fun); } \
|
||||
void name ## _reg(int32_t r1, int32_t r, int32_t imm) { int32_t ___ = read_reg16(r1); write_reg16(r1, fun); }
|
||||
|
||||
#define DEFINE_MODRM_INSTR_IMM_READ_WRITE_32(name, fun) \
|
||||
void name ## _mem(int32_t addr, int32_t r, int32_t imm) { SAFE_READ_WRITE32(addr, fun) } \
|
||||
void name ## _mem(int32_t addr, int32_t r, int32_t imm) { SAFE_READ_WRITE32(addr, fun); } \
|
||||
void name ## _reg(int32_t r1, int32_t r, int32_t imm) { int32_t ___ = read_reg32(r1); write_reg32(r1, fun); }
|
||||
|
||||
|
||||
#define DEFINE_MODRM_INSTR_READ_WRITE_8(name, fun) \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE8(addr, fun) } \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE8(addr, fun); } \
|
||||
void name ## _reg(int32_t r1, int32_t r) { int32_t ___ = read_reg8(r1); write_reg8(r1, fun); }
|
||||
|
||||
#define DEFINE_MODRM_INSTR_READ_WRITE_16(name, fun) \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE16(addr, fun) } \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE16(addr, fun); } \
|
||||
void name ## _reg(int32_t r1, int32_t r) { int32_t ___ = read_reg16(r1); write_reg16(r1, fun); }
|
||||
|
||||
#define DEFINE_MODRM_INSTR_READ_WRITE_32(name, fun) \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE32(addr, fun) } \
|
||||
void name ## _mem(int32_t addr, int32_t r) { SAFE_READ_WRITE32(addr, fun); } \
|
||||
void name ## _reg(int32_t r1, int32_t r) { int32_t ___ = read_reg32(r1); write_reg32(r1, fun); }
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -10,7 +9,7 @@
|
|||
extern void logop(int32_t, int32_t);
|
||||
extern void _dbg_trace(void);
|
||||
|
||||
#define dbg_log(...) { if(DEBUG) { printf(__VA_ARGS__); } }
|
||||
#define dbg_trace(...) { if(DEBUG) { _dbg_trace(__VA_ARGS__); } }
|
||||
#define dbg_assert(condition) { if(DEBUG) { if(!(condition)) dbg_log(#condition); assert(condition); } }
|
||||
#define dbg_assert_message(condition, message) { if(DEBUG && !(condition)) { dbg_log(message); assert(false); } }
|
||||
//#define dbg_log(...) { if(DEBUG) { printf(__VA_ARGS__); } }
|
||||
//#define dbg_trace(...) { if(DEBUG) { _dbg_trace(__VA_ARGS__); } }
|
||||
//#define dbg_assert(condition) { if(DEBUG) { if(!(condition)) dbg_log(#condition); assert(condition); } }
|
||||
//#define dbg_assert_message(condition, message) { if(DEBUG && !(condition)) { dbg_log(message); assert(false); } }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -11,6 +10,8 @@
|
|||
#include "profiler/profiler.h"
|
||||
#include "rust_imports.h"
|
||||
|
||||
const bool USE_A20 = false;
|
||||
|
||||
bool in_mapped_range(uint32_t addr)
|
||||
{
|
||||
return (addr >= 0xA0000 && addr < 0xC0000) || addr >= *memory_size;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -15,6 +14,11 @@ static int32_t resolve_sib(bool mod);
|
|||
#define ds get_seg_prefix_ds
|
||||
#define ss get_seg_prefix_ss
|
||||
|
||||
int32_t MODRM_ENTRY() { return 0; }
|
||||
int32_t MODRM_ENTRY16() { return 0; }
|
||||
int32_t MODRM_ENTRY32() { return 0; }
|
||||
|
||||
|
||||
#define MODRM_ENTRY(n, offset)\
|
||||
case (n) | 0 << 3:\
|
||||
case (n) | 1 << 3:\
|
||||
|
|
@ -35,19 +39,19 @@ int32_t resolve_modrm16(int32_t modrm_byte)
|
|||
{
|
||||
switch(modrm_byte)
|
||||
{
|
||||
MODRM_ENTRY16(0, ds, reg16[BX] + reg16[SI])
|
||||
MODRM_ENTRY16(1, ds, reg16[BX] + reg16[DI])
|
||||
MODRM_ENTRY16(2, ss, reg16[BP] + reg16[SI])
|
||||
MODRM_ENTRY16(3, ss, reg16[BP] + reg16[DI])
|
||||
MODRM_ENTRY16(4, ds, reg16[SI])
|
||||
MODRM_ENTRY16(5, ds, reg16[DI])
|
||||
MODRM_ENTRY16(0, ds, reg16[BX] + reg16[SI]);
|
||||
MODRM_ENTRY16(1, ds, reg16[BX] + reg16[DI]);
|
||||
MODRM_ENTRY16(2, ss, reg16[BP] + reg16[SI]);
|
||||
MODRM_ENTRY16(3, ss, reg16[BP] + reg16[DI]);
|
||||
MODRM_ENTRY16(4, ds, reg16[SI]);
|
||||
MODRM_ENTRY16(5, ds, reg16[DI]);
|
||||
|
||||
// special case
|
||||
MODRM_ENTRY(0x00 | 6, ds(read_imm16()))
|
||||
MODRM_ENTRY(0x40 | 6, ss(reg16[BP] + read_imm8s() & 0xFFFF))
|
||||
MODRM_ENTRY(0x80 | 6, ss(reg16[BP] + read_imm16() & 0xFFFF))
|
||||
MODRM_ENTRY(0x00 | 6, ds(read_imm16()));
|
||||
MODRM_ENTRY(0x40 | 6, ss(reg16[BP] + read_imm8s() & 0xFFFF));
|
||||
MODRM_ENTRY(0x80 | 6, ss(reg16[BP] + read_imm16() & 0xFFFF));
|
||||
|
||||
MODRM_ENTRY16(7, ds, reg16[BX])
|
||||
MODRM_ENTRY16(7, ds, reg16[BX]);
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
|
|
@ -63,25 +67,25 @@ int32_t resolve_modrm16(int32_t modrm_byte)
|
|||
MODRM_ENTRY(0x40 | (row), seg((value) + read_imm8s()))\
|
||||
MODRM_ENTRY(0x80 | (row), seg((value) + read_imm32s()))\
|
||||
|
||||
int32_t resolve_modrm32(int32_t modrm_byte)
|
||||
int32_t resolve_modrm32_(int32_t modrm_byte)
|
||||
{
|
||||
switch(modrm_byte)
|
||||
{
|
||||
MODRM_ENTRY32(0, ds, reg32s[EAX])
|
||||
MODRM_ENTRY32(1, ds, reg32s[ECX])
|
||||
MODRM_ENTRY32(2, ds, reg32s[EDX])
|
||||
MODRM_ENTRY32(3, ds, reg32s[EBX])
|
||||
MODRM_ENTRY32(0, ds, reg32s[EAX]);
|
||||
MODRM_ENTRY32(1, ds, reg32s[ECX]);
|
||||
MODRM_ENTRY32(2, ds, reg32s[EDX]);
|
||||
MODRM_ENTRY32(3, ds, reg32s[EBX]);
|
||||
|
||||
// special cases
|
||||
MODRM_ENTRY(0x00 | 4, resolve_sib(false))
|
||||
MODRM_ENTRY(0x40 | 4, resolve_sib(true) + read_imm8s())
|
||||
MODRM_ENTRY(0x80 | 4, resolve_sib(true) + read_imm32s())
|
||||
MODRM_ENTRY(0x00 | 5, ds(read_imm32s()))
|
||||
MODRM_ENTRY(0x40 | 5, ss(reg32s[EBP] + read_imm8s()))
|
||||
MODRM_ENTRY(0x80 | 5, ss(reg32s[EBP] + read_imm32s()))
|
||||
MODRM_ENTRY(0x00 | 4, resolve_sib(false));
|
||||
MODRM_ENTRY(0x40 | 4, resolve_sib(true) + read_imm8s());
|
||||
MODRM_ENTRY(0x80 | 4, resolve_sib(true) + read_imm32s());
|
||||
MODRM_ENTRY(0x00 | 5, ds(read_imm32s()));
|
||||
MODRM_ENTRY(0x40 | 5, ss(reg32s[EBP] + read_imm8s()));
|
||||
MODRM_ENTRY(0x80 | 5, ss(reg32s[EBP] + read_imm32s()));
|
||||
|
||||
MODRM_ENTRY32(6, ds, reg32s[ESI])
|
||||
MODRM_ENTRY32(7, ds, reg32s[EDI])
|
||||
MODRM_ENTRY32(6, ds, reg32s[ESI]);
|
||||
MODRM_ENTRY32(7, ds, reg32s[EDI]);
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
|
|
@ -190,8 +194,7 @@ static int32_t resolve_sib(bool mod)
|
|||
return get_seg_prefix(seg) + base + offset;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline int32_t resolve_modrm32_(int32_t modrm_byte)
|
||||
int32_t resolve_modrm32(int32_t modrm_byte)
|
||||
{
|
||||
uint8_t r = modrm_byte & 7;
|
||||
assert(modrm_byte < 0xC0);
|
||||
|
|
@ -230,4 +233,3 @@ static inline int32_t resolve_modrm32_(int32_t modrm_byte)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,89 +1,103 @@
|
|||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void assert(bool x) {}
|
||||
void dbg_assert(bool x) {}
|
||||
void dbg_assert_message(bool x, const char* msg) {}
|
||||
//void dbg_log(const char* m) {}
|
||||
//void dbg_log1(const char* m, int32_t x) {}
|
||||
//void dbg_log2(const char* m, int32_t x, int32_t y) {}
|
||||
//void dbg_log3(const char* m, int32_t x, int32_t y, int32_t z) {}
|
||||
//void dbg_log5(const char* m, int32_t x, int32_t y, int32_t z, int32_t i, int32_t j) {}
|
||||
//void dbg_trace() {}
|
||||
bool isnan_XXX(double f) { return f != f; }
|
||||
bool isfinite_XXX(double f) { return f == INFINITY || f == -INFINITY || !isnan_XXX(f); }
|
||||
|
||||
// via musl libc
|
||||
|
||||
void *memset(void *dest, int c, size_t n)
|
||||
{
|
||||
unsigned char *s = (unsigned char *)dest;
|
||||
size_t k;
|
||||
|
||||
/* Fill head and tail with minimal branching. Each
|
||||
* conditional ensures that all the subsequently used
|
||||
* offsets are well-defined and in the dest region. */
|
||||
|
||||
if (!n) return dest;
|
||||
s[0] = s[n-1] = c;
|
||||
if (n <= 2) return dest;
|
||||
s[1] = s[n-2] = c;
|
||||
s[2] = s[n-3] = c;
|
||||
if (n <= 6) return dest;
|
||||
s[3] = s[n-4] = c;
|
||||
if (n <= 8) return dest;
|
||||
|
||||
/* Advance pointer to align it at a 4-byte boundary,
|
||||
* and truncate n to a multiple of 4. The previous code
|
||||
* already took care of any head/tail that get cut off
|
||||
* by the alignment. */
|
||||
|
||||
k = -(uintptr_t)s & 3;
|
||||
s += k;
|
||||
n -= k;
|
||||
n &= -4;
|
||||
|
||||
#ifdef __GNUC__
|
||||
typedef uint32_t __attribute__((__may_alias__)) u32;
|
||||
typedef uint64_t __attribute__((__may_alias__)) u64;
|
||||
|
||||
u32 c32 = ((u32)-1)/255 * (unsigned char)c;
|
||||
|
||||
/* In preparation to copy 32 bytes at a time, aligned on
|
||||
* an 8-byte bounary, fill head/tail up to 28 bytes each.
|
||||
* As in the initial byte-based head/tail fill, each
|
||||
* conditional below ensures that the subsequent offsets
|
||||
* are valid (e.g. !(n<=24) implies n>=28). */
|
||||
|
||||
*(u32 *)(s+0) = c32;
|
||||
*(u32 *)(s+n-4) = c32;
|
||||
if (n <= 8) return dest;
|
||||
*(u32 *)(s+4) = c32;
|
||||
*(u32 *)(s+8) = c32;
|
||||
*(u32 *)(s+n-12) = c32;
|
||||
*(u32 *)(s+n-8) = c32;
|
||||
if (n <= 24) return dest;
|
||||
*(u32 *)(s+12) = c32;
|
||||
*(u32 *)(s+16) = c32;
|
||||
*(u32 *)(s+20) = c32;
|
||||
*(u32 *)(s+24) = c32;
|
||||
*(u32 *)(s+n-28) = c32;
|
||||
*(u32 *)(s+n-24) = c32;
|
||||
*(u32 *)(s+n-20) = c32;
|
||||
*(u32 *)(s+n-16) = c32;
|
||||
|
||||
/* Align to a multiple of 8 so we can fill 64 bits at a time,
|
||||
* and avoid writing the same bytes twice as much as is
|
||||
* practical without introducing additional branching. */
|
||||
|
||||
k = 24 + ((uintptr_t)s & 4);
|
||||
s += k;
|
||||
n -= k;
|
||||
|
||||
/* If this loop is reached, 28 tail bytes have already been
|
||||
* filled, so any remainder when n drops below 32 can be
|
||||
* safely ignored. */
|
||||
|
||||
u64 c64 = c32 | ((u64)c32 << 32);
|
||||
for (; n >= 32; n-=32, s+=32) {
|
||||
*(u64 *)(s+0) = c64;
|
||||
*(u64 *)(s+8) = c64;
|
||||
*(u64 *)(s+16) = c64;
|
||||
*(u64 *)(s+24) = c64;
|
||||
}
|
||||
#else
|
||||
/* Pure C fallback with no aliasing violations. */
|
||||
for (; n; n--, s++) *s = c;
|
||||
#endif
|
||||
|
||||
return dest;
|
||||
}
|
||||
//void *memset(void *dest, int c, size_t n)
|
||||
//{
|
||||
// unsigned char *s = (unsigned char *)dest;
|
||||
// size_t k;
|
||||
//
|
||||
// /* Fill head and tail with minimal branching. Each
|
||||
// * conditional ensures that all the subsequently used
|
||||
// * offsets are well-defined and in the dest region. */
|
||||
//
|
||||
// if (!n) return dest;
|
||||
// s[0] = s[n-1] = c;
|
||||
// if (n <= 2) return dest;
|
||||
// s[1] = s[n-2] = c;
|
||||
// s[2] = s[n-3] = c;
|
||||
// if (n <= 6) return dest;
|
||||
// s[3] = s[n-4] = c;
|
||||
// if (n <= 8) return dest;
|
||||
//
|
||||
// /* Advance pointer to align it at a 4-byte boundary,
|
||||
// * and truncate n to a multiple of 4. The previous code
|
||||
// * already took care of any head/tail that get cut off
|
||||
// * by the alignment. */
|
||||
//
|
||||
// k = -(uintptr_t)s & 3;
|
||||
// s += k;
|
||||
// n -= k;
|
||||
// n &= -4;
|
||||
//
|
||||
//#ifdef __GNUC__
|
||||
// typedef uint32_t __attribute__((__may_alias__)) u32;
|
||||
// typedef uint64_t __attribute__((__may_alias__)) u64;
|
||||
//
|
||||
// u32 c32 = ((u32)-1)/255 * (unsigned char)c;
|
||||
//
|
||||
// /* In preparation to copy 32 bytes at a time, aligned on
|
||||
// * an 8-byte bounary, fill head/tail up to 28 bytes each.
|
||||
// * As in the initial byte-based head/tail fill, each
|
||||
// * conditional below ensures that the subsequent offsets
|
||||
// * are valid (e.g. !(n<=24) implies n>=28). */
|
||||
//
|
||||
// *(u32 *)(s+0) = c32;
|
||||
// *(u32 *)(s+n-4) = c32;
|
||||
// if (n <= 8) return dest;
|
||||
// *(u32 *)(s+4) = c32;
|
||||
// *(u32 *)(s+8) = c32;
|
||||
// *(u32 *)(s+n-12) = c32;
|
||||
// *(u32 *)(s+n-8) = c32;
|
||||
// if (n <= 24) return dest;
|
||||
// *(u32 *)(s+12) = c32;
|
||||
// *(u32 *)(s+16) = c32;
|
||||
// *(u32 *)(s+20) = c32;
|
||||
// *(u32 *)(s+24) = c32;
|
||||
// *(u32 *)(s+n-28) = c32;
|
||||
// *(u32 *)(s+n-24) = c32;
|
||||
// *(u32 *)(s+n-20) = c32;
|
||||
// *(u32 *)(s+n-16) = c32;
|
||||
//
|
||||
// /* Align to a multiple of 8 so we can fill 64 bits at a time,
|
||||
// * and avoid writing the same bytes twice as much as is
|
||||
// * practical without introducing additional branching. */
|
||||
//
|
||||
// k = 24 + ((uintptr_t)s & 4);
|
||||
// s += k;
|
||||
// n -= k;
|
||||
//
|
||||
// /* If this loop is reached, 28 tail bytes have already been
|
||||
// * filled, so any remainder when n drops below 32 can be
|
||||
// * safely ignored. */
|
||||
//
|
||||
// u64 c64 = c32 | ((u64)c32 << 32);
|
||||
// for (; n >= 32; n-=32, s+=32) {
|
||||
// *(u64 *)(s+0) = c64;
|
||||
// *(u64 *)(s+8) = c64;
|
||||
// *(u64 *)(s+16) = c64;
|
||||
// *(u64 *)(s+24) = c64;
|
||||
// }
|
||||
//#else
|
||||
// /* Pure C fallback with no aliasing violations. */
|
||||
// for (; n; n--, s++) *s = c;
|
||||
//#endif
|
||||
//
|
||||
// return dest;
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -6,4 +6,16 @@
|
|||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
void *memset(void *dest, int c, size_t n);
|
||||
//void *memset(void *dest, int c, size_t n);
|
||||
|
||||
void assert(bool x);
|
||||
void dbg_assert(bool x);
|
||||
void dbg_assert_message(bool x, const char* msg);
|
||||
void dbg_log(const char* m);
|
||||
void dbg_log1(const char* m, int32_t x);
|
||||
void dbg_log2(const char* m, int32_t x, int32_t y);
|
||||
void dbg_log3(const char* m, int32_t x, int32_t y, int32_t z);
|
||||
void dbg_log5(const char* m, int32_t x, int32_t y, int32_t z, int32_t i, int32_t j);
|
||||
void dbg_trace();
|
||||
bool isnan_XXX(double f);
|
||||
bool isfinite_XXX(double f);
|
||||
|
|
|
|||
|
|
@ -408,14 +408,15 @@ bool sse_comparison(int32_t op, double_t x, double_t y)
|
|||
case 0: return x == y;
|
||||
case 1: return x < y;
|
||||
case 2: return x <= y;
|
||||
case 3: return isnan(x) || isnan(y);
|
||||
case 4: return x != y || isnan(x) || isnan(y);
|
||||
case 5: return x >= y || isnan(x) || isnan(y);
|
||||
case 6: return x > y || isnan(x) || isnan(y);
|
||||
case 7: return !isnan(x) && !isnan(y);
|
||||
case 3: return isnan_XXX(x) || isnan_XXX(y);
|
||||
case 4: return x != y || isnan_XXX(x) || isnan_XXX(y);
|
||||
case 5: return x >= y || isnan_XXX(x) || isnan_XXX(y);
|
||||
case 6: return x > y || isnan_XXX(x) || isnan_XXX(y);
|
||||
case 7: return !isnan_XXX(x) && !isnan_XXX(y);
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
double_t sse_min(double_t x, double_t y)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@
|
|||
#include "log.h"
|
||||
#include "memory.h"
|
||||
#include "string.h"
|
||||
#include "shared.h"
|
||||
|
||||
#define MAX_COUNT_PER_CYCLE 0x1000
|
||||
const int32_t MAX_COUNT_PER_CYCLE = 0x1000;
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
int32_t string_get_cycle_count(int32_t size, int32_t address)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ extern crate quickcheck;
|
|||
#[macro_use]
|
||||
mod dbg;
|
||||
|
||||
mod cpu2;
|
||||
|
||||
pub mod c_api;
|
||||
|
||||
mod analysis;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue