fix misleading comments

This commit is contained in:
water 2020-09-02 17:51:42 -04:00
parent ba37e241ce
commit f5a8d3d227
3 changed files with 86 additions and 24 deletions

View file

@ -1,3 +1,11 @@
/*!
* @file CodeTester.cpp
* The CodeTester is a utility to run the output of the compiler as part of a unit test.
* This is effective for tests which try all combinations of registers, etc.
*
* The CodeTester can't be used for tests requiring the full GOAL language/linking.
*/
#include <sys/mman.h>
#include "CodeTester.h"
#include "IGen.h"
@ -6,6 +14,9 @@ namespace emitter {
CodeTester::CodeTester() : m_info(RegisterInfo::make_register_info()) {}
/*!
* Convert to a string for comparison against an assembler or tests.
*/
std::string CodeTester::dump_to_hex_string(bool nospace) {
std::string result;
char buff[32];
@ -26,20 +37,25 @@ std::string CodeTester::dump_to_hex_string(bool nospace) {
return result;
}
/*!
* Add an instruction to the buffer.
*/
void CodeTester::emit(const Instruction& instr) {
code_buffer_size += instr.emit(code_buffer + code_buffer_size);
assert(code_buffer_size <= code_buffer_capacity);
}
void CodeTester::emit_set_gpr_as_return(Register gpr) {
assert(gpr.is_gpr());
emit(IGen::mov_gpr64_gpr64(RAX, gpr));
}
/*!
* Add a return instruction to the buffer.
*/
void CodeTester::emit_return() {
emit(IGen::ret());
}
/*!
* Pop all GPRs off of the stack. Optionally exclude rax.
* Pops RSP always, which is weird, but doesn't cause issues.
*/
void CodeTester::emit_pop_all_gprs(bool exclude_rax) {
for (int i = 16; i-- > 0;) {
if (i != RAX || !exclude_rax) {
@ -48,6 +64,10 @@ void CodeTester::emit_pop_all_gprs(bool exclude_rax) {
}
}
/*!
* Push all GPRs onto the stack. Optionally exclude RAX.
* Pushes RSP always, which is weird, but doesn't cause issues.
*/
void CodeTester::emit_push_all_gprs(bool exclude_rax) {
for (int i = 0; i < 16; i++) {
if (i != RAX || !exclude_rax) {
@ -56,6 +76,9 @@ void CodeTester::emit_push_all_gprs(bool exclude_rax) {
}
}
/*!
* Push all xmm registers (all 128-bits) to the stack.
*/
void CodeTester::emit_push_all_xmms() {
emit(IGen::sub_gpr64_imm8s(RSP, 8));
for (int i = 0; i < 16; i++) {
@ -64,6 +87,9 @@ void CodeTester::emit_push_all_xmms() {
}
}
/*!
* Pop all xmm registers (all 128-bits) from the stack
*/
void CodeTester::emit_pop_all_xmms() {
for (int i = 0; i < 16; i++) {
emit(IGen::load128_xmm128_gpr64(XMM0 + i, RSP));
@ -72,18 +98,31 @@ void CodeTester::emit_pop_all_xmms() {
emit(IGen::add_gpr64_imm8s(RSP, 8));
}
/*!
* Remove everything from the code buffer
*/
void CodeTester::clear() {
code_buffer_size = 0;
}
/*!
* Execute the buffered code with no arguments, return the value of RAX.
*/
u64 CodeTester::execute() {
return ((u64(*)())code_buffer)();
}
/*!
* Execute code buffer with arguments. Use get_c_abi_arg to figure out which registers the
* arguments will appear in (will handle windows/linux differences)
*/
u64 CodeTester::execute(u64 in0, u64 in1, u64 in2, u64 in3) {
return ((u64(*)(u64, u64, u64, u64))code_buffer)(in0, in1, in2, in3);
}
/*!
* Allocate a code buffer of the given size.
*/
void CodeTester::init_code_buffer(int capacity) {
code_buffer = (u8*)mmap(nullptr, capacity, PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);

View file

@ -1,3 +1,11 @@
/*!
* @file CodeTester.h
* The CodeTester is a utility to run the output of the compiler as part of a unit test.
* This is effective for tests which try all combinations of registers, etc.
*
* The CodeTester can't be used for tests requiring the full GOAL language/linking.
*/
#ifndef JAK_CODETESTER_H
#define JAK_CODETESTER_H
@ -17,11 +25,13 @@ class CodeTester {
void emit_push_all_xmms();
void emit_pop_all_xmms();
void emit_return();
void emit_set_gpr_as_return(Register gpr);
void emit(const Instruction& instr);
u64 execute();
u64 execute(u64 in0, u64 in1, u64 in2, u64 in3);
/*!
* Execute the function, get the return value in RAX, convert to a T, and return it.
*/
template <typename T>
T execute_ret(u64 in0, u64 in1, u64 in2, u64 in3) {
u64 result_u64 = ((u64(*)(u64, u64, u64, u64))code_buffer)(in0, in1, in2, in3);
@ -30,6 +40,9 @@ class CodeTester {
return result_T;
}
/*!
* Add data to the code buffer.
*/
template <typename T>
int emit_data(T x) {
auto ret = code_buffer_size;
@ -39,12 +52,8 @@ class CodeTester {
return ret;
}
void clear();
~CodeTester();
/*!
* Should allow emitter tests which run code to do the right thing on windows.
* Assumes RAX is return and RSP is stack pointer.
*/
Register get_c_abi_arg_reg(int i) {
#ifdef _WIN32
@ -76,10 +85,20 @@ class CodeTester {
#endif
}
/*!
* Get the name of the given register, for debugging.
*/
std::string reg_name(Register x) { return m_info.get_info(x).name; }
/*!
* Get number of bytes currently in use (offset of the next thing to be added)
*/
int size() const { return code_buffer_size; }
const u8* data() const { return code_buffer; }
/*!
* Write over existing data at the given offset.
*/
template <typename T>
void write(T x, int at) {
assert(at >= 0);
@ -87,6 +106,9 @@ class CodeTester {
memcpy(code_buffer + at, &x, sizeof(T));
}
/*!
* Read existing data at the given offset.
*/
template <typename T>
T read(int at) {
assert(at >= 0);
@ -96,7 +118,8 @@ class CodeTester {
return result;
}
const u8* data() const { return code_buffer; }
void clear();
~CodeTester();
private:
int code_buffer_size = 0;

View file

@ -16,23 +16,23 @@ namespace emitter {
// registers by name
enum X86_REG : u8 {
RAX, // return, temp
RCX, // arg 3
RDX, // arg 2
RBX, // X saved
RCX, // arg 3, temp
RDX, // arg 2, temp
RBX, // saved
RSP, // stack pointer !!!!
RBP, // saved !!!!
RSI, // arg 1
RDI, // arg 0
RSP, // stack pointer (special)
RBP, // saved
RSI, // arg 1, temp
RDI, // arg 0, temp
R8, // arg 4
R9, // arg 5, saved
R8, // arg 4, temp
R9, // arg 5, temp
R10, // arg 6, saved (arg in GOAL only)
R11, // arg 7, saved (arg in GOAL only)
R12, // X saved - pp register (like s6) !!
R13, // X saved - function call register (like t9) !!
R14, // X saved - offset (added in GOAL x86)
R15, // X saved - st (like s7)
R12, // saved
R13, // pp (special!)
R14, // st (special!)
R15, // offset (special!)
XMM0,
XMM1,
XMM2,