Moving alloy/ into xenia/cpu/ to start simplifying things.

This commit is contained in:
Ben Vanik 2015-03-24 07:46:18 -07:00
parent 59395318f3
commit 29912f44c0
519 changed files with 2246 additions and 2296 deletions

View File

@ -1,6 +1,5 @@
All code (headers and sources) lives under this path, excluding third_party code.
* alloy: the dynamic recompiler that parses PPC and generates code.
* poly: a lightweight cross-platform/compiler compatibility library.
* xdb: xenia debugger library and UI.
* xenia: emulator code.

View File

@ -1,29 +0,0 @@
alloy: small dynamic recompiler engine
===
Alloy is a transpiler framework that allows for pluggable frontends for decoding
guest machine instructions (such as PPC) and pluggable backends for generating
host code (such as x64). It features an SSA IR designed to model machine
instructions and vector operations and compilation passes that seek to efficiently
optimize previously-optimized code.
Future versions will cache generated code across runs and enable offline
precompilation.
Frontends
---
Frontends are responsible for translating guest machine instructions into IR.
Information about the guest machine and ABI is used to support efficient CPU
state accesses and debug information.
* PPC64 with Altivec extenions
Backends
---
A backend takes optimized IR and assembles an implementation-specific result.
The backend is also responsible for executing the code it generates and supporting
debugging features (such as breakpoints).
* x64: IA-64 with AVX2 code generator

View File

@ -1,24 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_ALLOY_PRIVATE_H_
#define ALLOY_ALLOY_PRIVATE_H_
#include <gflags/gflags.h>
DECLARE_bool(debug);
DECLARE_bool(always_disasm);
DECLARE_bool(validate_hir);
DECLARE_uint64(break_on_instruction);
DECLARE_uint64(break_on_memory);
DECLARE_bool(break_on_debugbreak);
#endif // ALLOY_ALLOY_PRIVATE_H_

View File

@ -1,35 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "alloy/alloy.h"
#include "alloy/alloy-private.h"
using namespace alloy;
#if 0 && DEBUG
#define DEFAULT_DEBUG_FLAG true
#else
#define DEFAULT_DEBUG_FLAG false
#endif
DEFINE_bool(debug, DEFAULT_DEBUG_FLAG,
"Allow debugging and retain debug information.");
DEFINE_bool(
always_disasm, false,
"Always add debug info to functions, even when no debugger is attached.");
DEFINE_bool(validate_hir, false,
"Perform validation checks on the HIR during compilation.");
// Breakpoints:
DEFINE_uint64(break_on_instruction, 0,
"int3 before the given guest address is executed.");
DEFINE_uint64(break_on_memory, 0,
"int3 on read/write to the given memory address.");
DEFINE_bool(break_on_debugbreak, true, "int3 on JITed __debugbreak requests.");

View File

@ -1,18 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_ALLOY_H_
#define ALLOY_ALLOY_H_
#include "alloy/runtime/function.h"
#include "alloy/runtime/module.h"
#include "alloy/runtime/runtime.h"
#include "alloy/runtime/thread_state.h"
#endif // ALLOY_ALLOY_H_

View File

@ -1,194 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_PPC_PPC_CONTEXT_H_
#define ALLOY_FRONTEND_PPC_PPC_CONTEXT_H_
#include "poly/poly.h"
#include "poly/vec128.h"
namespace alloy { namespace runtime {
class Runtime;
class ThreadState;
} }
namespace alloy {
namespace frontend {
namespace ppc {
using vec128_t = poly::vec128_t;
// Map:
// 0-31: GPR
// 32-63: FPR
// 64: LR
// 65: CTR
// 66: XER
// 67: FPSCR
// 68: VSCR
// 69-76: CR0-7
// 100: invalid
// 128-256: VR
#pragma pack(push, 4)
typedef struct alignas(64) PPCContext_s {
// Must be stored at 0x0 for now.
// TODO(benvanik): find a nice way to describe this to the JIT.
runtime::ThreadState* thread_state;
// TODO(benvanik): this is getting nasty. Must be here.
uint8_t* membase;
// Most frequently used registers first.
uint64_t r[32]; // General purpose registers
uint64_t lr; // Link register
uint64_t ctr; // Count register
// XER register
// Split to make it easier to do individual updates.
uint8_t xer_ca;
uint8_t xer_ov;
uint8_t xer_so;
// Condition registers
// These are split to make it easier to do DCE on unused stores.
union {
uint32_t value;
struct {
uint8_t cr0_lt; // Negative (LT) - result is negative
uint8_t cr0_gt; // Positive (GT) - result is positive (and not zero)
uint8_t cr0_eq; // Zero (EQ) - result is zero or a stwcx/stdcx completed successfully
uint8_t cr0_so; // Summary Overflow (SO) - copy of XER[SO]
};
} cr0;
union {
uint32_t value;
struct {
uint8_t cr1_fx; // FP exception summary - copy of FPSCR[FX]
uint8_t cr1_fex; // FP enabled exception summary - copy of FPSCR[FEX]
uint8_t cr1_vx; // FP invalid operation exception summary - copy of FPSCR[VX]
uint8_t cr1_ox; // FP overflow exception - copy of FPSCR[OX]
};
} cr1;
union {
uint32_t value;
struct {
uint8_t cr2_0; uint8_t cr2_1; uint8_t cr2_2; uint8_t cr2_3;
};
} cr2;
union {
uint32_t value;
struct {
uint8_t cr3_0; uint8_t cr3_1; uint8_t cr3_2; uint8_t cr3_3;
};
} cr3;
union {
uint32_t value;
struct {
uint8_t cr4_0; uint8_t cr4_1; uint8_t cr4_2; uint8_t cr4_3;
};
} cr4;
union {
uint32_t value;
struct {
uint8_t cr5_0; uint8_t cr5_1; uint8_t cr5_2; uint8_t cr5_3;
};
} cr5;
union {
uint32_t value;
struct {
uint8_t cr6_all_equal;
uint8_t cr6_1;
uint8_t cr6_none_equal;
uint8_t cr6_3;
};
} cr6;
union {
uint32_t value;
struct {
uint8_t cr7_0; uint8_t cr7_1; uint8_t cr7_2; uint8_t cr7_3;
};
} cr7;
union {
uint32_t value;
struct {
uint32_t rn :2; // FP rounding control: 00 = nearest
// 01 = toward zero
// 10 = toward +infinity
// 11 = toward -infinity
uint32_t ni :1; // Floating-point non-IEEE mode
uint32_t xe :1; // IEEE floating-point inexact exception enable
uint32_t ze :1; // IEEE floating-point zero divide exception enable
uint32_t ue :1; // IEEE floating-point underflow exception enable
uint32_t oe :1; // IEEE floating-point overflow exception enable
uint32_t ve :1; // FP invalid op exception enable
uint32_t vxcvi :1; // FP invalid op exception: invalid integer convert -- sticky
uint32_t vxsqrt :1; // FP invalid op exception: invalid sqrt -- sticky
uint32_t vxsoft :1; // FP invalid op exception: software request -- sticky
uint32_t reserved :1;
uint32_t fprf_un :1; // FP result unordered or NaN (FU or ?)
uint32_t fprf_eq :1; // FP result equal or zero (FE or =)
uint32_t fprf_gt :1; // FP result greater than or positive (FG or >)
uint32_t fprf_lt :1; // FP result less than or negative (FL or <)
uint32_t fprf_c :1; // FP result class
uint32_t fi :1; // FP fraction inexact
uint32_t fr :1; // FP fraction rounded
uint32_t vxvc :1; // FP invalid op exception: invalid compare -- sticky
uint32_t vximz :1; // FP invalid op exception: infinity * 0 -- sticky
uint32_t vxzdz :1; // FP invalid op exception: 0 / 0 -- sticky
uint32_t vxidi :1; // FP invalid op exception: infinity / infinity -- sticky
uint32_t vxisi :1; // FP invalid op exception: infinity - infinity -- sticky
uint32_t vxsnan :1; // FP invalid op exception: SNaN -- sticky
uint32_t xx :1; // FP inexact exception -- sticky
uint32_t zx :1; // FP zero divide exception -- sticky
uint32_t ux :1; // FP underflow exception -- sticky
uint32_t ox :1; // FP overflow exception -- sticky
uint32_t vx :1; // FP invalid operation exception summary
uint32_t fex :1; // FP enabled exception summary
uint32_t fx :1; // FP exception summary -- sticky
} bits;
} fpscr; // Floating-point status and control register
uint8_t vscr_sat;
double f[32]; // Floating-point registers
vec128_t v[128]; // VMX128 vector registers
// uint32_t get_fprf() {
// return fpscr.value & 0x000F8000;
// }
// void set_fprf(const uint32_t v) {
// fpscr.value = (fpscr.value & ~0x000F8000) | v;
// }
// Thread ID assigned to this context.
uint32_t thread_id;
// Reserve address for load acquire/store release. Shared.
uint64_t* reserve_address;
uint64_t* reserve_value;
// Used to shuttle data into externs. Contents volatile.
uint64_t scratch;
// Runtime-specific data pointer. Used on callbacks to get access to the
// current runtime and its data.
runtime::Runtime* runtime;
void SetRegFromString(const char* name, const char* value);
bool CompareRegWithString(const char* name, const char* value,
char* out_value, size_t out_value_size);
} PPCContext;
#pragma pack(pop)
} // namespace ppc
} // namespace frontend
} // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_CONTEXT_H_

View File

@ -1,76 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "alloy/memory.h"
#include "poly/poly.h"
namespace alloy {
Memory::Memory()
: membase_(nullptr),
reserve_address_(0),
reserve_value_(0),
trace_base_(0) {
system_page_size_ = poly::page_size();
}
Memory::~Memory() = default;
int Memory::Initialize() { return 0; }
void Memory::Zero(uint64_t address, size_t size) {
uint8_t* p = membase_ + address;
memset(p, 0, size);
}
void Memory::Fill(uint64_t address, size_t size, uint8_t value) {
uint8_t* p = membase_ + address;
memset(p, value, size);
}
void Memory::Copy(uint64_t dest, uint64_t src, size_t size) {
uint8_t* pdest = membase_ + dest;
const uint8_t* psrc = membase_ + src;
memcpy(pdest, psrc, size);
}
uint64_t Memory::SearchAligned(uint64_t start, uint64_t end,
const uint32_t* values, size_t value_count) {
assert_true(start <= end);
const uint32_t* p = reinterpret_cast<const uint32_t*>(membase_ + start);
const uint32_t* pe = reinterpret_cast<const uint32_t*>(membase_ + end);
while (p != pe) {
if (*p == values[0]) {
const uint32_t* pc = p + 1;
size_t matched = 1;
for (size_t n = 1; n < value_count; n++, pc++) {
if (*pc != values[n]) {
break;
}
matched++;
}
if (matched == value_count) {
return uint64_t(reinterpret_cast<const uint8_t*>(p) - membase_);
}
}
p++;
}
return 0;
}
SimpleMemory::SimpleMemory(size_t capacity) : memory_(capacity) {
membase_ = reinterpret_cast<uint8_t*>(memory_.data());
reserve_address_ = capacity - 8;
reserve_value_ = capacity - 16;
}
SimpleMemory::~SimpleMemory() = default;
} // namespace alloy

View File

@ -1,62 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef ALLOY_MEMORY_H_
#define ALLOY_MEMORY_H_
#include <cstdint>
#include <vector>
namespace alloy {
class Memory {
public:
Memory();
virtual ~Memory();
inline uint8_t* membase() const { return membase_; }
inline uint8_t* Translate(uint64_t guest_address) const {
return membase_ + guest_address;
};
inline uint64_t* reserve_address() { return &reserve_address_; }
inline uint64_t* reserve_value() { return &reserve_value_; }
uint64_t trace_base() const { return trace_base_; }
void set_trace_base(uint64_t value) { trace_base_ = value; }
virtual int Initialize();
// TODO(benvanik): make poly memory utils for these.
void Zero(uint64_t address, size_t size);
void Fill(uint64_t address, size_t size, uint8_t value);
void Copy(uint64_t dest, uint64_t src, size_t size);
uint64_t SearchAligned(uint64_t start, uint64_t end, const uint32_t* values,
size_t value_count);
protected:
size_t system_page_size_;
uint8_t* membase_;
uint64_t reserve_address_;
uint64_t reserve_value_;
uint64_t trace_base_;
};
class SimpleMemory : public Memory {
public:
SimpleMemory(size_t capacity);
~SimpleMemory() override;
private:
std::vector<uint8_t> memory_;
};
} // namespace alloy
#endif // ALLOY_MEMORY_H_

View File

@ -1,37 +0,0 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'alloy-private.h',
'alloy.cc',
'alloy.h',
'memory.cc',
'memory.h',
],
'conditions': [
['OS == "mac" or OS == "linux"', {
'sources': [
],
}],
['OS == "linux"', {
'sources': [
],
}],
['OS == "mac"', {
'sources': [
],
}],
['OS == "win"', {
'sources': [
],
}],
],
'includes': [
'backend/sources.gypi',
'compiler/sources.gypi',
'frontend/sources.gypi',
'hir/sources.gypi',
'runtime/sources.gypi',
],
}

View File

@ -1,87 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "alloy/test/util.h"
#include <cfloat>
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
using namespace poly;
TEST_CASE("INSERT_INT8", "[instr]") {
for (int i = 0; i < 16; ++i) {
TestFunction test([i](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Insert(LoadVR(b, 4), b.LoadConstant(i),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)));
b.Return();
});
test.Run(
[i](PPCContext* ctx) {
ctx->v[4] =
vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
ctx->r[4] = i;
ctx->r[5] = 100 + i;
},
[i](PPCContext* ctx) {
auto result = ctx->v[3];
auto expected =
vec128b(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
expected.i8[i ^ 0x3] = 100 + i;
REQUIRE(result == expected);
});
}
}
TEST_CASE("INSERT_INT16", "[instr]") {
for (int i = 0; i < 8; ++i) {
TestFunction test([i](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Insert(LoadVR(b, 4), b.LoadConstant(i),
b.Truncate(LoadGPR(b, 5), INT16_TYPE)));
b.Return();
});
test.Run(
[i](PPCContext* ctx) {
ctx->v[4] = vec128s(0, 1, 2, 3, 4, 5, 6, 7);
ctx->r[4] = i;
ctx->r[5] = 100 + i;
},
[i](PPCContext* ctx) {
auto result = ctx->v[3];
auto expected = vec128s(0, 1, 2, 3, 4, 5, 6, 7);
expected.i16[i ^ 0x1] = 100 + i;
REQUIRE(result == expected);
});
}
}
TEST_CASE("INSERT_INT32", "[instr]") {
for (int i = 0; i < 4; ++i) {
TestFunction test([i](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Insert(LoadVR(b, 4), b.LoadConstant(i),
b.Truncate(LoadGPR(b, 5), INT32_TYPE)));
b.Return();
});
test.Run(
[i](PPCContext* ctx) {
ctx->v[4] = vec128i(0, 1, 2, 3);
ctx->r[4] = i;
ctx->r[5] = 100 + i;
},
[i](PPCContext* ctx) {
auto result = ctx->v[3];
auto expected = vec128i(0, 1, 2, 3);
expected.i32[i] = 100 + i;
REQUIRE(result == expected);
});
}
}

View File

@ -1,279 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2014 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "alloy/test/util.h"
using namespace alloy;
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace alloy::test;
using alloy::frontend::ppc::PPCContext;
using namespace poly;
TEST_CASE("SHR_I8", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Shr(b.Truncate(LoadGPR(b, 4), INT8_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xF0;
ctx->r[5] = 4;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0x0F);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0xFF);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xFF;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0x7F);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0x80;
ctx->r[5] = 8;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0x7F;
ctx->r[5] = 7;
},
[](PPCContext* ctx) {
auto result = static_cast<uint8_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("SHR_I16", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Shr(b.Truncate(LoadGPR(b, 4), INT16_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xFF00;
ctx->r[5] = 8;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0x00FF);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xFFFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0xFFFF);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xFFFE;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0x7FFF);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0x8000;
ctx->r[5] = 16;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0x7FFF;
ctx->r[5] = 15;
},
[](PPCContext* ctx) {
auto result = static_cast<uint16_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("SHR_I32", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.ZeroExtend(b.Shr(b.Truncate(LoadGPR(b, 4), INT32_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)),
INT64_TYPE));
b.Return();
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xFFFF0000;
ctx->r[5] = 16;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0x0000FFFF);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFF;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFF);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFE;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0x7FFFFFFF);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0x80000000;
ctx->r[5] = 32;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0x80000000);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0x7FFFFFFF;
ctx->r[5] = 31;
},
[](PPCContext* ctx) {
auto result = static_cast<uint32_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("SHR_I64", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreGPR(b, 3, b.Shr(b.Truncate(LoadGPR(b, 4), INT64_TYPE),
b.Truncate(LoadGPR(b, 5), INT8_TYPE)));
b.Return();
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFF00000000ull;
ctx->r[5] = 32;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0x00000000FFFFFFFFull);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFFFFFFFFFFull;
ctx->r[5] = 0;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0xFFFFFFFFFFFFFFFFull);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0xFFFFFFFFFFFFFFFEull;
ctx->r[5] = 1;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0x7FFFFFFFFFFFFFFFull);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0x8000000000000000ull;
ctx->r[5] = 64;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0x8000000000000000ull);
});
test.Run(
[](PPCContext* ctx) {
ctx->r[4] = 0x7FFFFFFFFFFFFFFFull;
ctx->r[5] = 63;
},
[](PPCContext* ctx) {
auto result = static_cast<uint64_t>(ctx->r[3]);
REQUIRE(result == 0);
});
}
TEST_CASE("SHR_V128", "[instr]") {
TestFunction test([](hir::HIRBuilder& b) {
StoreVR(b, 3, b.Shr(LoadVR(b, 4), b.Truncate(LoadGPR(b, 1), INT8_TYPE)));
b.Return();
});
test.Run(
[](PPCContext* ctx) {
ctx->r[1] = 0;
ctx->v[4] = vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
},
[](PPCContext* ctx) {
auto result1 = ctx->v[3];
REQUIRE(result1 ==
vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF));
});
test.Run(
[](PPCContext* ctx) {
ctx->r[1] = 1;
ctx->v[4] = vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
},
[](PPCContext* ctx) {
auto result1 = ctx->v[3];
REQUIRE(result1 ==
vec128i(0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF));
});
test.Run(
[](PPCContext* ctx) {
ctx->r[1] = 2;
ctx->v[4] = vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
},
[](PPCContext* ctx) {
auto result1 = ctx->v[3];
REQUIRE(result1 ==
vec128i(0x3FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF));
});
test.Run(
[](PPCContext* ctx) {
ctx->r[1] = 8;
ctx->v[4] = vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
},
[](PPCContext* ctx) {
auto result1 = ctx->v[3];
REQUIRE(result1 ==
vec128i(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF));
});
}

View File

@ -7,9 +7,10 @@
******************************************************************************
*/
#include "alloy/backend/assembler.h"
#include "xenia/cpu/backend/assembler.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
Assembler::Assembler(Backend* backend) : backend_(backend) {}
@ -21,4 +22,5 @@ int Assembler::Initialize() { return 0; }
void Assembler::Reset() {}
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#ifndef ALLOY_BACKEND_ASSEMBLER_H_
#define ALLOY_BACKEND_ASSEMBLER_H_
#ifndef XENIA_BACKEND_ASSEMBLER_H_
#define XENIA_BACKEND_ASSEMBLER_H_
#include <memory>
namespace alloy {
namespace xe {
namespace cpu {
namespace hir {
class HIRBuilder;
} // namespace hir
@ -22,9 +23,11 @@ class Function;
class FunctionInfo;
class Runtime;
} // namespace runtime
} // namespace alloy
} // namespace cpu
} // namespace xe
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
class Backend;
@ -49,6 +52,7 @@ class Assembler {
};
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_BACKEND_ASSEMBLER_H_
#endif // XENIA_BACKEND_ASSEMBLER_H_

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#include "alloy/backend/backend.h"
#include "xenia/cpu/backend/backend.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
using alloy::runtime::Runtime;
using xe::cpu::runtime::Runtime;
Backend::Backend(Runtime* runtime) : runtime_(runtime) {
memset(&machine_info_, 0, sizeof(machine_info_));
@ -27,4 +28,5 @@ void* Backend::AllocThreadData() { return nullptr; }
void Backend::FreeThreadData(void* thread_data) {}
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,20 +7,23 @@
******************************************************************************
*/
#ifndef ALLOY_BACKEND_BACKEND_H_
#define ALLOY_BACKEND_BACKEND_H_
#ifndef XENIA_BACKEND_BACKEND_H_
#define XENIA_BACKEND_BACKEND_H_
#include <memory>
#include "alloy/backend/machine_info.h"
#include "xenia/cpu/backend/machine_info.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace runtime {
class Runtime;
} // namespace runtime
} // namespace alloy
} // namespace cpu
} // namespace xe
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
class Assembler;
@ -46,6 +49,7 @@ class Backend {
};
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_BACKEND_BACKEND_H_
#endif // XENIA_BACKEND_BACKEND_H_

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#ifndef ALLOY_BACKEND_MACHINE_INFO_H_
#define ALLOY_BACKEND_MACHINE_INFO_H_
#ifndef XENIA_BACKEND_MACHINE_INFO_H_
#define XENIA_BACKEND_MACHINE_INFO_H_
#include <cstdint>
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
struct MachineInfo {
@ -30,6 +31,7 @@ struct MachineInfo {
};
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_BACKEND_MACHINE_INFO_H_
#endif // XENIA_BACKEND_MACHINE_INFO_H_

View File

@ -7,14 +7,14 @@
******************************************************************************
*/
#include "alloy/backend/x64/x64_assembler.h"
#include "xenia/cpu/backend/x64/x64_assembler.h"
#include "alloy/backend/x64/x64_backend.h"
#include "alloy/backend/x64/x64_emitter.h"
#include "alloy/backend/x64/x64_function.h"
#include "alloy/hir/hir_builder.h"
#include "alloy/hir/label.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/backend/x64/x64_backend.h"
#include "xenia/cpu/backend/x64/x64_emitter.h"
#include "xenia/cpu/backend/x64/x64_function.h"
#include "xenia/cpu/hir/hir_builder.h"
#include "xenia/cpu/hir/label.h"
#include "xenia/cpu/runtime/runtime.h"
#include "poly/reset_scope.h"
#include "xenia/profiling.h"
@ -22,17 +22,18 @@ namespace BE {
#include <beaengine/BeaEngine.h>
} // namespace BE
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::runtime;
using namespace xe::cpu::runtime;
using alloy::hir::HIRBuilder;
using alloy::runtime::DebugInfo;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
using xe::cpu::hir::HIRBuilder;
using xe::cpu::runtime::DebugInfo;
using xe::cpu::runtime::Function;
using xe::cpu::runtime::FunctionInfo;
X64Assembler::X64Assembler(X64Backend* backend)
: Assembler(backend), x64_backend_(backend) {}
@ -64,7 +65,7 @@ int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
uint32_t debug_info_flags,
std::unique_ptr<DebugInfo> debug_info,
uint32_t trace_flags, Function** out_function) {
SCOPE_profile_cpu_f("alloy");
SCOPE_profile_cpu_f("cpu");
// Reset when we leave.
poly::make_reset_scope(this);
@ -130,4 +131,5 @@ void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,15 +7,16 @@
******************************************************************************
*/
#ifndef ALLOY_BACKEND_X64_X64_ASSEMBLER_H_
#define ALLOY_BACKEND_X64_X64_ASSEMBLER_H_
#ifndef XENIA_BACKEND_X64_X64_ASSEMBLER_H_
#define XENIA_BACKEND_X64_X64_ASSEMBLER_H_
#include <memory>
#include "alloy/backend/assembler.h"
#include "xenia/cpu/backend/assembler.h"
#include "poly/string_buffer.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
@ -51,6 +52,7 @@ class X64Assembler : public Assembler {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_BACKEND_X64_X64_ASSEMBLER_H_
#endif // XENIA_BACKEND_X64_X64_ASSEMBLER_H_

View File

@ -7,18 +7,19 @@
******************************************************************************
*/
#include "alloy/backend/x64/x64_backend.h"
#include "xenia/cpu/backend/x64/x64_backend.h"
#include "alloy/backend/x64/x64_assembler.h"
#include "alloy/backend/x64/x64_code_cache.h"
#include "alloy/backend/x64/x64_sequences.h"
#include "alloy/backend/x64/x64_thunk_emitter.h"
#include "xenia/cpu/backend/x64/x64_assembler.h"
#include "xenia/cpu/backend/x64/x64_code_cache.h"
#include "xenia/cpu/backend/x64/x64_sequences.h"
#include "xenia/cpu/backend/x64/x64_thunk_emitter.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
using alloy::runtime::Runtime;
using xe::cpu::runtime::Runtime;
X64Backend::X64Backend(Runtime* runtime) : Backend(runtime), code_cache_(0) {}
@ -62,4 +63,5 @@ std::unique_ptr<Assembler> X64Backend::CreateAssembler() {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,18 +7,19 @@
******************************************************************************
*/
#ifndef ALLOY_BACKEND_X64_X64_BACKEND_H_
#define ALLOY_BACKEND_X64_X64_BACKEND_H_
#ifndef XENIA_BACKEND_X64_X64_BACKEND_H_
#define XENIA_BACKEND_X64_X64_BACKEND_H_
#include "alloy/backend/backend.h"
#include "xenia/cpu/backend/backend.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
class X64CodeCache;
#define ALLOY_HAS_X64_BACKEND 1
#define XENIA_HAS_X64_BACKEND 1
typedef void* (*HostToGuestThunk)(void* target, void* arg0, void* arg1);
typedef void* (*GuestToHostThunk)(void* target, void* arg0, void* arg1);
@ -44,6 +45,7 @@ class X64Backend : public Backend {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_BACKEND_X64_X64_BACKEND_H_
#endif // XENIA_BACKEND_X64_X64_BACKEND_H_

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#ifndef ALLOY_BACKEND_X64_X64_CODE_CACHE_H_
#define ALLOY_BACKEND_X64_X64_CODE_CACHE_H_
#ifndef XENIA_BACKEND_X64_X64_CODE_CACHE_H_
#define XENIA_BACKEND_X64_X64_CODE_CACHE_H_
#include <mutex>
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
@ -41,6 +42,7 @@ class X64CodeCache {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_BACKEND_X64_X64_CODE_CACHE_H_
#endif // XENIA_BACKEND_X64_X64_CODE_CACHE_H_

View File

@ -7,15 +7,15 @@
******************************************************************************
*/
#include <alloy/backend/x64/x64_code_cache.h>
#include "xenia/cpu/backend/x64/x64_code_cache.h"
#include <sys/mman.h>
#include <poly/assert.h>
#include <poly/math.h>
#include <xenia/profiling.h>
#include "poly/assert.h"
#include "poly/math.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
@ -49,8 +49,6 @@ int X64CodeCache::Initialize() { return 0; }
void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size,
size_t stack_size) {
SCOPE_profile_cpu_f("alloy");
// Always move the code to land on 16b alignment. We do this by rounding up
// to 16b so that all offsets are aligned.
code_size = poly::round_up(code_size, 16);
@ -96,4 +94,5 @@ X64CodeChunk::~X64CodeChunk() {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,12 +7,12 @@
******************************************************************************
*/
#include "alloy/backend/x64/x64_code_cache.h"
#include "xenia/cpu/backend/x64/x64_code_cache.h"
#include "poly/poly.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
@ -59,8 +59,6 @@ int X64CodeCache::Initialize() { return 0; }
void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size,
size_t stack_size) {
SCOPE_profile_cpu_f("alloy");
size_t alloc_size = code_size;
// Add unwind info into the allocation size. Keep things 16b aligned.
@ -279,4 +277,5 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size,
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,42 +7,43 @@
******************************************************************************
*/
#include "alloy/backend/x64/x64_emitter.h"
#include "xenia/cpu/backend/x64/x64_emitter.h"
#include "alloy/alloy-private.h"
#include "alloy/backend/x64/x64_backend.h"
#include "alloy/backend/x64/x64_code_cache.h"
#include "alloy/backend/x64/x64_function.h"
#include "alloy/backend/x64/x64_sequences.h"
#include "alloy/backend/x64/x64_thunk_emitter.h"
#include "alloy/hir/hir_builder.h"
#include "alloy/runtime/debug_info.h"
#include "alloy/runtime/runtime.h"
#include "alloy/runtime/symbol_info.h"
#include "alloy/runtime/thread_state.h"
#include "xenia/cpu/backend/x64/x64_backend.h"
#include "xenia/cpu/backend/x64/x64_code_cache.h"
#include "xenia/cpu/backend/x64/x64_function.h"
#include "xenia/cpu/backend/x64/x64_sequences.h"
#include "xenia/cpu/backend/x64/x64_thunk_emitter.h"
#include "xenia/cpu/cpu-private.h"
#include "xenia/cpu/hir/hir_builder.h"
#include "xenia/cpu/runtime/debug_info.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/cpu/runtime/symbol_info.h"
#include "xenia/cpu/runtime/thread_state.h"
#include "poly/vec128.h"
#include "xdb/protocol.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace xe::cpu::hir;
using namespace xe::cpu::runtime;
using poly::vec128b;
using poly::vec128f;
using poly::vec128i;
using namespace Xbyak;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
using alloy::runtime::SourceMapEntry;
using alloy::runtime::ThreadState;
using xe::cpu::hir::HIRBuilder;
using xe::cpu::hir::Instr;
using xe::cpu::runtime::Function;
using xe::cpu::runtime::FunctionInfo;
using xe::cpu::runtime::SourceMapEntry;
using xe::cpu::runtime::ThreadState;
static const size_t MAX_CODE_SIZE = 1 * 1024 * 1024;
@ -77,7 +78,7 @@ int X64Emitter::Initialize() { return 0; }
int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags,
runtime::DebugInfo* debug_info, uint32_t trace_flags,
void*& out_code_address, size_t& out_code_size) {
SCOPE_profile_cpu_f("alloy");
SCOPE_profile_cpu_f("cpu");
// Reset.
if (debug_info_flags & DEBUG_INFO_SOURCE_MAP) {
@ -937,4 +938,5 @@ Address X64Emitter::StashXmm(int index, const Xmm& r) {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,14 +7,15 @@
******************************************************************************
*/
#ifndef ALLOY_BACKEND_X64_X64_EMITTER_H_
#define ALLOY_BACKEND_X64_X64_EMITTER_H_
#ifndef XENIA_BACKEND_X64_X64_EMITTER_H_
#define XENIA_BACKEND_X64_X64_EMITTER_H_
#include "alloy/hir/value.h"
#include "xenia/cpu/hir/value.h"
#include "poly/arena.h"
#include "third_party/xbyak/xbyak/xbyak.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace hir {
class HIRBuilder;
class Instr;
@ -25,9 +26,11 @@ class FunctionInfo;
class Runtime;
class SymbolInfo;
} // namespace runtime
} // namespace alloy
} // namespace cpu
} // namespace xe
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
@ -208,6 +211,7 @@ class X64Emitter : public Xbyak::CodeGenerator {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_BACKEND_X64_X64_EMITTER_H_
#endif // XENIA_BACKEND_X64_X64_EMITTER_H_

View File

@ -7,20 +7,21 @@
******************************************************************************
*/
#include "alloy/backend/x64/x64_function.h"
#include "xenia/cpu/backend/x64/x64_function.h"
#include "alloy/backend/x64/x64_backend.h"
#include "alloy/runtime/runtime.h"
#include "alloy/runtime/thread_state.h"
#include "xenia/cpu/backend/x64/x64_backend.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/cpu/runtime/thread_state.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
using alloy::runtime::Breakpoint;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
using alloy::runtime::ThreadState;
using xe::cpu::runtime::Breakpoint;
using xe::cpu::runtime::Function;
using xe::cpu::runtime::FunctionInfo;
using xe::cpu::runtime::ThreadState;
X64Function::X64Function(FunctionInfo* symbol_info)
: Function(symbol_info), machine_code_(nullptr), code_size_(0) {}
@ -47,4 +48,5 @@ int X64Function::CallImpl(ThreadState* thread_state, uint64_t return_address) {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,13 +7,14 @@
******************************************************************************
*/
#ifndef ALLOY_BACKEND_X64_X64_FUNCTION_H_
#define ALLOY_BACKEND_X64_X64_FUNCTION_H_
#ifndef XENIA_BACKEND_X64_X64_FUNCTION_H_
#define XENIA_BACKEND_X64_X64_FUNCTION_H_
#include "alloy/runtime/function.h"
#include "alloy/runtime/symbol_info.h"
#include "xenia/cpu/runtime/function.h"
#include "xenia/cpu/runtime/symbol_info.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
@ -40,6 +41,7 @@ class X64Function : public runtime::Function {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_BACKEND_X64_X64_FUNCTION_H_
#endif // XENIA_BACKEND_X64_X64_FUNCTION_H_

View File

@ -8,7 +8,7 @@
*/
// A note about vectors:
// Alloy represents vectors as xyzw pairs, with indices 0123.
// Xenia represents vectors as xyzw pairs, with indices 0123.
// XMM registers are xyzw pairs with indices 3210, making them more like wzyx.
// This makes things somewhat confusing. It'd be nice to just shuffle the
// registers around on load/store, however certain operations require that
@ -22,22 +22,23 @@
// load into xmm register:
// [0F 0E 0D 0C] [0B 0A 09 08] [07 06 05 04] [03 02 01 00] (w, z, y, x)
#include "alloy/backend/x64/x64_sequences.h"
#include "xenia/cpu/backend/x64/x64_sequences.h"
#include "alloy/backend/x64/x64_emitter.h"
#include "alloy/backend/x64/x64_tracers.h"
#include "alloy/hir/hir_builder.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/backend/x64/x64_emitter.h"
#include "xenia/cpu/backend/x64/x64_tracers.h"
#include "xenia/cpu/hir/hir_builder.h"
#include "xenia/cpu/runtime/runtime.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
using namespace Xbyak;
// TODO(benvanik): direct usings.
using namespace alloy::hir;
using namespace alloy::runtime;
using namespace xe::cpu::hir;
using namespace xe::cpu::runtime;
using poly::vec128b;
@ -45,7 +46,7 @@ typedef bool (*SequenceSelectFn)(X64Emitter&, const Instr*, const Instr**);
std::unordered_multimap<uint32_t, SequenceSelectFn> sequence_table;
// Utilities/types used only in this file:
#include "alloy/backend/x64/x64_sequence.inl"
#include "xenia/cpu/backend/x64/x64_sequence.inl"
// Selects the right byte/word/etc from a vector. We need to flip logical
// indices (0,1,2,3,4,5,6,7,...) = (3,2,1,0,7,6,5,4,...)
@ -5882,4 +5883,5 @@ bool SelectSequence(X64Emitter& e, const Instr* i, const Instr** new_tail) {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,16 +7,19 @@
******************************************************************************
*/
#ifndef ALLOY_BACKEND_X64_X64_SEQUENCES_H_
#define ALLOY_BACKEND_X64_X64_SEQUENCES_H_
#ifndef XENIA_BACKEND_X64_X64_SEQUENCES_H_
#define XENIA_BACKEND_X64_X64_SEQUENCES_H_
namespace alloy {
namespace xe {
namespace cpu {
namespace hir {
class Instr;
} // namespace hir
} // namespace alloy
} // namespace cpu
} // namespace xe
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
@ -28,6 +31,7 @@ bool SelectSequence(X64Emitter& e, const hir::Instr* i,
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_BACKEND_X64_X64_SEQUENCES_H_
#endif // XENIA_BACKEND_X64_X64_SEQUENCES_H_

View File

@ -7,11 +7,12 @@
******************************************************************************
*/
#include "alloy/backend/x64/x64_thunk_emitter.h"
#include "xenia/cpu/backend/x64/x64_thunk_emitter.h"
#include "third_party/xbyak/xbyak/xbyak.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
@ -142,4 +143,5 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,13 +7,14 @@
******************************************************************************
*/
#ifndef ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_
#define ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_
#ifndef XENIA_BACKEND_X64_X64_THUNK_EMITTER_H_
#define XENIA_BACKEND_X64_X64_THUNK_EMITTER_H_
#include "alloy/backend/x64/x64_backend.h"
#include "alloy/backend/x64/x64_emitter.h"
#include "xenia/cpu/backend/x64/x64_backend.h"
#include "xenia/cpu/backend/x64/x64_emitter.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
@ -136,6 +137,7 @@ class X64ThunkEmitter : public X64Emitter {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_
#endif // XENIA_BACKEND_X64_X64_THUNK_EMITTER_H_

View File

@ -7,17 +7,18 @@
******************************************************************************
*/
#include "alloy/backend/x64/x64_tracers.h"
#include "xenia/cpu/backend/x64/x64_tracers.h"
#include "alloy/backend/x64/x64_emitter.h"
#include "alloy/runtime/runtime.h"
#include "alloy/runtime/thread_state.h"
#include "xenia/cpu/backend/x64/x64_emitter.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/cpu/runtime/thread_state.h"
using namespace alloy;
using namespace alloy::backend::x64;
using namespace alloy::runtime;
using namespace xe;
using namespace xe::cpu::backend::x64;
using namespace xe::cpu::runtime;
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
@ -197,4 +198,5 @@ void TraceMemoryStoreV128(void* raw_context, uint32_t address, __m128 value) {
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,13 +7,14 @@
******************************************************************************
*/
#ifndef ALLOY_BACKEND_X64_X64_TRACERS_H_
#define ALLOY_BACKEND_X64_X64_TRACERS_H_
#ifndef XENIA_BACKEND_X64_X64_TRACERS_H_
#define XENIA_BACKEND_X64_X64_TRACERS_H_
#include <xmmintrin.h>
#include <cstdint>
namespace alloy {
namespace xe {
namespace cpu {
namespace backend {
namespace x64 {
class X64Emitter;
@ -65,6 +66,7 @@ void TraceMemoryStoreV128(void* raw_context, uint32_t address, __m128 value);
} // namespace x64
} // namespace backend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_BACKEND_X64_X64_TRACERS_H_
#endif // XENIA_BACKEND_X64_X64_TRACERS_H_

View File

@ -7,16 +7,17 @@
******************************************************************************
*/
#include "alloy/compiler/compiler.h"
#include "xenia/cpu/compiler/compiler.h"
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
using alloy::hir::HIRBuilder;
using alloy::runtime::Runtime;
using xe::cpu::hir::HIRBuilder;
using xe::cpu::runtime::Runtime;
Compiler::Compiler(Runtime* runtime) : runtime_(runtime) {}
@ -30,8 +31,6 @@ void Compiler::AddPass(std::unique_ptr<CompilerPass> pass) {
void Compiler::Reset() {}
int Compiler::Compile(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
// TODO(benvanik): sophisticated stuff. Run passes in parallel, run until they
// stop changing things, etc.
for (size_t i = 0; i < passes_.size(); ++i) {
@ -46,4 +45,5 @@ int Compiler::Compile(HIRBuilder* builder) {
}
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,22 +7,25 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_COMPILER_H_
#define ALLOY_COMPILER_COMPILER_H_
#ifndef XENIA_COMPILER_COMPILER_H_
#define XENIA_COMPILER_COMPILER_H_
#include <memory>
#include <vector>
#include "alloy/hir/hir_builder.h"
#include "xenia/cpu/hir/hir_builder.h"
#include "poly/arena.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace runtime {
class Runtime;
} // namespace runtime
} // namespace alloy
} // namespace cpu
} // namespace xe
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
class CompilerPass;
@ -49,6 +52,7 @@ class Compiler {
};
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_COMPILER_H_
#endif // XENIA_COMPILER_COMPILER_H_

View File

@ -7,11 +7,12 @@
******************************************************************************
*/
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
#include "alloy/compiler/compiler.h"
#include "xenia/cpu/compiler/compiler.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
CompilerPass::CompilerPass() : runtime_(0), compiler_(0) {}
@ -29,4 +30,5 @@ poly::Arena* CompilerPass::scratch_arena() const {
}
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,19 +7,22 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_COMPILER_PASS_H_
#define ALLOY_COMPILER_COMPILER_PASS_H_
#ifndef XENIA_COMPILER_COMPILER_PASS_H_
#define XENIA_COMPILER_COMPILER_PASS_H_
#include "alloy/hir/hir_builder.h"
#include "xenia/cpu/hir/hir_builder.h"
#include "poly/arena.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace runtime {
class Runtime;
} // namespace runtime
} // namespace alloy
} // namespace cpu
} // namespace xe
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
class Compiler;
@ -42,6 +45,7 @@ class CompilerPass {
};
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_COMPILER_PASS_H_
#endif // XENIA_COMPILER_COMPILER_PASS_H_

View File

@ -7,21 +7,21 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_COMPILER_PASSES_H_
#define ALLOY_COMPILER_COMPILER_PASSES_H_
#ifndef XENIA_COMPILER_COMPILER_PASSES_H_
#define XENIA_COMPILER_COMPILER_PASSES_H_
#include "alloy/compiler/passes/constant_propagation_pass.h"
#include "alloy/compiler/passes/context_promotion_pass.h"
#include "alloy/compiler/passes/control_flow_analysis_pass.h"
#include "alloy/compiler/passes/control_flow_simplification_pass.h"
#include "alloy/compiler/passes/data_flow_analysis_pass.h"
#include "alloy/compiler/passes/dead_code_elimination_pass.h"
//#include "alloy/compiler/passes/dead_store_elimination_pass.h"
#include "alloy/compiler/passes/finalization_pass.h"
#include "alloy/compiler/passes/register_allocation_pass.h"
#include "alloy/compiler/passes/simplification_pass.h"
#include "alloy/compiler/passes/validation_pass.h"
#include "alloy/compiler/passes/value_reduction_pass.h"
#include "xenia/cpu/compiler/passes/constant_propagation_pass.h"
#include "xenia/cpu/compiler/passes/context_promotion_pass.h"
#include "xenia/cpu/compiler/passes/control_flow_analysis_pass.h"
#include "xenia/cpu/compiler/passes/control_flow_simplification_pass.h"
#include "xenia/cpu/compiler/passes/data_flow_analysis_pass.h"
#include "xenia/cpu/compiler/passes/dead_code_elimination_pass.h"
//#include "xenia/cpu/compiler/passes/dead_store_elimination_pass.h"
#include "xenia/cpu/compiler/passes/finalization_pass.h"
#include "xenia/cpu/compiler/passes/register_allocation_pass.h"
#include "xenia/cpu/compiler/passes/simplification_pass.h"
#include "xenia/cpu/compiler/passes/validation_pass.h"
#include "xenia/cpu/compiler/passes/value_reduction_pass.h"
// TODO:
// - mark_use/mark_set
@ -176,4 +176,4 @@
// reg0 = load_local +123 <-- load inserted
// reg0 = mul reg0, reg1
#endif // ALLOY_COMPILER_COMPILER_PASSES_H_
#endif // XENIA_COMPILER_COMPILER_PASSES_H_

View File

@ -7,30 +7,29 @@
******************************************************************************
*/
#include "alloy/compiler/passes/constant_propagation_pass.h"
#include "xenia/cpu/compiler/passes/constant_propagation_pass.h"
#include "alloy/runtime/function.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/runtime/function.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::HIRBuilder;
using alloy::hir::TypeName;
using alloy::hir::Value;
using xe::cpu::hir::HIRBuilder;
using xe::cpu::hir::TypeName;
using xe::cpu::hir::Value;
ConstantPropagationPass::ConstantPropagationPass() : CompilerPass() {}
ConstantPropagationPass::~ConstantPropagationPass() {}
int ConstantPropagationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
// Once ContextPromotion has run there will likely be a whole slew of
// constants that can be pushed through the function.
// Example:
@ -302,7 +301,8 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) {
break;
// TODO(benvanik): ADD_CARRY (w/ ARITHMETIC_SET_CARRY)
case OPCODE_ADD_CARRY:
if (i->src1.value->IsConstantZero() && i->src2.value->IsConstantZero()) {
if (i->src1.value->IsConstantZero() &&
i->src2.value->IsConstantZero()) {
Value* ca = i->src3.value;
// If carry is set find the DID_CARRY and fix it.
if (!!(i->flags & ARITHMETIC_SET_CARRY)) {
@ -485,4 +485,5 @@ void ConstantPropagationPass::PropagateCarry(Value* v, bool did_carry) {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_PASSES_CONSTANT_PROPAGATION_PASS_H_
#define ALLOY_COMPILER_PASSES_CONSTANT_PROPAGATION_PASS_H_
#ifndef XENIA_COMPILER_PASSES_CONSTANT_PROPAGATION_PASS_H_
#define XENIA_COMPILER_PASSES_CONSTANT_PROPAGATION_PASS_H_
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
@ -29,6 +30,7 @@ class ConstantPropagationPass : public CompilerPass {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_PASSES_CONSTANT_PROPAGATION_PASS_H_
#endif // XENIA_COMPILER_PASSES_CONSTANT_PROPAGATION_PASS_H_

View File

@ -7,29 +7,30 @@
******************************************************************************
*/
#include "alloy/compiler/passes/context_promotion_pass.h"
#include "xenia/cpu/compiler/passes/context_promotion_pass.h"
#include <gflags/gflags.h>
#include "alloy/compiler/compiler.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/compiler/compiler.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/profiling.h"
DEFINE_bool(store_all_context_values, false,
"Don't strip dead context stores to aid in debugging.");
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::frontend::ContextInfo;
using alloy::hir::Block;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::hir::Value;
using xe::cpu::frontend::ContextInfo;
using xe::cpu::hir::Block;
using xe::cpu::hir::HIRBuilder;
using xe::cpu::hir::Instr;
using xe::cpu::hir::Value;
ContextPromotionPass::ContextPromotionPass() : CompilerPass() {}
@ -49,8 +50,6 @@ int ContextPromotionPass::Initialize(Compiler* compiler) {
}
int ContextPromotionPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
// Like mem2reg, but because context memory is unaliasable it's easier to
// check and convert LoadContext/StoreContext into value operations.
// Example of load->value promotion:
@ -147,4 +146,5 @@ void ContextPromotionPass::RemoveDeadStoresBlock(Block* block) {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,10 +7,10 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_
#define ALLOY_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_
#ifndef XENIA_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_
#define XENIA_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
#if XE_COMPILER_MSVC
#pragma warning(push)
@ -23,7 +23,8 @@
#include <llvm/ADT/BitVector.h>
#endif // XE_COMPILER_MSVC
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
@ -47,6 +48,7 @@ class ContextPromotionPass : public CompilerPass {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_
#endif // XENIA_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_

View File

@ -7,30 +7,29 @@
******************************************************************************
*/
#include "alloy/compiler/passes/control_flow_analysis_pass.h"
#include "xenia/cpu/compiler/passes/control_flow_analysis_pass.h"
#include "alloy/backend/backend.h"
#include "alloy/compiler/compiler.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/backend/backend.h"
#include "xenia/cpu/compiler/compiler.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::Edge;
using alloy::hir::HIRBuilder;
using xe::cpu::hir::Edge;
using xe::cpu::hir::HIRBuilder;
ControlFlowAnalysisPass::ControlFlowAnalysisPass() : CompilerPass() {}
ControlFlowAnalysisPass::~ControlFlowAnalysisPass() {}
int ControlFlowAnalysisPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
// Reset edges for all blocks. Needed to be re-runnable.
// Note that this wastes a bunch of arena memory, so we shouldn't
// re-run too often.
@ -77,4 +76,5 @@ int ControlFlowAnalysisPass::Run(HIRBuilder* builder) {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_
#define ALLOY_COMPILER_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_
#ifndef XENIA_COMPILER_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_
#define XENIA_COMPILER_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
@ -28,6 +29,7 @@ class ControlFlowAnalysisPass : public CompilerPass {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_
#endif // XENIA_COMPILER_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_

View File

@ -7,22 +7,23 @@
******************************************************************************
*/
#include "alloy/compiler/passes/control_flow_simplification_pass.h"
#include "xenia/cpu/compiler/passes/control_flow_simplification_pass.h"
#include "alloy/backend/backend.h"
#include "alloy/compiler/compiler.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/backend/backend.h"
#include "xenia/cpu/compiler/compiler.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::Edge;
using alloy::hir::HIRBuilder;
using xe::cpu::hir::Edge;
using xe::cpu::hir::HIRBuilder;
ControlFlowSimplificationPass::ControlFlowSimplificationPass()
: CompilerPass() {}
@ -30,8 +31,6 @@ ControlFlowSimplificationPass::ControlFlowSimplificationPass()
ControlFlowSimplificationPass::~ControlFlowSimplificationPass() {}
int ControlFlowSimplificationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
// Walk backwards and merge blocks if possible.
bool merged_any = false;
auto block = builder->last_block();
@ -58,4 +57,5 @@ int ControlFlowSimplificationPass::Run(HIRBuilder* builder) {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_
#define ALLOY_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_
#ifndef XENIA_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_
#define XENIA_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
@ -28,6 +29,7 @@ class ControlFlowSimplificationPass : public CompilerPass {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_
#endif // XENIA_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_

View File

@ -7,11 +7,11 @@
******************************************************************************
*/
#include "alloy/compiler/passes/data_flow_analysis_pass.h"
#include "xenia/cpu/compiler/passes/data_flow_analysis_pass.h"
#include "alloy/backend/backend.h"
#include "alloy/compiler/compiler.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/backend/backend.h"
#include "xenia/cpu/compiler/compiler.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/profiling.h"
#if XE_COMPILER_MSVC
@ -24,24 +24,23 @@
#include <llvm/ADT/BitVector.h>
#endif // XE_COMPILER_MSVC
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::HIRBuilder;
using alloy::hir::OpcodeSignatureType;
using alloy::hir::Value;
using xe::cpu::hir::HIRBuilder;
using xe::cpu::hir::OpcodeSignatureType;
using xe::cpu::hir::Value;
DataFlowAnalysisPass::DataFlowAnalysisPass() : CompilerPass() {}
DataFlowAnalysisPass::~DataFlowAnalysisPass() {}
int DataFlowAnalysisPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
// Linearize blocks so that we can detect cycles and propagate dependencies.
uint32_t block_count = LinearizeBlocks(builder);
@ -94,10 +93,10 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder,
auto instr = block->instr_head;
while (instr) {
uint32_t signature = instr->opcode->signature;
#define SET_INCOMING_VALUE(v) \
if (v->def && v->def->block != block) { \
incoming_values.set(v->ordinal); \
} \
#define SET_INCOMING_VALUE(v) \
if (v->def && v->def->block != block) { \
incoming_values.set(v->ordinal); \
} \
assert_true(v->ordinal < max_value_estimate); \
value_map[v->ordinal] = v;
if (GET_OPCODE_SIG_TYPE_SRC1(signature) == OPCODE_SIG_TYPE_V) {
@ -208,4 +207,5 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder,
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,33 +7,31 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_PASSES_DATA_FLOW_ANALYSIS_PASS_H_
#define ALLOY_COMPILER_PASSES_DATA_FLOW_ANALYSIS_PASS_H_
#ifndef XENIA_COMPILER_PASSES_DATA_FLOW_ANALYSIS_PASS_H_
#define XENIA_COMPILER_PASSES_DATA_FLOW_ANALYSIS_PASS_H_
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
class DataFlowAnalysisPass : public CompilerPass {
public:
public:
DataFlowAnalysisPass();
~DataFlowAnalysisPass() override;
int Run(hir::HIRBuilder* builder) override;
private:
private:
uint32_t LinearizeBlocks(hir::HIRBuilder* builder);
void AnalyzeFlow(hir::HIRBuilder* builder, uint32_t block_count);
};
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_PASSES_DATA_FLOW_ANALYSIS_PASS_H_
#endif // XENIA_COMPILER_PASSES_DATA_FLOW_ANALYSIS_PASS_H_

View File

@ -7,28 +7,27 @@
******************************************************************************
*/
#include "alloy/compiler/passes/dead_code_elimination_pass.h"
#include "xenia/cpu/compiler/passes/dead_code_elimination_pass.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::hir::Value;
using xe::cpu::hir::HIRBuilder;
using xe::cpu::hir::Instr;
using xe::cpu::hir::Value;
DeadCodeEliminationPass::DeadCodeEliminationPass() : CompilerPass() {}
DeadCodeEliminationPass::~DeadCodeEliminationPass() {}
int DeadCodeEliminationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
// ContextPromotion/DSE will likely leave around a lot of dead statements.
// Code generated for comparison/testing produces many unused statements and
// with proper use analysis it should be possible to remove most of them:
@ -215,4 +214,5 @@ bool DeadCodeEliminationPass::CheckLocalUse(Instr* i) {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,34 +7,32 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_PASSES_DEAD_CODE_ELIMINATION_PASS_H_
#define ALLOY_COMPILER_PASSES_DEAD_CODE_ELIMINATION_PASS_H_
#ifndef XENIA_COMPILER_PASSES_DEAD_CODE_ELIMINATION_PASS_H_
#define XENIA_COMPILER_PASSES_DEAD_CODE_ELIMINATION_PASS_H_
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
class DeadCodeEliminationPass : public CompilerPass {
public:
public:
DeadCodeEliminationPass();
~DeadCodeEliminationPass() override;
int Run(hir::HIRBuilder* builder) override;
private:
private:
void MakeNopRecursive(hir::Instr* i);
void ReplaceAssignment(hir::Instr* i);
bool CheckLocalUse(hir::Instr* i);
};
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_PASSES_DEAD_CODE_ELIMINATION_PASS_H_
#endif // XENIA_COMPILER_PASSES_DEAD_CODE_ELIMINATION_PASS_H_

View File

@ -7,29 +7,28 @@
******************************************************************************
*/
#include "alloy/compiler/passes/finalization_pass.h"
#include "xenia/cpu/compiler/passes/finalization_pass.h"
#include "alloy/backend/backend.h"
#include "alloy/compiler/compiler.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/backend/backend.h"
#include "xenia/cpu/compiler/compiler.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::HIRBuilder;
using xe::cpu::hir::HIRBuilder;
FinalizationPass::FinalizationPass() : CompilerPass() {}
FinalizationPass::~FinalizationPass() {}
int FinalizationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
// Process the HIR and prepare it for lowering.
// After this is done the HIR should be ready for emitting.
@ -71,4 +70,5 @@ int FinalizationPass::Run(HIRBuilder* builder) {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_PASSES_FINALIZATION_PASS_H_
#define ALLOY_COMPILER_PASSES_FINALIZATION_PASS_H_
#ifndef XENIA_COMPILER_PASSES_FINALIZATION_PASS_H_
#define XENIA_COMPILER_PASSES_FINALIZATION_PASS_H_
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
@ -28,6 +29,7 @@ class FinalizationPass : public CompilerPass {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_PASSES_FINALIZATION_PASS_H_
#endif // XENIA_COMPILER_PASSES_FINALIZATION_PASS_H_

View File

@ -7,26 +7,27 @@
******************************************************************************
*/
#include "alloy/compiler/passes/register_allocation_pass.h"
#include "xenia/cpu/compiler/passes/register_allocation_pass.h"
#include <algorithm>
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::backend::MachineInfo;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::hir::OpcodeSignatureType;
using alloy::hir::RegAssignment;
using alloy::hir::TypeName;
using alloy::hir::Value;
using xe::cpu::backend::MachineInfo;
using xe::cpu::hir::HIRBuilder;
using xe::cpu::hir::Instr;
using xe::cpu::hir::OpcodeSignatureType;
using xe::cpu::hir::RegAssignment;
using xe::cpu::hir::TypeName;
using xe::cpu::hir::Value;
#define ASSERT_NO_CYCLES 0
@ -66,8 +67,6 @@ RegisterAllocationPass::~RegisterAllocationPass() {
}
int RegisterAllocationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
// Simple per-block allocator that operates on SSA form.
// Registers do not move across blocks, though this could be
// optimized with some intra-block analysis (dominators/etc).
@ -561,4 +560,5 @@ void RegisterAllocationPass::SortUsageList(Value* value) {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,17 +7,18 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_
#define ALLOY_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_
#ifndef XENIA_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_
#define XENIA_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_
#include <algorithm>
#include <bitset>
#include <vector>
#include "alloy/backend/machine_info.h"
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/backend/machine_info.h"
#include "xenia/cpu/compiler/compiler_pass.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
@ -80,6 +81,7 @@ class RegisterAllocationPass : public CompilerPass {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_
#endif // XENIA_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_

View File

@ -7,28 +7,27 @@
******************************************************************************
*/
#include "alloy/compiler/passes/simplification_pass.h"
#include "xenia/cpu/compiler/passes/simplification_pass.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::hir::Value;
using xe::cpu::hir::HIRBuilder;
using xe::cpu::hir::Instr;
using xe::cpu::hir::Value;
SimplificationPass::SimplificationPass() : CompilerPass() {}
SimplificationPass::~SimplificationPass() {}
int SimplificationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
EliminateConversions(builder);
SimplifyAssignments(builder);
return 0;
@ -170,4 +169,5 @@ Value* SimplificationPass::CheckValue(Value* value) {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_PASSES_SIMPLIFICATION_PASS_H_
#define ALLOY_COMPILER_PASSES_SIMPLIFICATION_PASS_H_
#ifndef XENIA_COMPILER_PASSES_SIMPLIFICATION_PASS_H_
#define XENIA_COMPILER_PASSES_SIMPLIFICATION_PASS_H_
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
@ -34,6 +35,7 @@ class SimplificationPass : public CompilerPass {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_PASSES_SIMPLIFICATION_PASS_H_
#endif // XENIA_COMPILER_PASSES_SIMPLIFICATION_PASS_H_

View File

@ -7,33 +7,32 @@
******************************************************************************
*/
#include "alloy/compiler/passes/validation_pass.h"
#include "xenia/cpu/compiler/passes/validation_pass.h"
#include "alloy/backend/backend.h"
#include "alloy/compiler/compiler.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/backend/backend.h"
#include "xenia/cpu/compiler/compiler.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::Block;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::hir::OpcodeSignatureType;
using alloy::hir::Value;
using xe::cpu::hir::Block;
using xe::cpu::hir::HIRBuilder;
using xe::cpu::hir::Instr;
using xe::cpu::hir::OpcodeSignatureType;
using xe::cpu::hir::Value;
ValidationPass::ValidationPass() : CompilerPass() {}
ValidationPass::~ValidationPass() {}
int ValidationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
#if 0
StringBuffer str;
builder->Dump(&str);
@ -115,4 +114,5 @@ int ValidationPass::ValidateValue(Block* block, Instr* instr, Value* value) {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_PASSES_VALIDATION_PASS_H_
#define ALLOY_COMPILER_PASSES_VALIDATION_PASS_H_
#ifndef XENIA_COMPILER_PASSES_VALIDATION_PASS_H_
#define XENIA_COMPILER_PASSES_VALIDATION_PASS_H_
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
@ -30,6 +31,7 @@ class ValidationPass : public CompilerPass {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_PASSES_VALIDATION_PASS_H_
#endif // XENIA_COMPILER_PASSES_VALIDATION_PASS_H_

View File

@ -7,11 +7,11 @@
******************************************************************************
*/
#include "alloy/compiler/passes/value_reduction_pass.h"
#include "xenia/cpu/compiler/passes/value_reduction_pass.h"
#include "alloy/backend/backend.h"
#include "alloy/compiler/compiler.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/backend/backend.h"
#include "xenia/cpu/compiler/compiler.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/profiling.h"
#if XE_COMPILER_MSVC
@ -24,16 +24,17 @@
#include <llvm/ADT/BitVector.h>
#endif // XE_COMPILER_MSVC
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::HIRBuilder;
using alloy::hir::OpcodeInfo;
using alloy::hir::Value;
using xe::cpu::hir::HIRBuilder;
using xe::cpu::hir::OpcodeInfo;
using xe::cpu::hir::Value;
ValueReductionPass::ValueReductionPass() : CompilerPass() {}
@ -57,8 +58,6 @@ void ValueReductionPass::ComputeLastUse(Value* value) {
}
int ValueReductionPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy");
// Walk each block and reuse variable ordinals as much as possible.
llvm::BitVector ordinals(builder->max_value_ordinal());
@ -144,4 +143,5 @@ int ValueReductionPass::Run(HIRBuilder* builder) {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#ifndef ALLOY_COMPILER_PASSES_VALUE_REDUCTION_PASS_H_
#define ALLOY_COMPILER_PASSES_VALUE_REDUCTION_PASS_H_
#ifndef XENIA_COMPILER_PASSES_VALUE_REDUCTION_PASS_H_
#define XENIA_COMPILER_PASSES_VALUE_REDUCTION_PASS_H_
#include "alloy/compiler/compiler_pass.h"
#include "xenia/cpu/compiler/compiler_pass.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace compiler {
namespace passes {
@ -29,6 +30,7 @@ class ValueReductionPass : public CompilerPass {
} // namespace passes
} // namespace compiler
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_COMPILER_PASSES_VALUE_REDUCTION_PASS_H_
#endif // XENIA_COMPILER_PASSES_VALUE_REDUCTION_PASS_H_

View File

@ -22,4 +22,13 @@ DECLARE_string(load_module_map);
DECLARE_string(dump_path);
DECLARE_bool(dump_module_map);
DECLARE_bool(debug);
DECLARE_bool(always_disasm);
DECLARE_bool(validate_hir);
DECLARE_uint64(break_on_instruction);
DECLARE_uint64(break_on_memory);
DECLARE_bool(break_on_debugbreak);
#endif // XENIA_CPU_PRIVATE_H_

View File

@ -28,3 +28,25 @@ DEFINE_string(dump_path, "build/",
DEFINE_bool(dump_module_bitcode, true,
"Writes the module bitcode both before and after optimizations.");
DEFINE_bool(dump_module_map, true, "Dumps the module symbol database.");
#if 0 && DEBUG
#define DEFAULT_DEBUG_FLAG true
#else
#define DEFAULT_DEBUG_FLAG false
#endif
DEFINE_bool(debug, DEFAULT_DEBUG_FLAG,
"Allow debugging and retain debug information.");
DEFINE_bool(
always_disasm, false,
"Always add debug info to functions, even when no debugger is attached.");
DEFINE_bool(validate_hir, false,
"Perform validation checks on the HIR during compilation.");
// Breakpoints:
DEFINE_uint64(break_on_instruction, 0,
"int3 before the given guest address is executed.");
DEFINE_uint64(break_on_memory, 0,
"int3 on read/write to the given memory address.");
DEFINE_bool(break_on_debugbreak, true, "int3 on JITed __debugbreak requests.");

View File

@ -11,6 +11,10 @@
#define XENIA_CPU_CPU_H_
#include "xenia/cpu/processor.h"
#include "xenia/cpu/runtime/function.h"
#include "xenia/cpu/runtime/module.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/cpu/runtime/thread_state.h"
#include "xenia/cpu/xenon_runtime.h"
#include "xenia/cpu/xenon_thread_state.h"
#include "xenia/cpu/xex_module.h"

View File

@ -7,9 +7,10 @@
******************************************************************************
*/
#include "alloy/frontend/context_info.h"
#include "xenia/cpu/frontend/context_info.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
ContextInfo::ContextInfo(size_t size, uintptr_t thread_state_offset,
@ -21,4 +22,5 @@ ContextInfo::ContextInfo(size_t size, uintptr_t thread_state_offset,
ContextInfo::~ContextInfo() {}
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,13 +7,14 @@
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_CONTEXT_INFO_H_
#define ALLOY_FRONTEND_CONTEXT_INFO_H_
#ifndef XENIA_FRONTEND_CONTEXT_INFO_H_
#define XENIA_FRONTEND_CONTEXT_INFO_H_
#include <cstddef>
#include <cstdint>
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
class ContextInfo {
@ -34,6 +35,7 @@ class ContextInfo {
};
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_FRONTEND_CONTEXT_INFO_H_
#endif // XENIA_FRONTEND_CONTEXT_INFO_H_

View File

@ -7,11 +7,12 @@
******************************************************************************
*/
#include "alloy/frontend/frontend.h"
#include "xenia/cpu/frontend/frontend.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/runtime/runtime.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
Frontend::Frontend(runtime::Runtime* runtime) : runtime_(runtime) {}
@ -23,4 +24,5 @@ Memory* Frontend::memory() const { return runtime_->memory(); }
int Frontend::Initialize() { return 0; }
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,23 +7,26 @@
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_FRONTEND_H_
#define ALLOY_FRONTEND_FRONTEND_H_
#ifndef XENIA_FRONTEND_FRONTEND_H_
#define XENIA_FRONTEND_FRONTEND_H_
#include <memory>
#include "alloy/frontend/context_info.h"
#include "alloy/memory.h"
#include "alloy/runtime/function.h"
#include "alloy/runtime/symbol_info.h"
#include "xenia/cpu/frontend/context_info.h"
#include "xenia/memory.h"
#include "xenia/cpu/runtime/function.h"
#include "xenia/cpu/runtime/symbol_info.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace runtime {
class Runtime;
} // namespace runtime
} // namespace alloy
} // namespace cpu
} // namespace xe
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
class Frontend {
@ -48,6 +51,7 @@ class Frontend {
};
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_FRONTEND_FRONTEND_H_
#endif // XENIA_FRONTEND_FRONTEND_H_

View File

@ -7,11 +7,12 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_context.h"
#include "xenia/cpu/frontend/ppc/ppc_context.h"
#include <cstdlib>
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
@ -19,9 +20,7 @@ uint64_t ParseInt64(const char* value) {
return std::strtoull(value, nullptr, 0);
}
double ParseFloat64(const char* value) {
return std::strtod(value, nullptr);
}
double ParseFloat64(const char* value) { return std::strtod(value, nullptr); }
vec128_t ParseVec128(const char* value) {
vec128_t v;
@ -85,4 +84,5 @@ bool PPCContext::CompareRegWithString(const char* name, const char* value,
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -0,0 +1,227 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2013 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_FRONTEND_PPC_PPC_CONTEXT_H_
#define XENIA_FRONTEND_PPC_PPC_CONTEXT_H_
#include "poly/poly.h"
#include "poly/vec128.h"
namespace xe {
namespace cpu {
namespace runtime {
class Runtime;
class ThreadState;
} // namespace runtime
} // namespace cpu
} // namespace xe
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
using vec128_t = poly::vec128_t;
// Map:
// 0-31: GPR
// 32-63: FPR
// 64: LR
// 65: CTR
// 66: XER
// 67: FPSCR
// 68: VSCR
// 69-76: CR0-7
// 100: invalid
// 128-256: VR
#pragma pack(push, 4)
typedef struct alignas(64) PPCContext_s {
// Must be stored at 0x0 for now.
// TODO(benvanik): find a nice way to describe this to the JIT.
runtime::ThreadState* thread_state;
// TODO(benvanik): this is getting nasty. Must be here.
uint8_t* membase;
// Most frequently used registers first.
uint64_t r[32]; // General purpose registers
uint64_t lr; // Link register
uint64_t ctr; // Count register
// XER register
// Split to make it easier to do individual updates.
uint8_t xer_ca;
uint8_t xer_ov;
uint8_t xer_so;
// Condition registers
// These are split to make it easier to do DCE on unused stores.
union {
uint32_t value;
struct {
uint8_t cr0_lt; // Negative (LT) - result is negative
uint8_t cr0_gt; // Positive (GT) - result is positive (and not zero)
uint8_t cr0_eq; // Zero (EQ) - result is zero or a stwcx/stdcx completed
// successfully
uint8_t cr0_so; // Summary Overflow (SO) - copy of XER[SO]
};
} cr0;
union {
uint32_t value;
struct {
uint8_t cr1_fx; // FP exception summary - copy of FPSCR[FX]
uint8_t cr1_fex; // FP enabled exception summary - copy of FPSCR[FEX]
uint8_t
cr1_vx; // FP invalid operation exception summary - copy of FPSCR[VX]
uint8_t cr1_ox; // FP overflow exception - copy of FPSCR[OX]
};
} cr1;
union {
uint32_t value;
struct {
uint8_t cr2_0;
uint8_t cr2_1;
uint8_t cr2_2;
uint8_t cr2_3;
};
} cr2;
union {
uint32_t value;
struct {
uint8_t cr3_0;
uint8_t cr3_1;
uint8_t cr3_2;
uint8_t cr3_3;
};
} cr3;
union {
uint32_t value;
struct {
uint8_t cr4_0;
uint8_t cr4_1;
uint8_t cr4_2;
uint8_t cr4_3;
};
} cr4;
union {
uint32_t value;
struct {
uint8_t cr5_0;
uint8_t cr5_1;
uint8_t cr5_2;
uint8_t cr5_3;
};
} cr5;
union {
uint32_t value;
struct {
uint8_t cr6_all_equal;
uint8_t cr6_1;
uint8_t cr6_none_equal;
uint8_t cr6_3;
};
} cr6;
union {
uint32_t value;
struct {
uint8_t cr7_0;
uint8_t cr7_1;
uint8_t cr7_2;
uint8_t cr7_3;
};
} cr7;
union {
uint32_t value;
struct {
uint32_t rn : 2; // FP rounding control: 00 = nearest
// 01 = toward zero
// 10 = toward +infinity
// 11 = toward -infinity
uint32_t ni : 1; // Floating-point non-IEEE mode
uint32_t xe : 1; // IEEE floating-point inexact exception enable
uint32_t ze : 1; // IEEE floating-point zero divide exception enable
uint32_t ue : 1; // IEEE floating-point underflow exception enable
uint32_t oe : 1; // IEEE floating-point overflow exception enable
uint32_t ve : 1; // FP invalid op exception enable
uint32_t vxcvi : 1; // FP invalid op exception: invalid integer convert
// -- sticky
uint32_t vxsqrt : 1; // FP invalid op exception: invalid sqrt -- sticky
uint32_t vxsoft : 1; // FP invalid op exception: software request
// -- sticky
uint32_t reserved : 1;
uint32_t fprf_un : 1; // FP result unordered or NaN (FU or ?)
uint32_t fprf_eq : 1; // FP result equal or zero (FE or =)
uint32_t fprf_gt : 1; // FP result greater than or positive (FG or >)
uint32_t fprf_lt : 1; // FP result less than or negative (FL or <)
uint32_t fprf_c : 1; // FP result class
uint32_t fi : 1; // FP fraction inexact
uint32_t fr : 1; // FP fraction rounded
uint32_t vxvc : 1; // FP invalid op exception: invalid compare --
// sticky
uint32_t vximz : 1; // FP invalid op exception: infinity * 0 -- sticky
uint32_t vxzdz : 1; // FP invalid op exception: 0 / 0 -- sticky
uint32_t vxidi : 1; // FP invalid op exception: infinity / infinity
// -- sticky
uint32_t vxisi : 1; // FP invalid op exception: infinity - infinity
// -- sticky
uint32_t vxsnan : 1; // FP invalid op exception: SNaN -- sticky
uint32_t
xx : 1; // FP inexact exception -- sticky
uint32_t
zx : 1; // FP zero divide exception -- sticky
uint32_t
ux : 1; // FP underflow exception -- sticky
uint32_t
ox : 1; // FP overflow exception -- sticky
uint32_t vx : 1; // FP invalid operation exception summary
uint32_t fex : 1; // FP enabled exception summary
uint32_t
fx : 1; // FP exception summary -- sticky
} bits;
} fpscr; // Floating-point status and control register
uint8_t vscr_sat;
double f[32]; // Floating-point registers
vec128_t v[128]; // VMX128 vector registers
// uint32_t get_fprf() {
// return fpscr.value & 0x000F8000;
// }
// void set_fprf(const uint32_t v) {
// fpscr.value = (fpscr.value & ~0x000F8000) | v;
// }
// Thread ID assigned to this context.
uint32_t thread_id;
// Reserve address for load acquire/store release. Shared.
uint64_t* reserve_address;
uint64_t* reserve_value;
// Used to shuttle data into externs. Contents volatile.
uint64_t scratch;
// Runtime-specific data pointer. Used on callbacks to get access to the
// current runtime and its data.
runtime::Runtime* runtime;
void SetRegFromString(const char* name, const char* value);
bool CompareRegWithString(const char* name, const char* value,
char* out_value, size_t out_value_size);
} PPCContext;
#pragma pack(pop)
} // namespace ppc
} // namespace frontend
} // namespace cpu
} // namespace xe
#endif // XENIA_FRONTEND_PPC_PPC_CONTEXT_H_

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_disasm.h"
#include "xenia/cpu/frontend/ppc/ppc_disasm.h"
#include "poly/poly.h"
#include "poly/string_buffer.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
@ -62,41 +63,41 @@ void Disasm_X_FRT_RA0_RB(InstrData& i, poly::StringBuffer* str) {
}
void Disasm_D_RT_RA_I(InstrData& i, poly::StringBuffer* str) {
str->Append("%-8s r%d, r%d, %d", i.type->name, i.D.RT, i.D.RA,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
(int32_t)(int16_t) XEEXTS16(i.D.DS));
}
void Disasm_D_RT_RA0_I(InstrData& i, poly::StringBuffer* str) {
if (i.D.RA) {
str->Append("%-8s r%d, r%d, %d", i.type->name, i.D.RT, i.D.RA,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
(int32_t)(int16_t) XEEXTS16(i.D.DS));
} else {
str->Append("%-8s r%d, 0, %d", i.type->name, i.D.RT,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
(int32_t)(int16_t) XEEXTS16(i.D.DS));
}
}
void Disasm_D_FRT_RA_I(InstrData& i, poly::StringBuffer* str) {
str->Append("%-8s f%d, r%d, %d", i.type->name, i.D.RT, i.D.RA,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
(int32_t)(int16_t) XEEXTS16(i.D.DS));
}
void Disasm_D_FRT_RA0_I(InstrData& i, poly::StringBuffer* str) {
if (i.D.RA) {
str->Append("%-8s f%d, r%d, %d", i.type->name, i.D.RT, i.D.RA,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
(int32_t)(int16_t) XEEXTS16(i.D.DS));
} else {
str->Append("%-8s f%d, 0, %d", i.type->name, i.D.RT,
(int32_t)(int16_t)XEEXTS16(i.D.DS));
(int32_t)(int16_t) XEEXTS16(i.D.DS));
}
}
void Disasm_DS_RT_RA_I(InstrData& i, poly::StringBuffer* str) {
str->Append("%-8s r%d, r%d, %d", i.type->name, i.DS.RT, i.DS.RA,
(int32_t)(int16_t)XEEXTS16(i.DS.DS << 2));
(int32_t)(int16_t) XEEXTS16(i.DS.DS << 2));
}
void Disasm_DS_RT_RA0_I(InstrData& i, poly::StringBuffer* str) {
if (i.DS.RA) {
str->Append("%-8s r%d, r%d, %d", i.type->name, i.DS.RT, i.DS.RA,
(int32_t)(int16_t)XEEXTS16(i.DS.DS << 2));
(int32_t)(int16_t) XEEXTS16(i.DS.DS << 2));
} else {
str->Append("%-8s r%d, 0, %d", i.type->name, i.DS.RT,
(int32_t)(int16_t)XEEXTS16(i.DS.DS << 2));
(int32_t)(int16_t) XEEXTS16(i.DS.DS << 2));
}
}
void Disasm_D_RA(InstrData& i, poly::StringBuffer* str) {
@ -500,4 +501,5 @@ int DisasmPPC(InstrData& i, poly::StringBuffer* str) {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,13 +7,14 @@
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_PPC_PPC_DISASM_H_
#define ALLOY_FRONTEND_PPC_PPC_DISASM_H_
#ifndef XENIA_FRONTEND_PPC_PPC_DISASM_H_
#define XENIA_FRONTEND_PPC_PPC_DISASM_H_
#include "alloy/frontend/ppc/ppc_instr.h"
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
#include "poly/string_buffer.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
@ -21,6 +22,7 @@ int DisasmPPC(InstrData& i, poly::StringBuffer* str);
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_FRONTEND_PPC_PPC_DISASM_H_
#endif // XENIA_FRONTEND_PPC_PPC_DISASM_H_

View File

@ -7,13 +7,14 @@
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_
#define ALLOY_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_
#ifndef XENIA_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_
#define XENIA_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_
#include "alloy/frontend/ppc/ppc_emit.h"
#include "alloy/frontend/ppc/ppc_instr.h"
#include "xenia/cpu/frontend/ppc/ppc_emit.h"
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
@ -28,6 +29,7 @@ namespace ppc {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_
#endif // XENIA_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_

View File

@ -7,12 +7,13 @@
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_PPC_PPC_EMIT_H_
#define ALLOY_FRONTEND_PPC_PPC_EMIT_H_
#ifndef XENIA_FRONTEND_PPC_PPC_EMIT_H_
#define XENIA_FRONTEND_PPC_PPC_EMIT_H_
#include "alloy/frontend/ppc/ppc_instr.h"
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
@ -24,6 +25,7 @@ void RegisterEmitCategoryMemory();
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_FRONTEND_PPC_PPC_EMIT_H_
#endif // XENIA_FRONTEND_PPC_PPC_EMIT_H_

View File

@ -7,23 +7,24 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_emit-private.h"
#include "xenia/cpu/frontend/ppc/ppc_emit-private.h"
#include "alloy/frontend/ppc/ppc_context.h"
#include "alloy/frontend/ppc/ppc_hir_builder.h"
#include "xenia/cpu/frontend/ppc/ppc_context.h"
#include "xenia/cpu/frontend/ppc/ppc_hir_builder.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using poly::vec128b;
using poly::vec128f;
using poly::vec128i;
using poly::vec128s;
using alloy::hir::Value;
using xe::cpu::hir::Value;
Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb);
@ -1462,8 +1463,8 @@ XEEMITTER(vsldoi128, VX128_5(4, 16), VX128_5)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_vslo_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
// (VD) <- (VA) << (VB.b[F] & 0x78) (by octet)
// TODO(benvanik): flag for shift-by-octet as optimization.
Value* sh =
f.And(f.Extract(f.LoadVR(vb), 15, INT8_TYPE), f.LoadConstant(int8_t(0x78)));
Value* sh = f.And(f.Extract(f.LoadVR(vb), 15, INT8_TYPE),
f.LoadConstant(int8_t(0x78)));
Value* v = f.Permute(f.LoadVectorShl(sh), f.LoadVR(va),
f.LoadZero(VEC128_TYPE), INT8_TYPE);
f.StoreVR(vd, v);
@ -1761,7 +1762,8 @@ XEEMITTER(vpkpx, 0x1000030E, VX)(PPCHIRBuilder& f, InstrData& i) {
return 1;
}
int InstrEmit_vpkshss_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
int InstrEmit_vpkshss_(PPCHIRBuilder& f, uint32_t vd, uint32_t va,
uint32_t vb) {
// Vector Pack Signed Halfword Signed Saturate
// Convert VA and VB from signed words to signed saturated bytes then
// concat:
@ -1781,7 +1783,8 @@ XEEMITTER(vpkshss128, VX128(5, 512), VX128)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vpkshss_(f, VX128_VD128, VX128_VA128, VX128_VB128);
}
int InstrEmit_vpkswss_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
int InstrEmit_vpkswss_(PPCHIRBuilder& f, uint32_t vd, uint32_t va,
uint32_t vb) {
// Vector Pack Signed Word Signed Saturate
// Convert VA and VB from signed int words to signed saturated shorts then
// concat:
@ -1801,7 +1804,8 @@ XEEMITTER(vpkswss128, VX128(5, 640), VX128)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vpkswss_(f, VX128_VD128, VX128_VA128, VX128_VB128);
}
int InstrEmit_vpkswus_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
int InstrEmit_vpkswus_(PPCHIRBuilder& f, uint32_t vd, uint32_t va,
uint32_t vb) {
// Vector Pack Signed Word Unsigned Saturate
// Convert VA and VB from signed int words to unsigned saturated shorts then
// concat:
@ -1821,7 +1825,8 @@ XEEMITTER(vpkswus128, VX128(5, 704), VX128)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vpkswus_(f, VX128_VD128, VX128_VA128, VX128_VB128);
}
int InstrEmit_vpkuhum_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
int InstrEmit_vpkuhum_(PPCHIRBuilder& f, uint32_t vd, uint32_t va,
uint32_t vb) {
// Vector Pack Unsigned Halfword Unsigned Modulo
// Convert VA and VB from unsigned shorts to unsigned bytes then concat:
// for each i in VA + VB:
@ -1840,7 +1845,8 @@ XEEMITTER(vpkuhum128, VX128(5, 768), VX128)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vpkuhum_(f, VX128_VD128, VX128_VA128, VX128_VB128);
}
int InstrEmit_vpkuhus_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
int InstrEmit_vpkuhus_(PPCHIRBuilder& f, uint32_t vd, uint32_t va,
uint32_t vb) {
// Vector Pack Unsigned Halfword Unsigned Saturate
// Convert VA and VB from unsigned shorts to unsigned saturated bytes then
// concat:
@ -1860,7 +1866,8 @@ XEEMITTER(vpkuhus128, VX128(5, 832), VX128)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vpkuhus_(f, VX128_VD128, VX128_VA128, VX128_VB128);
}
int InstrEmit_vpkshus_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
int InstrEmit_vpkshus_(PPCHIRBuilder& f, uint32_t vd, uint32_t va,
uint32_t vb) {
// Vector Pack Signed Halfword Unsigned Saturate
// Convert VA and VB from signed shorts to unsigned saturated bytes then
// concat:
@ -1880,7 +1887,8 @@ XEEMITTER(vpkshus128, VX128(5, 576), VX128)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vpkshus_(f, VX128_VD128, VX128_VA128, VX128_VB128);
}
int InstrEmit_vpkuwum_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
int InstrEmit_vpkuwum_(PPCHIRBuilder& f, uint32_t vd, uint32_t va,
uint32_t vb) {
// Vector Pack Unsigned Word Unsigned Modulo
// Concat low shorts from VA + VB:
// for each i in VA + VB:
@ -1899,7 +1907,8 @@ XEEMITTER(vpkuwum128, VX128(5, 896), VX128)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vpkuwum_(f, VX128_VD128, VX128_VA128, VX128_VB128);
}
int InstrEmit_vpkuwus_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
int InstrEmit_vpkuwus_(PPCHIRBuilder& f, uint32_t vd, uint32_t va,
uint32_t vb) {
// Vector Pack Unsigned Word Unsigned Saturate
// Convert VA and VB from unsigned int words to unsigned saturated shorts then
// concat:
@ -1989,7 +1998,8 @@ XEEMITTER(vupkhsb128, VX128(6, 896), VX128)(PPCHIRBuilder& f, InstrData& i) {
int InstrEmit_vupklsb_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) {
// Vector Unpack Low Signed Byte
// bytes 8-15 expanded to halfwords 0-7 and sign extended
Value* v = f.Unpack(f.LoadVR(vb), PACK_TYPE_TO_LO | PACK_TYPE_8_IN_16 |
Value* v =
f.Unpack(f.LoadVR(vb), PACK_TYPE_TO_LO | PACK_TYPE_8_IN_16 |
PACK_TYPE_IN_SIGNED | PACK_TYPE_OUT_SIGNED);
f.StoreVR(vd, v);
return 0;
@ -2400,4 +2410,5 @@ void RegisterEmitCategoryAltivec() {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,19 +7,20 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_emit-private.h"
#include "xenia/cpu/frontend/ppc/ppc_emit-private.h"
#include "alloy/frontend/ppc/ppc_context.h"
#include "alloy/frontend/ppc/ppc_hir_builder.h"
#include "xenia/cpu/frontend/ppc/ppc_context.h"
#include "xenia/cpu/frontend/ppc/ppc_hir_builder.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::Value;
using xe::cpu::hir::Value;
// Integer arithmetic (A-3)
@ -1271,4 +1272,5 @@ void RegisterEmitCategoryALU() {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,20 +7,21 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_emit-private.h"
#include "xenia/cpu/frontend/ppc/ppc_emit-private.h"
#include "alloy/frontend/ppc/ppc_context.h"
#include "alloy/frontend/ppc/ppc_hir_builder.h"
#include "xenia/cpu/frontend/ppc/ppc_context.h"
#include "xenia/cpu/frontend/ppc/ppc_hir_builder.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::Label;
using alloy::hir::Value;
using xe::cpu::hir::Label;
using xe::cpu::hir::Value;
int InstrEmit_branch(PPCHIRBuilder& f, const char* src, uint64_t cia,
Value* nia, bool lk, Value* cond = NULL,
@ -749,4 +750,5 @@ void RegisterEmitCategoryControl() {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,20 +7,21 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_emit-private.h"
#include "xenia/cpu/frontend/ppc/ppc_emit-private.h"
#include "alloy/frontend/ppc/ppc_context.h"
#include "alloy/frontend/ppc/ppc_hir_builder.h"
#include "xenia/cpu/frontend/ppc/ppc_context.h"
#include "xenia/cpu/frontend/ppc/ppc_hir_builder.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::RoundMode;
using alloy::hir::Value;
using xe::cpu::hir::RoundMode;
using xe::cpu::hir::Value;
// Good source of information:
// http://mamedev.org/source/src/emu/cpu/powerpc/ppc_ops.c
@ -257,7 +258,7 @@ XEEMITTER(fmsubsx, 0xEC000038, A)(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fnmaddx, 0xFC00003E, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- -([frA x frC] + frB)
Value* v = f.Neg(
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
@ -271,7 +272,7 @@ XEEMITTER(fnmaddx, 0xFC00003E, A)(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fnmaddsx, 0xEC00003E, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- -([frA x frC] + frB)
Value* v = f.Neg(
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
@ -554,4 +555,5 @@ void RegisterEmitCategoryFPU() {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,19 +7,20 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_emit-private.h"
#include "xenia/cpu/frontend/ppc/ppc_emit-private.h"
#include "alloy/frontend/ppc/ppc_context.h"
#include "alloy/frontend/ppc/ppc_hir_builder.h"
#include "xenia/cpu/frontend/ppc/ppc_context.h"
#include "xenia/cpu/frontend/ppc/ppc_hir_builder.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::Value;
using xe::cpu::hir::Value;
#define TRUNCATE_ADDRESSES 0
@ -1083,4 +1084,5 @@ void RegisterEmitCategoryMemory() {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,21 +7,22 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_frontend.h"
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
#include "alloy/frontend/ppc/ppc_context.h"
#include "alloy/frontend/ppc/ppc_disasm.h"
#include "alloy/frontend/ppc/ppc_emit.h"
#include "alloy/frontend/ppc/ppc_translator.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/frontend/ppc/ppc_context.h"
#include "xenia/cpu/frontend/ppc/ppc_disasm.h"
#include "xenia/cpu/frontend/ppc/ppc_emit.h"
#include "xenia/cpu/frontend/ppc/ppc_translator.h"
#include "xenia/cpu/runtime/runtime.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
using alloy::runtime::Runtime;
using xe::cpu::runtime::Function;
using xe::cpu::runtime::FunctionInfo;
using xe::cpu::runtime::Runtime;
void InitializeIfNeeded();
void CleanupOnShutdown();
@ -103,16 +104,16 @@ int PPCFrontend::DeclareFunction(FunctionInfo* symbol_info) {
}
int PPCFrontend::DefineFunction(FunctionInfo* symbol_info,
uint32_t debug_info_flags,
uint32_t trace_flags,
uint32_t debug_info_flags, uint32_t trace_flags,
Function** out_function) {
PPCTranslator* translator = translator_pool_.Allocate(this);
int result =
translator->Translate(symbol_info, debug_info_flags, trace_flags, out_function);
int result = translator->Translate(symbol_info, debug_info_flags, trace_flags,
out_function);
translator_pool_.Release(translator);
return result;
}
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,15 +7,16 @@
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_PPC_PPC_FRONTEND_H_
#define ALLOY_FRONTEND_PPC_PPC_FRONTEND_H_
#ifndef XENIA_FRONTEND_PPC_PPC_FRONTEND_H_
#define XENIA_FRONTEND_PPC_PPC_FRONTEND_H_
#include <mutex>
#include "alloy/frontend/frontend.h"
#include "xenia/cpu/frontend/frontend.h"
#include "poly/type_pool.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
@ -49,6 +50,7 @@ class PPCFrontend : public Frontend {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_FRONTEND_PPC_PPC_FRONTEND_H_
#endif // XENIA_FRONTEND_PPC_PPC_FRONTEND_H_

View File

@ -7,29 +7,30 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_hir_builder.h"
#include "xenia/cpu/frontend/ppc/ppc_hir_builder.h"
#include "alloy/alloy-private.h"
#include "alloy/frontend/ppc/ppc_context.h"
#include "alloy/frontend/ppc/ppc_disasm.h"
#include "alloy/frontend/ppc/ppc_frontend.h"
#include "alloy/frontend/ppc/ppc_instr.h"
#include "alloy/hir/label.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/cpu-private.h"
#include "xenia/cpu/frontend/ppc/ppc_context.h"
#include "xenia/cpu/frontend/ppc/ppc_disasm.h"
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
#include "xenia/cpu/hir/label.h"
#include "xenia/cpu/runtime/runtime.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace xe::cpu::hir;
using alloy::hir::Label;
using alloy::hir::TypeName;
using alloy::hir::Value;
using alloy::runtime::Runtime;
using alloy::runtime::FunctionInfo;
using xe::cpu::hir::Label;
using xe::cpu::hir::TypeName;
using xe::cpu::hir::Value;
using xe::cpu::runtime::Runtime;
using xe::cpu::runtime::FunctionInfo;
PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend)
: HIRBuilder(), frontend_(frontend), comment_buffer_(4096) {}
@ -45,7 +46,7 @@ void PPCHIRBuilder::Reset() {
}
int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
SCOPE_profile_cpu_f("alloy");
SCOPE_profile_cpu_f("cpu");
Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase();
@ -464,9 +465,8 @@ Value* PPCHIRBuilder::LoadAcquire(Value* address, TypeName type,
Truncate(address, INT32_TYPE));
Value* value = Load(address, type, load_flags);
// Save the value so that we can compare it later in StoreRelease.
AtomicExchange(
LoadContext(offsetof(PPCContext, reserve_value), INT64_TYPE),
value);
AtomicExchange(LoadContext(offsetof(PPCContext, reserve_value), INT64_TYPE),
value);
return value;
}
@ -494,4 +494,5 @@ Value* PPCHIRBuilder::StoreRelease(Value* address, Value* value,
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,24 +7,25 @@
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_
#define ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_
#ifndef XENIA_FRONTEND_PPC_PPC_HIR_BUILDER_H_
#define XENIA_FRONTEND_PPC_PPC_HIR_BUILDER_H_
#include "alloy/hir/hir_builder.h"
#include "alloy/runtime/function.h"
#include "alloy/runtime/symbol_info.h"
#include "xenia/cpu/hir/hir_builder.h"
#include "xenia/cpu/runtime/function.h"
#include "xenia/cpu/runtime/symbol_info.h"
#include "poly/string_buffer.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
class PPCFrontend;
class PPCHIRBuilder : public hir::HIRBuilder {
using Instr = alloy::hir::Instr;
using Label = alloy::hir::Label;
using Value = alloy::hir::Value;
using Instr = xe::cpu::hir::Instr;
using Label = xe::cpu::hir::Label;
using Value = xe::cpu::hir::Value;
public:
PPCHIRBuilder(PPCFrontend* frontend);
@ -113,6 +114,7 @@ class PPCHIRBuilder : public hir::HIRBuilder {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_
#endif // XENIA_FRONTEND_PPC_PPC_HIR_BUILDER_H_

View File

@ -7,16 +7,17 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_instr.h"
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
#include <sstream>
#include <vector>
#include "alloy/frontend/ppc/ppc_instr_tables.h"
#include "xenia/cpu/frontend/ppc/ppc_instr_tables.h"
#include "poly/poly.h"
#include "poly/string_buffer.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
@ -75,14 +76,14 @@ void InstrOperand::Dump(std::string& out_str) {
switch (imm.width) {
case 1:
if (imm.is_signed) {
snprintf(buffer, max_count, "%d", (int32_t)(int8_t)imm.value);
snprintf(buffer, max_count, "%d", (int32_t)(int8_t) imm.value);
} else {
snprintf(buffer, max_count, "0x%.2X", (uint8_t)imm.value);
}
break;
case 2:
if (imm.is_signed) {
snprintf(buffer, max_count, "%d", (int32_t)(int16_t)imm.value);
snprintf(buffer, max_count, "%d", (int32_t)(int16_t) imm.value);
} else {
snprintf(buffer, max_count, "0x%.4X", (uint16_t)imm.value);
}
@ -403,4 +404,5 @@ int RegisterInstrEmit(uint32_t code, InstrEmitFn emit) {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,8 +7,8 @@
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_PPC_PPC_INSTR_H_
#define ALLOY_FRONTEND_PPC_PPC_INSTR_H_
#ifndef XENIA_FRONTEND_PPC_PPC_INSTR_H_
#define XENIA_FRONTEND_PPC_PPC_INSTR_H_
#include <cstdint>
#include <string>
@ -16,7 +16,8 @@
#include "poly/string_buffer.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
@ -59,7 +60,7 @@ typedef enum {
kXEPPCInstrFormatXDSS = 26,
} xe_ppc_instr_format_e;
typedef enum : uint32_t {
enum xe_ppc_instr_mask_e : uint32_t {
kXEPPCInstrMaskVXR = 0xFC0003FF,
kXEPPCInstrMaskVXA = 0xFC00003F,
kXEPPCInstrMaskVX128 = 0xFC0003D0,
@ -70,7 +71,7 @@ typedef enum : uint32_t {
kXEPPCInstrMaskVX128_5 = 0xFC000010,
kXEPPCInstrMaskVX128_P = 0xFC000630,
kXEPPCInstrMaskVX128_R = 0xFC000390,
} xe_ppc_instr_mask_e;
};
typedef enum {
kXEPPCInstrTypeGeneral = (1 << 0),
@ -570,6 +571,7 @@ int RegisterInstrEmit(uint32_t code, InstrEmitFn emit);
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_FRONTEND_PPC_PPC_INSTR_H_
#endif // XENIA_FRONTEND_PPC_PPC_INSTR_H_

View File

@ -7,16 +7,17 @@
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_PPC_PPC_INSTR_TABLES_H_
#define ALLOY_FRONTEND_PPC_PPC_INSTR_TABLES_H_
#ifndef XENIA_FRONTEND_PPC_PPC_INSTR_TABLES_H_
#define XENIA_FRONTEND_PPC_PPC_INSTR_TABLES_H_
#include <cmath>
#include "alloy/frontend/ppc/ppc_instr.h"
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
#include "poly/poly.h"
#include "poly/string_buffer.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
@ -1095,6 +1096,7 @@ static InstrType instr_table_scan[] = {
} // namespace tables
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_FRONTEND_PPC_PPC_INSTR_TABLES_H_
#endif // XENIA_FRONTEND_PPC_PPC_INSTR_TABLES_H_

View File

@ -7,14 +7,14 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_scanner.h"
#include "xenia/cpu/frontend/ppc/ppc_scanner.h"
#include <algorithm>
#include <map>
#include "alloy/frontend/ppc/ppc_frontend.h"
#include "alloy/frontend/ppc/ppc_instr.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
#include "xenia/cpu/runtime/runtime.h"
#include "poly/logging.h"
#include "poly/memory.h"
#include "xenia/profiling.h"
@ -25,11 +25,12 @@
#define LOGPPC(fmt, ...) POLY_EMPTY_MACRO
#endif
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
using alloy::runtime::FunctionInfo;
using xe::cpu::runtime::FunctionInfo;
PPCScanner::PPCScanner(PPCFrontend* frontend) : frontend_(frontend) {}
@ -44,8 +45,6 @@ bool PPCScanner::IsRestGprLr(uint64_t address) {
}
int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
SCOPE_profile_cpu_f("alloy");
// This is a simple basic block analyizer. It walks the start address to the
// end address looking for branches. Each span of instructions between
// branches is considered a basic block. When the last blr (that has no
@ -284,8 +283,6 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
}
std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
SCOPE_profile_cpu_f("alloy");
Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase();
@ -364,4 +361,5 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,14 +7,15 @@
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_PPC_PPC_SCANNER_H_
#define ALLOY_FRONTEND_PPC_PPC_SCANNER_H_
#ifndef XENIA_FRONTEND_PPC_PPC_SCANNER_H_
#define XENIA_FRONTEND_PPC_PPC_SCANNER_H_
#include <vector>
#include "alloy/runtime/symbol_info.h"
#include "xenia/cpu/runtime/symbol_info.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
@ -43,6 +44,7 @@ class PPCScanner {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_FRONTEND_PPC_PPC_SCANNER_H_
#endif // XENIA_FRONTEND_PPC_PPC_SCANNER_H_

View File

@ -7,31 +7,32 @@
******************************************************************************
*/
#include "alloy/frontend/ppc/ppc_translator.h"
#include "xenia/cpu/frontend/ppc/ppc_translator.h"
#include "alloy/alloy-private.h"
#include "alloy/compiler/compiler_passes.h"
#include "alloy/frontend/ppc/ppc_disasm.h"
#include "alloy/frontend/ppc/ppc_frontend.h"
#include "alloy/frontend/ppc/ppc_hir_builder.h"
#include "alloy/frontend/ppc/ppc_instr.h"
#include "alloy/frontend/ppc/ppc_scanner.h"
#include "alloy/runtime/runtime.h"
#include "xenia/cpu/compiler/compiler_passes.h"
#include "xenia/cpu/cpu-private.h"
#include "xenia/cpu/frontend/ppc/ppc_disasm.h"
#include "xenia/cpu/frontend/ppc/ppc_frontend.h"
#include "xenia/cpu/frontend/ppc/ppc_hir_builder.h"
#include "xenia/cpu/frontend/ppc/ppc_instr.h"
#include "xenia/cpu/frontend/ppc/ppc_scanner.h"
#include "xenia/cpu/runtime/runtime.h"
#include "poly/reset_scope.h"
#include "xenia/profiling.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::runtime;
using namespace xe::cpu::runtime;
using alloy::backend::Backend;
using alloy::compiler::Compiler;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
namespace passes = alloy::compiler::passes;
using xe::cpu::backend::Backend;
using xe::cpu::compiler::Compiler;
using xe::cpu::runtime::Function;
using xe::cpu::runtime::FunctionInfo;
namespace passes = xe::cpu::compiler::passes;
PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
Backend* backend = frontend->runtime()->backend();
@ -88,7 +89,7 @@ PPCTranslator::~PPCTranslator() = default;
int PPCTranslator::Translate(FunctionInfo* symbol_info,
uint32_t debug_info_flags, uint32_t trace_flags,
Function** out_function) {
SCOPE_profile_cpu_f("alloy");
SCOPE_profile_cpu_f("cpu");
// Reset() all caching when we leave.
poly::make_reset_scope(builder_);
@ -125,7 +126,7 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
}
if (false) {
alloy::frontend::ppc::DumpAllInstrCounts();
xe::cpu::frontend::ppc::DumpAllInstrCounts();
}
// Emit function.
@ -211,4 +212,5 @@ void PPCTranslator::DumpSource(runtime::FunctionInfo* symbol_info,
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe

View File

@ -7,17 +7,18 @@
******************************************************************************
*/
#ifndef ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_
#define ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_
#ifndef XENIA_FRONTEND_PPC_PPC_TRANSLATOR_H_
#define XENIA_FRONTEND_PPC_PPC_TRANSLATOR_H_
#include <memory>
#include "alloy/backend/assembler.h"
#include "alloy/compiler/compiler.h"
#include "alloy/runtime/symbol_info.h"
#include "xenia/cpu/backend/assembler.h"
#include "xenia/cpu/compiler/compiler.h"
#include "xenia/cpu/runtime/symbol_info.h"
#include "poly/string_buffer.h"
namespace alloy {
namespace xe {
namespace cpu {
namespace frontend {
namespace ppc {
@ -49,6 +50,7 @@ class PPCTranslator {
} // namespace ppc
} // namespace frontend
} // namespace alloy
} // namespace cpu
} // namespace xe
#endif // ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_
#endif // XENIA_FRONTEND_PPC_PPC_TRANSLATOR_H_

View File

@ -1,5 +1,5 @@
/vagrant/src/alloy/frontend/ppc/test/bin//instr_add.o: file format elf64-powerpc
/vagrant/src/xenia/cpu/frontend/ppc/test/bin//instr_add.o: file format elf64-powerpc
Disassembly of section .text:

Some files were not shown because too many files have changed in this diff Show More