Skip to content

Commit 1076c28

Browse files
committed
[a64] Remove x64 reference implementations
Removes all comments relating to x64 implementation details
1 parent d4a9a10 commit 1076c28

File tree

5 files changed

+24
-143
lines changed

5 files changed

+24
-143
lines changed

src/xenia/cpu/backend/a64/a64_emitter.cc

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -137,21 +137,11 @@ bool A64Emitter::Emit(GuestFunction* function, HIRBuilder* builder,
137137

138138
void* A64Emitter::Emplace(const EmitFunctionInfo& func_info,
139139
GuestFunction* function) {
140-
// To avoid changing xbyak, we do a switcharoo here.
141-
// top_ points to the Xbyak buffer, and since we are in AutoGrow mode
142-
// it has pending relocations. We copy the top_ to our buffer, swap the
143-
// pointer, relocate, then return the original scratch pointer for use.
144-
// top_ is used by Xbyak's ready() as both write base pointer and the absolute
145-
// address base, which would not work on platforms not supporting writable
146-
// executable memory, but Xenia doesn't use absolute label addresses in the
147-
// generated code.
148-
149-
// uint8_t* old_address = top_;
140+
// Copy the current oaknut instruction-buffer into the code-cache
150141
uint32_t* old_address = CodeBlock::ptr();
151142
void* new_execute_address;
152143
void* new_write_address;
153144

154-
// assert_true(func_info.code_size.total == size_);
155145
assert_true(func_info.code_size.total == offset());
156146

157147
if (function) {
@@ -162,15 +152,9 @@ void* A64Emitter::Emplace(const EmitFunctionInfo& func_info,
162152
code_cache_->PlaceHostCode(0, CodeBlock::ptr(), func_info,
163153
new_execute_address, new_write_address);
164154
}
165-
// top_ = reinterpret_cast<uint8_t*>(new_write_address);
166-
// set_wptr(reinterpret_cast<uint32_t*>(new_write_address));
167155

168-
// ready();
169-
170-
// top_ = old_address;
156+
// Reset the oaknut instruction-buffer
171157
set_wptr(reinterpret_cast<uint32_t*>(old_address));
172-
173-
// reset();
174158
label_lookup_.clear();
175159

176160
return new_execute_address;
@@ -357,7 +341,7 @@ void A64Emitter::MarkSourceOffset(const Instr* i) {
357341
}
358342

359343
void A64Emitter::EmitGetCurrentThreadId() {
360-
// rsi must point to context. We could fetch from the stack if needed.
344+
// X27 must point to context. We could fetch from the stack if needed.
361345
LDRH(W0, GetContextReg(), offsetof(ppc::PPCContext, thread_id));
362346
}
363347

@@ -442,14 +426,11 @@ void A64Emitter::Call(const hir::Instr* instr, GuestFunction* function) {
442426
// TODO(benvanik): is it worth it to do this? It removes the need for
443427
// a ResolveFunction call, but makes the table less useful.
444428
assert_zero(uint64_t(fn->machine_code()) & 0xFFFFFFFF00000000);
445-
// mov(eax, uint32_t(uint64_t(fn->machine_code())));
446429
MOV(X16, uint32_t(uint64_t(fn->machine_code())));
447430
} else if (code_cache_->has_indirection_table()) {
448431
// Load the pointer to the indirection table maintained in A64CodeCache.
449432
// The target dword will either contain the address of the generated code
450433
// or a thunk to ResolveAddress.
451-
// mov(ebx, function->address());
452-
// mov(eax, dword[ebx]);
453434
MOV(W17, function->address());
454435
LDR(W16, X17);
455436
} else {
@@ -476,10 +457,8 @@ void A64Emitter::Call(const hir::Instr* instr, GuestFunction* function) {
476457
BR(X16);
477458
} else {
478459
// Return address is from the previous SET_RETURN_ADDRESS.
479-
// mov(rcx, qword[rsp + StackLayout::GUEST_CALL_RET_ADDR]);
480460
LDR(X0, SP, StackLayout::GUEST_CALL_RET_ADDR);
481461

482-
// call(rax);
483462
BLR(X16);
484463
}
485464
}
@@ -488,8 +467,6 @@ void A64Emitter::CallIndirect(const hir::Instr* instr,
488467
const oaknut::XReg& reg) {
489468
// Check if return.
490469
if (instr->flags & hir::CALL_POSSIBLE_RETURN) {
491-
// cmp(reg.cvt32(), dword[rsp + StackLayout::GUEST_RET_ADDR]);
492-
// je(epilog_label(), CodeGenerator::T_NEAR);
493470
LDR(W16, SP, StackLayout::GUEST_RET_ADDR);
494471
CMP(reg.toW(), W16);
495472
B(oaknut::Cond::EQ, epilog_label());
@@ -622,8 +599,6 @@ void A64Emitter::CallNativeSafe(void* fn) {
622599
}
623600

624601
void A64Emitter::SetReturnAddress(uint64_t value) {
625-
// mov(rax, value);
626-
// mov(qword[rsp + StackLayout::GUEST_CALL_RET_ADDR], rax);
627602
MOV(X0, value);
628603
STR(X0, SP, StackLayout::GUEST_CALL_RET_ADDR);
629604
}

src/xenia/cpu/backend/a64/a64_emitter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ class A64Emitter : public oaknut::CodeBlock, public oaknut::CodeGenerator {
205205

206206
std::byte* GetVConstPtr() const;
207207
std::byte* GetVConstPtr(VConst id) const;
208-
static constexpr uintptr_t GetVConstOffset(VConst id){
208+
static constexpr uintptr_t GetVConstOffset(VConst id) {
209209
return sizeof(vec128_t) * id;
210210
}
211211
void LoadConstantV(oaknut::QReg dest, float v);

src/xenia/cpu/backend/a64/a64_op.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
******************************************************************************
33
* Xenia : Xbox 360 Emulator Research Project *
44
******************************************************************************
5-
* Copyright 2018 Xenia Developers. All rights reserved. *
5+
* Copyright 2024 Xenia Developers. All rights reserved. *
66
* Released under the BSD license - see LICENSE in the root for more details. *
77
******************************************************************************
88
*/

src/xenia/cpu/backend/a64/a64_seq_memory.cc

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,6 @@ struct LOAD_LOCAL_I8
290290
: Sequence<LOAD_LOCAL_I8, I<OPCODE_LOAD_LOCAL, I8Op, I32Op>> {
291291
static void Emit(A64Emitter& e, const EmitArgType& i) {
292292
e.LDRB(i.dest, SP, i.src1.constant());
293-
// e.mov(i.dest, e.byte[e.rsp + i.src1.constant()]);
294293
// e.TraceLoadI8(DATA_LOCAL, i.src1.constant, i.dest);
295294
}
296295
};
@@ -404,7 +403,6 @@ struct LOAD_CONTEXT_I8
404403
: Sequence<LOAD_CONTEXT_I8, I<OPCODE_LOAD_CONTEXT, I8Op, OffsetOp>> {
405404
static void Emit(A64Emitter& e, const EmitArgType& i) {
406405
e.LDRB(i.dest, e.GetContextReg(), i.src1.value);
407-
// e.mov(i.dest, e.byte[addr]);
408406
if (IsTracingData()) {
409407
e.MOV(e.GetNativeParam(0), i.src1.value);
410408
e.LDRB(e.GetNativeParam(1).toW(), e.GetContextReg(), i.src1.value);
@@ -1084,63 +1082,7 @@ struct CACHE_CONTROL
10841082
}
10851083
size_t cache_line_size = i.src2.value;
10861084

1087-
// RegExp addr;
1088-
// uint32_t address_constant;
1089-
// if (i.src1.is_constant) {
1090-
// // TODO(benvanik): figure out how to do this without a temp.
1091-
// // Since the constant is often 0x8... if we tried to use that as a
1092-
// // displacement it would be sign extended and mess things up.
1093-
// address_constant = static_cast<uint32_t>(i.src1.constant());
1094-
// if (address_constant < 0x80000000) {
1095-
// addr = e.GetMembaseReg() + address_constant;
1096-
// } else {
1097-
// if (address_constant >= 0xE0000000 &&
1098-
// xe::memory::allocation_granularity() > 0x1000) {
1099-
// // e.mov(e.eax, address_constant + 0x1000);
1100-
// } else {
1101-
// // e.mov(e.eax, address_constant);
1102-
// }
1103-
// addr = e.GetMembaseReg() + e.rax;
1104-
// }
1105-
// } else {
1106-
// if (xe::memory::allocation_granularity() > 0x1000) {
1107-
// // Emulate the 4 KB physical address offset in 0xE0000000+ when can't
1108-
// do
1109-
// // it via memory mapping.
1110-
// // e.cmp(i.src1.reg().cvt32(), 0xE0000000);
1111-
// // e.setae(e.al);
1112-
// // e.movzx(e.eax, e.al);
1113-
// // e.shl(e.eax, 12);
1114-
// // e.add(e.eax, i.src1.reg().cvt32());
1115-
// } else {
1116-
// // Clear the top 32 bits, as they are likely garbage.
1117-
// // TODO(benvanik): find a way to avoid doing this.
1118-
// // e.mov(e.eax, i.src1.reg().cvt32());
1119-
// }
1120-
// addr = e.GetMembaseReg() + e.rax;
1121-
// }
1122-
// if (is_clflush) {
1123-
// // e.clflush(e.ptr[addr]);
1124-
// }
1125-
// if (is_prefetch) {
1126-
// // e.prefetcht0(e.ptr[addr]);
1127-
// }
1128-
1129-
// if (cache_line_size >= 128) {
1130-
// // Prefetch the other 64 bytes of the 128-byte cache line.
1131-
// if (i.src1.is_constant && address_constant < 0x80000000) {
1132-
// addr = e.GetMembaseReg() + (address_constant ^ 64);
1133-
// } else {
1134-
// // e.xor_(e.eax, 64);
1135-
// }
1136-
// if (is_clflush) {
1137-
// // e.clflush(e.ptr[addr]);
1138-
// }
1139-
// if (is_prefetch) {
1140-
// // e.prefetcht0(e.ptr[addr]);
1141-
// }
1142-
// assert_true(cache_line_size == 128);
1143-
// }
1085+
// TODO(wunkolo): Arm64 cache-control
11441086
}
11451087
};
11461088
EMITTER_OPCODE_TABLE(OPCODE_CACHE_CONTROL, CACHE_CONTROL);
@@ -1151,10 +1093,6 @@ EMITTER_OPCODE_TABLE(OPCODE_CACHE_CONTROL, CACHE_CONTROL);
11511093
struct MEMORY_BARRIER
11521094
: Sequence<MEMORY_BARRIER, I<OPCODE_MEMORY_BARRIER, VoidOp>> {
11531095
static void Emit(A64Emitter& e, const EmitArgType& i) {
1154-
// mfence on x64 flushes all writes before any later instructions
1155-
// e.mfence();
1156-
1157-
// This is equivalent to DMB SY
11581096
e.DMB(BarrierOp::SY);
11591097
}
11601098
};

0 commit comments

Comments
 (0)