mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-24 09:31:05 +00:00
This code should now build the x86_x64-softmmu part 2.
This commit is contained in:
parent
37f9a248ea
commit
1aeaf5c40d
|
@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,7 @@
|
||||||
|
|
||||||
// posix specific
|
// posix specific
|
||||||
#else // _MSC_VER
|
#else // _MSC_VER
|
||||||
#include <unistd.h>
|
#include "platform.h"
|
||||||
#include <inttypes.h>
|
|
||||||
#include <unicorn/unicorn.h>
|
#include <unicorn/unicorn.h>
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
/* This is a hand made version for MSVC support */
|
/*
|
||||||
|
This is a hand made version for MSVC native support
|
||||||
|
It seems that most of these are not used by any source files.
|
||||||
|
The only one that I can see being used is: CONFIG_CPUID_H
|
||||||
|
*/
|
||||||
|
|
||||||
#define CONFIG_QEMU_CONFDIR "c:/Program Files/QEMU"
|
#define CONFIG_QEMU_CONFDIR "c:/Program Files/QEMU"
|
||||||
#define CONFIG_QEMU_DATADIR ""
|
#define CONFIG_QEMU_DATADIR ""
|
||||||
#define CONFIG_QEMU_DOCDIR "c:/Program Files/QEMU"
|
#define CONFIG_QEMU_DOCDIR "c:/Program Files/QEMU"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 2012
|
# Visual Studio 2012
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicorn", "unicorn\unicorn.vcxproj", "{B6EFD6D7-C2D4-4FBB-B363-2E08CE09CC96}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "x86_64-softmmu", "x86_64-softmmu\x86_64-softmmu.vcxproj", "{17077E86-AE7C-41AF-86ED-2BAC03B019BC}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
@ -9,10 +9,10 @@ Global
|
||||||
Release|Win32 = Release|Win32
|
Release|Win32 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{B6EFD6D7-C2D4-4FBB-B363-2E08CE09CC96}.Debug|Win32.ActiveCfg = Debug|Win32
|
{17077E86-AE7C-41AF-86ED-2BAC03B019BC}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{B6EFD6D7-C2D4-4FBB-B363-2E08CE09CC96}.Debug|Win32.Build.0 = Debug|Win32
|
{17077E86-AE7C-41AF-86ED-2BAC03B019BC}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{B6EFD6D7-C2D4-4FBB-B363-2E08CE09CC96}.Release|Win32.ActiveCfg = Release|Win32
|
{17077E86-AE7C-41AF-86ED-2BAC03B019BC}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{B6EFD6D7-C2D4-4FBB-B363-2E08CE09CC96}.Release|Win32.Build.0 = Release|Win32
|
{17077E86-AE7C-41AF-86ED-2BAC03B019BC}.Release|Win32.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -365,7 +365,7 @@
|
||||||
</PrecompiledHeader>
|
</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;inline=__inline;__func__=__FUNCTION__</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;inline=__inline;__func__=__FUNCTION__;UNICORN_HAS_X86;UNICORN_HAS_ARM;UNICORN_HAS_M68K;UNICORN_HAS_ARM64;UNICORN_HAS_MIPS;UNICORN_HAS_MIPSEL;UNICORN_HAS_MIPS64;UNICORN_HAS_MIPS64EL;UNICORN_HAS_SPARC</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
<AdditionalIncludeDirectories>../../..;../../../include;../../../qemu;../../../qemu/include;../../../qemu/tcg;</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>../../..;../../../include;../../../qemu;../../../qemu/include;../../../qemu/tcg;</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -382,8 +382,9 @@
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;;inline=__inline;__func__=__FUNCTION__</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;;inline=__inline;__func__=__FUNCTION__;UNICORN_HAS_X86;UNICORN_HAS_ARM;UNICORN_HAS_M68K;UNICORN_HAS_ARM64;UNICORN_HAS_MIPS;UNICORN_HAS_MIPSEL;UNICORN_HAS_MIPS64;UNICORN_HAS_MIPS64EL;UNICORN_HAS_SPARC</PreprocessorDefinitions>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
|
<AdditionalIncludeDirectories>../../..;../../../include;../../../qemu;../../../qemu/include;../../../qemu/tcg;</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef UC_LLIST_H
|
#ifndef UC_LLIST_H
|
||||||
#define UC_LLIST_H
|
#define UC_LLIST_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include "platform.h"
|
||||||
|
|
||||||
struct list_item {
|
struct list_item {
|
||||||
struct list_item *next;
|
struct list_item *next;
|
||||||
|
|
|
@ -238,6 +238,7 @@ static void usleep(const int64_t &t) {
|
||||||
|
|
||||||
// misc support
|
// misc support
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
#define va_copy(d,s) ((d) = (s))
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#define strcasecmp _stricmp
|
#define strcasecmp _stricmp
|
||||||
#if (_MSC_VER <= MSC_VER_VS2013)
|
#if (_MSC_VER <= MSC_VER_VS2013)
|
||||||
|
@ -247,4 +248,5 @@ static void usleep(const int64_t &t) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // UNICORN_PLATFORM_H
|
#endif // UNICORN_PLATFORM_H
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#ifndef UC_PRIV_H
|
#ifndef UC_PRIV_H
|
||||||
#define UC_PRIV_H
|
#define UC_PRIV_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "qemu.h"
|
#include "qemu.h"
|
||||||
|
@ -110,9 +110,11 @@ enum uc_hook_idx {
|
||||||
UC_HOOK_MAX,
|
UC_HOOK_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define HOOK_FOREACH_VAR_DECLARE \
|
||||||
|
struct list_item *cur
|
||||||
|
|
||||||
// for loop macro to loop over hook lists
|
// for loop macro to loop over hook lists
|
||||||
#define HOOK_FOREACH(uc, hh, idx) \
|
#define HOOK_FOREACH(uc, hh, idx) \
|
||||||
struct list_item *cur; \
|
|
||||||
for ( \
|
for ( \
|
||||||
cur = (uc)->hook[idx##_IDX].head; \
|
cur = (uc)->hook[idx##_IDX].head; \
|
||||||
cur != NULL && ((hh) = (struct hook *)cur->data) \
|
cur != NULL && ((hh) = (struct hook *)cur->data) \
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4201)
|
#pragma warning(disable:4201)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
|
|
||||||
// GCC SPARC toolchain has a default macro called "sparc" which breaks
|
// GCC SPARC toolchain has a default macro called "sparc" which breaks
|
||||||
// compilation
|
// compilation
|
||||||
|
|
|
@ -8,16 +8,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#ifdef _MSC_VER
|
|
||||||
#ifndef __cplusplus
|
|
||||||
typedef unsigned char bool;
|
|
||||||
#define false 0
|
|
||||||
#define true 1
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <stdbool.h>
|
|
||||||
#endif
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#if defined(UNICORN_HAS_OSXKERNEL)
|
#if defined(UNICORN_HAS_OSXKERNEL)
|
||||||
#include <libkern/libkern.h>
|
#include <libkern/libkern.h>
|
||||||
|
@ -38,6 +29,12 @@ typedef size_t uc_hook;
|
||||||
#include "mips.h"
|
#include "mips.h"
|
||||||
#include "sparc.h"
|
#include "sparc.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define DEFAULT_VISIBILITY __attribute__((visibility("default")))
|
||||||
|
#else
|
||||||
|
#define DEFAULT_VISIBILITY
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4201)
|
#pragma warning(disable:4201)
|
||||||
#pragma warning(disable:4100)
|
#pragma warning(disable:4100)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
|
|
||||||
// Memory-Management Register for instructions IDTR, GDTR, LDTR, TR.
|
// Memory-Management Register for instructions IDTR, GDTR, LDTR, TR.
|
||||||
// Borrow from SegmentCache in qemu/target-i386/cpu.h
|
// Borrow from SegmentCache in qemu/target-i386/cpu.h
|
||||||
|
|
2
list.c
2
list.c
|
@ -1,5 +1,5 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
// simple linked list implementation
|
// simple linked list implementation
|
||||||
|
|
21
qemu/accel.c
21
qemu/accel.c
|
@ -48,18 +48,25 @@ static int tcg_init(MachineState *ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo accel_type = {
|
static const TypeInfo accel_type = {
|
||||||
.name = TYPE_ACCEL,
|
TYPE_ACCEL,
|
||||||
.parent = TYPE_OBJECT,
|
TYPE_OBJECT,
|
||||||
.class_size = sizeof(AccelClass),
|
sizeof(AccelClass),
|
||||||
.instance_size = sizeof(AccelState),
|
sizeof(AccelState),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TYPE_TCG_ACCEL ACCEL_CLASS_NAME("tcg")
|
#define TYPE_TCG_ACCEL ACCEL_CLASS_NAME("tcg")
|
||||||
|
|
||||||
static const TypeInfo tcg_accel_type = {
|
static const TypeInfo tcg_accel_type = {
|
||||||
.name = TYPE_TCG_ACCEL,
|
TYPE_TCG_ACCEL,
|
||||||
.parent = TYPE_ACCEL,
|
TYPE_ACCEL,
|
||||||
.class_init = tcg_accel_class_init,
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
tcg_accel_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,7 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
|
||||||
#else
|
#else
|
||||||
bool catched = false;
|
bool catched = false;
|
||||||
// Unicorn: call registered interrupt callbacks
|
// Unicorn: call registered interrupt callbacks
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
HOOK_FOREACH(uc, hook, UC_HOOK_INTR) {
|
HOOK_FOREACH(uc, hook, UC_HOOK_INTR) {
|
||||||
((uc_cb_hookintr_t)hook->callback)(uc, cpu->exception_index, hook->user_data);
|
((uc_cb_hookintr_t)hook->callback)(uc, cpu->exception_index, hook->user_data);
|
||||||
catched = true;
|
catched = true;
|
||||||
|
@ -376,7 +377,7 @@ static TranslationBlock *tb_find_slow(CPUArchState *env, target_ulong pc,
|
||||||
}
|
}
|
||||||
not_found:
|
not_found:
|
||||||
/* if no translated code available, then translate it now */
|
/* if no translated code available, then translate it now */
|
||||||
tb = tb_gen_code(cpu, pc, cs_base, flags, 0); // qq
|
tb = tb_gen_code(cpu, pc, cs_base, (int)flags, 0); // qq
|
||||||
|
|
||||||
found:
|
found:
|
||||||
/* Move the last found TB to the head of the list */
|
/* Move the last found TB to the head of the list */
|
||||||
|
|
|
@ -235,7 +235,7 @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
|
||||||
addend = 0;
|
addend = 0;
|
||||||
} else {
|
} else {
|
||||||
/* TLB_MMIO for rom/romd handled below */
|
/* TLB_MMIO for rom/romd handled below */
|
||||||
addend = (uintptr_t)memory_region_get_ram_ptr(section->mr) + xlat;
|
addend = (uintptr_t)((char*)memory_region_get_ram_ptr(section->mr) + xlat);
|
||||||
}
|
}
|
||||||
|
|
||||||
code_address = address;
|
code_address = address;
|
||||||
|
@ -251,7 +251,7 @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
|
||||||
|
|
||||||
/* refill the tlb */
|
/* refill the tlb */
|
||||||
env->iotlb[mmu_idx][index] = iotlb - vaddr;
|
env->iotlb[mmu_idx][index] = iotlb - vaddr;
|
||||||
te->addend = addend - vaddr;
|
te->addend = (uintptr_t)(addend - vaddr);
|
||||||
if (prot & PAGE_READ) {
|
if (prot & PAGE_READ) {
|
||||||
te->addr_read = address;
|
te->addr_read = address;
|
||||||
} else {
|
} else {
|
||||||
|
@ -269,8 +269,8 @@ void tlb_set_page(CPUState *cpu, target_ulong vaddr,
|
||||||
/* Write access calls the I/O callback. */
|
/* Write access calls the I/O callback. */
|
||||||
te->addr_write = address | TLB_MMIO;
|
te->addr_write = address | TLB_MMIO;
|
||||||
} else if (memory_region_is_ram(section->mr)
|
} else if (memory_region_is_ram(section->mr)
|
||||||
&& cpu_physical_memory_is_clean(cpu->uc, section->mr->ram_addr
|
&& cpu_physical_memory_is_clean(cpu->uc, (ram_addr_t)(section->mr->ram_addr
|
||||||
+ xlat)) {
|
+ xlat))) {
|
||||||
te->addr_write = address | TLB_NOTDIRTY;
|
te->addr_write = address | TLB_NOTDIRTY;
|
||||||
} else {
|
} else {
|
||||||
te->addr_write = address;
|
te->addr_write = address;
|
||||||
|
|
78
qemu/exec.c
78
qemu/exec.c
|
@ -247,9 +247,11 @@ static void phys_page_compact(PhysPageEntry *lp, Node *nodes, unsigned long *com
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void phys_page_compact_all(AddressSpaceDispatch *d, int nodes_nb)
|
static void phys_page_compact_all(AddressSpaceDispatch *d, const int nodes_nb)
|
||||||
{
|
{
|
||||||
DECLARE_BITMAP(compacted, nodes_nb);
|
//DECLARE_BITMAP(compacted, nodes_nb);
|
||||||
|
// this isnt actually used
|
||||||
|
unsigned int* compacted = NULL;
|
||||||
|
|
||||||
if (d->phys_map.skip) {
|
if (d->phys_map.skip) {
|
||||||
phys_page_compact(&d->phys_map, d->map.nodes, compacted);
|
phys_page_compact(&d->phys_map, d->map.nodes, compacted);
|
||||||
|
@ -634,10 +636,11 @@ void cpu_single_step(CPUState *cpu, int enabled)
|
||||||
{
|
{
|
||||||
#if defined(TARGET_HAS_ICE)
|
#if defined(TARGET_HAS_ICE)
|
||||||
if (cpu->singlestep_enabled != enabled) {
|
if (cpu->singlestep_enabled != enabled) {
|
||||||
|
CPUArchState *env;
|
||||||
cpu->singlestep_enabled = enabled;
|
cpu->singlestep_enabled = enabled;
|
||||||
/* must flush all the translated code to avoid inconsistencies */
|
/* must flush all the translated code to avoid inconsistencies */
|
||||||
/* XXX: only flush what is necessary */
|
/* XXX: only flush what is necessary */
|
||||||
CPUArchState *env = cpu->env_ptr;
|
env = cpu->env_ptr;
|
||||||
tb_flush(env);
|
tb_flush(env);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -836,11 +839,8 @@ static void register_subpage(struct uc_struct* uc,
|
||||||
& TARGET_PAGE_MASK;
|
& TARGET_PAGE_MASK;
|
||||||
MemoryRegionSection *existing = phys_page_find(d->phys_map, base,
|
MemoryRegionSection *existing = phys_page_find(d->phys_map, base,
|
||||||
d->map.nodes, d->map.sections);
|
d->map.nodes, d->map.sections);
|
||||||
MemoryRegionSection subsection = {
|
|
||||||
.offset_within_address_space = base,
|
|
||||||
.size = int128_make64(TARGET_PAGE_SIZE),
|
|
||||||
};
|
|
||||||
hwaddr start, end;
|
hwaddr start, end;
|
||||||
|
MemoryRegionSection subsection = MemoryRegionSection_make(NULL, NULL, 0, int128_make64(TARGET_PAGE_SIZE), base, false);
|
||||||
|
|
||||||
assert(existing->mr->subpage || existing->mr == &uc->io_mem_unassigned);
|
assert(existing->mr->subpage || existing->mr == &uc->io_mem_unassigned);
|
||||||
|
|
||||||
|
@ -1227,10 +1227,10 @@ void *qemu_get_ram_ptr(struct uc_struct *uc, ram_addr_t addr)
|
||||||
* but takes a size argument */
|
* but takes a size argument */
|
||||||
static void *qemu_ram_ptr_length(struct uc_struct *uc, ram_addr_t addr, hwaddr *size)
|
static void *qemu_ram_ptr_length(struct uc_struct *uc, ram_addr_t addr, hwaddr *size)
|
||||||
{
|
{
|
||||||
|
RAMBlock *block;
|
||||||
if (*size == 0) {
|
if (*size == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
RAMBlock *block;
|
|
||||||
|
|
||||||
QTAILQ_FOREACH(block, &uc->ram_list.blocks, next) {
|
QTAILQ_FOREACH(block, &uc->ram_list.blocks, next) {
|
||||||
if (addr - block->offset < block->length) {
|
if (addr - block->offset < block->length) {
|
||||||
|
@ -1337,10 +1337,12 @@ static bool subpage_accepts(void *opaque, hwaddr addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps subpage_ops = {
|
static const MemoryRegionOps subpage_ops = {
|
||||||
.read = subpage_read,
|
subpage_read,
|
||||||
.write = subpage_write,
|
subpage_write,
|
||||||
.valid.accepts = subpage_accepts,
|
DEVICE_NATIVE_ENDIAN,
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
{
|
||||||
|
0, 0, false, subpage_accepts,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
|
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
|
||||||
|
@ -1398,9 +1400,12 @@ static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps notdirty_mem_ops = {
|
static const MemoryRegionOps notdirty_mem_ops = {
|
||||||
.write = notdirty_mem_write,
|
NULL,
|
||||||
.valid.accepts = notdirty_mem_accepts,
|
notdirty_mem_write,
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
DEVICE_NATIVE_ENDIAN,
|
||||||
|
{
|
||||||
|
0, 0, false, notdirty_mem_accepts,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void io_mem_init(struct uc_struct* uc)
|
static void io_mem_init(struct uc_struct* uc)
|
||||||
|
@ -1437,14 +1442,14 @@ static subpage_t *subpage_init(AddressSpace *as, hwaddr base)
|
||||||
static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as,
|
static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as,
|
||||||
MemoryRegion *mr)
|
MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
assert(as);
|
MemoryRegionSection section = MemoryRegionSection_make(
|
||||||
MemoryRegionSection section = {
|
mr, as, 0,
|
||||||
.address_space = as,
|
int128_2_64(),
|
||||||
.mr = mr,
|
false,
|
||||||
.offset_within_address_space = 0,
|
0
|
||||||
.offset_within_region = 0,
|
);
|
||||||
.size = int128_2_64(),
|
|
||||||
};
|
assert(as);
|
||||||
|
|
||||||
return phys_section_add(map, §ion);
|
return phys_section_add(map, §ion);
|
||||||
}
|
}
|
||||||
|
@ -1465,7 +1470,7 @@ static void mem_begin(MemoryListener *listener)
|
||||||
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
|
AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
|
||||||
AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
|
AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
|
||||||
uint16_t n;
|
uint16_t n;
|
||||||
|
PhysPageEntry ppe = { 1, PHYS_MAP_NODE_NIL };
|
||||||
struct uc_struct *uc = as->uc;
|
struct uc_struct *uc = as->uc;
|
||||||
|
|
||||||
n = dummy_section(&d->map, as, &uc->io_mem_unassigned);
|
n = dummy_section(&d->map, as, &uc->io_mem_unassigned);
|
||||||
|
@ -1477,7 +1482,7 @@ static void mem_begin(MemoryListener *listener)
|
||||||
// n = dummy_section(&d->map, as, &uc->io_mem_watch);
|
// n = dummy_section(&d->map, as, &uc->io_mem_watch);
|
||||||
// assert(n == PHYS_SECTION_WATCH);
|
// assert(n == PHYS_SECTION_WATCH);
|
||||||
|
|
||||||
d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 };
|
d->phys_map = ppe;
|
||||||
d->as = as;
|
d->as = as;
|
||||||
as->next_dispatch = d;
|
as->next_dispatch = d;
|
||||||
}
|
}
|
||||||
|
@ -1510,14 +1515,17 @@ static void tcg_commit(MemoryListener *listener)
|
||||||
|
|
||||||
void address_space_init_dispatch(AddressSpace *as)
|
void address_space_init_dispatch(AddressSpace *as)
|
||||||
{
|
{
|
||||||
as->dispatch = NULL;
|
MemoryListener ml = {
|
||||||
as->dispatch_listener = (MemoryListener) {
|
mem_begin,
|
||||||
.begin = mem_begin,
|
mem_commit,
|
||||||
.commit = mem_commit,
|
mem_add,
|
||||||
.region_add = mem_add,
|
NULL,
|
||||||
.region_nop = mem_add,
|
mem_add,
|
||||||
.priority = 0,
|
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
|
||||||
|
0,
|
||||||
};
|
};
|
||||||
|
as->dispatch = NULL;
|
||||||
|
as->dispatch_listener = ml;
|
||||||
memory_listener_register(as->uc, &as->dispatch_listener, as);
|
memory_listener_register(as->uc, &as->dispatch_listener, as);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1632,7 +1640,7 @@ static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
|
||||||
|
|
||||||
/* Bound the maximum access by the alignment of the address. */
|
/* Bound the maximum access by the alignment of the address. */
|
||||||
if (!mr->ops->impl.unaligned) {
|
if (!mr->ops->impl.unaligned) {
|
||||||
unsigned align_size_max = addr & -addr;
|
unsigned align_size_max = addr & (0-addr);
|
||||||
if (align_size_max != 0 && align_size_max < access_size_max) {
|
if (align_size_max != 0 && align_size_max < access_size_max) {
|
||||||
access_size_max = align_size_max;
|
access_size_max = align_size_max;
|
||||||
}
|
}
|
||||||
|
@ -1804,7 +1812,7 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* used for ROM loading : can write in RAM and ROM */
|
/* used for ROM loading : can write in RAM and ROM */
|
||||||
__attribute__ ((visibility ("default")))
|
DEFAULT_VISIBILITY
|
||||||
void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
|
void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
|
||||||
const uint8_t *buf, int len)
|
const uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
|
@ -1953,7 +1961,7 @@ void *cpu_physical_memory_map(AddressSpace *as, hwaddr addr,
|
||||||
void cpu_physical_memory_unmap(AddressSpace *as, void *buffer, hwaddr len,
|
void cpu_physical_memory_unmap(AddressSpace *as, void *buffer, hwaddr len,
|
||||||
int is_write, hwaddr access_len)
|
int is_write, hwaddr access_len)
|
||||||
{
|
{
|
||||||
return address_space_unmap(as, buffer, len, is_write, access_len);
|
address_space_unmap(as, buffer, len, is_write, access_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* warning: addr must be aligned */
|
/* warning: addr must be aligned */
|
||||||
|
|
|
@ -467,9 +467,9 @@ static inline void mul64To128( uint64_t a, uint64_t b, uint64_t *z0Ptr, uint64_t
|
||||||
uint32_t aHigh, aLow, bHigh, bLow;
|
uint32_t aHigh, aLow, bHigh, bLow;
|
||||||
uint64_t z0, zMiddleA, zMiddleB, z1;
|
uint64_t z0, zMiddleA, zMiddleB, z1;
|
||||||
|
|
||||||
aLow = a;
|
aLow = (uint32_t)a;
|
||||||
aHigh = a>>32;
|
aHigh = a>>32;
|
||||||
bLow = b;
|
bLow = (uint32_t)b;
|
||||||
bHigh = b>>32;
|
bHigh = b>>32;
|
||||||
z1 = ( (uint64_t) aLow ) * bLow;
|
z1 = ( (uint64_t) aLow ) * bLow;
|
||||||
zMiddleA = ( (uint64_t) aLow ) * bHigh;
|
zMiddleA = ( (uint64_t) aLow ) * bHigh;
|
||||||
|
@ -691,7 +691,7 @@ static int8 countLeadingZeros64( uint64_t a )
|
||||||
else {
|
else {
|
||||||
a >>= 32;
|
a >>= 32;
|
||||||
}
|
}
|
||||||
shiftCount += countLeadingZeros32( a );
|
shiftCount += countLeadingZeros32( (uint32_t)a );
|
||||||
return shiftCount;
|
return shiftCount;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM)
|
||||||
roundBits = absZ & 0x7F;
|
roundBits = absZ & 0x7F;
|
||||||
absZ = ( absZ + roundIncrement )>>7;
|
absZ = ( absZ + roundIncrement )>>7;
|
||||||
absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
|
absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
|
||||||
z = absZ;
|
z = (int32_t)absZ;
|
||||||
if ( zSign ) z = - z;
|
if ( zSign ) z = - z;
|
||||||
if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
|
if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
|
||||||
float_raise( float_flag_invalid STATUS_VAR);
|
float_raise( float_flag_invalid STATUS_VAR);
|
||||||
|
@ -786,7 +786,7 @@ static floatx80
|
||||||
}
|
}
|
||||||
if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
|
if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
|
||||||
zSig0 += roundIncrement;
|
zSig0 += roundIncrement;
|
||||||
if ( zSig0 < roundIncrement ) {
|
if ( zSig0 < (uint64_t)roundIncrement ) {
|
||||||
++zExp;
|
++zExp;
|
||||||
zSig0 = LIT64( 0x8000000000000000 );
|
zSig0 = LIT64( 0x8000000000000000 );
|
||||||
}
|
}
|
||||||
|
@ -1289,7 +1289,7 @@ float32 int64_to_float32(int64_t a STATUS_PARAM)
|
||||||
absA = zSign ? - a : a;
|
absA = zSign ? - a : a;
|
||||||
shiftCount = countLeadingZeros64( absA ) - 40;
|
shiftCount = countLeadingZeros64( absA ) - 40;
|
||||||
if ( 0 <= shiftCount ) {
|
if ( 0 <= shiftCount ) {
|
||||||
return packFloat32( zSign, 0x95 - shiftCount, absA<<shiftCount );
|
return packFloat32( zSign, 0x95 - shiftCount, (uint32_t)(absA<<shiftCount) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
shiftCount += 7;
|
shiftCount += 7;
|
||||||
|
@ -1299,7 +1299,7 @@ float32 int64_to_float32(int64_t a STATUS_PARAM)
|
||||||
else {
|
else {
|
||||||
absA <<= shiftCount;
|
absA <<= shiftCount;
|
||||||
}
|
}
|
||||||
return roundAndPackFloat32( zSign, 0x9C - shiftCount, absA STATUS_VAR );
|
return roundAndPackFloat32( zSign, 0x9C - shiftCount, (uint32_t)absA STATUS_VAR );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1311,7 +1311,7 @@ float32 uint64_to_float32(uint64_t a STATUS_PARAM)
|
||||||
if ( a == 0 ) return float32_zero;
|
if ( a == 0 ) return float32_zero;
|
||||||
shiftCount = countLeadingZeros64( a ) - 40;
|
shiftCount = countLeadingZeros64( a ) - 40;
|
||||||
if ( 0 <= shiftCount ) {
|
if ( 0 <= shiftCount ) {
|
||||||
return packFloat32(0, 0x95 - shiftCount, a<<shiftCount);
|
return packFloat32(0, 0x95 - shiftCount, (uint32_t)(a<<shiftCount));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
shiftCount += 7;
|
shiftCount += 7;
|
||||||
|
@ -1321,7 +1321,7 @@ float32 uint64_to_float32(uint64_t a STATUS_PARAM)
|
||||||
else {
|
else {
|
||||||
a <<= shiftCount;
|
a <<= shiftCount;
|
||||||
}
|
}
|
||||||
return roundAndPackFloat32(0, 0x9C - shiftCount, a STATUS_VAR);
|
return roundAndPackFloat32(0, 0x9C - shiftCount, (uint32_t)a STATUS_VAR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1415,7 +1415,8 @@ float128 int64_to_float128(int64_t a STATUS_PARAM)
|
||||||
float128 uint64_to_float128(uint64_t a STATUS_PARAM)
|
float128 uint64_to_float128(uint64_t a STATUS_PARAM)
|
||||||
{
|
{
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
return float128_zero;
|
float128 zero = {0};
|
||||||
|
return zero;
|
||||||
}
|
}
|
||||||
return normalizeRoundAndPackFloat128(0, 0x406E, a, 0 STATUS_VAR);
|
return normalizeRoundAndPackFloat128(0, 0x406E, a, 0 STATUS_VAR);
|
||||||
}
|
}
|
||||||
|
@ -1639,9 +1640,10 @@ uint64 float32_to_uint64(float32 a STATUS_PARAM)
|
||||||
|
|
||||||
uint64 float32_to_uint64_round_to_zero(float32 a STATUS_PARAM)
|
uint64 float32_to_uint64_round_to_zero(float32 a STATUS_PARAM)
|
||||||
{
|
{
|
||||||
signed char current_rounding_mode = STATUS(float_rounding_mode);
|
int64_t v;
|
||||||
|
signed char current_rounding_mode = STATUS(float_rounding_mode);
|
||||||
set_float_rounding_mode(float_round_to_zero STATUS_VAR);
|
set_float_rounding_mode(float_round_to_zero STATUS_VAR);
|
||||||
int64_t v = float32_to_uint64(a STATUS_VAR);
|
v = float32_to_uint64(a STATUS_VAR);
|
||||||
set_float_rounding_mode(current_rounding_mode STATUS_VAR);
|
set_float_rounding_mode(current_rounding_mode STATUS_VAR);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
@ -2116,7 +2118,7 @@ float32 float32_mul( float32 a, float32 b STATUS_PARAM )
|
||||||
aSig = ( aSig | 0x00800000 )<<7;
|
aSig = ( aSig | 0x00800000 )<<7;
|
||||||
bSig = ( bSig | 0x00800000 )<<8;
|
bSig = ( bSig | 0x00800000 )<<8;
|
||||||
shift64RightJamming( ( (uint64_t) aSig ) * bSig, 32, &zSig64 );
|
shift64RightJamming( ( (uint64_t) aSig ) * bSig, 32, &zSig64 );
|
||||||
zSig = zSig64;
|
zSig = (uint32_t)zSig64;
|
||||||
if ( 0 <= (int32_t) ( zSig<<1 ) ) {
|
if ( 0 <= (int32_t) ( zSig<<1 ) ) {
|
||||||
zSig <<= 1;
|
zSig <<= 1;
|
||||||
--zExp;
|
--zExp;
|
||||||
|
@ -2265,13 +2267,13 @@ float32 float32_rem( float32 a, float32 b STATUS_PARAM )
|
||||||
while ( 0 < expDiff ) {
|
while ( 0 < expDiff ) {
|
||||||
q64 = estimateDiv128To64( aSig64, 0, bSig64 );
|
q64 = estimateDiv128To64( aSig64, 0, bSig64 );
|
||||||
q64 = ( 2 < q64 ) ? q64 - 2 : 0;
|
q64 = ( 2 < q64 ) ? q64 - 2 : 0;
|
||||||
aSig64 = - ( ( bSig * q64 )<<38 );
|
aSig64 = 0- ( ( bSig * q64 )<<38 );
|
||||||
expDiff -= 62;
|
expDiff -= 62;
|
||||||
}
|
}
|
||||||
expDiff += 64;
|
expDiff += 64;
|
||||||
q64 = estimateDiv128To64( aSig64, 0, bSig64 );
|
q64 = estimateDiv128To64( aSig64, 0, bSig64 );
|
||||||
q64 = ( 2 < q64 ) ? q64 - 2 : 0;
|
q64 = ( 2 < q64 ) ? q64 - 2 : 0;
|
||||||
q = q64>>( 64 - expDiff );
|
q = (uint32_t)(q64>>( 64 - expDiff ));
|
||||||
bSig <<= 6;
|
bSig <<= 6;
|
||||||
aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
|
aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
|
||||||
}
|
}
|
||||||
|
@ -2285,7 +2287,7 @@ float32 float32_rem( float32 a, float32 b STATUS_PARAM )
|
||||||
aSig = alternateASig;
|
aSig = alternateASig;
|
||||||
}
|
}
|
||||||
zSign = ( (int32_t) aSig < 0 );
|
zSign = ( (int32_t) aSig < 0 );
|
||||||
if ( zSign ) aSig = - aSig;
|
if ( zSign ) aSig = 0- aSig;
|
||||||
return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig STATUS_VAR );
|
return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig STATUS_VAR );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2438,7 +2440,7 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM)
|
||||||
if (!cSig) {
|
if (!cSig) {
|
||||||
/* Throw out the special case of c being an exact zero now */
|
/* Throw out the special case of c being an exact zero now */
|
||||||
shift64RightJamming(pSig64, 32, &pSig64);
|
shift64RightJamming(pSig64, 32, &pSig64);
|
||||||
pSig = pSig64;
|
pSig = (uint32_t)pSig64;
|
||||||
if (flags & float_muladd_halve_result) {
|
if (flags & float_muladd_halve_result) {
|
||||||
pExp--;
|
pExp--;
|
||||||
}
|
}
|
||||||
|
@ -2511,7 +2513,7 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM)
|
||||||
}
|
}
|
||||||
|
|
||||||
shift64RightJamming(zSig64, 32, &zSig64);
|
shift64RightJamming(zSig64, 32, &zSig64);
|
||||||
return roundAndPackFloat32(zSign, zExp, zSig64 STATUS_VAR);
|
return roundAndPackFloat32(zSign, zExp, (uint32_t)zSig64 STATUS_VAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2693,7 +2695,7 @@ float32 float32_log2( float32 a STATUS_PARAM )
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( zSign )
|
if ( zSign )
|
||||||
zSig = -zSig;
|
zSig = 0-zSig;
|
||||||
|
|
||||||
return normalizeRoundAndPackFloat32( zSign, 0x85, zSig STATUS_VAR );
|
return normalizeRoundAndPackFloat32( zSign, 0x85, zSig STATUS_VAR );
|
||||||
}
|
}
|
||||||
|
@ -2971,7 +2973,7 @@ int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM )
|
||||||
shiftCount = 0x433 - aExp;
|
shiftCount = 0x433 - aExp;
|
||||||
savedASig = aSig;
|
savedASig = aSig;
|
||||||
aSig >>= shiftCount;
|
aSig >>= shiftCount;
|
||||||
z = aSig;
|
z = (int32_t)aSig;
|
||||||
if ( aSign ) z = - z;
|
if ( aSign ) z = - z;
|
||||||
if ( ( z < 0 ) ^ aSign ) {
|
if ( ( z < 0 ) ^ aSign ) {
|
||||||
invalid:
|
invalid:
|
||||||
|
@ -3021,7 +3023,7 @@ int_fast16_t float64_to_int16_round_to_zero(float64 a STATUS_PARAM)
|
||||||
shiftCount = 0x433 - aExp;
|
shiftCount = 0x433 - aExp;
|
||||||
savedASig = aSig;
|
savedASig = aSig;
|
||||||
aSig >>= shiftCount;
|
aSig >>= shiftCount;
|
||||||
z = aSig;
|
z = (int32)aSig;
|
||||||
if ( aSign ) {
|
if ( aSign ) {
|
||||||
z = - z;
|
z = - z;
|
||||||
}
|
}
|
||||||
|
@ -3155,7 +3157,7 @@ float32 float64_to_float32( float64 a STATUS_PARAM )
|
||||||
return packFloat32( aSign, 0xFF, 0 );
|
return packFloat32( aSign, 0xFF, 0 );
|
||||||
}
|
}
|
||||||
shift64RightJamming( aSig, 22, &aSig );
|
shift64RightJamming( aSig, 22, &aSig );
|
||||||
zSig = aSig;
|
zSig = (uint32_t)aSig;
|
||||||
if ( aExp || zSig ) {
|
if ( aExp || zSig ) {
|
||||||
zSig |= 0x40000000;
|
zSig |= 0x40000000;
|
||||||
aExp -= 0x381;
|
aExp -= 0x381;
|
||||||
|
@ -3435,7 +3437,7 @@ float16 float64_to_float16(float64 a, flag ieee STATUS_PARAM)
|
||||||
return packFloat16(aSign, 0x1f, 0);
|
return packFloat16(aSign, 0x1f, 0);
|
||||||
}
|
}
|
||||||
shift64RightJamming(aSig, 29, &aSig);
|
shift64RightJamming(aSig, 29, &aSig);
|
||||||
zSig = aSig;
|
zSig = (uint32_t)aSig;
|
||||||
if (aExp == 0 && zSig == 0) {
|
if (aExp == 0 && zSig == 0) {
|
||||||
return packFloat16(aSign, 0, 0);
|
return packFloat16(aSign, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -3995,7 +3997,7 @@ float64 float64_rem( float64 a, float64 b STATUS_PARAM )
|
||||||
while ( 0 < expDiff ) {
|
while ( 0 < expDiff ) {
|
||||||
q = estimateDiv128To64( aSig, 0, bSig );
|
q = estimateDiv128To64( aSig, 0, bSig );
|
||||||
q = ( 2 < q ) ? q - 2 : 0;
|
q = ( 2 < q ) ? q - 2 : 0;
|
||||||
aSig = - ( ( bSig>>2 ) * q );
|
aSig = 0- ( ( bSig>>2 ) * q );
|
||||||
expDiff -= 62;
|
expDiff -= 62;
|
||||||
}
|
}
|
||||||
expDiff += 64;
|
expDiff += 64;
|
||||||
|
@ -4020,7 +4022,7 @@ float64 float64_rem( float64 a, float64 b STATUS_PARAM )
|
||||||
aSig = alternateASig;
|
aSig = alternateASig;
|
||||||
}
|
}
|
||||||
zSign = ( (int64_t) aSig < 0 );
|
zSign = ( (int64_t) aSig < 0 );
|
||||||
if ( zSign ) aSig = - aSig;
|
if ( zSign ) aSig = 0- aSig;
|
||||||
return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig STATUS_VAR );
|
return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig STATUS_VAR );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4305,7 +4307,7 @@ float64 float64_sqrt( float64 a STATUS_PARAM )
|
||||||
}
|
}
|
||||||
zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
|
zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
|
||||||
aSig |= LIT64( 0x0010000000000000 );
|
aSig |= LIT64( 0x0010000000000000 );
|
||||||
zSig = estimateSqrt32( aExp, aSig>>21 );
|
zSig = estimateSqrt32( aExp, (uint32_t)(aSig>>21) );
|
||||||
aSig <<= 9 - ( aExp & 1 );
|
aSig <<= 9 - ( aExp & 1 );
|
||||||
zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 );
|
zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 );
|
||||||
if ( ( zSig & 0x1FF ) <= 5 ) {
|
if ( ( zSig & 0x1FF ) <= 5 ) {
|
||||||
|
@ -4366,7 +4368,7 @@ float64 float64_log2( float64 a STATUS_PARAM )
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( zSign )
|
if ( zSign )
|
||||||
zSig = -zSig;
|
zSig = 0-zSig;
|
||||||
return normalizeRoundAndPackFloat64( zSign, 0x408, zSig STATUS_VAR );
|
return normalizeRoundAndPackFloat64( zSign, 0x408, zSig STATUS_VAR );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4652,7 +4654,7 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
|
||||||
shiftCount = 0x403E - aExp;
|
shiftCount = 0x403E - aExp;
|
||||||
savedASig = aSig;
|
savedASig = aSig;
|
||||||
aSig >>= shiftCount;
|
aSig >>= shiftCount;
|
||||||
z = aSig;
|
z = (int32_t)aSig;
|
||||||
if ( aSign ) z = - z;
|
if ( aSign ) z = - z;
|
||||||
if ( ( z < 0 ) ^ aSign ) {
|
if ( ( z < 0 ) ^ aSign ) {
|
||||||
invalid:
|
invalid:
|
||||||
|
@ -4786,7 +4788,7 @@ float32 floatx80_to_float32( floatx80 a STATUS_PARAM )
|
||||||
}
|
}
|
||||||
shift64RightJamming( aSig, 33, &aSig );
|
shift64RightJamming( aSig, 33, &aSig );
|
||||||
if ( aExp || aSig ) aExp -= 0x3F81;
|
if ( aExp || aSig ) aExp -= 0x3F81;
|
||||||
return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
|
return roundAndPackFloat32( aSign, aExp, (uint32_t)aSig STATUS_VAR );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5771,7 +5773,7 @@ int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM )
|
||||||
shiftCount = 0x402F - aExp;
|
shiftCount = 0x402F - aExp;
|
||||||
savedASig = aSig0;
|
savedASig = aSig0;
|
||||||
aSig0 >>= shiftCount;
|
aSig0 >>= shiftCount;
|
||||||
z = aSig0;
|
z = (int32_t)aSig0;
|
||||||
if ( aSign ) z = - z;
|
if ( aSign ) z = - z;
|
||||||
if ( ( z < 0 ) ^ aSign ) {
|
if ( ( z < 0 ) ^ aSign ) {
|
||||||
invalid:
|
invalid:
|
||||||
|
@ -5915,7 +5917,7 @@ float32 float128_to_float32( float128 a STATUS_PARAM )
|
||||||
}
|
}
|
||||||
aSig0 |= ( aSig1 != 0 );
|
aSig0 |= ( aSig1 != 0 );
|
||||||
shift64RightJamming( aSig0, 18, &aSig0 );
|
shift64RightJamming( aSig0, 18, &aSig0 );
|
||||||
zSig = aSig0;
|
zSig = (uint32_t)aSig0;
|
||||||
if ( aExp || zSig ) {
|
if ( aExp || zSig ) {
|
||||||
zSig |= 0x40000000;
|
zSig |= 0x40000000;
|
||||||
aExp -= 0x3F81;
|
aExp -= 0x3F81;
|
||||||
|
@ -6636,7 +6638,7 @@ float128 float128_sqrt( float128 a STATUS_PARAM )
|
||||||
}
|
}
|
||||||
zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
|
zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
|
||||||
aSig0 |= LIT64( 0x0001000000000000 );
|
aSig0 |= LIT64( 0x0001000000000000 );
|
||||||
zSig0 = estimateSqrt32( aExp, aSig0>>17 );
|
zSig0 = estimateSqrt32( aExp, (uint32_t)(aSig0>>17) );
|
||||||
shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
|
shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
|
||||||
zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
|
zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
|
||||||
doubleZSig0 = zSig0<<1;
|
doubleZSig0 = zSig0<<1;
|
||||||
|
@ -6929,7 +6931,7 @@ uint32 float32_to_uint32( float32 a STATUS_PARAM )
|
||||||
} else if (v > 0xffffffff) {
|
} else if (v > 0xffffffff) {
|
||||||
res = 0xffffffff;
|
res = 0xffffffff;
|
||||||
} else {
|
} else {
|
||||||
return v;
|
return (uint32)v;
|
||||||
}
|
}
|
||||||
set_float_exception_flags(old_exc_flags STATUS_VAR);
|
set_float_exception_flags(old_exc_flags STATUS_VAR);
|
||||||
float_raise(float_flag_invalid STATUS_VAR);
|
float_raise(float_flag_invalid STATUS_VAR);
|
||||||
|
@ -6948,7 +6950,7 @@ uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
|
||||||
} else if (v > 0xffffffff) {
|
} else if (v > 0xffffffff) {
|
||||||
res = 0xffffffff;
|
res = 0xffffffff;
|
||||||
} else {
|
} else {
|
||||||
return v;
|
return (uint32)v;
|
||||||
}
|
}
|
||||||
set_float_exception_flags(old_exc_flags, status);
|
set_float_exception_flags(old_exc_flags, status);
|
||||||
float_raise(float_flag_invalid STATUS_VAR);
|
float_raise(float_flag_invalid STATUS_VAR);
|
||||||
|
@ -7007,7 +7009,7 @@ uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM)
|
||||||
} else if (v > 0xffff) {
|
} else if (v > 0xffff) {
|
||||||
res = 0xffff;
|
res = 0xffff;
|
||||||
} else {
|
} else {
|
||||||
return v;
|
return (uint_fast16_t)v;
|
||||||
}
|
}
|
||||||
set_float_exception_flags(old_exc_flags, status);
|
set_float_exception_flags(old_exc_flags, status);
|
||||||
float_raise(float_flag_invalid STATUS_VAR);
|
float_raise(float_flag_invalid STATUS_VAR);
|
||||||
|
@ -7024,7 +7026,7 @@ uint32 float64_to_uint32( float64 a STATUS_PARAM )
|
||||||
if (v > 0xffffffff) {
|
if (v > 0xffffffff) {
|
||||||
res = 0xffffffff;
|
res = 0xffffffff;
|
||||||
} else {
|
} else {
|
||||||
return v;
|
return (uint32)v;
|
||||||
}
|
}
|
||||||
set_float_exception_flags(old_exc_flags, status);
|
set_float_exception_flags(old_exc_flags, status);
|
||||||
float_raise(float_flag_invalid STATUS_VAR);
|
float_raise(float_flag_invalid STATUS_VAR);
|
||||||
|
@ -7041,7 +7043,7 @@ uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
|
||||||
if (v > 0xffffffff) {
|
if (v > 0xffffffff) {
|
||||||
res = 0xffffffff;
|
res = 0xffffffff;
|
||||||
} else {
|
} else {
|
||||||
return v;
|
return (uint32)v;
|
||||||
}
|
}
|
||||||
set_float_exception_flags(old_exc_flags, status);
|
set_float_exception_flags(old_exc_flags, status);
|
||||||
float_raise(float_flag_invalid STATUS_VAR);
|
float_raise(float_flag_invalid STATUS_VAR);
|
||||||
|
@ -7060,7 +7062,7 @@ int_fast16_t float64_to_int16(float64 a STATUS_PARAM)
|
||||||
} else if (v > 0x7fff) {
|
} else if (v > 0x7fff) {
|
||||||
res = 0x7fff;
|
res = 0x7fff;
|
||||||
} else {
|
} else {
|
||||||
return v;
|
return (int_fast16_t)v;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_float_exception_flags(old_exc_flags, status);
|
set_float_exception_flags(old_exc_flags, status);
|
||||||
|
@ -7080,7 +7082,7 @@ uint_fast16_t float64_to_uint16(float64 a STATUS_PARAM)
|
||||||
} else if (v > 0xffff) {
|
} else if (v > 0xffff) {
|
||||||
res = 0xffff;
|
res = 0xffff;
|
||||||
} else {
|
} else {
|
||||||
return v;
|
return (uint_fast16_t)v;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_float_exception_flags(old_exc_flags, status);
|
set_float_exception_flags(old_exc_flags, status);
|
||||||
|
@ -7100,7 +7102,7 @@ uint_fast16_t float64_to_uint16_round_to_zero(float64 a STATUS_PARAM)
|
||||||
} else if (v > 0xffff) {
|
} else if (v > 0xffff) {
|
||||||
res = 0xffff;
|
res = 0xffff;
|
||||||
} else {
|
} else {
|
||||||
return v;
|
return (uint_fast16_t)v;
|
||||||
}
|
}
|
||||||
set_float_exception_flags(old_exc_flags, status);
|
set_float_exception_flags(old_exc_flags, status);
|
||||||
float_raise(float_flag_invalid STATUS_VAR);
|
float_raise(float_flag_invalid STATUS_VAR);
|
||||||
|
@ -7156,9 +7158,10 @@ uint64_t float64_to_uint64(float64 a STATUS_PARAM)
|
||||||
|
|
||||||
uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
|
uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
|
||||||
{
|
{
|
||||||
signed char current_rounding_mode = STATUS(float_rounding_mode);
|
int64_t v;
|
||||||
|
signed char current_rounding_mode = STATUS(float_rounding_mode);
|
||||||
set_float_rounding_mode(float_round_to_zero STATUS_VAR);
|
set_float_rounding_mode(float_round_to_zero STATUS_VAR);
|
||||||
int64_t v = float64_to_uint64(a STATUS_VAR);
|
v = float64_to_uint64(a STATUS_VAR);
|
||||||
set_float_rounding_mode(current_rounding_mode STATUS_VAR);
|
set_float_rounding_mode(current_rounding_mode STATUS_VAR);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1217,16 +1217,18 @@ void g_free(gpointer ptr)
|
||||||
|
|
||||||
gpointer g_malloc(size_t size)
|
gpointer g_malloc(size_t size)
|
||||||
{
|
{
|
||||||
if (size == 0) return NULL;
|
void *res;
|
||||||
void *res = malloc(size);
|
if (size == 0) return NULL;
|
||||||
|
res = malloc(size);
|
||||||
if (res == NULL) exit(1);
|
if (res == NULL) exit(1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpointer g_malloc0(size_t size)
|
gpointer g_malloc0(size_t size)
|
||||||
{
|
{
|
||||||
|
void *res;
|
||||||
if (size == 0) return NULL;
|
if (size == 0) return NULL;
|
||||||
void *res = calloc(size, 1);
|
res = calloc(size, 1);
|
||||||
if (res == NULL) exit(1);
|
if (res == NULL) exit(1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1239,18 +1241,23 @@ gpointer g_try_malloc0(size_t size)
|
||||||
|
|
||||||
gpointer g_realloc(gpointer ptr, size_t size)
|
gpointer g_realloc(gpointer ptr, size_t size)
|
||||||
{
|
{
|
||||||
|
void *res;
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
free(ptr);
|
free(ptr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
void *res = realloc(ptr, size);
|
res = realloc(ptr, size);
|
||||||
if (res == NULL) exit(1);
|
if (res == NULL) exit(1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *g_strdup(const char *str)
|
char *g_strdup(const char *str)
|
||||||
{
|
{
|
||||||
return str ? strdup(str) : NULL;
|
#ifdef _MSC_VER
|
||||||
|
return str ? _strdup(str) : NULL;
|
||||||
|
#else
|
||||||
|
return str ? strdup(str) : NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char *g_strdup_printf(const char *format, ...)
|
char *g_strdup_printf(const char *format, ...)
|
||||||
|
@ -1266,7 +1273,17 @@ char *g_strdup_printf(const char *format, ...)
|
||||||
char *g_strdup_vprintf(const char *format, va_list ap)
|
char *g_strdup_vprintf(const char *format, va_list ap)
|
||||||
{
|
{
|
||||||
char *str_res = NULL;
|
char *str_res = NULL;
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
int len = _vscprintf(format, ap);
|
||||||
|
if( len < 0 )
|
||||||
|
return NULL;
|
||||||
|
str_res = (char *)malloc(len+1);
|
||||||
|
if(str_res==NULL)
|
||||||
|
return NULL;
|
||||||
|
vsnprintf(str_res, len+1, format, ap);
|
||||||
|
#else
|
||||||
vasprintf(&str_res, format, ap);
|
vasprintf(&str_res, format, ap);
|
||||||
|
#endif
|
||||||
return str_res;
|
return str_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,16 +149,30 @@ static void pc_machine_class_init(struct uc_struct *uc, ObjectClass *oc, void *d
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo pc_machine_info = {
|
static const TypeInfo pc_machine_info = {
|
||||||
.name = TYPE_PC_MACHINE,
|
TYPE_PC_MACHINE,
|
||||||
.parent = TYPE_MACHINE,
|
TYPE_MACHINE,
|
||||||
.abstract = true,
|
|
||||||
.instance_size = sizeof(PCMachineState),
|
sizeof(PCMachineClass),
|
||||||
.instance_init = pc_machine_initfn,
|
sizeof(PCMachineState),
|
||||||
.class_size = sizeof(PCMachineClass),
|
NULL,
|
||||||
.class_init = pc_machine_class_init,
|
|
||||||
.interfaces = (InterfaceInfo[]) {
|
pc_machine_initfn,
|
||||||
{ }
|
NULL,
|
||||||
},
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
pc_machine_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
true,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
// should this be added somehow?
|
||||||
|
//.interfaces = (InterfaceInfo[]) { { } },
|
||||||
};
|
};
|
||||||
|
|
||||||
void pc_machine_register_types(struct uc_struct *uc)
|
void pc_machine_register_types(struct uc_struct *uc)
|
||||||
|
|
|
@ -46,19 +46,14 @@ static int pc_init_pci(struct uc_struct *uc, MachineState *machine)
|
||||||
return pc_init1(uc, machine);
|
return pc_init1(uc, machine);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PC_I440FX_MACHINE_OPTIONS \
|
|
||||||
PC_DEFAULT_MACHINE_OPTIONS, \
|
|
||||||
.family = "pc_piix"
|
|
||||||
|
|
||||||
#define PC_I440FX_2_2_MACHINE_OPTIONS \
|
|
||||||
PC_I440FX_MACHINE_OPTIONS
|
|
||||||
|
|
||||||
static QEMUMachine pc_i440fx_machine_v2_2 = {
|
static QEMUMachine pc_i440fx_machine_v2_2 = {
|
||||||
PC_I440FX_2_2_MACHINE_OPTIONS,
|
"pc_piix",
|
||||||
.name = "pc-i440fx-2.2",
|
"pc-i440fx-2.2",
|
||||||
.init = pc_init_pci,
|
pc_init_pci,
|
||||||
.is_default = 1,
|
NULL,
|
||||||
.arch = UC_ARCH_X86, // X86
|
255,
|
||||||
|
1,
|
||||||
|
UC_ARCH_X86, // X86
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pc_generic_machine_class_init(struct uc_struct *uc, ObjectClass *oc, void *data)
|
static void pc_generic_machine_class_init(struct uc_struct *uc, ObjectClass *oc, void *data)
|
||||||
|
|
|
@ -205,10 +205,20 @@ static void apic_class_init(struct uc_struct *uc, ObjectClass *klass, void *data
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo apic_info = {
|
static const TypeInfo apic_info = {
|
||||||
.name = "apic",
|
"apic",
|
||||||
.instance_size = sizeof(APICCommonState),
|
TYPE_APIC_COMMON,
|
||||||
.parent = TYPE_APIC_COMMON,
|
|
||||||
.class_init = apic_class_init,
|
0,
|
||||||
|
sizeof(APICCommonState),
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
apic_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
void apic_register_types(struct uc_struct *uc)
|
void apic_register_types(struct uc_struct *uc)
|
||||||
|
|
|
@ -163,11 +163,13 @@ void apic_init_reset(struct uc_struct *uc, DeviceState *dev)
|
||||||
|
|
||||||
void apic_designate_bsp(struct uc_struct *uc, DeviceState *dev)
|
void apic_designate_bsp(struct uc_struct *uc, DeviceState *dev)
|
||||||
{
|
{
|
||||||
if (dev == NULL) {
|
APICCommonState *s;
|
||||||
|
|
||||||
|
if (dev == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
APICCommonState *s = APIC_COMMON(uc, dev);
|
s = APIC_COMMON(uc, dev);
|
||||||
s->apicbase |= MSR_IA32_APICBASE_BSP;
|
s->apicbase |= MSR_IA32_APICBASE_BSP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,12 +247,24 @@ static void apic_common_class_init(struct uc_struct *uc, ObjectClass *klass, voi
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo apic_common_type = {
|
static const TypeInfo apic_common_type = {
|
||||||
.name = TYPE_APIC_COMMON,
|
TYPE_APIC_COMMON,
|
||||||
.parent = TYPE_DEVICE,
|
TYPE_DEVICE,
|
||||||
.instance_size = sizeof(APICCommonState),
|
|
||||||
.class_size = sizeof(APICCommonClass),
|
sizeof(APICCommonClass),
|
||||||
.class_init = apic_common_class_init,
|
sizeof(APICCommonState),
|
||||||
.abstract = true,
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
apic_common_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
true,
|
||||||
};
|
};
|
||||||
|
|
||||||
void apic_common_register_types(struct uc_struct *uc)
|
void apic_common_register_types(struct uc_struct *uc)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef _QEMU_ELF_H
|
#ifndef _QEMU_ELF_H
|
||||||
#define _QEMU_ELF_H
|
#define _QEMU_ELF_H
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include "platform.h"
|
||||||
|
|
||||||
/* 32-bit ELF base types. */
|
/* 32-bit ELF base types. */
|
||||||
typedef uint32_t Elf32_Addr;
|
typedef uint32_t Elf32_Addr;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <inttypes.h>
|
#include "platform.h"
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
@ -96,7 +96,7 @@ typedef struct CPUTLBEntry {
|
||||||
/* padding to get a power of two size */
|
/* padding to get a power of two size */
|
||||||
uint8_t dummy[(1 << CPU_TLB_ENTRY_BITS) -
|
uint8_t dummy[(1 << CPU_TLB_ENTRY_BITS) -
|
||||||
(sizeof(target_ulong) * 3 +
|
(sizeof(target_ulong) * 3 +
|
||||||
((-sizeof(target_ulong) * 3) & (sizeof(uintptr_t) - 1)) +
|
(((-(int)sizeof(target_ulong)) * 3) & (sizeof(uintptr_t) - 1)) +
|
||||||
sizeof(uintptr_t))];
|
sizeof(uintptr_t))];
|
||||||
} CPUTLBEntry;
|
} CPUTLBEntry;
|
||||||
|
|
||||||
|
|
|
@ -391,7 +391,7 @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, target_ulong addr,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
haddr = addr + env->tlb_table[mmu_idx][index].addend;
|
haddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][index].addend);
|
||||||
return (void *)haddr;
|
return (void *)haddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
|
||||||
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
|
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
|
||||||
res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
|
res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
|
||||||
} else {
|
} else {
|
||||||
uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
|
uintptr_t hostaddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][page_index].addend);
|
||||||
res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
|
res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -100,7 +100,7 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
|
||||||
res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX),
|
res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX),
|
||||||
MMUSUFFIX)(env, addr, mmu_idx);
|
MMUSUFFIX)(env, addr, mmu_idx);
|
||||||
} else {
|
} else {
|
||||||
uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
|
uintptr_t hostaddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][page_index].addend);
|
||||||
res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
|
res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
@ -126,7 +126,7 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
|
||||||
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
|
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
|
||||||
glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
|
glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
|
||||||
} else {
|
} else {
|
||||||
uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
|
uintptr_t hostaddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][page_index].addend);
|
||||||
glue(glue(st, SUFFIX), _raw)(hostaddr, v);
|
glue(glue(st, SUFFIX), _raw)(hostaddr, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,7 +277,7 @@ static inline void tb_set_jmp_target(TranslationBlock *tb,
|
||||||
int n, uintptr_t addr)
|
int n, uintptr_t addr)
|
||||||
{
|
{
|
||||||
uint16_t offset = tb->tb_jmp_offset[n];
|
uint16_t offset = tb->tb_jmp_offset[n];
|
||||||
tb_set_jmp_target1((uintptr_t)(tb->tc_ptr + offset), addr);
|
tb_set_jmp_target1((uintptr_t)((char*)tb->tc_ptr + offset), addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -310,6 +310,9 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
|
||||||
#if defined(CONFIG_TCG_INTERPRETER)
|
#if defined(CONFIG_TCG_INTERPRETER)
|
||||||
extern uintptr_t tci_tb_ptr;
|
extern uintptr_t tci_tb_ptr;
|
||||||
# define GETRA() tci_tb_ptr
|
# define GETRA() tci_tb_ptr
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#include <intrin.h>
|
||||||
|
# define GETRA() (uintptr_t)_ReturnAddress()
|
||||||
#else
|
#else
|
||||||
# define GETRA() \
|
# define GETRA() \
|
||||||
((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0)))
|
((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0)))
|
||||||
|
|
|
@ -7,31 +7,31 @@
|
||||||
#include <exec/helper-head.h>
|
#include <exec/helper-head.h>
|
||||||
|
|
||||||
#define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \
|
#define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \
|
||||||
{ .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
|
{ HELPER(NAME), #NAME, FLAGS, \
|
||||||
.sizemask = dh_sizemask(ret, 0) },
|
dh_sizemask(ret, 0) },
|
||||||
|
|
||||||
#define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) \
|
#define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) \
|
||||||
{ .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
|
{ HELPER(NAME), #NAME, FLAGS, \
|
||||||
.sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) },
|
dh_sizemask(ret, 0) | dh_sizemask(t1, 1) },
|
||||||
|
|
||||||
#define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) \
|
#define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) \
|
||||||
{ .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
|
{ HELPER(NAME), #NAME, FLAGS, \
|
||||||
.sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
|
dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
|
||||||
| dh_sizemask(t2, 2) },
|
| dh_sizemask(t2, 2) },
|
||||||
|
|
||||||
#define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \
|
#define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \
|
||||||
{ .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
|
{ HELPER(NAME), #NAME, FLAGS, \
|
||||||
.sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
|
dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
|
||||||
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) },
|
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) },
|
||||||
|
|
||||||
#define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \
|
#define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \
|
||||||
{ .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
|
{ HELPER(NAME), #NAME, FLAGS, \
|
||||||
.sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
|
dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
|
||||||
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) },
|
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) },
|
||||||
|
|
||||||
#define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \
|
#define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \
|
||||||
{ .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
|
{ HELPER(NAME), #NAME, FLAGS, \
|
||||||
.sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
|
dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
|
||||||
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
|
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
|
||||||
| dh_sizemask(t5, 5) },
|
| dh_sizemask(t5, 5) },
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
/* hwaddr is the type of a physical address (its size can
|
/* hwaddr is the type of a physical address (its size can
|
||||||
be different from 'target_ulong'). */
|
be different from 'target_ulong'). */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
|
|
||||||
typedef uint64_t hwaddr;
|
typedef uint64_t hwaddr;
|
||||||
#define HWADDR_MAX UINT64_MAX
|
#define HWADDR_MAX UINT64_MAX
|
||||||
|
|
|
@ -21,8 +21,7 @@
|
||||||
#define DIRTY_MEMORY_MIGRATION 2
|
#define DIRTY_MEMORY_MIGRATION 2
|
||||||
#define DIRTY_MEMORY_NUM 3 /* num of dirty bits */
|
#define DIRTY_MEMORY_NUM 3 /* num of dirty bits */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "exec/cpu-common.h"
|
#include "exec/cpu-common.h"
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
@ -243,6 +242,19 @@ struct MemoryRegionSection {
|
||||||
bool readonly;
|
bool readonly;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline MemoryRegionSection MemoryRegionSection_make(MemoryRegion *mr, AddressSpace *address_space,
|
||||||
|
hwaddr offset_within_region, Int128 size, hwaddr offset_within_address_space, bool readonly)
|
||||||
|
{
|
||||||
|
MemoryRegionSection section;
|
||||||
|
section.mr = mr;
|
||||||
|
section.address_space = address_space;
|
||||||
|
section.offset_within_region = offset_within_region;
|
||||||
|
section.size = size;
|
||||||
|
section.offset_within_address_space = offset_within_address_space;
|
||||||
|
section.readonly = readonly;
|
||||||
|
return section;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* memory_region_init: Initialize a memory region
|
* memory_region_init: Initialize a memory region
|
||||||
*
|
*
|
||||||
|
|
|
@ -42,7 +42,7 @@ these four paragraphs for those parts of this code that are retained.
|
||||||
#include <sunmath.h>
|
#include <sunmath.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include "platform.h"
|
||||||
#include "config-host.h"
|
#include "config-host.h"
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ typedef struct {
|
||||||
uint16_t high;
|
uint16_t high;
|
||||||
} floatx80;
|
} floatx80;
|
||||||
#define make_floatx80(exp, mant) ((floatx80) { mant, exp })
|
#define make_floatx80(exp, mant) ((floatx80) { mant, exp })
|
||||||
#define make_floatx80_init(exp, mant) { .low = mant, .high = exp }
|
#define make_floatx80_init(exp, mant) { mant, exp }
|
||||||
typedef struct {
|
typedef struct {
|
||||||
#ifdef HOST_WORDS_BIGENDIAN
|
#ifdef HOST_WORDS_BIGENDIAN
|
||||||
uint64_t high, low;
|
uint64_t high, low;
|
||||||
|
@ -133,8 +133,13 @@ typedef struct {
|
||||||
uint64_t low, high;
|
uint64_t low, high;
|
||||||
#endif
|
#endif
|
||||||
} float128;
|
} float128;
|
||||||
#define make_float128(high_, low_) ((float128) { .high = high_, .low = low_ })
|
#ifdef HOST_WORDS_BIGENDIAN
|
||||||
#define make_float128_init(high_, low_) { .high = high_, .low = low_ }
|
#define make_float128(high_, low_) ((float128) { high_, low_ })
|
||||||
|
#define make_float128_init(high_, low_) { high_, low_ }
|
||||||
|
#else
|
||||||
|
#define make_float128(high_, low_) ((float128) { low_, high_ })
|
||||||
|
#define make_float128_init(high_, low_) { low_, high_ }
|
||||||
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Software IEC/IEEE floating-point underflow tininess-detection mode.
|
| Software IEC/IEEE floating-point underflow tininess-detection mode.
|
||||||
|
|
|
@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#ifndef __GLIB_COMPAT_H
|
#ifndef __GLIB_COMPAT_H
|
||||||
#define __GLIB_COMPAT_H
|
#define __GLIB_COMPAT_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
|
@ -128,13 +128,13 @@ struct APICCommonState {
|
||||||
hwaddr vapic_paddr; /* note: persistence via kvmvapic */
|
hwaddr vapic_paddr; /* note: persistence via kvmvapic */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct VAPICState {
|
QEMU_PACK( typedef struct VAPICState {
|
||||||
uint8_t tpr;
|
uint8_t tpr;
|
||||||
uint8_t isr;
|
uint8_t isr;
|
||||||
uint8_t zero;
|
uint8_t zero;
|
||||||
uint8_t irr;
|
uint8_t irr;
|
||||||
uint8_t enabled;
|
uint8_t enabled;
|
||||||
} QEMU_PACKED VAPICState;
|
}) VAPICState;
|
||||||
|
|
||||||
extern bool apic_report_tpr_access;
|
extern bool apic_report_tpr_access;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include "qemu/compiler.h"
|
#include "qemu/compiler.h"
|
||||||
#include "qapi-types.h"
|
#include "qapi-types.h"
|
||||||
#include <stdbool.h>
|
#include "platform.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class representing internal errors within QEMU. An error has a ErrorClass
|
* A class representing internal errors within QEMU. An error has a ErrorClass
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#ifndef QBOOL_H
|
#ifndef QBOOL_H
|
||||||
#define QBOOL_H
|
#define QBOOL_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include "qapi/qmp/qobject.h"
|
#include "qapi/qmp/qobject.h"
|
||||||
|
|
||||||
typedef struct QBool {
|
typedef struct QBool {
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
#include "qapi/qmp/qobject.h"
|
#include "qapi/qmp/qobject.h"
|
||||||
#include "qapi/qmp/qlist.h"
|
#include "qapi/qmp/qlist.h"
|
||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
#include <stdbool.h>
|
#include "platform.h"
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define QDICT_BUCKET_MAX 512
|
#define QDICT_BUCKET_MAX 512
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#ifndef QFLOAT_H
|
#ifndef QFLOAT_H
|
||||||
#define QFLOAT_H
|
#define QFLOAT_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include "qapi/qmp/qobject.h"
|
#include "qapi/qmp/qobject.h"
|
||||||
|
|
||||||
typedef struct QFloat {
|
typedef struct QFloat {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#ifndef QINT_H
|
#ifndef QINT_H
|
||||||
#define QINT_H
|
#define QINT_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include "qapi/qmp/qobject.h"
|
#include "qapi/qmp/qobject.h"
|
||||||
|
|
||||||
typedef struct QInt {
|
typedef struct QInt {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#ifndef QSTRING_H
|
#ifndef QSTRING_H
|
||||||
#define QSTRING_H
|
#define QSTRING_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include "qapi/qmp/qobject.h"
|
#include "qapi/qmp/qobject.h"
|
||||||
|
|
||||||
typedef struct QString {
|
typedef struct QString {
|
||||||
|
|
|
@ -27,18 +27,14 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include "platform.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "glib_compat.h"
|
#include "glib_compat.h"
|
||||||
|
@ -195,7 +191,7 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
|
||||||
rl = (uint64_t)u.l.low * (uint64_t)b;
|
rl = (uint64_t)u.l.low * (uint64_t)b;
|
||||||
rh = (uint64_t)u.l.high * (uint64_t)b;
|
rh = (uint64_t)u.l.high * (uint64_t)b;
|
||||||
rh += (rl >> 32);
|
rh += (rl >> 32);
|
||||||
res.l.high = rh / c;
|
res.l.high = (uint32_t)(rh / c);
|
||||||
res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
|
res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
|
||||||
return res.ll;
|
return res.ll;
|
||||||
}
|
}
|
||||||
|
@ -235,4 +231,23 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
|
||||||
#define ALL_EQ(v1, v2) ((v1) == (v2))
|
#define ALL_EQ(v1, v2) ((v1) == (v2))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// support for calling functions before main code is executed.
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma section(".CRT$XCU",read)
|
||||||
|
#define INITIALIZER2_(f,p) \
|
||||||
|
static void f(void); \
|
||||||
|
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
|
||||||
|
__pragma(comment(linker,"/include:" p #f "_")) \
|
||||||
|
static void f(void)
|
||||||
|
#ifdef _WIN64
|
||||||
|
#define INITIALIZER(f) INITIALIZER2_(f,"")
|
||||||
|
#else
|
||||||
|
#define INITIALIZER(f) INITIALIZER2_(f,"_")
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define INITIALIZER(f) \
|
||||||
|
static void f(void) __attribute__((constructor)); \
|
||||||
|
static void f(void)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,7 +18,12 @@
|
||||||
/* For C11 atomic ops */
|
/* For C11 atomic ops */
|
||||||
|
|
||||||
/* Compiler barrier */
|
/* Compiler barrier */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// TODO: fix me!!!
|
||||||
|
#define barrier() //{ __asm volatile("" ::: "memory"); (void)0; }
|
||||||
|
#else
|
||||||
#define barrier() ({ asm volatile("" ::: "memory"); (void)0; })
|
#define barrier() ({ asm volatile("" ::: "memory"); (void)0; })
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __ATOMIC_RELAXED
|
#ifndef __ATOMIC_RELAXED
|
||||||
|
|
||||||
|
@ -31,9 +36,19 @@
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
#if !QEMU_GNUC_PREREQ(4, 4)
|
#if !QEMU_GNUC_PREREQ(4, 4)
|
||||||
#if defined __x86_64__
|
#if defined __x86_64__
|
||||||
#define smp_mb() ({ asm volatile("mfence" ::: "memory"); (void)0; })
|
# ifdef _MSC_VER
|
||||||
|
// TODO: fix me!!!
|
||||||
|
# define smp_mb() //{ __asm volatile("mfence" ::: "memory"); (void)0; }
|
||||||
|
# else
|
||||||
|
# define smp_mb() ({ asm volatile("mfence" ::: "memory"); (void)0; })
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
#define smp_mb() ({ asm volatile("lock; addl $0,0(%%esp) " ::: "memory"); (void)0; })
|
# ifdef _MSC_VER
|
||||||
|
// TODO: fix me!!!
|
||||||
|
# define smp_mb() //{ __asm volatile("lock; addl $0,0(%esp) " ::: "memory"); (void)0; }
|
||||||
|
# else
|
||||||
|
# define smp_mb() ({ asm volatile("lock; addl $0,0(%%esp) " ::: "memory"); (void)0; })
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -183,6 +198,19 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Provide shorter names for GCC atomic builtins. */
|
/* Provide shorter names for GCC atomic builtins. */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#ifdef _WIN64
|
||||||
|
#define atomic_fetch_inc(ptr) InterlockedIncrement64(ptr)
|
||||||
|
#define atomic_fetch_dec(ptr) InterlockedDecrement64(ptr)
|
||||||
|
#define atomic_fetch_add(ptr, n) InterlockedAdd64(ptr, n)
|
||||||
|
#define atomic_fetch_sub(ptr, n) InterlockedAdd64(ptr, -n)
|
||||||
|
#else
|
||||||
|
#define atomic_fetch_inc(ptr) InterlockedIncrement(ptr)
|
||||||
|
#define atomic_fetch_dec(ptr) InterlockedDecrement(ptr)
|
||||||
|
#define atomic_fetch_add(ptr, n) InterlockedAdd(ptr, n)
|
||||||
|
#define atomic_fetch_sub(ptr, n) InterlockedAdd(ptr, -n)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#define atomic_fetch_inc(ptr) __sync_fetch_and_add(ptr, 1)
|
#define atomic_fetch_inc(ptr) __sync_fetch_and_add(ptr, 1)
|
||||||
#define atomic_fetch_dec(ptr) __sync_fetch_and_add(ptr, -1)
|
#define atomic_fetch_dec(ptr) __sync_fetch_and_add(ptr, -1)
|
||||||
#define atomic_fetch_add __sync_fetch_and_add
|
#define atomic_fetch_add __sync_fetch_and_add
|
||||||
|
@ -190,13 +218,28 @@
|
||||||
#define atomic_fetch_and __sync_fetch_and_and
|
#define atomic_fetch_and __sync_fetch_and_and
|
||||||
#define atomic_fetch_or __sync_fetch_and_or
|
#define atomic_fetch_or __sync_fetch_and_or
|
||||||
#define atomic_cmpxchg __sync_val_compare_and_swap
|
#define atomic_cmpxchg __sync_val_compare_and_swap
|
||||||
|
#endif
|
||||||
|
|
||||||
/* And even shorter names that return void. */
|
/* And even shorter names that return void. */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#ifdef _WIN64
|
||||||
|
#define atomic_inc(ptr) ((void) InterlockedIncrement64(ptr))
|
||||||
|
#define atomic_dec(ptr) ((void) InterlockedDecrement64(ptr))
|
||||||
|
#define atomic_add(ptr, n) ((void) InterlockedAdd64(ptr, n))
|
||||||
|
#define atomic_sub(ptr, n) ((void) InterlockedAdd64(ptr, -n))
|
||||||
|
#else
|
||||||
|
#define atomic_inc(ptr) ((void) InterlockedIncrement(ptr))
|
||||||
|
#define atomic_dec(ptr) ((void) InterlockedDecrement(ptr))
|
||||||
|
#define atomic_add(ptr, n) ((void) InterlockedAdd(ptr, n))
|
||||||
|
#define atomic_sub(ptr, n) ((void) InterlockedAdd(ptr, -n))
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#define atomic_inc(ptr) ((void) __sync_fetch_and_add(ptr, 1))
|
#define atomic_inc(ptr) ((void) __sync_fetch_and_add(ptr, 1))
|
||||||
#define atomic_dec(ptr) ((void) __sync_fetch_and_add(ptr, -1))
|
#define atomic_dec(ptr) ((void) __sync_fetch_and_add(ptr, -1))
|
||||||
#define atomic_add(ptr, n) ((void) __sync_fetch_and_add(ptr, n))
|
#define atomic_add(ptr, n) ((void) __sync_fetch_and_add(ptr, n))
|
||||||
#define atomic_sub(ptr, n) ((void) __sync_fetch_and_sub(ptr, n))
|
#define atomic_sub(ptr, n) ((void) __sync_fetch_and_sub(ptr, n))
|
||||||
#define atomic_and(ptr, n) ((void) __sync_fetch_and_and(ptr, n))
|
#define atomic_and(ptr, n) ((void) __sync_fetch_and_and(ptr, n))
|
||||||
#define atomic_or(ptr, n) ((void) __sync_fetch_and_or(ptr, n))
|
#define atomic_or(ptr, n) ((void) __sync_fetch_and_or(ptr, n))
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#ifndef BITOPS_H
|
#ifndef BITOPS_H
|
||||||
#define BITOPS_H
|
#define BITOPS_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "host-utils.h"
|
#include "host-utils.h"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define BSWAP_H
|
#define BSWAP_H
|
||||||
|
|
||||||
#include "config-host.h"
|
#include "config-host.h"
|
||||||
#include <inttypes.h>
|
#include "platform.h"
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "fpu/softfloat.h"
|
#include "fpu/softfloat.h"
|
||||||
|
|
|
@ -5,6 +5,58 @@
|
||||||
|
|
||||||
#include "config-host.h"
|
#include "config-host.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
// MSVC support
|
||||||
|
|
||||||
|
#define inline __inline
|
||||||
|
#define __func__ __FUNCTION__
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <float.h>
|
||||||
|
#define isinf(x) (!_finite(x))
|
||||||
|
|
||||||
|
static double rint( double x )
|
||||||
|
{
|
||||||
|
return floor(x < 0 ? x - 0.5 : x + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
union MSVC_FLOAT_HACK
|
||||||
|
{
|
||||||
|
unsigned char Bytes[4];
|
||||||
|
float Value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef NAN
|
||||||
|
static union MSVC_FLOAT_HACK __NAN = {{0x00, 0x00, 0xC0, 0x7F}};
|
||||||
|
#define NAN (__NAN.Value)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define QEMU_DIV0 __pragma(warning(suppress:2124)) // divide by zero error
|
||||||
|
|
||||||
|
#define QEMU_GNUC_PREREQ(maj, min) 0
|
||||||
|
|
||||||
|
#define QEMU_NORETURN __declspec(noreturn)
|
||||||
|
#define QEMU_UNUSED_VAR __pragma(warning(suppress:4100)) // unused variables only
|
||||||
|
#define QEMU_UNUSED_FUNC
|
||||||
|
#define QEMU_WARN_UNUSED_RESULT
|
||||||
|
#define QEMU_ARTIFICIAL
|
||||||
|
#define QEMU_PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )
|
||||||
|
|
||||||
|
#define QEMU_ALIGN(A, B) __declspec(align(A)) B
|
||||||
|
|
||||||
|
#define cat(x,y) x ## y
|
||||||
|
#define cat2(x,y) cat(x,y)
|
||||||
|
#define QEMU_BUILD_BUG_ON(x) \
|
||||||
|
typedef char cat2(qemu_build_bug_on__,__LINE__)[(x)?-1:1] QEMU_UNUSED_VAR;
|
||||||
|
|
||||||
|
#define GCC_FMT_ATTR(n, m)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef NAN
|
||||||
|
#define NAN (0.0 / 0.0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The macro QEMU_GNUC_PREREQ tests for minimum version of the GNU C compiler.
|
| The macro QEMU_GNUC_PREREQ tests for minimum version of the GNU C compiler.
|
||||||
| The code is a copy of SOFTFLOAT_GNUC_PREREQ, see softfloat-macros.h.
|
| The code is a copy of SOFTFLOAT_GNUC_PREREQ, see softfloat-macros.h.
|
||||||
|
@ -18,6 +70,9 @@
|
||||||
|
|
||||||
#define QEMU_NORETURN __attribute__ ((__noreturn__))
|
#define QEMU_NORETURN __attribute__ ((__noreturn__))
|
||||||
|
|
||||||
|
#define QEMU_UNUSED_VAR __attribute__((unused))
|
||||||
|
#define QEMU_UNUSED_FUNC __attribute__((unused))
|
||||||
|
|
||||||
#if QEMU_GNUC_PREREQ(3, 4)
|
#if QEMU_GNUC_PREREQ(3, 4)
|
||||||
#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||||
#else
|
#else
|
||||||
|
@ -31,11 +86,13 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# define QEMU_PACKED __attribute__((gcc_struct, packed))
|
# define QEMU_PACK( __Declaration__ ) __Declaration__ __attribute__((gcc_struct, packed))
|
||||||
#else
|
#else
|
||||||
# define QEMU_PACKED __attribute__((packed))
|
# define QEMU_PACK( __Declaration__ ) __Declaration__ __attribute__((packed))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define QEMU_ALIGN(A, B) B __attribute__((aligned(A)))
|
||||||
|
|
||||||
#define cat(x,y) x ## y
|
#define cat(x,y) x ## y
|
||||||
#define cat2(x,y) cat(x,y)
|
#define cat2(x,y) cat(x,y)
|
||||||
#define QEMU_BUILD_BUG_ON(x) \
|
#define QEMU_BUILD_BUG_ON(x) \
|
||||||
|
@ -58,4 +115,6 @@
|
||||||
#define GCC_FMT_ATTR(n, m)
|
#define GCC_FMT_ATTR(n, m)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
#endif /* COMPILER_H */
|
#endif /* COMPILER_H */
|
||||||
|
|
|
@ -150,7 +150,7 @@ static inline int clz64(uint64_t val)
|
||||||
val >>= 32;
|
val >>= 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cnt + clz32(val);
|
return cnt + clz32((uint32_t)val);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ static inline int ctz64(uint64_t val)
|
||||||
val >>= 32;
|
val >>= 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cnt + ctz32(val);
|
return cnt + ctz32((uint32_t)val);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ static inline int ctpop64(uint64_t val)
|
||||||
val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
|
val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
|
||||||
val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
|
val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
|
||||||
|
|
||||||
return val;
|
return (int)val;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,4 +379,13 @@ static inline int ctpop64(uint64_t val)
|
||||||
# error Unknown sizeof long
|
# error Unknown sizeof long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <float.h>
|
||||||
|
#if defined(_WIN64)
|
||||||
|
#define isnan _isnanf
|
||||||
|
#else
|
||||||
|
#define isnan _isnan
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
#define INT128_H
|
#define INT128_H
|
||||||
|
|
||||||
//#include <assert.h>
|
//#include <assert.h>
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
typedef struct Int128 Int128;
|
typedef struct Int128 Int128;
|
||||||
|
|
||||||
|
@ -14,7 +13,8 @@ struct Int128 {
|
||||||
|
|
||||||
static inline Int128 int128_make64(uint64_t a)
|
static inline Int128 int128_make64(uint64_t a)
|
||||||
{
|
{
|
||||||
return (Int128) { a, 0 };
|
Int128 i128 = { a, 0 };
|
||||||
|
return i128;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint64_t int128_get64(Int128 a)
|
static inline uint64_t int128_get64(Int128 a)
|
||||||
|
@ -35,17 +35,20 @@ static inline Int128 int128_one(void)
|
||||||
|
|
||||||
static inline Int128 int128_2_64(void)
|
static inline Int128 int128_2_64(void)
|
||||||
{
|
{
|
||||||
return (Int128) { 0, 1 };
|
Int128 i128 = { 0, 1 };
|
||||||
|
return i128;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Int128 int128_exts64(int64_t a)
|
static inline Int128 int128_exts64(int64_t a)
|
||||||
{
|
{
|
||||||
return (Int128) { .lo = a, .hi = (a < 0) ? -1 : 0 };
|
Int128 i128 = { a, (a < 0) ? -1 : 0 };
|
||||||
|
return i128;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Int128 int128_and(Int128 a, Int128 b)
|
static inline Int128 int128_and(Int128 a, Int128 b)
|
||||||
{
|
{
|
||||||
return (Int128) { a.lo & b.lo, a.hi & b.hi };
|
Int128 i128 = { a.lo & b.lo, a.hi & b.hi };
|
||||||
|
return i128;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Int128 int128_rshift(Int128 a, int n)
|
static inline Int128 int128_rshift(Int128 a, int n)
|
||||||
|
@ -56,9 +59,11 @@ static inline Int128 int128_rshift(Int128 a, int n)
|
||||||
}
|
}
|
||||||
h = a.hi >> (n & 63);
|
h = a.hi >> (n & 63);
|
||||||
if (n >= 64) {
|
if (n >= 64) {
|
||||||
return (Int128) { h, h >> 63 };
|
Int128 i128 = { h, h >> 63 };
|
||||||
|
return i128;
|
||||||
} else {
|
} else {
|
||||||
return (Int128) { (a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h };
|
Int128 i128 = { (a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h };
|
||||||
|
return i128;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,18 +77,21 @@ static inline Int128 int128_add(Int128 a, Int128 b)
|
||||||
*
|
*
|
||||||
* So the carry is lo < a.lo.
|
* So the carry is lo < a.lo.
|
||||||
*/
|
*/
|
||||||
return (Int128) { lo, (uint64_t)a.hi + b.hi + (lo < a.lo) };
|
Int128 i128 = { lo, (uint64_t)a.hi + b.hi + (lo < a.lo) };
|
||||||
|
return i128;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Int128 int128_neg(Int128 a)
|
static inline Int128 int128_neg(Int128 a)
|
||||||
{
|
{
|
||||||
uint64_t lo = -a.lo;
|
uint64_t lo = 0-a.lo;
|
||||||
return (Int128) { lo, ~(uint64_t)a.hi + !lo };
|
Int128 i128 = { lo, ~(uint64_t)a.hi + !lo };
|
||||||
|
return i128;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Int128 int128_sub(Int128 a, Int128 b)
|
static inline Int128 int128_sub(Int128 a, Int128 b)
|
||||||
{
|
{
|
||||||
return (Int128){ a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo) };
|
Int128 i128 = { a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo) };
|
||||||
|
return i128;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool int128_nonneg(Int128 a)
|
static inline bool int128_nonneg(Int128 a)
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
#define QEMU_LOG_H
|
#define QEMU_LOG_H
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include "platform.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include "qemu/compiler.h"
|
#include "qemu/compiler.h"
|
||||||
#include "qom/cpu.h"
|
#include "qom/cpu.h"
|
||||||
|
|
||||||
|
|
|
@ -26,15 +26,17 @@ void DSO_STAMP_FUN(void);
|
||||||
* check fails during module loading */
|
* check fails during module loading */
|
||||||
void qemu_module_dummy(void);
|
void qemu_module_dummy(void);
|
||||||
|
|
||||||
|
//static void __attribute__((constructor)) do_qemu_init_ ## function(void)
|
||||||
|
//static void __attribute__((constructor)) do_qemu_init_ ## function(void)
|
||||||
#define module_init(function, type) \
|
#define module_init(function, type) \
|
||||||
static void __attribute__((constructor)) do_qemu_init_ ## function(void) \
|
INITIALIZER(do_qemu_init_ ## function) \
|
||||||
{ \
|
{ \
|
||||||
register_dso_module_init(function, type); \
|
register_dso_module_init(function, type); \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* This should not be used directly. Use block_init etc. instead. */
|
/* This should not be used directly. Use block_init etc. instead. */
|
||||||
#define module_init(function, type) \
|
#define module_init(function, type) \
|
||||||
static void __attribute__((constructor)) do_qemu_init_ ## function(void) \
|
INITIALIZER(do_qemu_init_ ## function) \
|
||||||
{ \
|
{ \
|
||||||
register_module_init(function, type); \
|
register_module_init(function, type); \
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
#include "config-host.h"
|
#include "config-host.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include "platform.h"
|
||||||
#include <stdint.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
#include <sys/signal.h>
|
#include <sys/signal.h>
|
||||||
|
@ -18,7 +17,7 @@
|
||||||
#define WEXITSTATUS(x) (x)
|
#define WEXITSTATUS(x) (x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include "platform.h"
|
||||||
|
|
||||||
#if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10
|
#if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10
|
||||||
/* [u]int_fast*_t not in <sys/int_types.h> */
|
/* [u]int_fast*_t not in <sys/int_types.h> */
|
||||||
|
@ -44,15 +43,19 @@ typedef signed int int_fast16_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef container_of
|
#ifndef container_of
|
||||||
|
#ifndef _MSC_VER
|
||||||
#define container_of(ptr, type, member) ({ \
|
#define container_of(ptr, type, member) ({ \
|
||||||
const typeof(((type *) 0)->member) *__mptr = (ptr); \
|
const typeof(((type *) 0)->member) *__mptr = (ptr); \
|
||||||
(type *) ((char *) __mptr - offsetof(type, member));})
|
(type *) ((char *) __mptr - offsetof(type, member));})
|
||||||
|
#else
|
||||||
|
#define container_of(ptr, type, member) ((type *)((char *)(ptr) -offsetof(type,member)))
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Convert from a base type to a parent type, with compile time checking. */
|
/* Convert from a base type to a parent type, with compile time checking. */
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define DO_UPCAST(type, field, dev) ( __extension__ ( { \
|
#define DO_UPCAST(type, field, dev) ( __extension__ ( { \
|
||||||
char __attribute__((unused)) offset_must_be_zero[ \
|
char QEMU_UNUSED_VAR offset_must_be_zero[ \
|
||||||
-offsetof(type, field)]; \
|
-offsetof(type, field)]; \
|
||||||
container_of(dev, type, field);}))
|
container_of(dev, type, field);}))
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef QEMU_RANGE_H
|
#ifndef QEMU_RANGE_H
|
||||||
#define QEMU_RANGE_H
|
#define QEMU_RANGE_H
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include "platform.h"
|
||||||
#include <qemu/typedefs.h>
|
#include <qemu/typedefs.h>
|
||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#ifndef __QEMU_THREAD_H
|
#ifndef __QEMU_THREAD_H
|
||||||
#define __QEMU_THREAD_H 1
|
#define __QEMU_THREAD_H 1
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include "platform.h"
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
typedef struct QemuMutex QemuMutex;
|
typedef struct QemuMutex QemuMutex;
|
||||||
typedef struct QemuThread QemuThread;
|
typedef struct QemuThread QemuThread;
|
||||||
|
|
|
@ -493,7 +493,7 @@ static inline int64_t get_clock(void)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER ti;
|
LARGE_INTEGER ti;
|
||||||
QueryPerformanceCounter(&ti);
|
QueryPerformanceCounter(&ti);
|
||||||
return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
|
return muldiv64(ti.QuadPart, (uint32_t)get_ticks_per_sec(), (uint32_t)clock_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -545,9 +545,13 @@ static inline int64_t cpu_get_real_ticks(void)
|
||||||
|
|
||||||
static inline int64_t cpu_get_real_ticks(void)
|
static inline int64_t cpu_get_real_ticks(void)
|
||||||
{
|
{
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
return __rdtsc();
|
||||||
|
#else
|
||||||
int64_t val;
|
int64_t val;
|
||||||
asm volatile ("rdtsc" : "=A" (val));
|
asm volatile ("rdtsc" : "=A" (val));
|
||||||
return val;
|
return val;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__x86_64__)
|
#elif defined(__x86_64__)
|
||||||
|
|
|
@ -532,7 +532,7 @@ static inline void cpu_unaligned_access(CPUState *cpu, vaddr addr,
|
||||||
{
|
{
|
||||||
CPUClass *cc = CPU_GET_CLASS(cpu->uc, cpu);
|
CPUClass *cc = CPU_GET_CLASS(cpu->uc, cpu);
|
||||||
|
|
||||||
return cc->do_unaligned_access(cpu, addr, is_write, is_user, retaddr);
|
cc->do_unaligned_access(cpu, addr, is_write, is_user, retaddr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
#define QEMU_OBJECT_H
|
#define QEMU_OBJECT_H
|
||||||
|
|
||||||
#include "glib_compat.h"
|
#include "glib_compat.h"
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#ifndef QEMU_OS_WIN32_H
|
#ifndef QEMU_OS_WIN32_H
|
||||||
#define QEMU_OS_WIN32_H
|
#define QEMU_OS_WIN32_H
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ typedef struct MemoryRegionPortioList {
|
||||||
|
|
||||||
static uint64_t unassigned_io_read(struct uc_struct* uc, void *opaque, hwaddr addr, unsigned size)
|
static uint64_t unassigned_io_read(struct uc_struct* uc, void *opaque, hwaddr addr, unsigned size)
|
||||||
{
|
{
|
||||||
return -1ULL;
|
return 0-1ULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unassigned_io_write(struct uc_struct* uc, void *opaque, hwaddr addr, uint64_t val,
|
static void unassigned_io_write(struct uc_struct* uc, void *opaque, hwaddr addr, uint64_t val,
|
||||||
|
@ -58,9 +58,9 @@ static void unassigned_io_write(struct uc_struct* uc, void *opaque, hwaddr addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MemoryRegionOps unassigned_io_ops = {
|
const MemoryRegionOps unassigned_io_ops = {
|
||||||
.read = unassigned_io_read,
|
unassigned_io_read,
|
||||||
.write = unassigned_io_write,
|
unassigned_io_write,
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
DEVICE_NATIVE_ENDIAN,
|
||||||
};
|
};
|
||||||
|
|
||||||
void cpu_outb(struct uc_struct *uc, pio_addr_t addr, uint8_t val)
|
void cpu_outb(struct uc_struct *uc, pio_addr_t addr, uint8_t val)
|
||||||
|
@ -68,6 +68,7 @@ void cpu_outb(struct uc_struct *uc, pio_addr_t addr, uint8_t val)
|
||||||
//LOG_IOPORT("outb: %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
|
//LOG_IOPORT("outb: %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
|
||||||
// Unicorn: call registered OUT callbacks
|
// Unicorn: call registered OUT callbacks
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||||
if (hook->insn == UC_X86_INS_OUT)
|
if (hook->insn == UC_X86_INS_OUT)
|
||||||
((uc_cb_insn_out_t)hook->callback)(uc, addr, 1, val, hook->user_data);
|
((uc_cb_insn_out_t)hook->callback)(uc, addr, 1, val, hook->user_data);
|
||||||
|
@ -79,6 +80,7 @@ void cpu_outw(struct uc_struct *uc, pio_addr_t addr, uint16_t val)
|
||||||
//LOG_IOPORT("outw: %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
|
//LOG_IOPORT("outw: %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
|
||||||
// Unicorn: call registered OUT callbacks
|
// Unicorn: call registered OUT callbacks
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||||
if (hook->insn == UC_X86_INS_OUT)
|
if (hook->insn == UC_X86_INS_OUT)
|
||||||
((uc_cb_insn_out_t)hook->callback)(uc, addr, 2, val, hook->user_data);
|
((uc_cb_insn_out_t)hook->callback)(uc, addr, 2, val, hook->user_data);
|
||||||
|
@ -90,6 +92,7 @@ void cpu_outl(struct uc_struct *uc, pio_addr_t addr, uint32_t val)
|
||||||
//LOG_IOPORT("outl: %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
|
//LOG_IOPORT("outl: %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
|
||||||
// Unicorn: call registered OUT callbacks
|
// Unicorn: call registered OUT callbacks
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||||
if (hook->insn == UC_X86_INS_OUT)
|
if (hook->insn == UC_X86_INS_OUT)
|
||||||
((uc_cb_insn_out_t)hook->callback)(uc, addr, 4, val, hook->user_data);
|
((uc_cb_insn_out_t)hook->callback)(uc, addr, 4, val, hook->user_data);
|
||||||
|
@ -101,6 +104,7 @@ uint8_t cpu_inb(struct uc_struct *uc, pio_addr_t addr)
|
||||||
//LOG_IOPORT("inb : %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
|
//LOG_IOPORT("inb : %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
|
||||||
// Unicorn: call registered IN callbacks
|
// Unicorn: call registered IN callbacks
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||||
if (hook->insn == UC_X86_INS_IN)
|
if (hook->insn == UC_X86_INS_IN)
|
||||||
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 1, hook->user_data);
|
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 1, hook->user_data);
|
||||||
|
@ -114,6 +118,7 @@ uint16_t cpu_inw(struct uc_struct *uc, pio_addr_t addr)
|
||||||
//LOG_IOPORT("inw : %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
|
//LOG_IOPORT("inw : %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
|
||||||
// Unicorn: call registered IN callbacks
|
// Unicorn: call registered IN callbacks
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||||
if (hook->insn == UC_X86_INS_IN)
|
if (hook->insn == UC_X86_INS_IN)
|
||||||
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 2, hook->user_data);
|
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 2, hook->user_data);
|
||||||
|
@ -127,6 +132,7 @@ uint32_t cpu_inl(struct uc_struct *uc, pio_addr_t addr)
|
||||||
//LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
|
//LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
|
||||||
// Unicorn: call registered IN callbacks
|
// Unicorn: call registered IN callbacks
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
HOOK_FOREACH(uc, hook, UC_HOOK_INSN) {
|
||||||
if (hook->insn == UC_X86_INS_IN)
|
if (hook->insn == UC_X86_INS_IN)
|
||||||
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 4, hook->user_data);
|
return ((uc_cb_insn_in_t)hook->callback)(uc, addr, 4, hook->user_data);
|
||||||
|
|
117
qemu/memory.c
117
qemu/memory.c
|
@ -147,7 +147,10 @@ struct AddrRange {
|
||||||
|
|
||||||
static AddrRange addrrange_make(Int128 start, Int128 size)
|
static AddrRange addrrange_make(Int128 start, Int128 size)
|
||||||
{
|
{
|
||||||
return (AddrRange) { start, size };
|
AddrRange ar;
|
||||||
|
ar.start = start;
|
||||||
|
ar.size = size;
|
||||||
|
return ar;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool addrrange_equal(AddrRange r1, AddrRange r2)
|
static bool addrrange_equal(AddrRange r1, AddrRange r2)
|
||||||
|
@ -194,7 +197,7 @@ static bool memory_listener_match(MemoryListener *listener,
|
||||||
|| listener->address_space_filter == section->address_space;
|
|| listener->address_space_filter == section->address_space;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MEMORY_LISTENER_CALL_GLOBAL(_callback, _direction, _args...) \
|
#define MEMORY_LISTENER_CALL_GLOBAL(_callback, _direction, ...) \
|
||||||
do { \
|
do { \
|
||||||
MemoryListener *_listener; \
|
MemoryListener *_listener; \
|
||||||
\
|
\
|
||||||
|
@ -202,7 +205,7 @@ static bool memory_listener_match(MemoryListener *listener,
|
||||||
case Forward: \
|
case Forward: \
|
||||||
QTAILQ_FOREACH(_listener, &uc->memory_listeners, link) { \
|
QTAILQ_FOREACH(_listener, &uc->memory_listeners, link) { \
|
||||||
if (_listener->_callback) { \
|
if (_listener->_callback) { \
|
||||||
_listener->_callback(_listener, ##_args); \
|
_listener->_callback(_listener, ##__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
|
@ -210,7 +213,7 @@ static bool memory_listener_match(MemoryListener *listener,
|
||||||
QTAILQ_FOREACH_REVERSE(_listener, &uc->memory_listeners, \
|
QTAILQ_FOREACH_REVERSE(_listener, &uc->memory_listeners, \
|
||||||
memory_listeners, link) { \
|
memory_listeners, link) { \
|
||||||
if (_listener->_callback) { \
|
if (_listener->_callback) { \
|
||||||
_listener->_callback(_listener, ##_args); \
|
_listener->_callback(_listener, ##__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
|
@ -219,7 +222,7 @@ static bool memory_listener_match(MemoryListener *listener,
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define MEMORY_LISTENER_CALL(_callback, _direction, _section, _args...) \
|
#define MEMORY_LISTENER_CALL(_callback, _direction, _section, ...) \
|
||||||
do { \
|
do { \
|
||||||
MemoryListener *_listener; \
|
MemoryListener *_listener; \
|
||||||
\
|
\
|
||||||
|
@ -228,7 +231,7 @@ static bool memory_listener_match(MemoryListener *listener,
|
||||||
QTAILQ_FOREACH(_listener, &uc->memory_listeners, link) { \
|
QTAILQ_FOREACH(_listener, &uc->memory_listeners, link) { \
|
||||||
if (_listener->_callback \
|
if (_listener->_callback \
|
||||||
&& memory_listener_match(_listener, _section)) { \
|
&& memory_listener_match(_listener, _section)) { \
|
||||||
_listener->_callback(_listener, _section, ##_args); \
|
_listener->_callback(_listener, _section, ##__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
|
@ -237,7 +240,7 @@ static bool memory_listener_match(MemoryListener *listener,
|
||||||
memory_listeners, link) { \
|
memory_listeners, link) { \
|
||||||
if (_listener->_callback \
|
if (_listener->_callback \
|
||||||
&& memory_listener_match(_listener, _section)) { \
|
&& memory_listener_match(_listener, _section)) { \
|
||||||
_listener->_callback(_listener, _section, ##_args); \
|
_listener->_callback(_listener, _section, ##__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
|
@ -248,6 +251,11 @@ static bool memory_listener_match(MemoryListener *listener,
|
||||||
|
|
||||||
/* No need to ref/unref .mr, the FlatRange keeps it alive. */
|
/* No need to ref/unref .mr, the FlatRange keeps it alive. */
|
||||||
#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback) \
|
#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback) \
|
||||||
|
do { MemoryRegionSection _mrs = MemoryRegionSection_make((fr)->mr, as, (fr)->offset_in_region, \
|
||||||
|
(fr)->addr.size, int128_get64((fr)->addr.start), (fr)->readonly); \
|
||||||
|
MEMORY_LISTENER_CALL(callback, dir, &_mrs); } while(0);
|
||||||
|
|
||||||
|
/*
|
||||||
MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) { \
|
MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) { \
|
||||||
.mr = (fr)->mr, \
|
.mr = (fr)->mr, \
|
||||||
.address_space = (as), \
|
.address_space = (as), \
|
||||||
|
@ -256,6 +264,7 @@ static bool memory_listener_match(MemoryListener *listener,
|
||||||
.offset_within_address_space = int128_get64((fr)->addr.start), \
|
.offset_within_address_space = int128_get64((fr)->addr.start), \
|
||||||
.readonly = (fr)->readonly, \
|
.readonly = (fr)->readonly, \
|
||||||
}))
|
}))
|
||||||
|
*/
|
||||||
|
|
||||||
struct CoalescedMemoryRange {
|
struct CoalescedMemoryRange {
|
||||||
AddrRange addr;
|
AddrRange addr;
|
||||||
|
@ -269,6 +278,16 @@ struct MemoryRegionIoeventfd {
|
||||||
EventNotifier *e;
|
EventNotifier *e;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static MemoryRegionIoeventfd MemoryRegionIoeventfd_make(AddrRange addr, bool match_data, uint64_t data, EventNotifier *e)
|
||||||
|
{
|
||||||
|
MemoryRegionIoeventfd mrfd;
|
||||||
|
mrfd.addr = addr;
|
||||||
|
mrfd.match_data = match_data;
|
||||||
|
mrfd.data = data;
|
||||||
|
mrfd.e = e;
|
||||||
|
return mrfd;
|
||||||
|
}
|
||||||
|
|
||||||
static bool memory_region_ioeventfd_before(MemoryRegionIoeventfd a,
|
static bool memory_region_ioeventfd_before(MemoryRegionIoeventfd a,
|
||||||
MemoryRegionIoeventfd b)
|
MemoryRegionIoeventfd b)
|
||||||
{
|
{
|
||||||
|
@ -546,7 +565,7 @@ static void access_with_adjusted_size(hwaddr addr,
|
||||||
|
|
||||||
/* FIXME: support unaligned access? */
|
/* FIXME: support unaligned access? */
|
||||||
access_size = MAX(MIN(size, access_size_max), access_size_min);
|
access_size = MAX(MIN(size, access_size_max), access_size_min);
|
||||||
access_mask = -1ULL >> (64 - access_size * 8);
|
access_mask = (0-1ULL) >> (64 - access_size * 8);
|
||||||
if (memory_region_big_endian(mr)) {
|
if (memory_region_big_endian(mr)) {
|
||||||
for (i = 0; i < size; i += access_size) {
|
for (i = 0; i < size; i += access_size) {
|
||||||
access(mr, addr + i, value, access_size,
|
access(mr, addr + i, value, access_size,
|
||||||
|
@ -700,11 +719,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
|
||||||
|| memory_region_ioeventfd_before(fds_old[iold],
|
|| memory_region_ioeventfd_before(fds_old[iold],
|
||||||
fds_new[inew]))) {
|
fds_new[inew]))) {
|
||||||
fd = &fds_old[iold];
|
fd = &fds_old[iold];
|
||||||
section = (MemoryRegionSection) {
|
section = MemoryRegionSection_make(NULL, as, 0, fd->addr.size, int128_get64(fd->addr.start), false);
|
||||||
.address_space = as,
|
|
||||||
.offset_within_address_space = int128_get64(fd->addr.start),
|
|
||||||
.size = fd->addr.size,
|
|
||||||
};
|
|
||||||
MEMORY_LISTENER_CALL(eventfd_del, Forward, §ion,
|
MEMORY_LISTENER_CALL(eventfd_del, Forward, §ion,
|
||||||
fd->match_data, fd->data, fd->e);
|
fd->match_data, fd->data, fd->e);
|
||||||
++iold;
|
++iold;
|
||||||
|
@ -713,11 +728,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
|
||||||
|| memory_region_ioeventfd_before(fds_new[inew],
|
|| memory_region_ioeventfd_before(fds_new[inew],
|
||||||
fds_old[iold]))) {
|
fds_old[iold]))) {
|
||||||
fd = &fds_new[inew];
|
fd = &fds_new[inew];
|
||||||
section = (MemoryRegionSection) {
|
section = MemoryRegionSection_make(NULL, as, 0, fd->addr.size, int128_get64(fd->addr.start), false);
|
||||||
.address_space = as,
|
|
||||||
.offset_within_address_space = int128_get64(fd->addr.start),
|
|
||||||
.size = fd->addr.size,
|
|
||||||
};
|
|
||||||
MEMORY_LISTENER_CALL(eventfd_add, Reverse, §ion,
|
MEMORY_LISTENER_CALL(eventfd_add, Reverse, §ion,
|
||||||
fd->match_data, fd->data, fd->e);
|
fd->match_data, fd->data, fd->e);
|
||||||
++inew;
|
++inew;
|
||||||
|
@ -1101,8 +1112,12 @@ static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MemoryRegionOps unassigned_mem_ops = {
|
const MemoryRegionOps unassigned_mem_ops = {
|
||||||
.valid.accepts = unassigned_mem_accepts,
|
NULL,
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
NULL,
|
||||||
|
|
||||||
|
DEVICE_NATIVE_ENDIAN,
|
||||||
|
|
||||||
|
{0,0,false,unassigned_mem_accepts},
|
||||||
};
|
};
|
||||||
|
|
||||||
bool memory_region_access_valid(MemoryRegion *mr,
|
bool memory_region_access_valid(MemoryRegion *mr,
|
||||||
|
@ -1356,7 +1371,7 @@ bool memory_region_is_rom(MemoryRegion *mr)
|
||||||
|
|
||||||
bool memory_region_is_iommu(MemoryRegion *mr)
|
bool memory_region_is_iommu(MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
return mr->iommu_ops;
|
return mr->iommu_ops != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n)
|
void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n)
|
||||||
|
@ -1416,7 +1431,7 @@ int memory_region_get_fd(MemoryRegion *mr)
|
||||||
void *memory_region_get_ram_ptr(MemoryRegion *mr)
|
void *memory_region_get_ram_ptr(MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
if (mr->alias) {
|
if (mr->alias) {
|
||||||
return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
|
return (char*)memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(mr->terminates);
|
assert(mr->terminates);
|
||||||
|
@ -1436,11 +1451,7 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
|
||||||
view = address_space_get_flatview(as);
|
view = address_space_get_flatview(as);
|
||||||
FOR_EACH_FLAT_RANGE(fr, view) {
|
FOR_EACH_FLAT_RANGE(fr, view) {
|
||||||
if (fr->mr == mr) {
|
if (fr->mr == mr) {
|
||||||
section = (MemoryRegionSection) {
|
section = MemoryRegionSection_make(NULL, as, 0, fr->addr.size, int128_get64(fr->addr.start), false);
|
||||||
.address_space = as,
|
|
||||||
.offset_within_address_space = int128_get64(fr->addr.start),
|
|
||||||
.size = fr->addr.size,
|
|
||||||
};
|
|
||||||
|
|
||||||
MEMORY_LISTENER_CALL(coalesced_mmio_del, Reverse, §ion,
|
MEMORY_LISTENER_CALL(coalesced_mmio_del, Reverse, §ion,
|
||||||
int128_get64(fr->addr.start),
|
int128_get64(fr->addr.start),
|
||||||
|
@ -1498,13 +1509,9 @@ void memory_region_add_eventfd(MemoryRegion *mr,
|
||||||
uint64_t data,
|
uint64_t data,
|
||||||
EventNotifier *e)
|
EventNotifier *e)
|
||||||
{
|
{
|
||||||
MemoryRegionIoeventfd mrfd = {
|
MemoryRegionIoeventfd mrfd = MemoryRegionIoeventfd_make(
|
||||||
.addr.start = int128_make64(addr),
|
addrrange_make(int128_make64(addr), int128_make64(size)),
|
||||||
.addr.size = int128_make64(size),
|
match_data, data, e);
|
||||||
.match_data = match_data,
|
|
||||||
.data = data,
|
|
||||||
.e = e,
|
|
||||||
};
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
adjust_endianness(mr, &mrfd.data, size);
|
adjust_endianness(mr, &mrfd.data, size);
|
||||||
|
@ -1531,13 +1538,9 @@ void memory_region_del_eventfd(MemoryRegion *mr,
|
||||||
uint64_t data,
|
uint64_t data,
|
||||||
EventNotifier *e)
|
EventNotifier *e)
|
||||||
{
|
{
|
||||||
MemoryRegionIoeventfd mrfd = {
|
MemoryRegionIoeventfd mrfd = MemoryRegionIoeventfd_make(
|
||||||
.addr.start = int128_make64(addr),
|
addrrange_make(int128_make64(addr), int128_make64(size)),
|
||||||
.addr.size = int128_make64(size),
|
match_data, data, e);
|
||||||
.match_data = match_data,
|
|
||||||
.data = data,
|
|
||||||
.e = e,
|
|
||||||
};
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
adjust_endianness(mr, &mrfd.data, size);
|
adjust_endianness(mr, &mrfd.data, size);
|
||||||
|
@ -1736,7 +1739,7 @@ bool memory_region_is_mapped(MemoryRegion *mr)
|
||||||
MemoryRegionSection memory_region_find(MemoryRegion *mr,
|
MemoryRegionSection memory_region_find(MemoryRegion *mr,
|
||||||
hwaddr addr, uint64_t size)
|
hwaddr addr, uint64_t size)
|
||||||
{
|
{
|
||||||
MemoryRegionSection ret = { .mr = NULL };
|
MemoryRegionSection ret = { NULL };
|
||||||
MemoryRegion *root;
|
MemoryRegion *root;
|
||||||
AddressSpace *as;
|
AddressSpace *as;
|
||||||
AddrRange range;
|
AddrRange range;
|
||||||
|
@ -1800,14 +1803,13 @@ static void listener_add_address_space(MemoryListener *listener,
|
||||||
|
|
||||||
view = address_space_get_flatview(as);
|
view = address_space_get_flatview(as);
|
||||||
FOR_EACH_FLAT_RANGE(fr, view) {
|
FOR_EACH_FLAT_RANGE(fr, view) {
|
||||||
MemoryRegionSection section = {
|
MemoryRegionSection section = MemoryRegionSection_make(
|
||||||
.mr = fr->mr,
|
fr->mr,
|
||||||
.address_space = as,
|
as,
|
||||||
.offset_within_region = fr->offset_in_region,
|
fr->offset_in_region,
|
||||||
.size = fr->addr.size,
|
fr->addr.size,
|
||||||
.offset_within_address_space = int128_get64(fr->addr.start),
|
int128_get64(fr->addr.start),
|
||||||
.readonly = fr->readonly,
|
fr->readonly);
|
||||||
};
|
|
||||||
if (listener->region_add) {
|
if (listener->region_add) {
|
||||||
listener->region_add(listener, §ion);
|
listener->region_add(listener, §ion);
|
||||||
}
|
}
|
||||||
|
@ -1908,11 +1910,16 @@ struct MemoryRegionList {
|
||||||
typedef QTAILQ_HEAD(queue, MemoryRegionList) MemoryRegionListHead;
|
typedef QTAILQ_HEAD(queue, MemoryRegionList) MemoryRegionListHead;
|
||||||
|
|
||||||
static const TypeInfo memory_region_info = {
|
static const TypeInfo memory_region_info = {
|
||||||
.parent = TYPE_OBJECT,
|
TYPE_MEMORY_REGION,
|
||||||
.name = TYPE_MEMORY_REGION,
|
TYPE_OBJECT,
|
||||||
.instance_size = sizeof(MemoryRegion),
|
|
||||||
.instance_init = memory_region_initfn,
|
0,
|
||||||
.instance_finalize = memory_region_finalize,
|
sizeof(MemoryRegion),
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
memory_region_initfn,
|
||||||
|
NULL,
|
||||||
|
memory_region_finalize,
|
||||||
};
|
};
|
||||||
|
|
||||||
void memory_register_types(struct uc_struct *uc)
|
void memory_register_types(struct uc_struct *uc)
|
||||||
|
|
|
@ -114,7 +114,7 @@ void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
|
||||||
"uint8_t");
|
"uint8_t");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*obj = value;
|
*obj = (uint8_t)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp
|
||||||
"uint16_t");
|
"uint16_t");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*obj = value;
|
*obj = (uint16_t)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp
|
||||||
"uint32_t");
|
"uint32_t");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*obj = value;
|
*obj = (uint32_t)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp)
|
||||||
"int8_t");
|
"int8_t");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*obj = value;
|
*obj = (int8_t)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp)
|
||||||
"int16_t");
|
"int16_t");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*obj = value;
|
*obj = (int16_t)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp)
|
||||||
"int32_t");
|
"int32_t");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*obj = value;
|
*obj = (int32_t)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,5 +309,5 @@ void input_type_enum(Visitor *v, int *obj, const char *strings[],
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(enum_str);
|
g_free(enum_str);
|
||||||
*obj = value;
|
*obj = (int)value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp)
|
||||||
if (top_ht) {
|
if (top_ht) {
|
||||||
if (g_hash_table_size(top_ht)) {
|
if (g_hash_table_size(top_ht)) {
|
||||||
const char *key;
|
const char *key;
|
||||||
g_hash_table_find(top_ht, always_true, &key);
|
g_hash_table_find(top_ht, always_true, (gpointer)&key);
|
||||||
error_set(errp, QERR_QMP_EXTRA_MEMBER, key);
|
error_set(errp, QERR_QMP_EXTRA_MEMBER, key);
|
||||||
}
|
}
|
||||||
g_hash_table_unref(top_ht);
|
g_hash_table_unref(top_ht);
|
||||||
|
@ -280,7 +280,7 @@ static void qmp_input_type_number(Visitor *v, double *obj, const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qobject_type(qobj) == QTYPE_QINT) {
|
if (qobject_type(qobj) == QTYPE_QINT) {
|
||||||
*obj = qint_get_int(qobject_to_qint(qobj));
|
*obj = (double)qint_get_int(qobject_to_qint(qobj));
|
||||||
} else {
|
} else {
|
||||||
*obj = qfloat_get_double(qobject_to_qfloat(qobj));
|
*obj = qfloat_get_double(qobject_to_qfloat(qobj));
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
#include "qemu/range.h"
|
#include "qemu/range.h"
|
||||||
|
#include <stdlib.h> // strtoll
|
||||||
|
|
||||||
|
|
||||||
struct StringInputVisitor
|
struct StringInputVisitor
|
||||||
|
@ -148,7 +149,7 @@ next_list(Visitor *v, GenericList **list, Error **errp)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (siv->cur < r->begin || siv->cur >= r->end) {
|
if ((uint64_t)siv->cur < r->begin || (uint64_t)siv->cur >= r->end) {
|
||||||
siv->cur_range = g_list_next(siv->cur_range);
|
siv->cur_range = g_list_next(siv->cur_range);
|
||||||
if (!siv->cur_range) {
|
if (!siv->cur_range) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
static void qbool_destroy_obj(QObject *obj);
|
static void qbool_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
static const QType qbool_type = {
|
static const QType qbool_type = {
|
||||||
.code = QTYPE_QBOOL,
|
QTYPE_QBOOL,
|
||||||
.destroy = qbool_destroy_obj,
|
qbool_destroy_obj,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
static void qdict_destroy_obj(QObject *obj);
|
static void qdict_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
static const QType qdict_type = {
|
static const QType qdict_type = {
|
||||||
.code = QTYPE_QDICT,
|
QTYPE_QDICT,
|
||||||
.destroy = qdict_destroy_obj,
|
qdict_destroy_obj,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -213,7 +213,7 @@ double qdict_get_double(const QDict *qdict, const char *key)
|
||||||
case QTYPE_QFLOAT:
|
case QTYPE_QFLOAT:
|
||||||
return qfloat_get_double(qobject_to_qfloat(obj));
|
return qfloat_get_double(qobject_to_qfloat(obj));
|
||||||
case QTYPE_QINT:
|
case QTYPE_QINT:
|
||||||
return qint_get_int(qobject_to_qint(obj));
|
return (double)qint_get_int(qobject_to_qint(obj));
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@ -662,7 +662,7 @@ void qdict_array_split(QDict *src, QList **dst)
|
||||||
qdict_del(src, indexstr);
|
qdict_del(src, indexstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
qlist_append_obj(*dst, subqobj ?: QOBJECT(subqdict));
|
qlist_append_obj(*dst, (subqobj!=NULL) ? subqobj : QOBJECT(subqdict));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
static void qfloat_destroy_obj(QObject *obj);
|
static void qfloat_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
static const QType qfloat_type = {
|
static const QType qfloat_type = {
|
||||||
.code = QTYPE_QFLOAT,
|
QTYPE_QFLOAT,
|
||||||
.destroy = qfloat_destroy_obj,
|
qfloat_destroy_obj,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
static void qint_destroy_obj(QObject *obj);
|
static void qint_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
static const QType qint_type = {
|
static const QType qint_type = {
|
||||||
.code = QTYPE_QINT,
|
QTYPE_QINT,
|
||||||
.destroy = qint_destroy_obj,
|
qint_destroy_obj,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
static void qlist_destroy_obj(QObject *obj);
|
static void qlist_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
static const QType qlist_type = {
|
static const QType qlist_type = {
|
||||||
.code = QTYPE_QLIST,
|
QTYPE_QLIST,
|
||||||
.destroy = qlist_destroy_obj,
|
qlist_destroy_obj,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
static void qstring_destroy_obj(QObject *obj);
|
static void qstring_destroy_obj(QObject *obj);
|
||||||
|
|
||||||
static const QType qstring_type = {
|
static const QType qstring_type = {
|
||||||
.code = QTYPE_QSTRING,
|
QTYPE_QSTRING,
|
||||||
.destroy = qstring_destroy_obj,
|
qstring_destroy_obj,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,9 +15,10 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
static const TypeInfo container_info = {
|
static const TypeInfo container_info = {
|
||||||
.name = "container",
|
"container",
|
||||||
.instance_size = sizeof(Object),
|
TYPE_OBJECT,
|
||||||
.parent = TYPE_OBJECT,
|
0,
|
||||||
|
sizeof(Object),
|
||||||
};
|
};
|
||||||
|
|
||||||
void container_register_types(struct uc_struct *uc)
|
void container_register_types(struct uc_struct *uc)
|
||||||
|
|
|
@ -89,7 +89,7 @@ void cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
|
||||||
{
|
{
|
||||||
CPUClass *cc = CPU_GET_CLASS(cpu->uc, cpu);
|
CPUClass *cc = CPU_GET_CLASS(cpu->uc, cpu);
|
||||||
|
|
||||||
return cc->get_memory_mapping(cpu, list, errp);
|
cc->get_memory_mapping(cpu, list, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpu_common_get_memory_mapping(CPUState *cpu,
|
static void cpu_common_get_memory_mapping(CPUState *cpu,
|
||||||
|
@ -258,13 +258,24 @@ static void cpu_class_init(struct uc_struct *uc, ObjectClass *klass, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo cpu_type_info = {
|
static const TypeInfo cpu_type_info = {
|
||||||
.name = TYPE_CPU,
|
TYPE_CPU,
|
||||||
.parent = TYPE_DEVICE,
|
TYPE_DEVICE,
|
||||||
.instance_size = sizeof(CPUState),
|
|
||||||
.instance_init = cpu_common_initfn,
|
sizeof(CPUClass),
|
||||||
.abstract = true,
|
sizeof(CPUState),
|
||||||
.class_size = sizeof(CPUClass),
|
NULL,
|
||||||
.class_init = cpu_class_init,
|
|
||||||
|
cpu_common_initfn,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
cpu_class_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
true,
|
||||||
};
|
};
|
||||||
|
|
||||||
void cpu_register_types(struct uc_struct *uc)
|
void cpu_register_types(struct uc_struct *uc)
|
||||||
|
|
|
@ -217,7 +217,7 @@ static void type_initialize_interface(struct uc_struct *uc, TypeImpl *ti, TypeIm
|
||||||
TypeImpl *parent_type)
|
TypeImpl *parent_type)
|
||||||
{
|
{
|
||||||
InterfaceClass *new_iface;
|
InterfaceClass *new_iface;
|
||||||
TypeInfo info = { };
|
TypeInfo info = { 0 };
|
||||||
TypeImpl *iface_impl;
|
TypeImpl *iface_impl;
|
||||||
|
|
||||||
info.parent = parent_type->name;
|
info.parent = parent_type->name;
|
||||||
|
@ -252,9 +252,9 @@ static void type_initialize(struct uc_struct *uc, TypeImpl *ti)
|
||||||
|
|
||||||
parent = type_get_parent(uc, ti);
|
parent = type_get_parent(uc, ti);
|
||||||
if (parent) {
|
if (parent) {
|
||||||
type_initialize(uc, parent);
|
|
||||||
GSList *e;
|
GSList *e;
|
||||||
int i;
|
int i;
|
||||||
|
type_initialize(uc, parent);
|
||||||
|
|
||||||
g_assert(parent->class_size <= ti->class_size);
|
g_assert(parent->class_size <= ti->class_size);
|
||||||
memcpy(ti->class, parent->class, parent->class_size);
|
memcpy(ti->class, parent->class, parent->class_size);
|
||||||
|
@ -1645,16 +1645,45 @@ static void object_instance_init(struct uc_struct *uc, Object *obj, void *opaque
|
||||||
void register_types_object(struct uc_struct *uc)
|
void register_types_object(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
static TypeInfo interface_info = {
|
static TypeInfo interface_info = {
|
||||||
.name = TYPE_INTERFACE,
|
TYPE_INTERFACE, // name
|
||||||
.class_size = sizeof(InterfaceClass),
|
NULL,
|
||||||
.abstract = true,
|
|
||||||
|
sizeof(InterfaceClass), // class_size
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
true, // abstract
|
||||||
};
|
};
|
||||||
|
|
||||||
static TypeInfo object_info = {
|
static TypeInfo object_info = {
|
||||||
.name = TYPE_OBJECT,
|
TYPE_OBJECT,
|
||||||
.instance_size = sizeof(Object),
|
NULL,
|
||||||
.instance_init = object_instance_init,
|
|
||||||
.abstract = true,
|
0,
|
||||||
|
sizeof(Object),
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
object_instance_init,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
true,
|
||||||
};
|
};
|
||||||
|
|
||||||
uc->type_interface = type_register_internal(uc, &interface_info);
|
uc->type_interface = type_register_internal(uc, &interface_info);
|
||||||
|
|
|
@ -1,26 +1,14 @@
|
||||||
/*
|
/* * Software MMU support * * Generate helpers used by TCG for qemu_ld/st ops
|
||||||
* Software MMU support
|
and code load * functions. * * Included from target op helpers and exec.c. * *
|
||||||
*
|
Copyright (c) 2003 Fabrice Bellard * * This library is free software; you can
|
||||||
* Generate helpers used by TCG for qemu_ld/st ops and code load
|
redistribute it and/or * modify it under the terms of the GNU Lesser General
|
||||||
* functions.
|
Public * License as published by the Free Software Foundation; either * version
|
||||||
*
|
2 of the License, or (at your option) any later version. * * This library is
|
||||||
* Included from target op helpers and exec.c.
|
distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY;
|
||||||
*
|
without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A
|
||||||
* Copyright (c) 2003 Fabrice Bellard
|
PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more
|
||||||
*
|
details. * * You should have received a copy of the GNU Lesser General Public *
|
||||||
* This library is free software; you can redistribute it and/or
|
License along with this library; if not, see <http://www.gnu.org/licenses/>. */
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
/* Modified for Unicorn Engine by Nguyen Anh Quynh, 2015 */
|
/* Modified for Unicorn Engine by Nguyen Anh Quynh, 2015 */
|
||||||
|
|
||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
|
@ -120,8 +108,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* macro to check the victim tlb */
|
/* macro to check the victim tlb */
|
||||||
#define VICTIM_TLB_HIT(ty) \
|
#define VICTIM_TLB_HIT(ty) \
|
||||||
({ \
|
|
||||||
/* we are about to do a page table walk. our last hope is the \
|
/* we are about to do a page table walk. our last hope is the \
|
||||||
* victim tlb. try to refill from the victim tlb before walking the \
|
* victim tlb. try to refill from the victim tlb before walking the \
|
||||||
* page table. */ \
|
* page table. */ \
|
||||||
|
@ -141,8 +128,20 @@
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
/* return true when there is a vtlb hit, i.e. vidx >=0 */ \
|
/* return true when there is a vtlb hit, i.e. vidx >=0 */ \
|
||||||
vidx >= 0; \
|
return (vidx >= 0)
|
||||||
})
|
|
||||||
|
#ifndef victim_tlb_hit_funcs
|
||||||
|
#define victim_tlb_hit_funcs
|
||||||
|
static inline bool victim_tlb_hit_read(CPUArchState *env, target_ulong addr, int mmu_idx, int index)
|
||||||
|
{
|
||||||
|
VICTIM_TLB_HIT(ADDR_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool victim_tlb_hit_write(CPUArchState *env, target_ulong addr, int mmu_idx, int index)
|
||||||
|
{
|
||||||
|
VICTIM_TLB_HIT(addr_write);
|
||||||
|
}
|
||||||
|
#endif // victim_tlb_hit_funcs
|
||||||
|
|
||||||
#ifndef SOFTMMU_CODE_ACCESS
|
#ifndef SOFTMMU_CODE_ACCESS
|
||||||
static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
|
static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
|
||||||
|
@ -163,12 +162,12 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
|
||||||
|
|
||||||
cpu->mem_io_vaddr = addr;
|
cpu->mem_io_vaddr = addr;
|
||||||
io_mem_read(mr, physaddr, &val, 1 << SHIFT);
|
io_mem_read(mr, physaddr, &val, 1 << SHIFT);
|
||||||
return val;
|
return (DATA_TYPE)val;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SOFTMMU_CODE_ACCESS
|
#ifdef SOFTMMU_CODE_ACCESS
|
||||||
static __attribute__((unused))
|
static QEMU_UNUSED_FUNC
|
||||||
#endif
|
#endif
|
||||||
WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
uintptr_t retaddr)
|
uintptr_t retaddr)
|
||||||
|
@ -180,6 +179,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
int error_code;
|
int error_code;
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
bool handled;
|
bool handled;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
|
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
MemoryRegion *mr = memory_mapping(uc, addr);
|
MemoryRegion *mr = memory_mapping(uc, addr);
|
||||||
|
@ -293,7 +293,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!VICTIM_TLB_HIT(ADDR_READ)) {
|
if (!victim_tlb_hit_read(env, addr, mmu_idx, index)) {
|
||||||
tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||||
mmu_idx, retaddr);
|
mmu_idx, retaddr);
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
haddr = addr + env->tlb_table[mmu_idx][index].addend;
|
haddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][index].addend);
|
||||||
#if DATA_SIZE == 1
|
#if DATA_SIZE == 1
|
||||||
res = glue(glue(ld, LSUFFIX), _p)((uint8_t *)haddr);
|
res = glue(glue(ld, LSUFFIX), _p)((uint8_t *)haddr);
|
||||||
#else
|
#else
|
||||||
|
@ -395,7 +395,7 @@ _out:
|
||||||
|
|
||||||
#if DATA_SIZE > 1
|
#if DATA_SIZE > 1
|
||||||
#ifdef SOFTMMU_CODE_ACCESS
|
#ifdef SOFTMMU_CODE_ACCESS
|
||||||
static __attribute__((unused))
|
static QEMU_UNUSED_FUNC
|
||||||
#endif
|
#endif
|
||||||
WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
uintptr_t retaddr)
|
uintptr_t retaddr)
|
||||||
|
@ -407,6 +407,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
int error_code;
|
int error_code;
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
bool handled;
|
bool handled;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
|
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
MemoryRegion *mr = memory_mapping(uc, addr);
|
MemoryRegion *mr = memory_mapping(uc, addr);
|
||||||
|
@ -520,7 +521,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!VICTIM_TLB_HIT(ADDR_READ)) {
|
if (!victim_tlb_hit_read(env, addr, mmu_idx, index)) {
|
||||||
tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||||
mmu_idx, retaddr);
|
mmu_idx, retaddr);
|
||||||
}
|
}
|
||||||
|
@ -599,7 +600,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
haddr = addr + env->tlb_table[mmu_idx][index].addend;
|
haddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][index].addend);
|
||||||
res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr);
|
res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr);
|
||||||
|
|
||||||
_out:
|
_out:
|
||||||
|
@ -671,6 +672,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
uintptr_t haddr;
|
uintptr_t haddr;
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
bool handled;
|
bool handled;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
|
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
MemoryRegion *mr = memory_mapping(uc, addr);
|
MemoryRegion *mr = memory_mapping(uc, addr);
|
||||||
|
@ -742,7 +744,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!VICTIM_TLB_HIT(addr_write)) {
|
if (!victim_tlb_hit_write(env, addr, mmu_idx, index)) {
|
||||||
tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
|
tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
|
||||||
}
|
}
|
||||||
tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
|
tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
|
||||||
|
@ -789,7 +791,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
* previous page from the TLB cache. */
|
* previous page from the TLB cache. */
|
||||||
for (i = DATA_SIZE - 1; i >= 0; i--) {
|
for (i = DATA_SIZE - 1; i >= 0; i--) {
|
||||||
/* Little-endian extract. */
|
/* Little-endian extract. */
|
||||||
uint8_t val8 = val >> (i * 8);
|
uint8_t val8 = (uint8_t)(val >> (i * 8));
|
||||||
/* Note the adjustment at the beginning of the function.
|
/* Note the adjustment at the beginning of the function.
|
||||||
Undo that for the recursion. */
|
Undo that for the recursion. */
|
||||||
glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
|
glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
|
||||||
|
@ -812,7 +814,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
haddr = addr + env->tlb_table[mmu_idx][index].addend;
|
haddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][index].addend);
|
||||||
#if DATA_SIZE == 1
|
#if DATA_SIZE == 1
|
||||||
glue(glue(st, SUFFIX), _p)((uint8_t *)haddr, val);
|
glue(glue(st, SUFFIX), _p)((uint8_t *)haddr, val);
|
||||||
#else
|
#else
|
||||||
|
@ -829,6 +831,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
uintptr_t haddr;
|
uintptr_t haddr;
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
bool handled;
|
bool handled;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
|
|
||||||
struct uc_struct *uc = env->uc;
|
struct uc_struct *uc = env->uc;
|
||||||
MemoryRegion *mr = memory_mapping(uc, addr);
|
MemoryRegion *mr = memory_mapping(uc, addr);
|
||||||
|
@ -900,7 +903,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!VICTIM_TLB_HIT(addr_write)) {
|
if (!victim_tlb_hit_write(env, addr, mmu_idx, index)) {
|
||||||
tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
|
tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
|
||||||
}
|
}
|
||||||
tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
|
tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
|
||||||
|
@ -947,7 +950,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
* previous page from the TLB cache. */
|
* previous page from the TLB cache. */
|
||||||
for (i = DATA_SIZE - 1; i >= 0; i--) {
|
for (i = DATA_SIZE - 1; i >= 0; i--) {
|
||||||
/* Big-endian extract. */
|
/* Big-endian extract. */
|
||||||
uint8_t val8 = val >> (((DATA_SIZE - 1) * 8) - (i * 8));
|
uint8_t val8 = (uint8_t)(val >> (((DATA_SIZE - 1) * 8) - (i * 8)));
|
||||||
/* Note the adjustment at the beginning of the function.
|
/* Note the adjustment at the beginning of the function.
|
||||||
Undo that for the recursion. */
|
Undo that for the recursion. */
|
||||||
glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
|
glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
|
||||||
|
@ -970,7 +973,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
haddr = addr + env->tlb_table[mmu_idx][index].addend;
|
haddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][index].addend);
|
||||||
glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val);
|
glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val);
|
||||||
}
|
}
|
||||||
#endif /* DATA_SIZE > 1 */
|
#endif /* DATA_SIZE > 1 */
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include "platform.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include "platform.h"
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "tcg-op.h"
|
#include "tcg-op.h"
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include "platform.h"
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "internals.h"
|
#include "internals.h"
|
||||||
|
|
|
@ -13,10 +13,10 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals,
|
||||||
void arm_reg_reset(struct uc_struct *uc);
|
void arm_reg_reset(struct uc_struct *uc);
|
||||||
void arm64_reg_reset(struct uc_struct *uc);
|
void arm64_reg_reset(struct uc_struct *uc);
|
||||||
|
|
||||||
__attribute__ ((visibility ("default")))
|
DEFAULT_VISIBILITY
|
||||||
void arm_uc_init(struct uc_struct* uc);
|
void arm_uc_init(struct uc_struct* uc);
|
||||||
|
|
||||||
__attribute__ ((visibility ("default")))
|
DEFAULT_VISIBILITY
|
||||||
void arm64_uc_init(struct uc_struct* uc);
|
void arm64_uc_init(struct uc_struct* uc);
|
||||||
|
|
||||||
extern const int ARM_REGS_STORAGE_SIZE;
|
extern const int ARM_REGS_STORAGE_SIZE;
|
||||||
|
|
|
@ -113,7 +113,7 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void* const* vals,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((visibility ("default")))
|
DEFAULT_VISIBILITY
|
||||||
void arm64_uc_init(struct uc_struct* uc)
|
void arm64_uc_init(struct uc_struct* uc)
|
||||||
{
|
{
|
||||||
register_accel_types(uc);
|
register_accel_types(uc);
|
||||||
|
|
|
@ -218,7 +218,7 @@ target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1,
|
||||||
|
|
||||||
uint32_t cpu_cc_compute_all(CPUX86State *env, int op)
|
uint32_t cpu_cc_compute_all(CPUX86State *env, int op)
|
||||||
{
|
{
|
||||||
return helper_cc_compute_all(CC_DST, CC_SRC, CC_SRC2, op);
|
return (uint32_t)helper_cc_compute_all(CC_DST, CC_SRC, CC_SRC2, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1,
|
target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1,
|
||||||
|
@ -323,7 +323,7 @@ target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1,
|
||||||
void helper_write_eflags(CPUX86State *env, target_ulong t0,
|
void helper_write_eflags(CPUX86State *env, target_ulong t0,
|
||||||
uint32_t update_mask)
|
uint32_t update_mask)
|
||||||
{
|
{
|
||||||
cpu_load_eflags(env, t0, update_mask);
|
cpu_load_eflags(env, (int)t0, update_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
target_ulong helper_read_eflags(CPUX86State *env)
|
target_ulong helper_read_eflags(CPUX86State *env)
|
||||||
|
|
|
@ -141,7 +141,7 @@ static int glue(compute_all_inc, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
|
||||||
int cf, pf, af, zf, sf, of;
|
int cf, pf, af, zf, sf, of;
|
||||||
DATA_TYPE src2;
|
DATA_TYPE src2;
|
||||||
|
|
||||||
cf = src1;
|
cf = (int)src1;
|
||||||
src1 = dst - 1;
|
src1 = dst - 1;
|
||||||
src2 = 1;
|
src2 = 1;
|
||||||
pf = parity_table[(uint8_t)dst];
|
pf = parity_table[(uint8_t)dst];
|
||||||
|
@ -157,7 +157,7 @@ static int glue(compute_all_dec, SUFFIX)(DATA_TYPE dst, DATA_TYPE src1)
|
||||||
int cf, pf, af, zf, sf, of;
|
int cf, pf, af, zf, sf, of;
|
||||||
DATA_TYPE src2;
|
DATA_TYPE src2;
|
||||||
|
|
||||||
cf = src1;
|
cf = (int)src1;
|
||||||
src1 = dst + 1;
|
src1 = dst + 1;
|
||||||
src2 = 1;
|
src2 = 1;
|
||||||
pf = parity_table[(uint8_t)dst];
|
pf = parity_table[(uint8_t)dst];
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -805,7 +805,7 @@ typedef struct BNDCSReg {
|
||||||
#define MMX_Q(n) q
|
#define MMX_Q(n) q
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
floatx80 d __attribute__((aligned(16)));
|
floatx80 QEMU_ALIGN(16, d);
|
||||||
MMXReg mmx;
|
MMXReg mmx;
|
||||||
} FPReg;
|
} FPReg;
|
||||||
|
|
||||||
|
@ -869,7 +869,8 @@ typedef struct CPUX86State {
|
||||||
uint64_t msr_bndcfgs;
|
uint64_t msr_bndcfgs;
|
||||||
|
|
||||||
/* Beginning of state preserved by INIT (dummy marker). */
|
/* Beginning of state preserved by INIT (dummy marker). */
|
||||||
struct {} start_init_save;
|
//struct {} start_init_save;
|
||||||
|
int start_init_save;
|
||||||
|
|
||||||
/* FPU state */
|
/* FPU state */
|
||||||
unsigned int fpstt; /* top of stack index */
|
unsigned int fpstt; /* top of stack index */
|
||||||
|
@ -937,7 +938,8 @@ typedef struct CPUX86State {
|
||||||
uint32_t smbase;
|
uint32_t smbase;
|
||||||
|
|
||||||
/* End of state preserved by INIT (dummy marker). */
|
/* End of state preserved by INIT (dummy marker). */
|
||||||
struct {} end_init_save;
|
//struct {} end_init_save;
|
||||||
|
int end_init_save;
|
||||||
|
|
||||||
uint64_t system_time_msr;
|
uint64_t system_time_msr;
|
||||||
uint64_t wall_clock_msr;
|
uint64_t wall_clock_msr;
|
||||||
|
|
|
@ -489,42 +489,58 @@ void helper_fabs_ST0(CPUX86State *env)
|
||||||
|
|
||||||
void helper_fld1_ST0(CPUX86State *env)
|
void helper_fld1_ST0(CPUX86State *env)
|
||||||
{
|
{
|
||||||
ST0 = floatx80_one;
|
//ST0 = floatx80_one;
|
||||||
|
floatx80 one = { 0x8000000000000000LL, 0x3fff };
|
||||||
|
ST0 = one;
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_fldl2t_ST0(CPUX86State *env)
|
void helper_fldl2t_ST0(CPUX86State *env)
|
||||||
{
|
{
|
||||||
ST0 = floatx80_l2t;
|
//ST0 = floatx80_l2t;
|
||||||
|
floatx80 l2t = { 0xd49a784bcd1b8afeLL, 0x4000 };
|
||||||
|
ST0 = l2t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_fldl2e_ST0(CPUX86State *env)
|
void helper_fldl2e_ST0(CPUX86State *env)
|
||||||
{
|
{
|
||||||
ST0 = floatx80_l2e;
|
//ST0 = floatx80_l2e;
|
||||||
|
floatx80 l2e = { 0xb8aa3b295c17f0bcLL, 0x3fff };
|
||||||
|
ST0 = l2e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_fldpi_ST0(CPUX86State *env)
|
void helper_fldpi_ST0(CPUX86State *env)
|
||||||
{
|
{
|
||||||
ST0 = floatx80_pi;
|
//ST0 = floatx80_pi;
|
||||||
|
floatx80 pi = { 0xc90fdaa22168c235LL, 0x4000 };
|
||||||
|
ST0 = pi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_fldlg2_ST0(CPUX86State *env)
|
void helper_fldlg2_ST0(CPUX86State *env)
|
||||||
{
|
{
|
||||||
ST0 = floatx80_lg2;
|
//ST0 = floatx80_lg2;
|
||||||
|
floatx80 lg2 = { 0x9a209a84fbcff799LL, 0x3ffd };
|
||||||
|
ST0 = lg2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_fldln2_ST0(CPUX86State *env)
|
void helper_fldln2_ST0(CPUX86State *env)
|
||||||
{
|
{
|
||||||
ST0 = floatx80_ln2;
|
//ST0 = floatx80_ln2;
|
||||||
|
floatx80 ln2 = { 0xb17217f7d1cf79acLL, 0x3ffe };
|
||||||
|
ST0 = ln2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_fldz_ST0(CPUX86State *env)
|
void helper_fldz_ST0(CPUX86State *env)
|
||||||
{
|
{
|
||||||
ST0 = floatx80_zero;
|
//ST0 = floatx80_zero;
|
||||||
|
floatx80 zero = { 0x0000000000000000LL, 0x0000 };
|
||||||
|
ST0 = zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
void helper_fldz_FT0(CPUX86State *env)
|
void helper_fldz_FT0(CPUX86State *env)
|
||||||
{
|
{
|
||||||
FT0 = floatx80_zero;
|
//FT0 = floatx80_zero;
|
||||||
|
floatx80 zero = { 0x0000000000000000LL, 0x0000 };
|
||||||
|
ST0 = zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t helper_fnstsw(CPUX86State *env)
|
uint32_t helper_fnstsw(CPUX86State *env)
|
||||||
|
@ -686,10 +702,11 @@ void helper_fptan(CPUX86State *env)
|
||||||
if ((fptemp > MAXTAN) || (fptemp < -MAXTAN)) {
|
if ((fptemp > MAXTAN) || (fptemp < -MAXTAN)) {
|
||||||
env->fpus |= 0x400;
|
env->fpus |= 0x400;
|
||||||
} else {
|
} else {
|
||||||
fptemp = tan(fptemp);
|
floatx80 one = { 0x8000000000000000LL, 0x3fff };
|
||||||
|
fptemp = tan(fptemp);
|
||||||
ST0 = double_to_floatx80(env, fptemp);
|
ST0 = double_to_floatx80(env, fptemp);
|
||||||
fpush(env);
|
fpush(env);
|
||||||
ST0 = floatx80_one;
|
ST0 = one;
|
||||||
env->fpus &= ~0x400; /* C2 <-- 0 */
|
env->fpus &= ~0x400; /* C2 <-- 0 */
|
||||||
/* the above code is for |arg| < 2**52 only */
|
/* the above code is for |arg| < 2**52 only */
|
||||||
}
|
}
|
||||||
|
@ -713,7 +730,9 @@ void helper_fxtract(CPUX86State *env)
|
||||||
|
|
||||||
if (floatx80_is_zero(ST0)) {
|
if (floatx80_is_zero(ST0)) {
|
||||||
/* Easy way to generate -inf and raising division by 0 exception */
|
/* Easy way to generate -inf and raising division by 0 exception */
|
||||||
ST0 = floatx80_div(floatx80_chs(floatx80_one), floatx80_zero,
|
floatx80 zero = { 0x0000000000000000LL, 0x0000 };
|
||||||
|
floatx80 one = { 0x8000000000000000LL, 0x3fff };
|
||||||
|
ST0 = floatx80_div(floatx80_chs(one), zero,
|
||||||
&env->fp_status);
|
&env->fp_status);
|
||||||
fpush(env);
|
fpush(env);
|
||||||
ST0 = temp.d;
|
ST0 = temp.d;
|
||||||
|
@ -740,7 +759,8 @@ void helper_fprem1(CPUX86State *env)
|
||||||
st1 = floatx80_to_double(env, ST1);
|
st1 = floatx80_to_double(env, ST1);
|
||||||
|
|
||||||
if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
|
if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
|
||||||
ST0 = double_to_floatx80(env, 0.0 / 0.0); /* NaN */
|
|
||||||
|
ST0 = double_to_floatx80(env, NAN); /* NaN */
|
||||||
env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */
|
env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -799,7 +819,7 @@ void helper_fprem(CPUX86State *env)
|
||||||
st1 = floatx80_to_double(env, ST1);
|
st1 = floatx80_to_double(env, ST1);
|
||||||
|
|
||||||
if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
|
if (isinf(st0) || isnan(st0) || isnan(st1) || (st1 == 0.0)) {
|
||||||
ST0 = double_to_floatx80(env, 0.0 / 0.0); /* NaN */
|
ST0 = double_to_floatx80(env, NAN); /* NaN */
|
||||||
env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */
|
env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -992,7 +1012,7 @@ void helper_fstenv(CPUX86State *env, target_ulong ptr, int data32)
|
||||||
cpu_stl_data(env, ptr, env->fpuc);
|
cpu_stl_data(env, ptr, env->fpuc);
|
||||||
cpu_stl_data(env, ptr + 4, fpus);
|
cpu_stl_data(env, ptr + 4, fpus);
|
||||||
cpu_stl_data(env, ptr + 8, fptag);
|
cpu_stl_data(env, ptr + 8, fptag);
|
||||||
cpu_stl_data(env, ptr + 12, env->fpip); /* fpip */
|
cpu_stl_data(env, ptr + 12, (uint32_t)env->fpip); /* fpip */
|
||||||
cpu_stl_data(env, ptr + 20, 0); /* fpcs */
|
cpu_stl_data(env, ptr + 20, 0); /* fpcs */
|
||||||
cpu_stl_data(env, ptr + 24, 0); /* fpoo */
|
cpu_stl_data(env, ptr + 24, 0); /* fpoo */
|
||||||
cpu_stl_data(env, ptr + 28, 0); /* fpos */
|
cpu_stl_data(env, ptr + 28, 0); /* fpos */
|
||||||
|
@ -1001,7 +1021,7 @@ void helper_fstenv(CPUX86State *env, target_ulong ptr, int data32)
|
||||||
cpu_stl_data(env, ptr, env->fpuc);
|
cpu_stl_data(env, ptr, env->fpuc);
|
||||||
cpu_stl_data(env, ptr + 4, fpus);
|
cpu_stl_data(env, ptr + 4, fpus);
|
||||||
cpu_stl_data(env, ptr + 8, fptag);
|
cpu_stl_data(env, ptr + 8, fptag);
|
||||||
cpu_stl_data(env, ptr + 12, env->fpip); /* fpip */
|
cpu_stl_data(env, ptr + 12, (uint32_t)env->fpip); /* fpip */
|
||||||
cpu_stl_data(env, ptr + 16, 0); /* fpcs */
|
cpu_stl_data(env, ptr + 16, 0); /* fpcs */
|
||||||
cpu_stl_data(env, ptr + 20, 0); /* fpoo */
|
cpu_stl_data(env, ptr + 20, 0); /* fpoo */
|
||||||
cpu_stl_data(env, ptr + 24, 0); /* fpos */
|
cpu_stl_data(env, ptr + 24, 0); /* fpos */
|
||||||
|
@ -1010,7 +1030,7 @@ void helper_fstenv(CPUX86State *env, target_ulong ptr, int data32)
|
||||||
cpu_stw_data(env, ptr, env->fpuc);
|
cpu_stw_data(env, ptr, env->fpuc);
|
||||||
cpu_stw_data(env, ptr + 2, fpus);
|
cpu_stw_data(env, ptr + 2, fpus);
|
||||||
cpu_stw_data(env, ptr + 4, fptag);
|
cpu_stw_data(env, ptr + 4, fptag);
|
||||||
cpu_stw_data(env, ptr + 6, env->fpip);
|
cpu_stw_data(env, ptr + 6, (uint32_t)env->fpip);
|
||||||
cpu_stw_data(env, ptr + 8, 0);
|
cpu_stw_data(env, ptr + 8, 0);
|
||||||
cpu_stw_data(env, ptr + 10, 0);
|
cpu_stw_data(env, ptr + 10, 0);
|
||||||
cpu_stw_data(env, ptr + 12, 0);
|
cpu_stw_data(env, ptr + 12, 0);
|
||||||
|
|
|
@ -1002,7 +1002,7 @@ bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bp_match || wp_match) {
|
if (bp_match || wp_match) {
|
||||||
dr6 |= 1 << reg;
|
dr6 |= 1ULL << reg;
|
||||||
if (hw_breakpoint_enabled(env->dr[7], reg)) {
|
if (hw_breakpoint_enabled(env->dr[7], reg)) {
|
||||||
hit_enabled = true;
|
hit_enabled = true;
|
||||||
}
|
}
|
||||||
|
@ -1083,7 +1083,7 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
|
||||||
dt = &env->gdt;
|
dt = &env->gdt;
|
||||||
index = selector & ~7;
|
index = selector & ~7;
|
||||||
ptr = dt->base + index;
|
ptr = dt->base + index;
|
||||||
if ((index + 7) > dt->limit
|
if ((uint32_t)(index + 7) > dt->limit
|
||||||
|| cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
|
|| cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
|
||||||
|| cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
|
|| cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -121,7 +121,7 @@ void helper_divl_EAX(CPUX86State *env, target_ulong t0)
|
||||||
uint64_t num, q;
|
uint64_t num, q;
|
||||||
|
|
||||||
num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
|
num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
|
||||||
den = t0;
|
den = (unsigned int)t0;
|
||||||
if (den == 0) {
|
if (den == 0) {
|
||||||
raise_exception(env, EXCP00_DIVZ);
|
raise_exception(env, EXCP00_DIVZ);
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ void helper_idivl_EAX(CPUX86State *env, target_ulong t0)
|
||||||
int64_t num, q;
|
int64_t num, q;
|
||||||
|
|
||||||
num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
|
num = ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
|
||||||
den = t0;
|
den = (int)t0;
|
||||||
if (den == 0) {
|
if (den == 0) {
|
||||||
raise_exception(env, EXCP00_DIVZ);
|
raise_exception(env, EXCP00_DIVZ);
|
||||||
}
|
}
|
||||||
|
@ -362,14 +362,14 @@ static int idiv64(uint64_t *plow, uint64_t *phigh, int64_t b)
|
||||||
if (*plow > (1ULL << 63)) {
|
if (*plow > (1ULL << 63)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
*plow = -*plow;
|
*plow = 0-*plow;
|
||||||
} else {
|
} else {
|
||||||
if (*plow >= (1ULL << 63)) {
|
if (*plow >= (1ULL << 63)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sa) {
|
if (sa) {
|
||||||
*phigh = -*phigh;
|
*phigh = 0-*phigh;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,17 +126,17 @@ void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
|
||||||
cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0);
|
cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0);
|
||||||
switch (reg) {
|
switch (reg) {
|
||||||
case 0:
|
case 0:
|
||||||
cpu_x86_update_cr0(env, t0);
|
cpu_x86_update_cr0(env, (uint32_t)t0);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
cpu_x86_update_cr3(env, t0);
|
cpu_x86_update_cr3(env, t0);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
cpu_x86_update_cr4(env, t0);
|
cpu_x86_update_cr4(env, (uint32_t)t0);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
if (!(env->hflags2 & HF2_VINTR_MASK)) {
|
if (!(env->hflags2 & HF2_VINTR_MASK)) {
|
||||||
cpu_set_apic_tpr(env->uc, x86_env_get_cpu(env)->apic_state, t0);
|
cpu_set_apic_tpr(env->uc, x86_env_get_cpu(env)->apic_state, (uint8_t)t0);
|
||||||
}
|
}
|
||||||
env->v_tpr = t0 & 0x0f;
|
env->v_tpr = t0 & 0x0f;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1945,7 +1945,7 @@ static inline int pcmp_elen(CPUX86State *env, int reg, uint32_t ctrl)
|
||||||
|
|
||||||
/* Presence of REX.W is indicated by a bit higher than 7 set */
|
/* Presence of REX.W is indicated by a bit higher than 7 set */
|
||||||
if (ctrl >> 8) {
|
if (ctrl >> 8) {
|
||||||
val = abs1((int64_t)env->regs[reg]);
|
val = abs1((int)env->regs[reg]);
|
||||||
} else {
|
} else {
|
||||||
val = abs1((int32_t)env->regs[reg]);
|
val = abs1((int32_t)env->regs[reg]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -947,6 +947,7 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
||||||
{
|
{
|
||||||
// Unicorn: call registered syscall hooks
|
// Unicorn: call registered syscall hooks
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_INSN) {
|
HOOK_FOREACH(env->uc, hook, UC_HOOK_INSN) {
|
||||||
if (!HOOK_BOUND_CHECK(hook, env->eip))
|
if (!HOOK_BOUND_CHECK(hook, env->eip))
|
||||||
continue;
|
continue;
|
||||||
|
@ -956,7 +957,7 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
||||||
|
|
||||||
env->eip += next_eip_addend;
|
env->eip += next_eip_addend;
|
||||||
return;
|
return;
|
||||||
|
/*
|
||||||
int selector;
|
int selector;
|
||||||
|
|
||||||
if (!(env->efer & MSR_EFER_SCE)) {
|
if (!(env->efer & MSR_EFER_SCE)) {
|
||||||
|
@ -1005,6 +1006,7 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
|
||||||
DESC_W_MASK | DESC_A_MASK);
|
DESC_W_MASK | DESC_A_MASK);
|
||||||
env->eip = (uint32_t)env->star;
|
env->eip = (uint32_t)env->star;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -2307,6 +2309,7 @@ void helper_sysenter(CPUX86State *env, int next_eip_addend)
|
||||||
{
|
{
|
||||||
// Unicorn: call registered SYSENTER hooks
|
// Unicorn: call registered SYSENTER hooks
|
||||||
struct hook *hook;
|
struct hook *hook;
|
||||||
|
HOOK_FOREACH_VAR_DECLARE;
|
||||||
HOOK_FOREACH(env->uc, hook, UC_HOOK_INSN) {
|
HOOK_FOREACH(env->uc, hook, UC_HOOK_INSN) {
|
||||||
if (!HOOK_BOUND_CHECK(hook, env->eip))
|
if (!HOOK_BOUND_CHECK(hook, env->eip))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -55,7 +55,7 @@ target_ulong glue(helper_rcl, SUFFIX)(CPUX86State *env, target_ulong t0,
|
||||||
count = rclb_table[count];
|
count = rclb_table[count];
|
||||||
#endif
|
#endif
|
||||||
if (count) {
|
if (count) {
|
||||||
eflags = env->cc_src;
|
eflags = (int)env->cc_src;
|
||||||
t0 &= DATA_MASK;
|
t0 &= DATA_MASK;
|
||||||
src = t0;
|
src = t0;
|
||||||
res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
|
res = (t0 << count) | ((target_ulong)(eflags & CC_C) << (count - 1));
|
||||||
|
@ -84,7 +84,7 @@ target_ulong glue(helper_rcr, SUFFIX)(CPUX86State *env, target_ulong t0,
|
||||||
count = rclb_table[count];
|
count = rclb_table[count];
|
||||||
#endif
|
#endif
|
||||||
if (count) {
|
if (count) {
|
||||||
eflags = env->cc_src;
|
eflags = (int)env->cc_src;
|
||||||
t0 &= DATA_MASK;
|
t0 &= DATA_MASK;
|
||||||
src = t0;
|
src = t0;
|
||||||
res = (t0 >> count) |
|
res = (t0 >> count) |
|
||||||
|
|
|
@ -97,12 +97,12 @@ void do_smm_enter(X86CPU *cpu)
|
||||||
}
|
}
|
||||||
stq_phys(cs->as, sm_state + 0x7f78, env->eip);
|
stq_phys(cs->as, sm_state + 0x7f78, env->eip);
|
||||||
stl_phys(cs->as, sm_state + 0x7f70, cpu_compute_eflags(env));
|
stl_phys(cs->as, sm_state + 0x7f70, cpu_compute_eflags(env));
|
||||||
stl_phys(cs->as, sm_state + 0x7f68, env->dr[6]);
|
stl_phys(cs->as, sm_state + 0x7f68, (uint32_t)env->dr[6]);
|
||||||
stl_phys(cs->as, sm_state + 0x7f60, env->dr[7]);
|
stl_phys(cs->as, sm_state + 0x7f60, (uint32_t)env->dr[7]);
|
||||||
|
|
||||||
stl_phys(cs->as, sm_state + 0x7f48, env->cr[4]);
|
stl_phys(cs->as, sm_state + 0x7f48, (uint32_t)env->cr[4]);
|
||||||
stl_phys(cs->as, sm_state + 0x7f50, env->cr[3]);
|
stl_phys(cs->as, sm_state + 0x7f50, (uint32_t)env->cr[3]);
|
||||||
stl_phys(cs->as, sm_state + 0x7f58, env->cr[0]);
|
stl_phys(cs->as, sm_state + 0x7f58, (uint32_t)env->cr[0]);
|
||||||
|
|
||||||
stl_phys(cs->as, sm_state + 0x7efc, SMM_REVISION_ID);
|
stl_phys(cs->as, sm_state + 0x7efc, SMM_REVISION_ID);
|
||||||
stl_phys(cs->as, sm_state + 0x7f00, env->smbase);
|
stl_phys(cs->as, sm_state + 0x7f00, env->smbase);
|
||||||
|
|
|
@ -130,7 +130,7 @@
|
||||||
|
|
||||||
#define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */
|
#define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */
|
||||||
|
|
||||||
struct QEMU_PACKED vmcb_control_area {
|
QEMU_PACK( struct vmcb_control_area {
|
||||||
uint16_t intercept_cr_read;
|
uint16_t intercept_cr_read;
|
||||||
uint16_t intercept_cr_write;
|
uint16_t intercept_cr_write;
|
||||||
uint16_t intercept_dr_read;
|
uint16_t intercept_dr_read;
|
||||||
|
@ -160,16 +160,16 @@ struct QEMU_PACKED vmcb_control_area {
|
||||||
uint64_t nested_cr3;
|
uint64_t nested_cr3;
|
||||||
uint64_t lbr_ctl;
|
uint64_t lbr_ctl;
|
||||||
uint8_t reserved_5[832];
|
uint8_t reserved_5[832];
|
||||||
};
|
});
|
||||||
|
|
||||||
struct QEMU_PACKED vmcb_seg {
|
QEMU_PACK( struct vmcb_seg {
|
||||||
uint16_t selector;
|
uint16_t selector;
|
||||||
uint16_t attrib;
|
uint16_t attrib;
|
||||||
uint32_t limit;
|
uint32_t limit;
|
||||||
uint64_t base;
|
uint64_t base;
|
||||||
};
|
});
|
||||||
|
|
||||||
struct QEMU_PACKED vmcb_save_area {
|
QEMU_PACK( struct vmcb_save_area {
|
||||||
struct vmcb_seg es;
|
struct vmcb_seg es;
|
||||||
struct vmcb_seg cs;
|
struct vmcb_seg cs;
|
||||||
struct vmcb_seg ss;
|
struct vmcb_seg ss;
|
||||||
|
@ -212,11 +212,11 @@ struct QEMU_PACKED vmcb_save_area {
|
||||||
uint64_t br_to;
|
uint64_t br_to;
|
||||||
uint64_t last_excp_from;
|
uint64_t last_excp_from;
|
||||||
uint64_t last_excp_to;
|
uint64_t last_excp_to;
|
||||||
};
|
});
|
||||||
|
|
||||||
struct QEMU_PACKED vmcb {
|
QEMU_PACK( struct vmcb {
|
||||||
struct vmcb_control_area control;
|
struct vmcb_control_area control;
|
||||||
struct vmcb_save_area save;
|
struct vmcb_save_area save;
|
||||||
};
|
});
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -486,33 +486,27 @@ void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type,
|
||||||
if (likely(!(env->hflags & HF_SVMI_MASK))) {
|
if (likely(!(env->hflags & HF_SVMI_MASK))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (type) {
|
if( type >= SVM_EXIT_READ_CR0 && type <= SVM_EXIT_READ_CR0 + 8 ) {
|
||||||
case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8:
|
|
||||||
if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) {
|
if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) {
|
||||||
helper_vmexit(env, type, param);
|
helper_vmexit(env, type, param);
|
||||||
}
|
}
|
||||||
break;
|
} else if( type >= SVM_EXIT_WRITE_CR0 && type <= SVM_EXIT_WRITE_CR0 + 8 ) {
|
||||||
case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8:
|
|
||||||
if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) {
|
if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) {
|
||||||
helper_vmexit(env, type, param);
|
helper_vmexit(env, type, param);
|
||||||
}
|
}
|
||||||
break;
|
} else if( type >= SVM_EXIT_READ_DR0 && type <= SVM_EXIT_READ_DR0 + 7 ) {
|
||||||
case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 7:
|
|
||||||
if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) {
|
if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) {
|
||||||
helper_vmexit(env, type, param);
|
helper_vmexit(env, type, param);
|
||||||
}
|
}
|
||||||
break;
|
} else if( type >= SVM_EXIT_WRITE_DR0 && type <= SVM_EXIT_WRITE_DR0 + 7 ) {
|
||||||
case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 7:
|
|
||||||
if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) {
|
if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) {
|
||||||
helper_vmexit(env, type, param);
|
helper_vmexit(env, type, param);
|
||||||
}
|
}
|
||||||
break;
|
} else if( type >= SVM_EXIT_EXCP_BASE && type <= SVM_EXIT_EXCP_BASE + 31 ) {
|
||||||
case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 31:
|
|
||||||
if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))) {
|
if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))) {
|
||||||
helper_vmexit(env, type, param);
|
helper_vmexit(env, type, param);
|
||||||
}
|
}
|
||||||
break;
|
} else if( type == SVM_EXIT_MSR ) {
|
||||||
case SVM_EXIT_MSR:
|
|
||||||
if (env->intercept & (1ULL << (SVM_EXIT_MSR - SVM_EXIT_INTR))) {
|
if (env->intercept & (1ULL << (SVM_EXIT_MSR - SVM_EXIT_INTR))) {
|
||||||
/* FIXME: this should be read in at vmrun (faster this way?) */
|
/* FIXME: this should be read in at vmrun (faster this way?) */
|
||||||
uint64_t addr = ldq_phys(cs->as, env->vm_vmcb +
|
uint64_t addr = ldq_phys(cs->as, env->vm_vmcb +
|
||||||
|
@ -520,38 +514,32 @@ void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type,
|
||||||
control.msrpm_base_pa));
|
control.msrpm_base_pa));
|
||||||
uint32_t t0, t1;
|
uint32_t t0, t1;
|
||||||
|
|
||||||
switch ((uint32_t)env->regs[R_ECX]) {
|
uint32_t ecx = (uint32_t)env->regs[R_ECX];
|
||||||
case 0 ... 0x1fff:
|
if( ecx >= 0 && ecx <= 0x1fff ) {
|
||||||
t0 = (env->regs[R_ECX] * 2) % 8;
|
t0 = (env->regs[R_ECX] * 2) % 8;
|
||||||
t1 = (env->regs[R_ECX] * 2) / 8;
|
t1 = (env->regs[R_ECX] * 2) / 8;
|
||||||
break;
|
} else if( ecx >= 0xc0000000 && ecx <= 0xc0001fff ) {
|
||||||
case 0xc0000000 ... 0xc0001fff:
|
|
||||||
t0 = (8192 + env->regs[R_ECX] - 0xc0000000) * 2;
|
t0 = (8192 + env->regs[R_ECX] - 0xc0000000) * 2;
|
||||||
t1 = (t0 / 8);
|
t1 = (t0 / 8);
|
||||||
t0 %= 8;
|
t0 %= 8;
|
||||||
break;
|
} else if( ecx >= 0xc0010000 && ecx <= 0xc0011fff ) {
|
||||||
case 0xc0010000 ... 0xc0011fff:
|
|
||||||
t0 = (16384 + env->regs[R_ECX] - 0xc0010000) * 2;
|
t0 = (16384 + env->regs[R_ECX] - 0xc0010000) * 2;
|
||||||
t1 = (t0 / 8);
|
t1 = (t0 / 8);
|
||||||
t0 %= 8;
|
t0 %= 8;
|
||||||
break;
|
} else {
|
||||||
default:
|
|
||||||
helper_vmexit(env, type, param);
|
helper_vmexit(env, type, param);
|
||||||
t0 = 0;
|
t0 = 0;
|
||||||
t1 = 0;
|
t1 = 0;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (ldub_phys(cs->as, addr + t1) & ((1 << param) << t0)) {
|
if (ldub_phys(cs->as, addr + t1) & ((1 << param) << t0)) {
|
||||||
helper_vmexit(env, type, param);
|
helper_vmexit(env, type, param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
default:
|
|
||||||
if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) {
|
if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) {
|
||||||
helper_vmexit(env, type, param);
|
helper_vmexit(env, type, param);
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
|
void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
* CPUID Fn8000_0008_ECX[ApicIdCoreIdSize[3:0]] is set to apicid_core_width().
|
* CPUID Fn8000_0008_ECX[ApicIdCoreIdSize[3:0]] is set to apicid_core_width().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "platform.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "qemu/bitops.h"
|
#include "qemu/bitops.h"
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -150,10 +150,17 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
|
||||||
switch(regid) {
|
switch(regid) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_FP0 ... UC_X86_REG_FP7:
|
case UC_X86_REG_FP0:
|
||||||
|
case UC_X86_REG_FP1:
|
||||||
|
case UC_X86_REG_FP2:
|
||||||
|
case UC_X86_REG_FP3:
|
||||||
|
case UC_X86_REG_FP4:
|
||||||
|
case UC_X86_REG_FP5:
|
||||||
|
case UC_X86_REG_FP6:
|
||||||
|
case UC_X86_REG_FP7:
|
||||||
{
|
{
|
||||||
floatx80 reg = X86_CPU(uc, mycpu)->env.fpregs[regid - UC_X86_REG_FP0].d;
|
floatx80 reg = X86_CPU(uc, mycpu)->env.fpregs[regid - UC_X86_REG_FP0].d;
|
||||||
cpu_get_fp80(value, value+sizeof(uint64_t), reg);
|
cpu_get_fp80(value, (uint16_t*)((char*)value+sizeof(uint64_t)), reg);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case UC_X86_REG_FPSW:
|
case UC_X86_REG_FPSW:
|
||||||
|
@ -197,7 +204,14 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
|
||||||
*(uint16_t*) value = fptag;
|
*(uint16_t*) value = fptag;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case UC_X86_REG_XMM0 ... UC_X86_REG_XMM7:
|
case UC_X86_REG_XMM0:
|
||||||
|
case UC_X86_REG_XMM1:
|
||||||
|
case UC_X86_REG_XMM2:
|
||||||
|
case UC_X86_REG_XMM3:
|
||||||
|
case UC_X86_REG_XMM4:
|
||||||
|
case UC_X86_REG_XMM5:
|
||||||
|
case UC_X86_REG_XMM6:
|
||||||
|
case UC_X86_REG_XMM7:
|
||||||
{
|
{
|
||||||
float64 *dst = (float64*)value;
|
float64 *dst = (float64*)value;
|
||||||
XMMReg *reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_XMM0];
|
XMMReg *reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_XMM0];
|
||||||
|
@ -234,10 +248,21 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
|
||||||
switch(regid) {
|
switch(regid) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_CR0 ... UC_X86_REG_CR4:
|
case UC_X86_REG_CR0:
|
||||||
|
case UC_X86_REG_CR1:
|
||||||
|
case UC_X86_REG_CR2:
|
||||||
|
case UC_X86_REG_CR3:
|
||||||
|
case UC_X86_REG_CR4:
|
||||||
*(int32_t *)value = X86_CPU(uc, mycpu)->env.cr[regid - UC_X86_REG_CR0];
|
*(int32_t *)value = X86_CPU(uc, mycpu)->env.cr[regid - UC_X86_REG_CR0];
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_DR0 ... UC_X86_REG_DR7:
|
case UC_X86_REG_DR0:
|
||||||
|
case UC_X86_REG_DR1:
|
||||||
|
case UC_X86_REG_DR2:
|
||||||
|
case UC_X86_REG_DR3:
|
||||||
|
case UC_X86_REG_DR4:
|
||||||
|
case UC_X86_REG_DR5:
|
||||||
|
case UC_X86_REG_DR6:
|
||||||
|
case UC_X86_REG_DR7:
|
||||||
*(int32_t *)value = X86_CPU(uc, mycpu)->env.dr[regid - UC_X86_REG_DR0];
|
*(int32_t *)value = X86_CPU(uc, mycpu)->env.dr[regid - UC_X86_REG_DR0];
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_EFLAGS:
|
case UC_X86_REG_EFLAGS:
|
||||||
|
@ -367,10 +392,21 @@ int x86_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals, int coun
|
||||||
switch(regid) {
|
switch(regid) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_CR0 ... UC_X86_REG_CR4:
|
case UC_X86_REG_CR0:
|
||||||
|
case UC_X86_REG_CR1:
|
||||||
|
case UC_X86_REG_CR2:
|
||||||
|
case UC_X86_REG_CR3:
|
||||||
|
case UC_X86_REG_CR4:
|
||||||
*(int64_t *)value = X86_CPU(uc, mycpu)->env.cr[regid - UC_X86_REG_CR0];
|
*(int64_t *)value = X86_CPU(uc, mycpu)->env.cr[regid - UC_X86_REG_CR0];
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_DR0 ... UC_X86_REG_DR7:
|
case UC_X86_REG_DR0:
|
||||||
|
case UC_X86_REG_DR1:
|
||||||
|
case UC_X86_REG_DR2:
|
||||||
|
case UC_X86_REG_DR3:
|
||||||
|
case UC_X86_REG_DR4:
|
||||||
|
case UC_X86_REG_DR5:
|
||||||
|
case UC_X86_REG_DR6:
|
||||||
|
case UC_X86_REG_DR7:
|
||||||
*(int64_t *)value = X86_CPU(uc, mycpu)->env.dr[regid - UC_X86_REG_DR0];
|
*(int64_t *)value = X86_CPU(uc, mycpu)->env.dr[regid - UC_X86_REG_DR0];
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_EFLAGS:
|
case UC_X86_REG_EFLAGS:
|
||||||
|
@ -647,10 +683,17 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i
|
||||||
switch(regid) {
|
switch(regid) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_FP0 ... UC_X86_REG_FP7:
|
case UC_X86_REG_FP0:
|
||||||
|
case UC_X86_REG_FP1:
|
||||||
|
case UC_X86_REG_FP2:
|
||||||
|
case UC_X86_REG_FP3:
|
||||||
|
case UC_X86_REG_FP4:
|
||||||
|
case UC_X86_REG_FP5:
|
||||||
|
case UC_X86_REG_FP6:
|
||||||
|
case UC_X86_REG_FP7:
|
||||||
{
|
{
|
||||||
uint64_t mant = *(uint64_t*) value;
|
uint64_t mant = *(uint64_t*) value;
|
||||||
uint16_t upper = *(uint16_t*) (value + sizeof(uint64_t));
|
uint16_t upper = *(uint16_t*) ((char*)value + sizeof(uint64_t));
|
||||||
X86_CPU(uc, mycpu)->env.fpregs[regid - UC_X86_REG_FP0].d = cpu_set_fp80(mant, upper);
|
X86_CPU(uc, mycpu)->env.fpregs[regid - UC_X86_REG_FP0].d = cpu_set_fp80(mant, upper);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -676,7 +719,14 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_XMM0 ... UC_X86_REG_XMM7:
|
case UC_X86_REG_XMM0:
|
||||||
|
case UC_X86_REG_XMM1:
|
||||||
|
case UC_X86_REG_XMM2:
|
||||||
|
case UC_X86_REG_XMM3:
|
||||||
|
case UC_X86_REG_XMM4:
|
||||||
|
case UC_X86_REG_XMM5:
|
||||||
|
case UC_X86_REG_XMM6:
|
||||||
|
case UC_X86_REG_XMM7:
|
||||||
{
|
{
|
||||||
float64 *src = (float64*)value;
|
float64 *src = (float64*)value;
|
||||||
XMMReg *reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_XMM0];
|
XMMReg *reg = &X86_CPU(uc, mycpu)->env.xmm_regs[regid - UC_X86_REG_XMM0];
|
||||||
|
@ -714,10 +764,21 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i
|
||||||
switch(regid) {
|
switch(regid) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_CR0 ... UC_X86_REG_CR4:
|
case UC_X86_REG_CR0:
|
||||||
|
case UC_X86_REG_CR1:
|
||||||
|
case UC_X86_REG_CR2:
|
||||||
|
case UC_X86_REG_CR3:
|
||||||
|
case UC_X86_REG_CR4:
|
||||||
X86_CPU(uc, mycpu)->env.cr[regid - UC_X86_REG_CR0] = *(uint32_t *)value;
|
X86_CPU(uc, mycpu)->env.cr[regid - UC_X86_REG_CR0] = *(uint32_t *)value;
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_DR0 ... UC_X86_REG_DR7:
|
case UC_X86_REG_DR0:
|
||||||
|
case UC_X86_REG_DR1:
|
||||||
|
case UC_X86_REG_DR2:
|
||||||
|
case UC_X86_REG_DR3:
|
||||||
|
case UC_X86_REG_DR4:
|
||||||
|
case UC_X86_REG_DR5:
|
||||||
|
case UC_X86_REG_DR6:
|
||||||
|
case UC_X86_REG_DR7:
|
||||||
X86_CPU(uc, mycpu)->env.dr[regid - UC_X86_REG_DR0] = *(uint32_t *)value;
|
X86_CPU(uc, mycpu)->env.dr[regid - UC_X86_REG_DR0] = *(uint32_t *)value;
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_EFLAGS:
|
case UC_X86_REG_EFLAGS:
|
||||||
|
@ -854,10 +915,21 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i
|
||||||
switch(regid) {
|
switch(regid) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_CR0 ... UC_X86_REG_CR4:
|
case UC_X86_REG_CR0:
|
||||||
|
case UC_X86_REG_CR1:
|
||||||
|
case UC_X86_REG_CR2:
|
||||||
|
case UC_X86_REG_CR3:
|
||||||
|
case UC_X86_REG_CR4:
|
||||||
X86_CPU(uc, mycpu)->env.cr[regid - UC_X86_REG_CR0] = *(uint64_t *)value;
|
X86_CPU(uc, mycpu)->env.cr[regid - UC_X86_REG_CR0] = *(uint64_t *)value;
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_DR0 ... UC_X86_REG_DR7:
|
case UC_X86_REG_DR0:
|
||||||
|
case UC_X86_REG_DR1:
|
||||||
|
case UC_X86_REG_DR2:
|
||||||
|
case UC_X86_REG_DR3:
|
||||||
|
case UC_X86_REG_DR4:
|
||||||
|
case UC_X86_REG_DR5:
|
||||||
|
case UC_X86_REG_DR6:
|
||||||
|
case UC_X86_REG_DR7:
|
||||||
X86_CPU(uc, mycpu)->env.dr[regid - UC_X86_REG_DR0] = *(uint64_t *)value;
|
X86_CPU(uc, mycpu)->env.dr[regid - UC_X86_REG_DR0] = *(uint64_t *)value;
|
||||||
break;
|
break;
|
||||||
case UC_X86_REG_EFLAGS:
|
case UC_X86_REG_EFLAGS:
|
||||||
|
@ -1133,7 +1205,7 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, i
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((visibility ("default")))
|
DEFAULT_VISIBILITY
|
||||||
int x86_uc_machine_init(struct uc_struct *uc)
|
int x86_uc_machine_init(struct uc_struct *uc)
|
||||||
{
|
{
|
||||||
return machine_initialize(uc);
|
return machine_initialize(uc);
|
||||||
|
@ -1151,7 +1223,7 @@ static bool x86_stop_interrupt(int intno)
|
||||||
|
|
||||||
void pc_machine_init(struct uc_struct *uc);
|
void pc_machine_init(struct uc_struct *uc);
|
||||||
|
|
||||||
__attribute__ ((visibility ("default")))
|
DEFAULT_VISIBILITY
|
||||||
void x86_uc_init(struct uc_struct* uc)
|
void x86_uc_init(struct uc_struct* uc)
|
||||||
{
|
{
|
||||||
apic_register_types(uc);
|
apic_register_types(uc);
|
||||||
|
|
|
@ -21,10 +21,9 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include "platform.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
|
@ -105,7 +105,7 @@ int m68k_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((visibility ("default")))
|
DEFAULT_VISIBILITY
|
||||||
void m68k_uc_init(struct uc_struct* uc)
|
void m68k_uc_init(struct uc_struct* uc)
|
||||||
{
|
{
|
||||||
register_accel_types(uc);
|
register_accel_types(uc);
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include "platform.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
|
@ -124,7 +124,7 @@ int mips_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((visibility ("default")))
|
DEFAULT_VISIBILITY
|
||||||
#ifdef TARGET_MIPS64
|
#ifdef TARGET_MIPS64
|
||||||
#ifdef TARGET_WORDS_BIGENDIAN
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
void mips64_uc_init(struct uc_struct* uc)
|
void mips64_uc_init(struct uc_struct* uc)
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include "platform.h"
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "exec/helper-proto.h"
|
#include "exec/helper-proto.h"
|
||||||
|
|
|
@ -135,7 +135,7 @@ int sparc_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((visibility ("default")))
|
DEFAULT_VISIBILITY
|
||||||
void sparc_uc_init(struct uc_struct* uc)
|
void sparc_uc_init(struct uc_struct* uc)
|
||||||
{
|
{
|
||||||
register_accel_types(uc);
|
register_accel_types(uc);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue