mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 20:44:37 +03:00
Fixed AVX/XOP bugs when encoding instruction that uses register(s) with index greater than 7.
Refactored a bit testing code and added ability to asmjit_test_opcode to use registers having indexes greater than 7.
This commit is contained in:
@@ -37,8 +37,8 @@ script:
|
|||||||
- make
|
- make
|
||||||
- cd ..
|
- cd ..
|
||||||
|
|
||||||
- ./build/asmjit_test
|
- ./build/asmjit_test_unit
|
||||||
- ./build/asmjit_test_x86
|
- ./build/asmjit_test_x86
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then valgrind --leak-check=full --show-reachable=yes ./build/asmjit_test; fi;
|
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then valgrind --leak-check=full --show-reachable=yes ./build/asmjit_test_unit; fi;
|
||||||
|
|||||||
@@ -320,31 +320,31 @@ EndIf()
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
# AsmJit library is always embedded into the tests executable. This way it's
|
# AsmJit library is always embedded into the tests executable. This way it's
|
||||||
# much easier to test private functions compared to just linking to AsmJit.
|
# much easier to test private functions than just linking to `libasmjit.so`.
|
||||||
If(ASMJIT_BUILD_TEST)
|
If(ASMJIT_BUILD_TEST)
|
||||||
AsmJit_AddSource(ASMJIT_TEST_SRC asmjit/test broken.cpp broken.h main.cpp)
|
AsmJit_AddSource(ASMJIT_TEST_SRC test asmjit_test_unit.cpp broken.cpp broken.h)
|
||||||
|
|
||||||
Set(ASMJIT_TEST_CFLAGS
|
Set(ASMJIT_TEST_CFLAGS
|
||||||
${ASMJIT_CFLAGS}
|
${ASMJIT_CFLAGS}
|
||||||
${ASMJIT_DEFINE}ASMJIT_STATIC
|
${ASMJIT_DEFINE}ASMJIT_STATIC
|
||||||
${ASMJIT_DEFINE}ASMJIT_TEST)
|
${ASMJIT_DEFINE}ASMJIT_TEST)
|
||||||
|
|
||||||
Add_Executable(asmjit_test ${ASMJIT_SRC} ${ASMJIT_TEST_SRC})
|
Add_Executable(asmjit_test_unit ${ASMJIT_SRC} ${ASMJIT_TEST_SRC})
|
||||||
Target_Link_Libraries(asmjit_test ${ASMJIT_DEPS})
|
Target_Link_Libraries(asmjit_test_unit ${ASMJIT_DEPS})
|
||||||
|
|
||||||
If(${CMAKE_BUILD_TYPE})
|
If(${CMAKE_BUILD_TYPE})
|
||||||
If(${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
If(${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
||||||
Set_Target_Properties(asmjit_test PROPERTIES COMPILE_FLAGS ${ASMJIT_TEST_CFLAGS} ${ASMJIT_CFLAGS_DBG})
|
Set_Target_Properties(asmjit_test_unit PROPERTIES COMPILE_FLAGS ${ASMJIT_TEST_CFLAGS} ${ASMJIT_CFLAGS_DBG})
|
||||||
Else()
|
Else()
|
||||||
Set_Target_Properties(asmjit_test PROPERTIES COMPILE_FLAGS ${ASMJIT_TEST_CFLAGS} ${ASMJIT_CFLAGS_REL})
|
Set_Target_Properties(asmjit_test_unit PROPERTIES COMPILE_FLAGS ${ASMJIT_TEST_CFLAGS} ${ASMJIT_CFLAGS_REL})
|
||||||
EndIf()
|
EndIf()
|
||||||
Else()
|
Else()
|
||||||
Target_Compile_Options(asmjit_test PUBLIC ${ASMJIT_TEST_CFLAGS}
|
Target_Compile_Options(asmjit_test_unit PUBLIC ${ASMJIT_TEST_CFLAGS}
|
||||||
$<$<CONFIG:Debug>:${ASMJIT_CFLAGS_DBG}>
|
$<$<CONFIG:Debug>:${ASMJIT_CFLAGS_DBG}>
|
||||||
$<$<NOT:$<CONFIG:Debug>>:${ASMJIT_CFLAGS_REL}>)
|
$<$<NOT:$<CONFIG:Debug>>:${ASMJIT_CFLAGS_REL}>)
|
||||||
EndIf()
|
EndIf()
|
||||||
|
|
||||||
Set_Target_Properties(asmjit_test PROPERTIES LINK_FLAGS "${ASMJIT_LFLAGS}")
|
Set_Target_Properties(asmjit_test_unit PROPERTIES LINK_FLAGS "${ASMJIT_LFLAGS}")
|
||||||
EndIf()
|
EndIf()
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -359,7 +359,7 @@ If(ASMJIT_BUILD_SAMPLES)
|
|||||||
)
|
)
|
||||||
|
|
||||||
ForEach(file ${ASMJIT_SRC_SAMPLES})
|
ForEach(file ${ASMJIT_SRC_SAMPLES})
|
||||||
Add_Executable(${file} src/app/test/${file}.cpp)
|
Add_Executable(${file} src/test/${file}.cpp)
|
||||||
Target_Link_Libraries(${file} asmjit ${ASMJIT_DEPS})
|
Target_Link_Libraries(${file} asmjit ${ASMJIT_DEPS})
|
||||||
EndForEach(file)
|
EndForEach(file)
|
||||||
EndIf()
|
EndIf()
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
// [AsmJit]
|
|
||||||
// Complete x86/x64 JIT and Remote Assembler for C++.
|
|
||||||
//
|
|
||||||
// [License]
|
|
||||||
// Zlib - See LICENSE.md file in the package.
|
|
||||||
|
|
||||||
// This file is used to test opcodes generated by AsmJit. Output can be
|
|
||||||
// disassembled in your IDE or by your favourite disassembler. Instructions
|
|
||||||
// are grouped by category and then sorted alphabetically.
|
|
||||||
|
|
||||||
// [Dependencies - AsmJit]
|
|
||||||
#include <asmjit/asmjit.h>
|
|
||||||
|
|
||||||
// [Dependencies - Test]
|
|
||||||
#include "genopcode.h"
|
|
||||||
|
|
||||||
// [Dependencies - C]
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
typedef void (*VoidFunc)(void);
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
using namespace asmjit;
|
|
||||||
using namespace asmjit::host;
|
|
||||||
|
|
||||||
FileLogger logger(stdout);
|
|
||||||
logger.setOption(kLoggerOptionBinaryForm, true);
|
|
||||||
|
|
||||||
JitRuntime runtime;
|
|
||||||
X86Assembler a(&runtime);
|
|
||||||
|
|
||||||
a.setLogger(&logger);
|
|
||||||
asmgen::opcode(a);
|
|
||||||
|
|
||||||
VoidFunc p = asmjit_cast<VoidFunc>(a.make());
|
|
||||||
p();
|
|
||||||
runtime.release((void*)p);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -365,15 +365,15 @@
|
|||||||
//! \brief Contributions.
|
//! \brief Contributions.
|
||||||
|
|
||||||
// [Dependencies - Base]
|
// [Dependencies - Base]
|
||||||
#include "base.h"
|
#include "./base.h"
|
||||||
|
|
||||||
// [Dependencies - X86/X64]
|
// [Dependencies - X86/X64]
|
||||||
#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
|
#if defined(ASMJIT_BUILD_X86) || defined(ASMJIT_BUILD_X64)
|
||||||
#include "x86.h"
|
#include "./x86.h"
|
||||||
#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
|
#endif // ASMJIT_BUILD_X86 || ASMJIT_BUILD_X64
|
||||||
|
|
||||||
// [Dependencies - Host]
|
// [Dependencies - Host]
|
||||||
#include "host.h"
|
#include "./host.h"
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#endif // _ASMJIT_ASMJIT_H
|
#endif // _ASMJIT_ASMJIT_H
|
||||||
|
|||||||
@@ -9,26 +9,26 @@
|
|||||||
#define _ASMJIT_BASE_H
|
#define _ASMJIT_BASE_H
|
||||||
|
|
||||||
// [Dependencies - AsmJit]
|
// [Dependencies - AsmJit]
|
||||||
#include "build.h"
|
#include "./build.h"
|
||||||
|
|
||||||
#include "base/assembler.h"
|
#include "./base/assembler.h"
|
||||||
#include "base/codegen.h"
|
#include "./base/codegen.h"
|
||||||
#include "base/compiler.h"
|
#include "./base/compiler.h"
|
||||||
#include "base/constpool.h"
|
#include "./base/constpool.h"
|
||||||
#include "base/containers.h"
|
#include "./base/containers.h"
|
||||||
#include "base/cpuinfo.h"
|
#include "./base/cpuinfo.h"
|
||||||
#include "base/cputicks.h"
|
#include "./base/cputicks.h"
|
||||||
#include "base/error.h"
|
#include "./base/error.h"
|
||||||
#include "base/globals.h"
|
#include "./base/globals.h"
|
||||||
#include "base/intutil.h"
|
#include "./base/intutil.h"
|
||||||
#include "base/lock.h"
|
#include "./base/lock.h"
|
||||||
#include "base/logger.h"
|
#include "./base/logger.h"
|
||||||
#include "base/operand.h"
|
#include "./base/operand.h"
|
||||||
#include "base/runtime.h"
|
#include "./base/runtime.h"
|
||||||
#include "base/string.h"
|
#include "./base/string.h"
|
||||||
#include "base/vectypes.h"
|
#include "./base/vectypes.h"
|
||||||
#include "base/vmem.h"
|
#include "./base/vmem.h"
|
||||||
#include "base/zone.h"
|
#include "./base/zone.h"
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#endif // _ASMJIT_BASE_H
|
#endif // _ASMJIT_BASE_H
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ typedef unsigned __int64 uint64_t;
|
|||||||
|
|
||||||
// Include a unit testing package if this is a `asmjit_test` build.
|
// Include a unit testing package if this is a `asmjit_test` build.
|
||||||
#if defined(ASMJIT_TEST)
|
#if defined(ASMJIT_TEST)
|
||||||
#include "./test/broken.h"
|
#include "../test/broken.h"
|
||||||
#endif // ASMJIT_TEST
|
#endif // ASMJIT_TEST
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
#define _ASMJIT_HOST_H
|
#define _ASMJIT_HOST_H
|
||||||
|
|
||||||
// [Dependencies - Core]
|
// [Dependencies - Core]
|
||||||
#include "base.h"
|
#include "./base.h"
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [asmjit::host - X86 / X64]
|
// [asmjit::host - X86 / X64]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64)
|
#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64)
|
||||||
#include "x86.h"
|
#include "./x86.h"
|
||||||
|
|
||||||
namespace asmjit {
|
namespace asmjit {
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
#define _ASMJIT_X86_H
|
#define _ASMJIT_X86_H
|
||||||
|
|
||||||
// [Dependencies - AsmJit]
|
// [Dependencies - AsmJit]
|
||||||
#include "base.h"
|
#include "./base.h"
|
||||||
|
|
||||||
#include "x86/x86assembler.h"
|
#include "./x86/x86assembler.h"
|
||||||
#include "x86/x86compiler.h"
|
#include "./x86/x86compiler.h"
|
||||||
#include "x86/x86cpuinfo.h"
|
#include "./x86/x86cpuinfo.h"
|
||||||
#include "x86/x86inst.h"
|
#include "./x86/x86inst.h"
|
||||||
#include "x86/x86operand.h"
|
#include "./x86/x86operand.h"
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#endif // _ASMJIT_X86_H
|
#endif // _ASMJIT_X86_H
|
||||||
|
|||||||
@@ -155,11 +155,17 @@ static ASMJIT_INLINE bool x86RexIsInvalid(uint32_t rex) {
|
|||||||
|
|
||||||
//! Encode ModR/M.
|
//! Encode ModR/M.
|
||||||
static ASMJIT_INLINE uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm) {
|
static ASMJIT_INLINE uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm) {
|
||||||
|
ASMJIT_ASSERT(m <= 7);
|
||||||
|
ASMJIT_ASSERT(o <= 7);
|
||||||
|
ASMJIT_ASSERT(rm <= 7);
|
||||||
return (m << 6) + (o << 3) + rm;
|
return (m << 6) + (o << 3) + rm;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Encode SIB.
|
//! Encode SIB.
|
||||||
static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) {
|
static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) {
|
||||||
|
ASMJIT_ASSERT(s <= 7);
|
||||||
|
ASMJIT_ASSERT(i <= 7);
|
||||||
|
ASMJIT_ASSERT(b <= 7);
|
||||||
return (s << 6) + (i << 3) + b;
|
return (s << 6) + (i << 3) + b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +193,7 @@ static ASMJIT_INLINE uint32_t x86RegAndVvvv(uint32_t regIndex, uint32_t vvvvInde
|
|||||||
|
|
||||||
//! Get `O` field of `opCode`.
|
//! Get `O` field of `opCode`.
|
||||||
static ASMJIT_INLINE uint32_t x86ExtractO(uint32_t opCode) {
|
static ASMJIT_INLINE uint32_t x86ExtractO(uint32_t opCode) {
|
||||||
return (opCode >> kX86InstOpCode_O_Shift) & 0x7;
|
return (opCode >> kX86InstOpCode_O_Shift) & 0x07;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -1429,7 +1435,7 @@ _Prepare:
|
|||||||
// INC r16|r32 is not encodable in 64-bit mode.
|
// INC r16|r32 is not encodable in 64-bit mode.
|
||||||
if (Arch == kArchX86 && (o0->getSize() == 2 || o0->getSize() == 4)) {
|
if (Arch == kArchX86 && (o0->getSize() == 2 || o0->getSize() == 4)) {
|
||||||
opCode &= kX86InstOpCode_PP_66 | kX86InstOpCode_W;
|
opCode &= kX86InstOpCode_PP_66 | kX86InstOpCode_W;
|
||||||
opCode |= extendedInfo.getSecondaryOpCode() + (static_cast<uint32_t>(rmReg) & 0x7);
|
opCode |= extendedInfo.getSecondaryOpCode() + (static_cast<uint32_t>(rmReg) & 0x07);
|
||||||
goto _EmitX86Op;
|
goto _EmitX86Op;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -3493,7 +3499,7 @@ _EmitX86OpWithOpReg:
|
|||||||
|
|
||||||
if (rex & ~static_cast<uint32_t>(_kX86InstOptionNoRex)) {
|
if (rex & ~static_cast<uint32_t>(_kX86InstOptionNoRex)) {
|
||||||
rex |= kX86ByteRex;
|
rex |= kX86ByteRex;
|
||||||
opReg &= 0x7;
|
opReg &= 0x07;
|
||||||
EMIT_BYTE(rex);
|
EMIT_BYTE(rex);
|
||||||
|
|
||||||
if (x86RexIsInvalid(rex))
|
if (x86RexIsInvalid(rex))
|
||||||
@@ -3524,8 +3530,8 @@ _EmitX86R:
|
|||||||
|
|
||||||
if (rex & ~static_cast<uint32_t>(_kX86InstOptionNoRex)) {
|
if (rex & ~static_cast<uint32_t>(_kX86InstOptionNoRex)) {
|
||||||
rex |= kX86ByteRex;
|
rex |= kX86ByteRex;
|
||||||
opReg &= 0x7;
|
opReg &= 0x07;
|
||||||
rmReg &= 0x7;
|
rmReg &= 0x07;
|
||||||
EMIT_BYTE(rex);
|
EMIT_BYTE(rex);
|
||||||
|
|
||||||
if (x86RexIsInvalid(rex))
|
if (x86RexIsInvalid(rex))
|
||||||
@@ -3582,14 +3588,14 @@ _EmitX86M:
|
|||||||
|
|
||||||
if (rex & ~static_cast<uint32_t>(_kX86InstOptionNoRex)) {
|
if (rex & ~static_cast<uint32_t>(_kX86InstOptionNoRex)) {
|
||||||
rex |= kX86ByteRex;
|
rex |= kX86ByteRex;
|
||||||
opReg &= 0x7;
|
opReg &= 0x07;
|
||||||
EMIT_BYTE(rex);
|
EMIT_BYTE(rex);
|
||||||
|
|
||||||
if (x86RexIsInvalid(rex))
|
if (x86RexIsInvalid(rex))
|
||||||
goto _IllegalInst;
|
goto _IllegalInst;
|
||||||
}
|
}
|
||||||
|
|
||||||
mBase &= 0x7;
|
mBase &= 0x07;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instruction opcodes.
|
// Instruction opcodes.
|
||||||
@@ -3643,7 +3649,7 @@ _EmitSib:
|
|||||||
uint32_t shift = rmMem->getShift();
|
uint32_t shift = rmMem->getShift();
|
||||||
|
|
||||||
// Esp/Rsp/R12 register can't be used as an index.
|
// Esp/Rsp/R12 register can't be used as an index.
|
||||||
mIndex &= 0x7;
|
mIndex &= 0x07;
|
||||||
ASMJIT_ASSERT(mIndex != kX86RegIndexSp);
|
ASMJIT_ASSERT(mIndex != kX86RegIndexSp);
|
||||||
|
|
||||||
if (mBase != kX86RegIndexBp && dispOffset == 0) {
|
if (mBase != kX86RegIndexBp && dispOffset == 0) {
|
||||||
@@ -3734,7 +3740,7 @@ _EmitSib:
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// [Disp32 + Index * Scale].
|
// [Disp32 + Index * Scale].
|
||||||
mIndex &= 0x7;
|
mIndex &= 0x07;
|
||||||
ASMJIT_ASSERT(mIndex != kX86RegIndexSp);
|
ASMJIT_ASSERT(mIndex != kX86RegIndexSp);
|
||||||
|
|
||||||
uint32_t shift = rmMem->getShift();
|
uint32_t shift = rmMem->getShift();
|
||||||
@@ -3857,8 +3863,8 @@ _EmitFpuOp:
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
mBase &= 0x7; \
|
mBase &= 0x07; \
|
||||||
opReg &= 0x7;
|
opReg &= 0x07;
|
||||||
|
|
||||||
_EmitAvxOp:
|
_EmitAvxOp:
|
||||||
{
|
{
|
||||||
@@ -3920,7 +3926,7 @@ _EmitAvxR:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EMIT_BYTE(x86EncodeMod(3, opReg, static_cast<uint32_t>(rmReg)));
|
EMIT_BYTE(x86EncodeMod(3, opReg & 0x07, static_cast<uint32_t>(rmReg)));
|
||||||
|
|
||||||
if (imLen == 0)
|
if (imLen == 0)
|
||||||
goto _EmitDone;
|
goto _EmitDone;
|
||||||
@@ -3939,7 +3945,7 @@ _EmitAvxV:
|
|||||||
goto _IllegalInst;
|
goto _IllegalInst;
|
||||||
|
|
||||||
if (Arch == kArchX64)
|
if (Arch == kArchX64)
|
||||||
mIndex &= 0x7;
|
mIndex &= 0x07;
|
||||||
|
|
||||||
dispOffset = rmMem->getDisplacement();
|
dispOffset = rmMem->getDisplacement();
|
||||||
if (rmMem->isBaseIndexType()) {
|
if (rmMem->isBaseIndexType()) {
|
||||||
@@ -4046,8 +4052,8 @@ _EmitAvxV:
|
|||||||
EMIT_OP(opCode); \
|
EMIT_OP(opCode); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
mBase &= 0x7; \
|
mBase &= 0x07; \
|
||||||
opReg &= 0x7;
|
opReg &= 0x07;
|
||||||
|
|
||||||
_EmitXopR:
|
_EmitXopR:
|
||||||
{
|
{
|
||||||
@@ -4074,7 +4080,7 @@ _EmitXopR:
|
|||||||
rmReg &= 0x07;
|
rmReg &= 0x07;
|
||||||
}
|
}
|
||||||
|
|
||||||
EMIT_BYTE(x86EncodeMod(3, opReg, static_cast<uint32_t>(rmReg)));
|
EMIT_BYTE(x86EncodeMod(3, opReg & 0x07, static_cast<uint32_t>(rmReg)));
|
||||||
|
|
||||||
if (imLen == 0)
|
if (imLen == 0)
|
||||||
goto _EmitDone;
|
goto _EmitDone;
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
// Zlib - See LICENSE.md file in the package.
|
// Zlib - See LICENSE.md file in the package.
|
||||||
|
|
||||||
// [Dependencies - AsmJit]
|
// [Dependencies - AsmJit]
|
||||||
#include <asmjit/asmjit.h>
|
#include "../asmjit/asmjit.h"
|
||||||
|
|
||||||
// [Dependencies - Test]
|
// [Dependencies - Test]
|
||||||
#include "genblend.h"
|
#include "./asmjit_test_opcode.h"
|
||||||
#include "genopcode.h"
|
#include "./genblend.h"
|
||||||
|
|
||||||
// [Dependencies - C]
|
// [Dependencies - C]
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
75
src/test/asmjit_test_opcode.cpp
Normal file
75
src/test/asmjit_test_opcode.cpp
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
// [AsmJit]
|
||||||
|
// Complete x86/x64 JIT and Remote Assembler for C++.
|
||||||
|
//
|
||||||
|
// [License]
|
||||||
|
// Zlib - See LICENSE.md file in the package.
|
||||||
|
|
||||||
|
// This file is used to test opcodes generated by AsmJit. Output can be
|
||||||
|
// disassembled in your IDE or by your favourite disassembler. Instructions
|
||||||
|
// are grouped by category and then sorted alphabetically.
|
||||||
|
|
||||||
|
// [Dependencies - AsmJit]
|
||||||
|
#include "../asmjit/asmjit.h"
|
||||||
|
|
||||||
|
// [Dependencies - Test]
|
||||||
|
#include "./asmjit_test_opcode.h"
|
||||||
|
|
||||||
|
// [Dependencies - C]
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef void (*VoidFunc)(void);
|
||||||
|
|
||||||
|
struct OpcodeDumpInfo {
|
||||||
|
uint32_t arch;
|
||||||
|
bool useRex;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* archIdToString(uint32_t archId) {
|
||||||
|
switch (archId) {
|
||||||
|
case asmjit::kArchNone: return "None";
|
||||||
|
case asmjit::kArchX86: return "X86";
|
||||||
|
case asmjit::kArchX64: return "X64";
|
||||||
|
case asmjit::kArchArm: return "ARM";
|
||||||
|
default: return "<unknown>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
asmjit::FileLogger logger(stdout);
|
||||||
|
logger.setOption(asmjit::kLoggerOptionBinaryForm, true);
|
||||||
|
|
||||||
|
OpcodeDumpInfo infoList[] = {
|
||||||
|
# if defined(ASMJIT_BUILD_X86)
|
||||||
|
{ asmjit::kArchX86, false },
|
||||||
|
# endif // ASMJIT_BUILD_X86
|
||||||
|
# if defined(ASMJIT_BUILD_X64)
|
||||||
|
{ asmjit::kArchX64, false },
|
||||||
|
{ asmjit::kArchX64, true }
|
||||||
|
# endif // ASMJIT_BUILD_X64
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < ASMJIT_ARRAY_SIZE(infoList); i++) {
|
||||||
|
const OpcodeDumpInfo& info = infoList[i];
|
||||||
|
|
||||||
|
printf("Opcodes [ARCH=%s REX=%s]\n",
|
||||||
|
archIdToString(info.arch),
|
||||||
|
info.useRex ? "true" : "false");
|
||||||
|
|
||||||
|
asmjit::JitRuntime runtime;
|
||||||
|
asmjit::X86Assembler a(&runtime, info.arch);
|
||||||
|
a.setLogger(&logger);
|
||||||
|
|
||||||
|
asmgen::opcode(a, info.useRex);
|
||||||
|
VoidFunc p = asmjit_cast<VoidFunc>(a.make());
|
||||||
|
|
||||||
|
// Only run if disassembly makes sense.
|
||||||
|
if (info.arch == asmjit::kArchHost)
|
||||||
|
p();
|
||||||
|
|
||||||
|
runtime.release((void*)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
2859
src/test/asmjit_test_opcode.h
Normal file
2859
src/test/asmjit_test_opcode.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,9 +5,7 @@
|
|||||||
// Zlib - See LICENSE.md file in the package.
|
// Zlib - See LICENSE.md file in the package.
|
||||||
|
|
||||||
// [Dependencies - AsmJit]
|
// [Dependencies - AsmJit]
|
||||||
#include "../asmjit.h"
|
#include "../asmjit/asmjit.h"
|
||||||
|
|
||||||
using namespace asmjit;
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [DumpCpu]
|
// [DumpCpu]
|
||||||
@@ -18,14 +16,14 @@ struct DumpCpuFeature {
|
|||||||
const char* name;
|
const char* name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dumpCpuFeatures(const CpuInfo* cpuInfo, const DumpCpuFeature* data, size_t count) {
|
static void dumpCpuFeatures(const asmjit::CpuInfo* cpuInfo, const DumpCpuFeature* data, size_t count) {
|
||||||
for (size_t i = 0; i < count; i++)
|
for (size_t i = 0; i < count; i++)
|
||||||
if (cpuInfo->hasFeature(data[i].feature))
|
if (cpuInfo->hasFeature(data[i].feature))
|
||||||
INFO(" %s", data[i].name);
|
INFO(" %s", data[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dumpCpu(void) {
|
static void dumpCpu(void) {
|
||||||
const CpuInfo* cpu = CpuInfo::getHost();
|
const asmjit::CpuInfo* cpu = asmjit::CpuInfo::getHost();
|
||||||
|
|
||||||
INFO("Host CPU Info:");
|
INFO("Host CPU Info:");
|
||||||
INFO(" Vendor string : %s", cpu->getVendorString());
|
INFO(" Vendor string : %s", cpu->getVendorString());
|
||||||
@@ -41,67 +39,67 @@ static void dumpCpu(void) {
|
|||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64)
|
#if defined(ASMJIT_ARCH_X86) || defined(ASMJIT_ARCH_X64)
|
||||||
const X86CpuInfo* x86Cpu = static_cast<const X86CpuInfo*>(cpu);
|
const asmjit::X86CpuInfo* x86Cpu = static_cast<const asmjit::X86CpuInfo*>(cpu);
|
||||||
|
|
||||||
static const DumpCpuFeature x86FeaturesList[] = {
|
static const DumpCpuFeature x86FeaturesList[] = {
|
||||||
{ kX86CpuFeatureNX , "NX (Non-Execute Bit)" },
|
{ asmjit::kX86CpuFeatureNX , "NX (Non-Execute Bit)" },
|
||||||
{ kX86CpuFeatureMT , "MT (Multi-Threading)" },
|
{ asmjit::kX86CpuFeatureMT , "MT (Multi-Threading)" },
|
||||||
{ kX86CpuFeatureRDTSC , "RDTSC" },
|
{ asmjit::kX86CpuFeatureRDTSC , "RDTSC" },
|
||||||
{ kX86CpuFeatureRDTSCP , "RDTSCP" },
|
{ asmjit::kX86CpuFeatureRDTSCP , "RDTSCP" },
|
||||||
{ kX86CpuFeatureCMOV , "CMOV" },
|
{ asmjit::kX86CpuFeatureCMOV , "CMOV" },
|
||||||
{ kX86CpuFeatureCMPXCHG8B , "CMPXCHG8B" },
|
{ asmjit::kX86CpuFeatureCMPXCHG8B , "CMPXCHG8B" },
|
||||||
{ kX86CpuFeatureCMPXCHG16B , "CMPXCHG16B" },
|
{ asmjit::kX86CpuFeatureCMPXCHG16B , "CMPXCHG16B" },
|
||||||
{ kX86CpuFeatureCLFLUSH , "CLFLUSH" },
|
{ asmjit::kX86CpuFeatureCLFLUSH , "CLFLUSH" },
|
||||||
{ kX86CpuFeatureCLFLUSHOpt , "CLFLUSH (Opt)" },
|
{ asmjit::kX86CpuFeatureCLFLUSHOpt , "CLFLUSH (Opt)" },
|
||||||
{ kX86CpuFeaturePREFETCH , "PREFETCH" },
|
{ asmjit::kX86CpuFeaturePREFETCH , "PREFETCH" },
|
||||||
{ kX86CpuFeaturePREFETCHWT1 , "PREFETCHWT1" },
|
{ asmjit::kX86CpuFeaturePREFETCHWT1 , "PREFETCHWT1" },
|
||||||
{ kX86CpuFeatureLahfSahf , "LAHF/SAHF" },
|
{ asmjit::kX86CpuFeatureLahfSahf , "LAHF/SAHF" },
|
||||||
{ kX86CpuFeatureFXSR , "FXSR" },
|
{ asmjit::kX86CpuFeatureFXSR , "FXSR" },
|
||||||
{ kX86CpuFeatureFXSROpt , "FXSR (Opt)" },
|
{ asmjit::kX86CpuFeatureFXSROpt , "FXSR (Opt)" },
|
||||||
{ kX86CpuFeatureMMX , "MMX" },
|
{ asmjit::kX86CpuFeatureMMX , "MMX" },
|
||||||
{ kX86CpuFeatureMMX2 , "MMX2" },
|
{ asmjit::kX86CpuFeatureMMX2 , "MMX2" },
|
||||||
{ kX86CpuFeature3DNOW , "3DNOW" },
|
{ asmjit::kX86CpuFeature3DNOW , "3DNOW" },
|
||||||
{ kX86CpuFeature3DNOW2 , "3DNOW2" },
|
{ asmjit::kX86CpuFeature3DNOW2 , "3DNOW2" },
|
||||||
{ kX86CpuFeatureSSE , "SSE" },
|
{ asmjit::kX86CpuFeatureSSE , "SSE" },
|
||||||
{ kX86CpuFeatureSSE2 , "SSE2" },
|
{ asmjit::kX86CpuFeatureSSE2 , "SSE2" },
|
||||||
{ kX86CpuFeatureSSE3 , "SSE3" },
|
{ asmjit::kX86CpuFeatureSSE3 , "SSE3" },
|
||||||
{ kX86CpuFeatureSSSE3 , "SSSE3" },
|
{ asmjit::kX86CpuFeatureSSSE3 , "SSSE3" },
|
||||||
{ kX86CpuFeatureSSE4A , "SSE4A" },
|
{ asmjit::kX86CpuFeatureSSE4A , "SSE4A" },
|
||||||
{ kX86CpuFeatureSSE4_1 , "SSE4.1" },
|
{ asmjit::kX86CpuFeatureSSE4_1 , "SSE4.1" },
|
||||||
{ kX86CpuFeatureSSE4_2 , "SSE4.2" },
|
{ asmjit::kX86CpuFeatureSSE4_2 , "SSE4.2" },
|
||||||
{ kX86CpuFeatureMSSE , "Misaligned SSE" },
|
{ asmjit::kX86CpuFeatureMSSE , "Misaligned SSE" },
|
||||||
{ kX86CpuFeatureMONITOR , "MONITOR/MWAIT" },
|
{ asmjit::kX86CpuFeatureMONITOR , "MONITOR/MWAIT" },
|
||||||
{ kX86CpuFeatureMOVBE , "MOVBE" },
|
{ asmjit::kX86CpuFeatureMOVBE , "MOVBE" },
|
||||||
{ kX86CpuFeaturePOPCNT , "POPCNT" },
|
{ asmjit::kX86CpuFeaturePOPCNT , "POPCNT" },
|
||||||
{ kX86CpuFeatureLZCNT , "LZCNT" },
|
{ asmjit::kX86CpuFeatureLZCNT , "LZCNT" },
|
||||||
{ kX86CpuFeatureAESNI , "AESNI" },
|
{ asmjit::kX86CpuFeatureAESNI , "AESNI" },
|
||||||
{ kX86CpuFeaturePCLMULQDQ , "PCLMULQDQ" },
|
{ asmjit::kX86CpuFeaturePCLMULQDQ , "PCLMULQDQ" },
|
||||||
{ kX86CpuFeatureRDRAND , "RDRAND" },
|
{ asmjit::kX86CpuFeatureRDRAND , "RDRAND" },
|
||||||
{ kX86CpuFeatureRDSEED , "RDSEED" },
|
{ asmjit::kX86CpuFeatureRDSEED , "RDSEED" },
|
||||||
{ kX86CpuFeatureSHA , "SHA" },
|
{ asmjit::kX86CpuFeatureSHA , "SHA" },
|
||||||
{ kX86CpuFeatureXSave , "XSAVE" },
|
{ asmjit::kX86CpuFeatureXSave , "XSAVE" },
|
||||||
{ kX86CpuFeatureXSaveOS , "XSAVE (OS)" },
|
{ asmjit::kX86CpuFeatureXSaveOS , "XSAVE (OS)" },
|
||||||
{ kX86CpuFeatureAVX , "AVX" },
|
{ asmjit::kX86CpuFeatureAVX , "AVX" },
|
||||||
{ kX86CpuFeatureAVX2 , "AVX2" },
|
{ asmjit::kX86CpuFeatureAVX2 , "AVX2" },
|
||||||
{ kX86CpuFeatureF16C , "F16C" },
|
{ asmjit::kX86CpuFeatureF16C , "F16C" },
|
||||||
{ kX86CpuFeatureFMA3 , "FMA3" },
|
{ asmjit::kX86CpuFeatureFMA3 , "FMA3" },
|
||||||
{ kX86CpuFeatureFMA4 , "FMA4" },
|
{ asmjit::kX86CpuFeatureFMA4 , "FMA4" },
|
||||||
{ kX86CpuFeatureXOP , "XOP" },
|
{ asmjit::kX86CpuFeatureXOP , "XOP" },
|
||||||
{ kX86CpuFeatureBMI , "BMI" },
|
{ asmjit::kX86CpuFeatureBMI , "BMI" },
|
||||||
{ kX86CpuFeatureBMI2 , "BMI2" },
|
{ asmjit::kX86CpuFeatureBMI2 , "BMI2" },
|
||||||
{ kX86CpuFeatureHLE , "HLE" },
|
{ asmjit::kX86CpuFeatureHLE , "HLE" },
|
||||||
{ kX86CpuFeatureRTM , "RTM" },
|
{ asmjit::kX86CpuFeatureRTM , "RTM" },
|
||||||
{ kX86CpuFeatureADX , "ADX" },
|
{ asmjit::kX86CpuFeatureADX , "ADX" },
|
||||||
{ kX86CpuFeatureMPX , "MPX" },
|
{ asmjit::kX86CpuFeatureMPX , "MPX" },
|
||||||
{ kX86CpuFeatureFSGSBase , "FS/GS Base" },
|
{ asmjit::kX86CpuFeatureFSGSBase , "FS/GS Base" },
|
||||||
{ kX86CpuFeatureMOVSBSTOSBOpt , "REP MOVSB/STOSB (Opt)" },
|
{ asmjit::kX86CpuFeatureMOVSBSTOSBOpt , "REP MOVSB/STOSB (Opt)" },
|
||||||
{ kX86CpuFeatureAVX512F , "AVX512F" },
|
{ asmjit::kX86CpuFeatureAVX512F , "AVX512F" },
|
||||||
{ kX86CpuFeatureAVX512CD , "AVX512CD" },
|
{ asmjit::kX86CpuFeatureAVX512CD , "AVX512CD" },
|
||||||
{ kX86CpuFeatureAVX512PF , "AVX512PF" },
|
{ asmjit::kX86CpuFeatureAVX512PF , "AVX512PF" },
|
||||||
{ kX86CpuFeatureAVX512ER , "AVX512ER" },
|
{ asmjit::kX86CpuFeatureAVX512ER , "AVX512ER" },
|
||||||
{ kX86CpuFeatureAVX512DQ , "AVX512DQ" },
|
{ asmjit::kX86CpuFeatureAVX512DQ , "AVX512DQ" },
|
||||||
{ kX86CpuFeatureAVX512BW , "AVX512BW" },
|
{ asmjit::kX86CpuFeatureAVX512BW , "AVX512BW" },
|
||||||
{ kX86CpuFeatureAVX512VL , "AVX512VL" }
|
{ asmjit::kX86CpuFeatureAVX512VL , "AVX512VL" }
|
||||||
};
|
};
|
||||||
|
|
||||||
INFO("Host CPU Info (X86/X64):");
|
INFO("Host CPU Info (X86/X64):");
|
||||||
@@ -5,10 +5,10 @@
|
|||||||
// Zlib - See LICENSE.md file in the package.
|
// Zlib - See LICENSE.md file in the package.
|
||||||
|
|
||||||
// [Dependencies - AsmJit]
|
// [Dependencies - AsmJit]
|
||||||
#include <asmjit/asmjit.h>
|
#include "../asmjit/asmjit.h"
|
||||||
|
|
||||||
// [Dependencies - Test]
|
// [Dependencies - Test]
|
||||||
#include "genblend.h"
|
#include "./genblend.h"
|
||||||
|
|
||||||
// [Dependencies - C]
|
// [Dependencies - C]
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -1799,7 +1799,7 @@ struct X86Test_CallBase : public X86Test {
|
|||||||
|
|
||||||
// Call function.
|
// Call function.
|
||||||
X86GpVar fn(c, kVarTypeIntPtr, "fn");
|
X86GpVar fn(c, kVarTypeIntPtr, "fn");
|
||||||
c.mov(fn, imm_ptr((void*)calledFunc));
|
c.mov(fn, imm_ptr(calledFunc));
|
||||||
|
|
||||||
X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder3<int, int, int, int>());
|
X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder3<int, int, int, int>());
|
||||||
call->setArg(0, v2);
|
call->setArg(0, v2);
|
||||||
@@ -1845,7 +1845,7 @@ struct X86Test_CallFast : public X86Test {
|
|||||||
c.addFunc(kFuncConvHost, FuncBuilder1<int, int>());
|
c.addFunc(kFuncConvHost, FuncBuilder1<int, int>());
|
||||||
c.setArg(0, var);
|
c.setArg(0, var);
|
||||||
|
|
||||||
c.mov(fn, imm_ptr((void*)calledFunc));
|
c.mov(fn, imm_ptr(calledFunc));
|
||||||
X86CallNode* call;
|
X86CallNode* call;
|
||||||
|
|
||||||
call = c.call(fn, kFuncConvHostFastCall, FuncBuilder1<int, int>());
|
call = c.call(fn, kFuncConvHostFastCall, FuncBuilder1<int, int>());
|
||||||
@@ -1910,7 +1910,7 @@ struct X86Test_CallManyArgs : public X86Test {
|
|||||||
X86GpVar vi(c, kVarTypeInt32, "vi");
|
X86GpVar vi(c, kVarTypeInt32, "vi");
|
||||||
X86GpVar vj(c, kVarTypeInt32, "vj");
|
X86GpVar vj(c, kVarTypeInt32, "vj");
|
||||||
|
|
||||||
c.mov(fn, imm_ptr((void*)calledFunc));
|
c.mov(fn, imm_ptr(calledFunc));
|
||||||
c.mov(va, 0x03);
|
c.mov(va, 0x03);
|
||||||
c.mov(vb, 0x12);
|
c.mov(vb, 0x12);
|
||||||
c.mov(vc, 0xA0);
|
c.mov(vc, 0xA0);
|
||||||
@@ -1977,7 +1977,7 @@ struct X86Test_CallDuplicateArgs : public X86Test {
|
|||||||
X86GpVar fn(c, kVarTypeIntPtr, "fn");
|
X86GpVar fn(c, kVarTypeIntPtr, "fn");
|
||||||
X86GpVar a(c, kVarTypeInt32, "a");
|
X86GpVar a(c, kVarTypeInt32, "a");
|
||||||
|
|
||||||
c.mov(fn, imm_ptr((void*)calledFunc));
|
c.mov(fn, imm_ptr(calledFunc));
|
||||||
c.mov(a, 3);
|
c.mov(a, 3);
|
||||||
|
|
||||||
// Call function.
|
// Call function.
|
||||||
@@ -2031,7 +2031,7 @@ struct X86Test_CallImmArgs : public X86Test {
|
|||||||
X86GpVar fn(c, kVarTypeIntPtr, "fn");
|
X86GpVar fn(c, kVarTypeIntPtr, "fn");
|
||||||
X86GpVar rv(c, kVarTypeInt32, "rv");
|
X86GpVar rv(c, kVarTypeInt32, "rv");
|
||||||
|
|
||||||
c.mov(fn, imm_ptr((void*)X86Test_CallManyArgs::calledFunc));
|
c.mov(fn, imm_ptr(X86Test_CallManyArgs::calledFunc));
|
||||||
|
|
||||||
// Call function.
|
// Call function.
|
||||||
X86CallNode* call = c.call(fn, kFuncConvHost,
|
X86CallNode* call = c.call(fn, kFuncConvHost,
|
||||||
@@ -2097,7 +2097,7 @@ struct X86Test_CallPtrArgs : public X86Test {
|
|||||||
X86GpVar fn(c, kVarTypeIntPtr, "fn");
|
X86GpVar fn(c, kVarTypeIntPtr, "fn");
|
||||||
X86GpVar rv(c, kVarTypeInt32, "rv");
|
X86GpVar rv(c, kVarTypeInt32, "rv");
|
||||||
|
|
||||||
c.mov(fn, imm_ptr((void*)calledFunc));
|
c.mov(fn, imm_ptr(calledFunc));
|
||||||
|
|
||||||
// Call function.
|
// Call function.
|
||||||
X86CallNode* call = c.call(fn, kFuncConvHost,
|
X86CallNode* call = c.call(fn, kFuncConvHost,
|
||||||
@@ -2159,7 +2159,7 @@ struct X86Test_CallFloatAsXmmRet : public X86Test {
|
|||||||
|
|
||||||
// Prepare.
|
// Prepare.
|
||||||
X86GpVar fn(c);
|
X86GpVar fn(c);
|
||||||
c.mov(fn, imm_ptr((void*)calledFunc));
|
c.mov(fn, imm_ptr(calledFunc));
|
||||||
|
|
||||||
// Call function.
|
// Call function.
|
||||||
X86CallNode* call = c.call(fn, kFuncConvHost,
|
X86CallNode* call = c.call(fn, kFuncConvHost,
|
||||||
@@ -2213,7 +2213,7 @@ struct X86Test_CallDoubleAsXmmRet : public X86Test {
|
|||||||
c.setArg(1, b);
|
c.setArg(1, b);
|
||||||
|
|
||||||
X86GpVar fn(c);
|
X86GpVar fn(c);
|
||||||
c.mov(fn, imm_ptr((void*)calledFunc));
|
c.mov(fn, imm_ptr(calledFunc));
|
||||||
|
|
||||||
X86CallNode* call = c.call(fn, kFuncConvHost,
|
X86CallNode* call = c.call(fn, kFuncConvHost,
|
||||||
FuncBuilder2<double, double, double>());
|
FuncBuilder2<double, double, double>());
|
||||||
@@ -2474,7 +2474,7 @@ struct X86Test_CallMisc1 : public X86Test {
|
|||||||
c.alloc(a, x86::eax);
|
c.alloc(a, x86::eax);
|
||||||
c.alloc(b, x86::ebx);
|
c.alloc(b, x86::ebx);
|
||||||
|
|
||||||
X86CallNode* call = c.call(imm_ptr((void*)dummy), kFuncConvHost, FuncBuilder2<void, int, int>());
|
X86CallNode* call = c.call(imm_ptr(dummy), kFuncConvHost, FuncBuilder2<void, int, int>());
|
||||||
call->setArg(0, a);
|
call->setArg(0, a);
|
||||||
call->setArg(1, b);
|
call->setArg(1, b);
|
||||||
|
|
||||||
@@ -2520,7 +2520,7 @@ struct X86Test_CallMisc2 : public X86Test {
|
|||||||
|
|
||||||
c.setArg(0, p);
|
c.setArg(0, p);
|
||||||
c.movsd(arg, x86::ptr(p));
|
c.movsd(arg, x86::ptr(p));
|
||||||
c.mov(fn, imm_ptr((void*)op));
|
c.mov(fn, imm_ptr(op));
|
||||||
|
|
||||||
X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder1<double, double>());
|
X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder1<double, double>());
|
||||||
call->setArg(0, arg);
|
call->setArg(0, arg);
|
||||||
@@ -2570,7 +2570,7 @@ struct X86Test_CallMisc3 : public X86Test {
|
|||||||
|
|
||||||
c.setArg(0, p);
|
c.setArg(0, p);
|
||||||
c.movsd(arg, x86::ptr(p));
|
c.movsd(arg, x86::ptr(p));
|
||||||
c.mov(fn, imm_ptr((void*)op));
|
c.mov(fn, imm_ptr(op));
|
||||||
|
|
||||||
X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder1<double, double>());
|
X86CallNode* call = c.call(fn, kFuncConvHost, FuncBuilder1<double, double>());
|
||||||
call->setArg(0, arg);
|
call->setArg(0, arg);
|
||||||
@@ -2601,6 +2601,49 @@ struct X86Test_CallMisc3 : public X86Test {
|
|||||||
static double op(double a) { return a * a; }
|
static double op(double a) { return a * a; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// [X86Test_CallMisc4]
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
struct X86Test_CallMisc4 : public X86Test {
|
||||||
|
X86Test_CallMisc4() : X86Test("[Call] Misc #4") {}
|
||||||
|
|
||||||
|
static void add(PodVector<X86Test*>& tests) {
|
||||||
|
tests.append(new X86Test_CallMisc4());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(X86Compiler& c) {
|
||||||
|
FuncBuilderX funcPrototype;
|
||||||
|
funcPrototype.setRet(kVarTypeFp64);
|
||||||
|
X86FuncNode* func = c.addFunc(kFuncConvHost, funcPrototype);
|
||||||
|
|
||||||
|
FuncBuilderX callPrototype;
|
||||||
|
callPrototype.setRet(kVarTypeFp64);
|
||||||
|
X86CallNode* call = c.call(imm_ptr(calledFunc), kFuncConvHost, callPrototype);
|
||||||
|
|
||||||
|
X86XmmVar ret(c, kX86VarTypeXmmSd, "ret");
|
||||||
|
call->setRet(0, ret);
|
||||||
|
c.ret(ret);
|
||||||
|
|
||||||
|
c.endFunc();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) {
|
||||||
|
typedef double (*Func)(void);
|
||||||
|
Func func = asmjit_cast<Func>(_func);
|
||||||
|
|
||||||
|
double resultRet = func();
|
||||||
|
double expectRet = 3.14;
|
||||||
|
|
||||||
|
result.setFormat("ret=%g", resultRet);
|
||||||
|
expect.setFormat("ret=%g", expectRet);
|
||||||
|
|
||||||
|
return resultRet == expectRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double calledFunc() { return 3.14; }
|
||||||
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [X86Test_MiscConstPool]
|
// [X86Test_MiscConstPool]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -2732,14 +2775,14 @@ struct X86Test_MiscMultiRet : public X86Test {
|
|||||||
expect.setFormat("ret={%d %d %d %d}", e0, e1, e2, e3);
|
expect.setFormat("ret={%d %d %d %d}", e0, e1, e2, e3);
|
||||||
|
|
||||||
return result.eq(expect);
|
return result.eq(expect);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// [X86Test_MiscUnfollow]
|
// [X86Test_MiscUnfollow]
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// Global (I didn't find better way to really test this).
|
// Global (I didn't find a better way to test this).
|
||||||
static jmp_buf globalJmpBuf;
|
static jmp_buf globalJmpBuf;
|
||||||
|
|
||||||
struct X86Test_MiscUnfollow : public X86Test {
|
struct X86Test_MiscUnfollow : public X86Test {
|
||||||
@@ -2881,6 +2924,7 @@ X86TestSuite::X86TestSuite() :
|
|||||||
ADD_TEST(X86Test_CallMisc1);
|
ADD_TEST(X86Test_CallMisc1);
|
||||||
ADD_TEST(X86Test_CallMisc2);
|
ADD_TEST(X86Test_CallMisc2);
|
||||||
ADD_TEST(X86Test_CallMisc3);
|
ADD_TEST(X86Test_CallMisc3);
|
||||||
|
ADD_TEST(X86Test_CallMisc4);
|
||||||
|
|
||||||
// Misc.
|
// Misc.
|
||||||
ADD_TEST(X86Test_MiscConstPool);
|
ADD_TEST(X86Test_MiscConstPool);
|
||||||
@@ -5,11 +5,11 @@
|
|||||||
// Zlib - See LICENSE.md file in the package.
|
// Zlib - See LICENSE.md file in the package.
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#ifndef _APP_TEST_GENBLEND_H
|
#ifndef _TEST_GENBLEND_H
|
||||||
#define _APP_TEST_GENBLEND_H
|
#define _TEST_GENBLEND_H
|
||||||
|
|
||||||
// [Dependencies]
|
// [Dependencies]
|
||||||
#include <asmjit/asmjit.h>
|
#include "../asmjit/asmjit.h"
|
||||||
|
|
||||||
namespace asmgen {
|
namespace asmgen {
|
||||||
|
|
||||||
@@ -177,4 +177,4 @@ static void blend(asmjit::X86Compiler& c) {
|
|||||||
} // asmgen namespace
|
} // asmgen namespace
|
||||||
|
|
||||||
// [Guard]
|
// [Guard]
|
||||||
#endif // _APP_TEST_GENBLEND_H
|
#endif // _TEST_GENBLEND_H
|
||||||
Reference in New Issue
Block a user