Preparation C code for c2rust conversion

This commit is contained in:
Fabian 2018-08-02 13:31:15 -04:00
commit 6de0bb374b
23 changed files with 908 additions and 564 deletions

0
src/native/all.c Normal file
View file

View file

@ -1,4 +1,3 @@
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>

View file

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

View file

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

View file

@ -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)

View file

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

View file

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

View file

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

View 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;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,3 @@
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>

View file

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

View file

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

View file

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

View file

@ -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)

View file

@ -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)

View file

@ -7,6 +7,8 @@ extern crate quickcheck;
#[macro_use]
mod dbg;
mod cpu2;
pub mod c_api;
mod analysis;