TriCore Support (#1568)
* TriCore Support python sample * Update sample_tricore.py Correct attribution * Update sample_tricore.py Fixed byte code to execute properly. * Update sample_tricore.py Removed testing artifact * Added tricore msvc config-file.h * Added STATIC to tricore config and added helper methods to symbol file generation. * Update op_helper.c Use built in crc32 * Fix tricore samples and small code blocks are now handled properly * Add CPU types * Generate bindings * Format code Co-authored-by: lazymio <mio@lazym.io>
This commit is contained in:
parent
f49f62ecef
commit
cfee2139a0
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,8 +12,6 @@
|
||||
*.jar
|
||||
*~
|
||||
|
||||
qemu/*-softmmu/
|
||||
|
||||
tags
|
||||
qemu/config-host.ld
|
||||
qemu/config.log
|
||||
|
@ -44,7 +44,7 @@ option(BUILD_SHARED_LIBS "Build shared instead of static library" ${PROJECT_IS_T
|
||||
option(UNICORN_FUZZ "Enable fuzzing" OFF)
|
||||
option(UNICORN_BUILD_TESTS "Build unicorn tests" ${PROJECT_IS_TOP_LEVEL})
|
||||
option(UNICORN_INSTALL "Enable unicorn installation" ${PROJECT_IS_TOP_LEVEL})
|
||||
set(UNICORN_ARCH "x86;arm;aarch64;riscv;mips;sparc;m68k;ppc;s390x" CACHE STRING "Enabled unicorn architectures")
|
||||
set(UNICORN_ARCH "x86;arm;aarch64;riscv;mips;sparc;m68k;ppc;s390x;tricore" CACHE STRING "Enabled unicorn architectures")
|
||||
option(UNICORN_TRACER "Trace unicorn execution" OFF)
|
||||
|
||||
foreach(ARCH_LOOP ${UNICORN_ARCH})
|
||||
@ -209,6 +209,11 @@ else()
|
||||
set(UNICORN_TARGET_ARCH "s390")
|
||||
break()
|
||||
endif()
|
||||
string(FIND ${UC_COMPILER_MACRO} "__tricore__" UC_RET)
|
||||
if (${UC_RET} GREATER_EQUAL "0")
|
||||
set(UNICORN_TARGET_ARCH "tricore")
|
||||
break()
|
||||
endif()
|
||||
message(FATAL_ERROR "Unknown host compiler: ${CMAKE_C_COMPILER}.")
|
||||
endwhile(TRUE)
|
||||
endif()
|
||||
@ -241,6 +246,9 @@ else()
|
||||
if (UNICORN_HAS_S390X)
|
||||
set (EXTRA_CFLAGS "${EXTRA_CFLAGS}-DUNICORN_HAS_S390X ")
|
||||
endif()
|
||||
if (UNICORN_HAS_TRICORE)
|
||||
set (EXTRA_CFLAGS "${EXTRA_CFLAGS}-DUNICORN_HAS_TRICORE ")
|
||||
endif()
|
||||
|
||||
set(EXTRA_CFLAGS "${EXTRA_CFLAGS}-fPIC")
|
||||
if(ANDROID_ABI)
|
||||
@ -282,6 +290,9 @@ else()
|
||||
if(UNICORN_HAS_S390X)
|
||||
set(TARGET_LIST "${TARGET_LIST}s390x-softmmu, ")
|
||||
endif()
|
||||
if (UNICORN_HAS_TRICORE)
|
||||
set (TARGET_LIST "${TARGET_LIST}tricore-softmmu, ")
|
||||
endif()
|
||||
set(TARGET_LIST "${TARGET_LIST} ")
|
||||
|
||||
# GEN config-host.mak & target directories
|
||||
@ -373,6 +384,12 @@ else()
|
||||
OUTPUT_FILE ${CMAKE_BINARY_DIR}/s390x-softmmu/config-target.h
|
||||
)
|
||||
endif()
|
||||
if (UNICORN_HAS_TRICORE)
|
||||
execute_process(COMMAND sh ${CMAKE_CURRENT_SOURCE_DIR}/qemu/scripts/create_config
|
||||
INPUT_FILE ${CMAKE_BINARY_DIR}/tricore-softmmu/config-target.mak
|
||||
OUTPUT_FILE ${CMAKE_BINARY_DIR}/tricore-softmmu/config-target.h
|
||||
)
|
||||
endif()
|
||||
add_compile_options(
|
||||
${UNICORN_CFLAGS}
|
||||
-I${CMAKE_CURRENT_SOURCE_DIR}/qemu/tcg/${UNICORN_TARGET_ARCH}
|
||||
@ -1034,6 +1051,36 @@ endif()
|
||||
endif()
|
||||
|
||||
|
||||
if (UNICORN_HAS_TRICORE)
|
||||
add_library(tricore-softmmu STATIC
|
||||
${UNICORN_ARCH_COMMON}
|
||||
|
||||
qemu/target/tricore/cpu.c
|
||||
qemu/target/tricore/fpu_helper.c
|
||||
qemu/target/tricore/helper.c
|
||||
qemu/target/tricore/op_helper.c
|
||||
qemu/target/tricore/translate.c
|
||||
qemu/target/tricore/unicorn.c
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(tricore-softmmu PRIVATE
|
||||
-DNEED_CPU_H
|
||||
/FItricore.h
|
||||
/I${CMAKE_CURRENT_SOURCE_DIR}/msvc/tricore-softmmu
|
||||
/I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target/tricore
|
||||
)
|
||||
else()
|
||||
target_compile_options(tricore-softmmu PRIVATE
|
||||
-DNEED_CPU_H
|
||||
-include tricore.h
|
||||
-I${CMAKE_BINARY_DIR}/tricore-softmmu
|
||||
-I${CMAKE_CURRENT_SOURCE_DIR}/qemu/target/tricore
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
set(UNICORN_SRCS
|
||||
uc.c
|
||||
|
||||
@ -1194,6 +1241,13 @@ if (UNICORN_HAS_S390X)
|
||||
target_link_libraries(s390x-softmmu PRIVATE unicorn-common)
|
||||
set(UNICORN_TEST_FILE ${UNICORN_TEST_FILE} test_s390x)
|
||||
endif()
|
||||
if (UNICORN_HAS_TRICORE)
|
||||
set(UNICORN_COMPILE_OPTIONS ${UNICORN_COMPILE_OPTIONS} -DUNICORN_HAS_TRICORE)
|
||||
set(UNICORN_LINK_LIBRARIES ${UNICORN_LINK_LIBRARIES} tricore-softmmu)
|
||||
set(UNICORN_SAMPLE_FILE ${UNICORN_SAMPLE_FILE} sample_tricore)
|
||||
target_link_libraries(tricore-softmmu unicorn-common)
|
||||
set(UNICORN_TEST_FILE ${UNICORN_TEST_FILE} test_tricore)
|
||||
endif()
|
||||
|
||||
# Extra tests
|
||||
set(UNICORN_TEST_FILE ${UNICORN_TEST_FILE} test_mem)
|
||||
|
@ -6,7 +6,7 @@ import sys, re, os
|
||||
|
||||
INCL_DIR = os.path.join('..', 'include', 'unicorn')
|
||||
|
||||
include = [ 'arm.h', 'arm64.h', 'mips.h', 'x86.h', 'sparc.h', 'm68k.h', 'ppc.h', 'riscv.h', 's390x.h', 'unicorn.h' ]
|
||||
include = [ 'arm.h', 'arm64.h', 'mips.h', 'x86.h', 'sparc.h', 'm68k.h', 'ppc.h', 'riscv.h', 's390x.h', 'tricore.h', 'unicorn.h' ]
|
||||
|
||||
template = {
|
||||
'python': {
|
||||
@ -24,6 +24,7 @@ template = {
|
||||
'ppc.h': 'ppc',
|
||||
'riscv.h': 'riscv',
|
||||
's390x.h' : 's390x',
|
||||
'tricore.h' : 'tricore',
|
||||
'unicorn.h': 'unicorn',
|
||||
'comment_open': '#',
|
||||
'comment_close': '',
|
||||
@ -43,6 +44,7 @@ template = {
|
||||
'ppc.h': 'ppc',
|
||||
'riscv.h': 'riscv',
|
||||
's390x.h' : 's390x',
|
||||
'tricore.h' : 'tricore',
|
||||
'unicorn.h': 'unicorn',
|
||||
'comment_open': '#',
|
||||
'comment_close': '',
|
||||
@ -62,6 +64,7 @@ template = {
|
||||
'ppc.h': 'ppc',
|
||||
'riscv.h': 'riscv',
|
||||
's390x.h' : 's390x',
|
||||
'tricore.h' : 'tricore',
|
||||
'unicorn.h': 'unicorn',
|
||||
'comment_open': '//',
|
||||
'comment_close': '',
|
||||
@ -81,6 +84,7 @@ template = {
|
||||
'ppc.h': 'Ppc',
|
||||
'riscv.h': 'Riscv',
|
||||
's390x.h' : 'S390x',
|
||||
'tricore.h' : 'TriCore',
|
||||
'unicorn.h': 'Unicorn',
|
||||
'comment_open': '//',
|
||||
'comment_close': '',
|
||||
@ -100,6 +104,7 @@ template = {
|
||||
'ppc.h': 'Ppc',
|
||||
'riscv.h': 'Riscv',
|
||||
's390x.h' : 'S390x',
|
||||
'tricore.h' : 'TriCore',
|
||||
'unicorn.h': 'Common',
|
||||
'comment_open': ' //',
|
||||
'comment_close': '',
|
||||
@ -119,6 +124,7 @@ template = {
|
||||
'ppc.h': 'Ppc',
|
||||
'riscv.h': 'Riscv',
|
||||
's390x.h' : 'S390x',
|
||||
'tricore.h' : 'TriCore',
|
||||
'unicorn.h': 'Unicorn',
|
||||
'comment_open': '//',
|
||||
'comment_close': '',
|
||||
|
@ -29,7 +29,8 @@ module Common =
|
||||
let UC_ARCH_M68K = 7
|
||||
let UC_ARCH_RISCV = 8
|
||||
let UC_ARCH_S390X = 9
|
||||
let UC_ARCH_MAX = 10
|
||||
let UC_ARCH_TRICORE = 10
|
||||
let UC_ARCH_MAX = 11
|
||||
|
||||
let UC_MODE_LITTLE_ENDIAN = 0
|
||||
let UC_MODE_BIG_ENDIAN = 1073741824
|
||||
|
132
bindings/dotnet/UnicornManaged/Const/TriCore.fs
Normal file
132
bindings/dotnet/UnicornManaged/Const/TriCore.fs
Normal file
@ -0,0 +1,132 @@
|
||||
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
|
||||
|
||||
namespace UnicornManaged.Const
|
||||
|
||||
open System
|
||||
|
||||
[<AutoOpen>]
|
||||
module TriCore =
|
||||
|
||||
// TRICORE CPU
|
||||
|
||||
let UC_CPU_TRICORE_TC1796 = 0
|
||||
let UC_CPU_TRICORE_TC1797 = 1
|
||||
let UC_CPU_TRICORE_TC27X = 2
|
||||
let UC_CPU_TRICORE_ENDING = 3
|
||||
|
||||
// TRICORE registers
|
||||
|
||||
let UC_TRICORE_REG_INVALID = 0
|
||||
let UC_TRICORE_REG_A0 = 1
|
||||
let UC_TRICORE_REG_A1 = 2
|
||||
let UC_TRICORE_REG_A2 = 3
|
||||
let UC_TRICORE_REG_A3 = 4
|
||||
let UC_TRICORE_REG_A4 = 5
|
||||
let UC_TRICORE_REG_A5 = 6
|
||||
let UC_TRICORE_REG_A6 = 7
|
||||
let UC_TRICORE_REG_A7 = 8
|
||||
let UC_TRICORE_REG_A8 = 9
|
||||
let UC_TRICORE_REG_A9 = 10
|
||||
let UC_TRICORE_REG_A10 = 11
|
||||
let UC_TRICORE_REG_A11 = 12
|
||||
let UC_TRICORE_REG_A12 = 13
|
||||
let UC_TRICORE_REG_A13 = 14
|
||||
let UC_TRICORE_REG_A14 = 15
|
||||
let UC_TRICORE_REG_A15 = 16
|
||||
let UC_TRICORE_REG_D0 = 17
|
||||
let UC_TRICORE_REG_D1 = 18
|
||||
let UC_TRICORE_REG_D2 = 19
|
||||
let UC_TRICORE_REG_D3 = 20
|
||||
let UC_TRICORE_REG_D4 = 21
|
||||
let UC_TRICORE_REG_D5 = 22
|
||||
let UC_TRICORE_REG_D6 = 23
|
||||
let UC_TRICORE_REG_D7 = 24
|
||||
let UC_TRICORE_REG_D8 = 25
|
||||
let UC_TRICORE_REG_D9 = 26
|
||||
let UC_TRICORE_REG_D10 = 27
|
||||
let UC_TRICORE_REG_D11 = 28
|
||||
let UC_TRICORE_REG_D12 = 29
|
||||
let UC_TRICORE_REG_D13 = 30
|
||||
let UC_TRICORE_REG_D14 = 31
|
||||
let UC_TRICORE_REG_D15 = 32
|
||||
let UC_TRICORE_REG_PCXI = 33
|
||||
let UC_TRICORE_REG_PSW = 34
|
||||
let UC_TRICORE_REG_PSW_USB_C = 35
|
||||
let UC_TRICORE_REG_PSW_USB_V = 36
|
||||
let UC_TRICORE_REG_PSW_USB_SV = 37
|
||||
let UC_TRICORE_REG_PSW_USB_AV = 38
|
||||
let UC_TRICORE_REG_PSW_USB_SAV = 39
|
||||
let UC_TRICORE_REG_PC = 40
|
||||
let UC_TRICORE_REG_SYSCON = 41
|
||||
let UC_TRICORE_REG_CPU_ID = 42
|
||||
let UC_TRICORE_REG_BIV = 43
|
||||
let UC_TRICORE_REG_BTV = 44
|
||||
let UC_TRICORE_REG_ISP = 45
|
||||
let UC_TRICORE_REG_ICR = 46
|
||||
let UC_TRICORE_REG_FCX = 47
|
||||
let UC_TRICORE_REG_LCX = 48
|
||||
let UC_TRICORE_REG_COMPAT = 49
|
||||
let UC_TRICORE_REG_DPR0_U = 50
|
||||
let UC_TRICORE_REG_DPR1_U = 51
|
||||
let UC_TRICORE_REG_DPR2_U = 52
|
||||
let UC_TRICORE_REG_DPR3_U = 53
|
||||
let UC_TRICORE_REG_DPR0_L = 54
|
||||
let UC_TRICORE_REG_DPR1_L = 55
|
||||
let UC_TRICORE_REG_DPR2_L = 56
|
||||
let UC_TRICORE_REG_DPR3_L = 57
|
||||
let UC_TRICORE_REG_CPR0_U = 58
|
||||
let UC_TRICORE_REG_CPR1_U = 59
|
||||
let UC_TRICORE_REG_CPR2_U = 60
|
||||
let UC_TRICORE_REG_CPR3_U = 61
|
||||
let UC_TRICORE_REG_CPR0_L = 62
|
||||
let UC_TRICORE_REG_CPR1_L = 63
|
||||
let UC_TRICORE_REG_CPR2_L = 64
|
||||
let UC_TRICORE_REG_CPR3_L = 65
|
||||
let UC_TRICORE_REG_DPM0 = 66
|
||||
let UC_TRICORE_REG_DPM1 = 67
|
||||
let UC_TRICORE_REG_DPM2 = 68
|
||||
let UC_TRICORE_REG_DPM3 = 69
|
||||
let UC_TRICORE_REG_CPM0 = 70
|
||||
let UC_TRICORE_REG_CPM1 = 71
|
||||
let UC_TRICORE_REG_CPM2 = 72
|
||||
let UC_TRICORE_REG_CPM3 = 73
|
||||
let UC_TRICORE_REG_MMU_CON = 74
|
||||
let UC_TRICORE_REG_MMU_ASI = 75
|
||||
let UC_TRICORE_REG_MMU_TVA = 76
|
||||
let UC_TRICORE_REG_MMU_TPA = 77
|
||||
let UC_TRICORE_REG_MMU_TPX = 78
|
||||
let UC_TRICORE_REG_MMU_TFA = 79
|
||||
let UC_TRICORE_REG_BMACON = 80
|
||||
let UC_TRICORE_REG_SMACON = 81
|
||||
let UC_TRICORE_REG_DIEAR = 82
|
||||
let UC_TRICORE_REG_DIETR = 83
|
||||
let UC_TRICORE_REG_CCDIER = 84
|
||||
let UC_TRICORE_REG_MIECON = 85
|
||||
let UC_TRICORE_REG_PIEAR = 86
|
||||
let UC_TRICORE_REG_PIETR = 87
|
||||
let UC_TRICORE_REG_CCPIER = 88
|
||||
let UC_TRICORE_REG_DBGSR = 89
|
||||
let UC_TRICORE_REG_EXEVT = 90
|
||||
let UC_TRICORE_REG_CREVT = 91
|
||||
let UC_TRICORE_REG_SWEVT = 92
|
||||
let UC_TRICORE_REG_TR0EVT = 93
|
||||
let UC_TRICORE_REG_TR1EVT = 94
|
||||
let UC_TRICORE_REG_DMS = 95
|
||||
let UC_TRICORE_REG_DCX = 96
|
||||
let UC_TRICORE_REG_DBGTCR = 97
|
||||
let UC_TRICORE_REG_CCTRL = 98
|
||||
let UC_TRICORE_REG_CCNT = 99
|
||||
let UC_TRICORE_REG_ICNT = 100
|
||||
let UC_TRICORE_REG_M1CNT = 101
|
||||
let UC_TRICORE_REG_M2CNT = 102
|
||||
let UC_TRICORE_REG_M3CNT = 103
|
||||
let UC_TRICORE_REG_ENDING = 104
|
||||
let UC_TRICORE_REG_GA0 = 1
|
||||
let UC_TRICORE_REG_GA1 = 2
|
||||
let UC_TRICORE_REG_GA8 = 9
|
||||
let UC_TRICORE_REG_GA9 = 10
|
||||
let UC_TRICORE_REG_SP = 11
|
||||
let UC_TRICORE_REG_LR = 12
|
||||
let UC_TRICORE_REG_IA = 16
|
||||
let UC_TRICORE_REG_ID = 32
|
||||
|
127
bindings/go/unicorn/tricore_const.go
Normal file
127
bindings/go/unicorn/tricore_const.go
Normal file
@ -0,0 +1,127 @@
|
||||
package unicorn
|
||||
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [tricore_const.go]
|
||||
const (
|
||||
|
||||
// TRICORE CPU
|
||||
|
||||
CPU_TRICORE_TC1796 = 0
|
||||
CPU_TRICORE_TC1797 = 1
|
||||
CPU_TRICORE_TC27X = 2
|
||||
CPU_TRICORE_ENDING = 3
|
||||
|
||||
// TRICORE registers
|
||||
|
||||
TRICORE_REG_INVALID = 0
|
||||
TRICORE_REG_A0 = 1
|
||||
TRICORE_REG_A1 = 2
|
||||
TRICORE_REG_A2 = 3
|
||||
TRICORE_REG_A3 = 4
|
||||
TRICORE_REG_A4 = 5
|
||||
TRICORE_REG_A5 = 6
|
||||
TRICORE_REG_A6 = 7
|
||||
TRICORE_REG_A7 = 8
|
||||
TRICORE_REG_A8 = 9
|
||||
TRICORE_REG_A9 = 10
|
||||
TRICORE_REG_A10 = 11
|
||||
TRICORE_REG_A11 = 12
|
||||
TRICORE_REG_A12 = 13
|
||||
TRICORE_REG_A13 = 14
|
||||
TRICORE_REG_A14 = 15
|
||||
TRICORE_REG_A15 = 16
|
||||
TRICORE_REG_D0 = 17
|
||||
TRICORE_REG_D1 = 18
|
||||
TRICORE_REG_D2 = 19
|
||||
TRICORE_REG_D3 = 20
|
||||
TRICORE_REG_D4 = 21
|
||||
TRICORE_REG_D5 = 22
|
||||
TRICORE_REG_D6 = 23
|
||||
TRICORE_REG_D7 = 24
|
||||
TRICORE_REG_D8 = 25
|
||||
TRICORE_REG_D9 = 26
|
||||
TRICORE_REG_D10 = 27
|
||||
TRICORE_REG_D11 = 28
|
||||
TRICORE_REG_D12 = 29
|
||||
TRICORE_REG_D13 = 30
|
||||
TRICORE_REG_D14 = 31
|
||||
TRICORE_REG_D15 = 32
|
||||
TRICORE_REG_PCXI = 33
|
||||
TRICORE_REG_PSW = 34
|
||||
TRICORE_REG_PSW_USB_C = 35
|
||||
TRICORE_REG_PSW_USB_V = 36
|
||||
TRICORE_REG_PSW_USB_SV = 37
|
||||
TRICORE_REG_PSW_USB_AV = 38
|
||||
TRICORE_REG_PSW_USB_SAV = 39
|
||||
TRICORE_REG_PC = 40
|
||||
TRICORE_REG_SYSCON = 41
|
||||
TRICORE_REG_CPU_ID = 42
|
||||
TRICORE_REG_BIV = 43
|
||||
TRICORE_REG_BTV = 44
|
||||
TRICORE_REG_ISP = 45
|
||||
TRICORE_REG_ICR = 46
|
||||
TRICORE_REG_FCX = 47
|
||||
TRICORE_REG_LCX = 48
|
||||
TRICORE_REG_COMPAT = 49
|
||||
TRICORE_REG_DPR0_U = 50
|
||||
TRICORE_REG_DPR1_U = 51
|
||||
TRICORE_REG_DPR2_U = 52
|
||||
TRICORE_REG_DPR3_U = 53
|
||||
TRICORE_REG_DPR0_L = 54
|
||||
TRICORE_REG_DPR1_L = 55
|
||||
TRICORE_REG_DPR2_L = 56
|
||||
TRICORE_REG_DPR3_L = 57
|
||||
TRICORE_REG_CPR0_U = 58
|
||||
TRICORE_REG_CPR1_U = 59
|
||||
TRICORE_REG_CPR2_U = 60
|
||||
TRICORE_REG_CPR3_U = 61
|
||||
TRICORE_REG_CPR0_L = 62
|
||||
TRICORE_REG_CPR1_L = 63
|
||||
TRICORE_REG_CPR2_L = 64
|
||||
TRICORE_REG_CPR3_L = 65
|
||||
TRICORE_REG_DPM0 = 66
|
||||
TRICORE_REG_DPM1 = 67
|
||||
TRICORE_REG_DPM2 = 68
|
||||
TRICORE_REG_DPM3 = 69
|
||||
TRICORE_REG_CPM0 = 70
|
||||
TRICORE_REG_CPM1 = 71
|
||||
TRICORE_REG_CPM2 = 72
|
||||
TRICORE_REG_CPM3 = 73
|
||||
TRICORE_REG_MMU_CON = 74
|
||||
TRICORE_REG_MMU_ASI = 75
|
||||
TRICORE_REG_MMU_TVA = 76
|
||||
TRICORE_REG_MMU_TPA = 77
|
||||
TRICORE_REG_MMU_TPX = 78
|
||||
TRICORE_REG_MMU_TFA = 79
|
||||
TRICORE_REG_BMACON = 80
|
||||
TRICORE_REG_SMACON = 81
|
||||
TRICORE_REG_DIEAR = 82
|
||||
TRICORE_REG_DIETR = 83
|
||||
TRICORE_REG_CCDIER = 84
|
||||
TRICORE_REG_MIECON = 85
|
||||
TRICORE_REG_PIEAR = 86
|
||||
TRICORE_REG_PIETR = 87
|
||||
TRICORE_REG_CCPIER = 88
|
||||
TRICORE_REG_DBGSR = 89
|
||||
TRICORE_REG_EXEVT = 90
|
||||
TRICORE_REG_CREVT = 91
|
||||
TRICORE_REG_SWEVT = 92
|
||||
TRICORE_REG_TR0EVT = 93
|
||||
TRICORE_REG_TR1EVT = 94
|
||||
TRICORE_REG_DMS = 95
|
||||
TRICORE_REG_DCX = 96
|
||||
TRICORE_REG_DBGTCR = 97
|
||||
TRICORE_REG_CCTRL = 98
|
||||
TRICORE_REG_CCNT = 99
|
||||
TRICORE_REG_ICNT = 100
|
||||
TRICORE_REG_M1CNT = 101
|
||||
TRICORE_REG_M2CNT = 102
|
||||
TRICORE_REG_M3CNT = 103
|
||||
TRICORE_REG_ENDING = 104
|
||||
TRICORE_REG_GA0 = 1
|
||||
TRICORE_REG_GA1 = 2
|
||||
TRICORE_REG_GA8 = 9
|
||||
TRICORE_REG_GA9 = 10
|
||||
TRICORE_REG_SP = 11
|
||||
TRICORE_REG_LR = 12
|
||||
TRICORE_REG_IA = 16
|
||||
TRICORE_REG_ID = 32
|
||||
)
|
@ -24,7 +24,8 @@ const (
|
||||
ARCH_M68K = 7
|
||||
ARCH_RISCV = 8
|
||||
ARCH_S390X = 9
|
||||
ARCH_MAX = 10
|
||||
ARCH_TRICORE = 10
|
||||
ARCH_MAX = 11
|
||||
|
||||
MODE_LITTLE_ENDIAN = 0
|
||||
MODE_BIG_ENDIAN = 1073741824
|
||||
|
130
bindings/java/unicorn/TriCoreConst.java
Normal file
130
bindings/java/unicorn/TriCoreConst.java
Normal file
@ -0,0 +1,130 @@
|
||||
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
|
||||
|
||||
package unicorn;
|
||||
|
||||
public interface TriCoreConst {
|
||||
|
||||
// TRICORE CPU
|
||||
|
||||
public static final int UC_CPU_TRICORE_TC1796 = 0;
|
||||
public static final int UC_CPU_TRICORE_TC1797 = 1;
|
||||
public static final int UC_CPU_TRICORE_TC27X = 2;
|
||||
public static final int UC_CPU_TRICORE_ENDING = 3;
|
||||
|
||||
// TRICORE registers
|
||||
|
||||
public static final int UC_TRICORE_REG_INVALID = 0;
|
||||
public static final int UC_TRICORE_REG_A0 = 1;
|
||||
public static final int UC_TRICORE_REG_A1 = 2;
|
||||
public static final int UC_TRICORE_REG_A2 = 3;
|
||||
public static final int UC_TRICORE_REG_A3 = 4;
|
||||
public static final int UC_TRICORE_REG_A4 = 5;
|
||||
public static final int UC_TRICORE_REG_A5 = 6;
|
||||
public static final int UC_TRICORE_REG_A6 = 7;
|
||||
public static final int UC_TRICORE_REG_A7 = 8;
|
||||
public static final int UC_TRICORE_REG_A8 = 9;
|
||||
public static final int UC_TRICORE_REG_A9 = 10;
|
||||
public static final int UC_TRICORE_REG_A10 = 11;
|
||||
public static final int UC_TRICORE_REG_A11 = 12;
|
||||
public static final int UC_TRICORE_REG_A12 = 13;
|
||||
public static final int UC_TRICORE_REG_A13 = 14;
|
||||
public static final int UC_TRICORE_REG_A14 = 15;
|
||||
public static final int UC_TRICORE_REG_A15 = 16;
|
||||
public static final int UC_TRICORE_REG_D0 = 17;
|
||||
public static final int UC_TRICORE_REG_D1 = 18;
|
||||
public static final int UC_TRICORE_REG_D2 = 19;
|
||||
public static final int UC_TRICORE_REG_D3 = 20;
|
||||
public static final int UC_TRICORE_REG_D4 = 21;
|
||||
public static final int UC_TRICORE_REG_D5 = 22;
|
||||
public static final int UC_TRICORE_REG_D6 = 23;
|
||||
public static final int UC_TRICORE_REG_D7 = 24;
|
||||
public static final int UC_TRICORE_REG_D8 = 25;
|
||||
public static final int UC_TRICORE_REG_D9 = 26;
|
||||
public static final int UC_TRICORE_REG_D10 = 27;
|
||||
public static final int UC_TRICORE_REG_D11 = 28;
|
||||
public static final int UC_TRICORE_REG_D12 = 29;
|
||||
public static final int UC_TRICORE_REG_D13 = 30;
|
||||
public static final int UC_TRICORE_REG_D14 = 31;
|
||||
public static final int UC_TRICORE_REG_D15 = 32;
|
||||
public static final int UC_TRICORE_REG_PCXI = 33;
|
||||
public static final int UC_TRICORE_REG_PSW = 34;
|
||||
public static final int UC_TRICORE_REG_PSW_USB_C = 35;
|
||||
public static final int UC_TRICORE_REG_PSW_USB_V = 36;
|
||||
public static final int UC_TRICORE_REG_PSW_USB_SV = 37;
|
||||
public static final int UC_TRICORE_REG_PSW_USB_AV = 38;
|
||||
public static final int UC_TRICORE_REG_PSW_USB_SAV = 39;
|
||||
public static final int UC_TRICORE_REG_PC = 40;
|
||||
public static final int UC_TRICORE_REG_SYSCON = 41;
|
||||
public static final int UC_TRICORE_REG_CPU_ID = 42;
|
||||
public static final int UC_TRICORE_REG_BIV = 43;
|
||||
public static final int UC_TRICORE_REG_BTV = 44;
|
||||
public static final int UC_TRICORE_REG_ISP = 45;
|
||||
public static final int UC_TRICORE_REG_ICR = 46;
|
||||
public static final int UC_TRICORE_REG_FCX = 47;
|
||||
public static final int UC_TRICORE_REG_LCX = 48;
|
||||
public static final int UC_TRICORE_REG_COMPAT = 49;
|
||||
public static final int UC_TRICORE_REG_DPR0_U = 50;
|
||||
public static final int UC_TRICORE_REG_DPR1_U = 51;
|
||||
public static final int UC_TRICORE_REG_DPR2_U = 52;
|
||||
public static final int UC_TRICORE_REG_DPR3_U = 53;
|
||||
public static final int UC_TRICORE_REG_DPR0_L = 54;
|
||||
public static final int UC_TRICORE_REG_DPR1_L = 55;
|
||||
public static final int UC_TRICORE_REG_DPR2_L = 56;
|
||||
public static final int UC_TRICORE_REG_DPR3_L = 57;
|
||||
public static final int UC_TRICORE_REG_CPR0_U = 58;
|
||||
public static final int UC_TRICORE_REG_CPR1_U = 59;
|
||||
public static final int UC_TRICORE_REG_CPR2_U = 60;
|
||||
public static final int UC_TRICORE_REG_CPR3_U = 61;
|
||||
public static final int UC_TRICORE_REG_CPR0_L = 62;
|
||||
public static final int UC_TRICORE_REG_CPR1_L = 63;
|
||||
public static final int UC_TRICORE_REG_CPR2_L = 64;
|
||||
public static final int UC_TRICORE_REG_CPR3_L = 65;
|
||||
public static final int UC_TRICORE_REG_DPM0 = 66;
|
||||
public static final int UC_TRICORE_REG_DPM1 = 67;
|
||||
public static final int UC_TRICORE_REG_DPM2 = 68;
|
||||
public static final int UC_TRICORE_REG_DPM3 = 69;
|
||||
public static final int UC_TRICORE_REG_CPM0 = 70;
|
||||
public static final int UC_TRICORE_REG_CPM1 = 71;
|
||||
public static final int UC_TRICORE_REG_CPM2 = 72;
|
||||
public static final int UC_TRICORE_REG_CPM3 = 73;
|
||||
public static final int UC_TRICORE_REG_MMU_CON = 74;
|
||||
public static final int UC_TRICORE_REG_MMU_ASI = 75;
|
||||
public static final int UC_TRICORE_REG_MMU_TVA = 76;
|
||||
public static final int UC_TRICORE_REG_MMU_TPA = 77;
|
||||
public static final int UC_TRICORE_REG_MMU_TPX = 78;
|
||||
public static final int UC_TRICORE_REG_MMU_TFA = 79;
|
||||
public static final int UC_TRICORE_REG_BMACON = 80;
|
||||
public static final int UC_TRICORE_REG_SMACON = 81;
|
||||
public static final int UC_TRICORE_REG_DIEAR = 82;
|
||||
public static final int UC_TRICORE_REG_DIETR = 83;
|
||||
public static final int UC_TRICORE_REG_CCDIER = 84;
|
||||
public static final int UC_TRICORE_REG_MIECON = 85;
|
||||
public static final int UC_TRICORE_REG_PIEAR = 86;
|
||||
public static final int UC_TRICORE_REG_PIETR = 87;
|
||||
public static final int UC_TRICORE_REG_CCPIER = 88;
|
||||
public static final int UC_TRICORE_REG_DBGSR = 89;
|
||||
public static final int UC_TRICORE_REG_EXEVT = 90;
|
||||
public static final int UC_TRICORE_REG_CREVT = 91;
|
||||
public static final int UC_TRICORE_REG_SWEVT = 92;
|
||||
public static final int UC_TRICORE_REG_TR0EVT = 93;
|
||||
public static final int UC_TRICORE_REG_TR1EVT = 94;
|
||||
public static final int UC_TRICORE_REG_DMS = 95;
|
||||
public static final int UC_TRICORE_REG_DCX = 96;
|
||||
public static final int UC_TRICORE_REG_DBGTCR = 97;
|
||||
public static final int UC_TRICORE_REG_CCTRL = 98;
|
||||
public static final int UC_TRICORE_REG_CCNT = 99;
|
||||
public static final int UC_TRICORE_REG_ICNT = 100;
|
||||
public static final int UC_TRICORE_REG_M1CNT = 101;
|
||||
public static final int UC_TRICORE_REG_M2CNT = 102;
|
||||
public static final int UC_TRICORE_REG_M3CNT = 103;
|
||||
public static final int UC_TRICORE_REG_ENDING = 104;
|
||||
public static final int UC_TRICORE_REG_GA0 = 1;
|
||||
public static final int UC_TRICORE_REG_GA1 = 2;
|
||||
public static final int UC_TRICORE_REG_GA8 = 9;
|
||||
public static final int UC_TRICORE_REG_GA9 = 10;
|
||||
public static final int UC_TRICORE_REG_SP = 11;
|
||||
public static final int UC_TRICORE_REG_LR = 12;
|
||||
public static final int UC_TRICORE_REG_IA = 16;
|
||||
public static final int UC_TRICORE_REG_ID = 32;
|
||||
|
||||
}
|
@ -26,7 +26,8 @@ public interface UnicornConst {
|
||||
public static final int UC_ARCH_M68K = 7;
|
||||
public static final int UC_ARCH_RISCV = 8;
|
||||
public static final int UC_ARCH_S390X = 9;
|
||||
public static final int UC_ARCH_MAX = 10;
|
||||
public static final int UC_ARCH_TRICORE = 10;
|
||||
public static final int UC_ARCH_MAX = 11;
|
||||
|
||||
public static final int UC_MODE_LITTLE_ENDIAN = 0;
|
||||
public static final int UC_MODE_BIG_ENDIAN = 1073741824;
|
||||
|
132
bindings/pascal/unicorn/TriCoreConst.pas
Normal file
132
bindings/pascal/unicorn/TriCoreConst.pas
Normal file
@ -0,0 +1,132 @@
|
||||
// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT
|
||||
|
||||
unit TriCoreConst;
|
||||
|
||||
interface
|
||||
|
||||
const
|
||||
// TRICORE CPU
|
||||
|
||||
UC_CPU_TRICORE_TC1796 = 0;
|
||||
UC_CPU_TRICORE_TC1797 = 1;
|
||||
UC_CPU_TRICORE_TC27X = 2;
|
||||
UC_CPU_TRICORE_ENDING = 3;
|
||||
|
||||
// TRICORE registers
|
||||
|
||||
UC_TRICORE_REG_INVALID = 0;
|
||||
UC_TRICORE_REG_A0 = 1;
|
||||
UC_TRICORE_REG_A1 = 2;
|
||||
UC_TRICORE_REG_A2 = 3;
|
||||
UC_TRICORE_REG_A3 = 4;
|
||||
UC_TRICORE_REG_A4 = 5;
|
||||
UC_TRICORE_REG_A5 = 6;
|
||||
UC_TRICORE_REG_A6 = 7;
|
||||
UC_TRICORE_REG_A7 = 8;
|
||||
UC_TRICORE_REG_A8 = 9;
|
||||
UC_TRICORE_REG_A9 = 10;
|
||||
UC_TRICORE_REG_A10 = 11;
|
||||
UC_TRICORE_REG_A11 = 12;
|
||||
UC_TRICORE_REG_A12 = 13;
|
||||
UC_TRICORE_REG_A13 = 14;
|
||||
UC_TRICORE_REG_A14 = 15;
|
||||
UC_TRICORE_REG_A15 = 16;
|
||||
UC_TRICORE_REG_D0 = 17;
|
||||
UC_TRICORE_REG_D1 = 18;
|
||||
UC_TRICORE_REG_D2 = 19;
|
||||
UC_TRICORE_REG_D3 = 20;
|
||||
UC_TRICORE_REG_D4 = 21;
|
||||
UC_TRICORE_REG_D5 = 22;
|
||||
UC_TRICORE_REG_D6 = 23;
|
||||
UC_TRICORE_REG_D7 = 24;
|
||||
UC_TRICORE_REG_D8 = 25;
|
||||
UC_TRICORE_REG_D9 = 26;
|
||||
UC_TRICORE_REG_D10 = 27;
|
||||
UC_TRICORE_REG_D11 = 28;
|
||||
UC_TRICORE_REG_D12 = 29;
|
||||
UC_TRICORE_REG_D13 = 30;
|
||||
UC_TRICORE_REG_D14 = 31;
|
||||
UC_TRICORE_REG_D15 = 32;
|
||||
UC_TRICORE_REG_PCXI = 33;
|
||||
UC_TRICORE_REG_PSW = 34;
|
||||
UC_TRICORE_REG_PSW_USB_C = 35;
|
||||
UC_TRICORE_REG_PSW_USB_V = 36;
|
||||
UC_TRICORE_REG_PSW_USB_SV = 37;
|
||||
UC_TRICORE_REG_PSW_USB_AV = 38;
|
||||
UC_TRICORE_REG_PSW_USB_SAV = 39;
|
||||
UC_TRICORE_REG_PC = 40;
|
||||
UC_TRICORE_REG_SYSCON = 41;
|
||||
UC_TRICORE_REG_CPU_ID = 42;
|
||||
UC_TRICORE_REG_BIV = 43;
|
||||
UC_TRICORE_REG_BTV = 44;
|
||||
UC_TRICORE_REG_ISP = 45;
|
||||
UC_TRICORE_REG_ICR = 46;
|
||||
UC_TRICORE_REG_FCX = 47;
|
||||
UC_TRICORE_REG_LCX = 48;
|
||||
UC_TRICORE_REG_COMPAT = 49;
|
||||
UC_TRICORE_REG_DPR0_U = 50;
|
||||
UC_TRICORE_REG_DPR1_U = 51;
|
||||
UC_TRICORE_REG_DPR2_U = 52;
|
||||
UC_TRICORE_REG_DPR3_U = 53;
|
||||
UC_TRICORE_REG_DPR0_L = 54;
|
||||
UC_TRICORE_REG_DPR1_L = 55;
|
||||
UC_TRICORE_REG_DPR2_L = 56;
|
||||
UC_TRICORE_REG_DPR3_L = 57;
|
||||
UC_TRICORE_REG_CPR0_U = 58;
|
||||
UC_TRICORE_REG_CPR1_U = 59;
|
||||
UC_TRICORE_REG_CPR2_U = 60;
|
||||
UC_TRICORE_REG_CPR3_U = 61;
|
||||
UC_TRICORE_REG_CPR0_L = 62;
|
||||
UC_TRICORE_REG_CPR1_L = 63;
|
||||
UC_TRICORE_REG_CPR2_L = 64;
|
||||
UC_TRICORE_REG_CPR3_L = 65;
|
||||
UC_TRICORE_REG_DPM0 = 66;
|
||||
UC_TRICORE_REG_DPM1 = 67;
|
||||
UC_TRICORE_REG_DPM2 = 68;
|
||||
UC_TRICORE_REG_DPM3 = 69;
|
||||
UC_TRICORE_REG_CPM0 = 70;
|
||||
UC_TRICORE_REG_CPM1 = 71;
|
||||
UC_TRICORE_REG_CPM2 = 72;
|
||||
UC_TRICORE_REG_CPM3 = 73;
|
||||
UC_TRICORE_REG_MMU_CON = 74;
|
||||
UC_TRICORE_REG_MMU_ASI = 75;
|
||||
UC_TRICORE_REG_MMU_TVA = 76;
|
||||
UC_TRICORE_REG_MMU_TPA = 77;
|
||||
UC_TRICORE_REG_MMU_TPX = 78;
|
||||
UC_TRICORE_REG_MMU_TFA = 79;
|
||||
UC_TRICORE_REG_BMACON = 80;
|
||||
UC_TRICORE_REG_SMACON = 81;
|
||||
UC_TRICORE_REG_DIEAR = 82;
|
||||
UC_TRICORE_REG_DIETR = 83;
|
||||
UC_TRICORE_REG_CCDIER = 84;
|
||||
UC_TRICORE_REG_MIECON = 85;
|
||||
UC_TRICORE_REG_PIEAR = 86;
|
||||
UC_TRICORE_REG_PIETR = 87;
|
||||
UC_TRICORE_REG_CCPIER = 88;
|
||||
UC_TRICORE_REG_DBGSR = 89;
|
||||
UC_TRICORE_REG_EXEVT = 90;
|
||||
UC_TRICORE_REG_CREVT = 91;
|
||||
UC_TRICORE_REG_SWEVT = 92;
|
||||
UC_TRICORE_REG_TR0EVT = 93;
|
||||
UC_TRICORE_REG_TR1EVT = 94;
|
||||
UC_TRICORE_REG_DMS = 95;
|
||||
UC_TRICORE_REG_DCX = 96;
|
||||
UC_TRICORE_REG_DBGTCR = 97;
|
||||
UC_TRICORE_REG_CCTRL = 98;
|
||||
UC_TRICORE_REG_CCNT = 99;
|
||||
UC_TRICORE_REG_ICNT = 100;
|
||||
UC_TRICORE_REG_M1CNT = 101;
|
||||
UC_TRICORE_REG_M2CNT = 102;
|
||||
UC_TRICORE_REG_M3CNT = 103;
|
||||
UC_TRICORE_REG_ENDING = 104;
|
||||
UC_TRICORE_REG_GA0 = 1;
|
||||
UC_TRICORE_REG_GA1 = 2;
|
||||
UC_TRICORE_REG_GA8 = 9;
|
||||
UC_TRICORE_REG_GA9 = 10;
|
||||
UC_TRICORE_REG_SP = 11;
|
||||
UC_TRICORE_REG_LR = 12;
|
||||
UC_TRICORE_REG_IA = 16;
|
||||
UC_TRICORE_REG_ID = 32;
|
||||
|
||||
implementation
|
||||
end.
|
@ -27,7 +27,8 @@ const UC_API_MAJOR = 2;
|
||||
UC_ARCH_M68K = 7;
|
||||
UC_ARCH_RISCV = 8;
|
||||
UC_ARCH_S390X = 9;
|
||||
UC_ARCH_MAX = 10;
|
||||
UC_ARCH_TRICORE = 10;
|
||||
UC_ARCH_MAX = 11;
|
||||
|
||||
UC_MODE_LITTLE_ENDIAN = 0;
|
||||
UC_MODE_BIG_ENDIAN = 1073741824;
|
||||
|
57
bindings/python/sample_tricore.py
Executable file
57
bindings/python/sample_tricore.py
Executable file
@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Created for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
'''
|
||||
|
||||
from __future__ import print_function
|
||||
from unicorn import *
|
||||
from unicorn.tricore_const import *
|
||||
|
||||
# code to be emulated
|
||||
TRICORE_CODE = b"\x82\x11\xbb\x00\x00\x08" # mov d0, #0x1; mov.u d0, #0x8000
|
||||
# memory address where emulation starts
|
||||
ADDRESS = 0x10000
|
||||
|
||||
# callback for tracing basic blocks
|
||||
def hook_block(uc, address, size, user_data):
|
||||
print(">>> Tracing basic block at 0x%x, block size = 0x%x" %(address, size))
|
||||
|
||||
# callback for tracing instructions
|
||||
def hook_code(uc, address, size, user_data):
|
||||
print(">>> Tracing instruction at 0x%x, instruction size = 0x%x" %(address, size))
|
||||
|
||||
# Test TriCore
|
||||
def test_tricore():
|
||||
print("Emulate TriCore code")
|
||||
try:
|
||||
# Initialize emulator in TriCore mode
|
||||
mu = Uc(UC_ARCH_TRICORE, UC_MODE_LITTLE_ENDIAN)
|
||||
|
||||
# map 2MB memory for this emulation
|
||||
mu.mem_map(ADDRESS, 2 * 1024 * 1024)
|
||||
|
||||
# write machine code to be emulated to memory
|
||||
mu.mem_write(ADDRESS, TRICORE_CODE)
|
||||
|
||||
# tracing all basic blocks with customized callback
|
||||
mu.hook_add(UC_HOOK_BLOCK, hook_block)
|
||||
|
||||
# tracing one instruction at ADDRESS with customized callback
|
||||
mu.hook_add(UC_HOOK_CODE, hook_code)
|
||||
|
||||
# emulate machine code in infinite time
|
||||
mu.emu_start(ADDRESS, ADDRESS + len(TRICORE_CODE))
|
||||
|
||||
# now print out some registers
|
||||
print(">>> Emulation done. Below is the CPU context")
|
||||
|
||||
r0 = mu.reg_read(UC_TRICORE_REG_D0)
|
||||
print(">>> D0 = 0x%x" %r0)
|
||||
|
||||
except UcError as e:
|
||||
print("ERROR: %s" % e)
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_tricore()
|
124
bindings/python/unicorn/tricore_const.py
Normal file
124
bindings/python/unicorn/tricore_const.py
Normal file
@ -0,0 +1,124 @@
|
||||
# For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [tricore_const.py]
|
||||
|
||||
# TRICORE CPU
|
||||
|
||||
UC_CPU_TRICORE_TC1796 = 0
|
||||
UC_CPU_TRICORE_TC1797 = 1
|
||||
UC_CPU_TRICORE_TC27X = 2
|
||||
UC_CPU_TRICORE_ENDING = 3
|
||||
|
||||
# TRICORE registers
|
||||
|
||||
UC_TRICORE_REG_INVALID = 0
|
||||
UC_TRICORE_REG_A0 = 1
|
||||
UC_TRICORE_REG_A1 = 2
|
||||
UC_TRICORE_REG_A2 = 3
|
||||
UC_TRICORE_REG_A3 = 4
|
||||
UC_TRICORE_REG_A4 = 5
|
||||
UC_TRICORE_REG_A5 = 6
|
||||
UC_TRICORE_REG_A6 = 7
|
||||
UC_TRICORE_REG_A7 = 8
|
||||
UC_TRICORE_REG_A8 = 9
|
||||
UC_TRICORE_REG_A9 = 10
|
||||
UC_TRICORE_REG_A10 = 11
|
||||
UC_TRICORE_REG_A11 = 12
|
||||
UC_TRICORE_REG_A12 = 13
|
||||
UC_TRICORE_REG_A13 = 14
|
||||
UC_TRICORE_REG_A14 = 15
|
||||
UC_TRICORE_REG_A15 = 16
|
||||
UC_TRICORE_REG_D0 = 17
|
||||
UC_TRICORE_REG_D1 = 18
|
||||
UC_TRICORE_REG_D2 = 19
|
||||
UC_TRICORE_REG_D3 = 20
|
||||
UC_TRICORE_REG_D4 = 21
|
||||
UC_TRICORE_REG_D5 = 22
|
||||
UC_TRICORE_REG_D6 = 23
|
||||
UC_TRICORE_REG_D7 = 24
|
||||
UC_TRICORE_REG_D8 = 25
|
||||
UC_TRICORE_REG_D9 = 26
|
||||
UC_TRICORE_REG_D10 = 27
|
||||
UC_TRICORE_REG_D11 = 28
|
||||
UC_TRICORE_REG_D12 = 29
|
||||
UC_TRICORE_REG_D13 = 30
|
||||
UC_TRICORE_REG_D14 = 31
|
||||
UC_TRICORE_REG_D15 = 32
|
||||
UC_TRICORE_REG_PCXI = 33
|
||||
UC_TRICORE_REG_PSW = 34
|
||||
UC_TRICORE_REG_PSW_USB_C = 35
|
||||
UC_TRICORE_REG_PSW_USB_V = 36
|
||||
UC_TRICORE_REG_PSW_USB_SV = 37
|
||||
UC_TRICORE_REG_PSW_USB_AV = 38
|
||||
UC_TRICORE_REG_PSW_USB_SAV = 39
|
||||
UC_TRICORE_REG_PC = 40
|
||||
UC_TRICORE_REG_SYSCON = 41
|
||||
UC_TRICORE_REG_CPU_ID = 42
|
||||
UC_TRICORE_REG_BIV = 43
|
||||
UC_TRICORE_REG_BTV = 44
|
||||
UC_TRICORE_REG_ISP = 45
|
||||
UC_TRICORE_REG_ICR = 46
|
||||
UC_TRICORE_REG_FCX = 47
|
||||
UC_TRICORE_REG_LCX = 48
|
||||
UC_TRICORE_REG_COMPAT = 49
|
||||
UC_TRICORE_REG_DPR0_U = 50
|
||||
UC_TRICORE_REG_DPR1_U = 51
|
||||
UC_TRICORE_REG_DPR2_U = 52
|
||||
UC_TRICORE_REG_DPR3_U = 53
|
||||
UC_TRICORE_REG_DPR0_L = 54
|
||||
UC_TRICORE_REG_DPR1_L = 55
|
||||
UC_TRICORE_REG_DPR2_L = 56
|
||||
UC_TRICORE_REG_DPR3_L = 57
|
||||
UC_TRICORE_REG_CPR0_U = 58
|
||||
UC_TRICORE_REG_CPR1_U = 59
|
||||
UC_TRICORE_REG_CPR2_U = 60
|
||||
UC_TRICORE_REG_CPR3_U = 61
|
||||
UC_TRICORE_REG_CPR0_L = 62
|
||||
UC_TRICORE_REG_CPR1_L = 63
|
||||
UC_TRICORE_REG_CPR2_L = 64
|
||||
UC_TRICORE_REG_CPR3_L = 65
|
||||
UC_TRICORE_REG_DPM0 = 66
|
||||
UC_TRICORE_REG_DPM1 = 67
|
||||
UC_TRICORE_REG_DPM2 = 68
|
||||
UC_TRICORE_REG_DPM3 = 69
|
||||
UC_TRICORE_REG_CPM0 = 70
|
||||
UC_TRICORE_REG_CPM1 = 71
|
||||
UC_TRICORE_REG_CPM2 = 72
|
||||
UC_TRICORE_REG_CPM3 = 73
|
||||
UC_TRICORE_REG_MMU_CON = 74
|
||||
UC_TRICORE_REG_MMU_ASI = 75
|
||||
UC_TRICORE_REG_MMU_TVA = 76
|
||||
UC_TRICORE_REG_MMU_TPA = 77
|
||||
UC_TRICORE_REG_MMU_TPX = 78
|
||||
UC_TRICORE_REG_MMU_TFA = 79
|
||||
UC_TRICORE_REG_BMACON = 80
|
||||
UC_TRICORE_REG_SMACON = 81
|
||||
UC_TRICORE_REG_DIEAR = 82
|
||||
UC_TRICORE_REG_DIETR = 83
|
||||
UC_TRICORE_REG_CCDIER = 84
|
||||
UC_TRICORE_REG_MIECON = 85
|
||||
UC_TRICORE_REG_PIEAR = 86
|
||||
UC_TRICORE_REG_PIETR = 87
|
||||
UC_TRICORE_REG_CCPIER = 88
|
||||
UC_TRICORE_REG_DBGSR = 89
|
||||
UC_TRICORE_REG_EXEVT = 90
|
||||
UC_TRICORE_REG_CREVT = 91
|
||||
UC_TRICORE_REG_SWEVT = 92
|
||||
UC_TRICORE_REG_TR0EVT = 93
|
||||
UC_TRICORE_REG_TR1EVT = 94
|
||||
UC_TRICORE_REG_DMS = 95
|
||||
UC_TRICORE_REG_DCX = 96
|
||||
UC_TRICORE_REG_DBGTCR = 97
|
||||
UC_TRICORE_REG_CCTRL = 98
|
||||
UC_TRICORE_REG_CCNT = 99
|
||||
UC_TRICORE_REG_ICNT = 100
|
||||
UC_TRICORE_REG_M1CNT = 101
|
||||
UC_TRICORE_REG_M2CNT = 102
|
||||
UC_TRICORE_REG_M3CNT = 103
|
||||
UC_TRICORE_REG_ENDING = 104
|
||||
UC_TRICORE_REG_GA0 = 1
|
||||
UC_TRICORE_REG_GA1 = 2
|
||||
UC_TRICORE_REG_GA8 = 9
|
||||
UC_TRICORE_REG_GA9 = 10
|
||||
UC_TRICORE_REG_SP = 11
|
||||
UC_TRICORE_REG_LR = 12
|
||||
UC_TRICORE_REG_IA = 16
|
||||
UC_TRICORE_REG_ID = 32
|
@ -22,7 +22,8 @@ UC_ARCH_SPARC = 6
|
||||
UC_ARCH_M68K = 7
|
||||
UC_ARCH_RISCV = 8
|
||||
UC_ARCH_S390X = 9
|
||||
UC_ARCH_MAX = 10
|
||||
UC_ARCH_TRICORE = 10
|
||||
UC_ARCH_MAX = 11
|
||||
|
||||
UC_MODE_LITTLE_ENDIAN = 0
|
||||
UC_MODE_BIG_ENDIAN = 1073741824
|
||||
|
127
bindings/ruby/unicorn_gem/lib/unicorn_engine/tricore_const.rb
Normal file
127
bindings/ruby/unicorn_gem/lib/unicorn_engine/tricore_const.rb
Normal file
@ -0,0 +1,127 @@
|
||||
# For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT [tricore_const.rb]
|
||||
|
||||
module UnicornEngine
|
||||
|
||||
# TRICORE CPU
|
||||
|
||||
UC_CPU_TRICORE_TC1796 = 0
|
||||
UC_CPU_TRICORE_TC1797 = 1
|
||||
UC_CPU_TRICORE_TC27X = 2
|
||||
UC_CPU_TRICORE_ENDING = 3
|
||||
|
||||
# TRICORE registers
|
||||
|
||||
UC_TRICORE_REG_INVALID = 0
|
||||
UC_TRICORE_REG_A0 = 1
|
||||
UC_TRICORE_REG_A1 = 2
|
||||
UC_TRICORE_REG_A2 = 3
|
||||
UC_TRICORE_REG_A3 = 4
|
||||
UC_TRICORE_REG_A4 = 5
|
||||
UC_TRICORE_REG_A5 = 6
|
||||
UC_TRICORE_REG_A6 = 7
|
||||
UC_TRICORE_REG_A7 = 8
|
||||
UC_TRICORE_REG_A8 = 9
|
||||
UC_TRICORE_REG_A9 = 10
|
||||
UC_TRICORE_REG_A10 = 11
|
||||
UC_TRICORE_REG_A11 = 12
|
||||
UC_TRICORE_REG_A12 = 13
|
||||
UC_TRICORE_REG_A13 = 14
|
||||
UC_TRICORE_REG_A14 = 15
|
||||
UC_TRICORE_REG_A15 = 16
|
||||
UC_TRICORE_REG_D0 = 17
|
||||
UC_TRICORE_REG_D1 = 18
|
||||
UC_TRICORE_REG_D2 = 19
|
||||
UC_TRICORE_REG_D3 = 20
|
||||
UC_TRICORE_REG_D4 = 21
|
||||
UC_TRICORE_REG_D5 = 22
|
||||
UC_TRICORE_REG_D6 = 23
|
||||
UC_TRICORE_REG_D7 = 24
|
||||
UC_TRICORE_REG_D8 = 25
|
||||
UC_TRICORE_REG_D9 = 26
|
||||
UC_TRICORE_REG_D10 = 27
|
||||
UC_TRICORE_REG_D11 = 28
|
||||
UC_TRICORE_REG_D12 = 29
|
||||
UC_TRICORE_REG_D13 = 30
|
||||
UC_TRICORE_REG_D14 = 31
|
||||
UC_TRICORE_REG_D15 = 32
|
||||
UC_TRICORE_REG_PCXI = 33
|
||||
UC_TRICORE_REG_PSW = 34
|
||||
UC_TRICORE_REG_PSW_USB_C = 35
|
||||
UC_TRICORE_REG_PSW_USB_V = 36
|
||||
UC_TRICORE_REG_PSW_USB_SV = 37
|
||||
UC_TRICORE_REG_PSW_USB_AV = 38
|
||||
UC_TRICORE_REG_PSW_USB_SAV = 39
|
||||
UC_TRICORE_REG_PC = 40
|
||||
UC_TRICORE_REG_SYSCON = 41
|
||||
UC_TRICORE_REG_CPU_ID = 42
|
||||
UC_TRICORE_REG_BIV = 43
|
||||
UC_TRICORE_REG_BTV = 44
|
||||
UC_TRICORE_REG_ISP = 45
|
||||
UC_TRICORE_REG_ICR = 46
|
||||
UC_TRICORE_REG_FCX = 47
|
||||
UC_TRICORE_REG_LCX = 48
|
||||
UC_TRICORE_REG_COMPAT = 49
|
||||
UC_TRICORE_REG_DPR0_U = 50
|
||||
UC_TRICORE_REG_DPR1_U = 51
|
||||
UC_TRICORE_REG_DPR2_U = 52
|
||||
UC_TRICORE_REG_DPR3_U = 53
|
||||
UC_TRICORE_REG_DPR0_L = 54
|
||||
UC_TRICORE_REG_DPR1_L = 55
|
||||
UC_TRICORE_REG_DPR2_L = 56
|
||||
UC_TRICORE_REG_DPR3_L = 57
|
||||
UC_TRICORE_REG_CPR0_U = 58
|
||||
UC_TRICORE_REG_CPR1_U = 59
|
||||
UC_TRICORE_REG_CPR2_U = 60
|
||||
UC_TRICORE_REG_CPR3_U = 61
|
||||
UC_TRICORE_REG_CPR0_L = 62
|
||||
UC_TRICORE_REG_CPR1_L = 63
|
||||
UC_TRICORE_REG_CPR2_L = 64
|
||||
UC_TRICORE_REG_CPR3_L = 65
|
||||
UC_TRICORE_REG_DPM0 = 66
|
||||
UC_TRICORE_REG_DPM1 = 67
|
||||
UC_TRICORE_REG_DPM2 = 68
|
||||
UC_TRICORE_REG_DPM3 = 69
|
||||
UC_TRICORE_REG_CPM0 = 70
|
||||
UC_TRICORE_REG_CPM1 = 71
|
||||
UC_TRICORE_REG_CPM2 = 72
|
||||
UC_TRICORE_REG_CPM3 = 73
|
||||
UC_TRICORE_REG_MMU_CON = 74
|
||||
UC_TRICORE_REG_MMU_ASI = 75
|
||||
UC_TRICORE_REG_MMU_TVA = 76
|
||||
UC_TRICORE_REG_MMU_TPA = 77
|
||||
UC_TRICORE_REG_MMU_TPX = 78
|
||||
UC_TRICORE_REG_MMU_TFA = 79
|
||||
UC_TRICORE_REG_BMACON = 80
|
||||
UC_TRICORE_REG_SMACON = 81
|
||||
UC_TRICORE_REG_DIEAR = 82
|
||||
UC_TRICORE_REG_DIETR = 83
|
||||
UC_TRICORE_REG_CCDIER = 84
|
||||
UC_TRICORE_REG_MIECON = 85
|
||||
UC_TRICORE_REG_PIEAR = 86
|
||||
UC_TRICORE_REG_PIETR = 87
|
||||
UC_TRICORE_REG_CCPIER = 88
|
||||
UC_TRICORE_REG_DBGSR = 89
|
||||
UC_TRICORE_REG_EXEVT = 90
|
||||
UC_TRICORE_REG_CREVT = 91
|
||||
UC_TRICORE_REG_SWEVT = 92
|
||||
UC_TRICORE_REG_TR0EVT = 93
|
||||
UC_TRICORE_REG_TR1EVT = 94
|
||||
UC_TRICORE_REG_DMS = 95
|
||||
UC_TRICORE_REG_DCX = 96
|
||||
UC_TRICORE_REG_DBGTCR = 97
|
||||
UC_TRICORE_REG_CCTRL = 98
|
||||
UC_TRICORE_REG_CCNT = 99
|
||||
UC_TRICORE_REG_ICNT = 100
|
||||
UC_TRICORE_REG_M1CNT = 101
|
||||
UC_TRICORE_REG_M2CNT = 102
|
||||
UC_TRICORE_REG_M3CNT = 103
|
||||
UC_TRICORE_REG_ENDING = 104
|
||||
UC_TRICORE_REG_GA0 = 1
|
||||
UC_TRICORE_REG_GA1 = 2
|
||||
UC_TRICORE_REG_GA8 = 9
|
||||
UC_TRICORE_REG_GA9 = 10
|
||||
UC_TRICORE_REG_SP = 11
|
||||
UC_TRICORE_REG_LR = 12
|
||||
UC_TRICORE_REG_IA = 16
|
||||
UC_TRICORE_REG_ID = 32
|
||||
end
|
@ -24,7 +24,8 @@ module UnicornEngine
|
||||
UC_ARCH_M68K = 7
|
||||
UC_ARCH_RISCV = 8
|
||||
UC_ARCH_S390X = 9
|
||||
UC_ARCH_MAX = 10
|
||||
UC_ARCH_TRICORE = 10
|
||||
UC_ARCH_MAX = 11
|
||||
|
||||
UC_MODE_LITTLE_ENDIAN = 0
|
||||
UC_MODE_BIG_ENDIAN = 1073741824
|
||||
|
@ -33,6 +33,7 @@
|
||||
#define UC_MODE_RISCV_MASK \
|
||||
(UC_MODE_RISCV32 | UC_MODE_RISCV64 | UC_MODE_LITTLE_ENDIAN)
|
||||
#define UC_MODE_S390X_MASK (UC_MODE_BIG_ENDIAN)
|
||||
#define UC_MODE_TRICORE_MASK (UC_MODE_LITTLE_ENDIAN)
|
||||
|
||||
#define ARR_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
|
174
include/unicorn/tricore.h
Normal file
174
include/unicorn/tricore.h
Normal file
@ -0,0 +1,174 @@
|
||||
/* This file is released under LGPL2.
|
||||
See COPYING.LGPL2 in root directory for more details
|
||||
*/
|
||||
|
||||
/*
|
||||
Created for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
*/
|
||||
|
||||
#ifndef UNICORN_TRICORE_H
|
||||
#define UNICORN_TRICORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4201)
|
||||
#endif
|
||||
|
||||
//> TRICORE CPU
|
||||
typedef enum uc_cpu_tricore {
|
||||
UC_CPU_TRICORE_TC1796,
|
||||
UC_CPU_TRICORE_TC1797,
|
||||
UC_CPU_TRICORE_TC27X,
|
||||
|
||||
UC_CPU_TRICORE_ENDING
|
||||
} uc_cpu_tricore;
|
||||
|
||||
//> TRICORE registers
|
||||
typedef enum uc_tricore_reg {
|
||||
UC_TRICORE_REG_INVALID = 0,
|
||||
|
||||
// General purpose registers (GPR)
|
||||
// Address GPR
|
||||
UC_TRICORE_REG_A0,
|
||||
UC_TRICORE_REG_A1,
|
||||
UC_TRICORE_REG_A2,
|
||||
UC_TRICORE_REG_A3,
|
||||
UC_TRICORE_REG_A4,
|
||||
UC_TRICORE_REG_A5,
|
||||
UC_TRICORE_REG_A6,
|
||||
UC_TRICORE_REG_A7,
|
||||
UC_TRICORE_REG_A8,
|
||||
UC_TRICORE_REG_A9,
|
||||
UC_TRICORE_REG_A10,
|
||||
UC_TRICORE_REG_A11,
|
||||
UC_TRICORE_REG_A12,
|
||||
UC_TRICORE_REG_A13,
|
||||
UC_TRICORE_REG_A14,
|
||||
UC_TRICORE_REG_A15,
|
||||
// Data GPR
|
||||
UC_TRICORE_REG_D0,
|
||||
UC_TRICORE_REG_D1,
|
||||
UC_TRICORE_REG_D2,
|
||||
UC_TRICORE_REG_D3,
|
||||
UC_TRICORE_REG_D4,
|
||||
UC_TRICORE_REG_D5,
|
||||
UC_TRICORE_REG_D6,
|
||||
UC_TRICORE_REG_D7,
|
||||
UC_TRICORE_REG_D8,
|
||||
UC_TRICORE_REG_D9,
|
||||
UC_TRICORE_REG_D10,
|
||||
UC_TRICORE_REG_D11,
|
||||
UC_TRICORE_REG_D12,
|
||||
UC_TRICORE_REG_D13,
|
||||
UC_TRICORE_REG_D14,
|
||||
UC_TRICORE_REG_D15,
|
||||
|
||||
/* CSFR Register */
|
||||
UC_TRICORE_REG_PCXI,
|
||||
|
||||
UC_TRICORE_REG_PSW,
|
||||
|
||||
/* PSW flag cache for faster execution */
|
||||
UC_TRICORE_REG_PSW_USB_C,
|
||||
UC_TRICORE_REG_PSW_USB_V,
|
||||
UC_TRICORE_REG_PSW_USB_SV,
|
||||
UC_TRICORE_REG_PSW_USB_AV,
|
||||
UC_TRICORE_REG_PSW_USB_SAV,
|
||||
|
||||
UC_TRICORE_REG_PC,
|
||||
UC_TRICORE_REG_SYSCON,
|
||||
UC_TRICORE_REG_CPU_ID,
|
||||
UC_TRICORE_REG_BIV,
|
||||
UC_TRICORE_REG_BTV,
|
||||
UC_TRICORE_REG_ISP,
|
||||
UC_TRICORE_REG_ICR,
|
||||
UC_TRICORE_REG_FCX,
|
||||
UC_TRICORE_REG_LCX,
|
||||
UC_TRICORE_REG_COMPAT,
|
||||
|
||||
UC_TRICORE_REG_DPR0_U,
|
||||
UC_TRICORE_REG_DPR1_U,
|
||||
UC_TRICORE_REG_DPR2_U,
|
||||
UC_TRICORE_REG_DPR3_U,
|
||||
UC_TRICORE_REG_DPR0_L,
|
||||
UC_TRICORE_REG_DPR1_L,
|
||||
UC_TRICORE_REG_DPR2_L,
|
||||
UC_TRICORE_REG_DPR3_L,
|
||||
|
||||
UC_TRICORE_REG_CPR0_U,
|
||||
UC_TRICORE_REG_CPR1_U,
|
||||
UC_TRICORE_REG_CPR2_U,
|
||||
UC_TRICORE_REG_CPR3_U,
|
||||
UC_TRICORE_REG_CPR0_L,
|
||||
UC_TRICORE_REG_CPR1_L,
|
||||
UC_TRICORE_REG_CPR2_L,
|
||||
UC_TRICORE_REG_CPR3_L,
|
||||
|
||||
UC_TRICORE_REG_DPM0,
|
||||
UC_TRICORE_REG_DPM1,
|
||||
UC_TRICORE_REG_DPM2,
|
||||
UC_TRICORE_REG_DPM3,
|
||||
|
||||
UC_TRICORE_REG_CPM0,
|
||||
UC_TRICORE_REG_CPM1,
|
||||
UC_TRICORE_REG_CPM2,
|
||||
UC_TRICORE_REG_CPM3,
|
||||
|
||||
/* Memory Management Registers */
|
||||
UC_TRICORE_REG_MMU_CON,
|
||||
UC_TRICORE_REG_MMU_ASI,
|
||||
UC_TRICORE_REG_MMU_TVA,
|
||||
UC_TRICORE_REG_MMU_TPA,
|
||||
UC_TRICORE_REG_MMU_TPX,
|
||||
UC_TRICORE_REG_MMU_TFA,
|
||||
|
||||
// 1.3.1 Only
|
||||
UC_TRICORE_REG_BMACON,
|
||||
UC_TRICORE_REG_SMACON,
|
||||
UC_TRICORE_REG_DIEAR,
|
||||
UC_TRICORE_REG_DIETR,
|
||||
UC_TRICORE_REG_CCDIER,
|
||||
UC_TRICORE_REG_MIECON,
|
||||
UC_TRICORE_REG_PIEAR,
|
||||
UC_TRICORE_REG_PIETR,
|
||||
UC_TRICORE_REG_CCPIER,
|
||||
|
||||
/* Debug Registers */
|
||||
UC_TRICORE_REG_DBGSR,
|
||||
UC_TRICORE_REG_EXEVT,
|
||||
UC_TRICORE_REG_CREVT,
|
||||
UC_TRICORE_REG_SWEVT,
|
||||
UC_TRICORE_REG_TR0EVT,
|
||||
UC_TRICORE_REG_TR1EVT,
|
||||
UC_TRICORE_REG_DMS,
|
||||
UC_TRICORE_REG_DCX,
|
||||
UC_TRICORE_REG_DBGTCR,
|
||||
UC_TRICORE_REG_CCTRL,
|
||||
UC_TRICORE_REG_CCNT,
|
||||
UC_TRICORE_REG_ICNT,
|
||||
UC_TRICORE_REG_M1CNT,
|
||||
UC_TRICORE_REG_M2CNT,
|
||||
UC_TRICORE_REG_M3CNT,
|
||||
|
||||
UC_TRICORE_REG_ENDING, // <-- mark the end of the list of registers
|
||||
|
||||
// alias registers
|
||||
UC_TRICORE_REG_GA0 = UC_TRICORE_REG_A0,
|
||||
UC_TRICORE_REG_GA1 = UC_TRICORE_REG_A1,
|
||||
UC_TRICORE_REG_GA8 = UC_TRICORE_REG_A8,
|
||||
UC_TRICORE_REG_GA9 = UC_TRICORE_REG_A9,
|
||||
UC_TRICORE_REG_SP = UC_TRICORE_REG_A10,
|
||||
UC_TRICORE_REG_LR = UC_TRICORE_REG_A11,
|
||||
UC_TRICORE_REG_IA = UC_TRICORE_REG_A15,
|
||||
UC_TRICORE_REG_ID = UC_TRICORE_REG_D15,
|
||||
} uc_tricore_reg;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -35,6 +35,7 @@ typedef size_t uc_hook;
|
||||
#include "ppc.h"
|
||||
#include "riscv.h"
|
||||
#include "s390x.h"
|
||||
#include "tricore.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define DEFAULT_VISIBILITY __attribute__((visibility("default")))
|
||||
@ -103,6 +104,7 @@ typedef enum uc_arch {
|
||||
UC_ARCH_M68K, // M68K architecture
|
||||
UC_ARCH_RISCV, // RISCV architecture
|
||||
UC_ARCH_S390X, // S390X architecture
|
||||
UC_ARCH_TRICORE, // TriCore architecture
|
||||
UC_ARCH_MAX,
|
||||
} uc_arch;
|
||||
|
||||
|
5
msvc/tricore-softmmu/config-target.h
Normal file
5
msvc/tricore-softmmu/config-target.h
Normal file
@ -0,0 +1,5 @@
|
||||
/* Automatically generated by create_config - do not modify */
|
||||
#define TARGET_TRICORE 1
|
||||
#define TARGET_NAME "tricore"
|
||||
#define TARGET_TRICORE 1
|
||||
#define CONFIG_SOFTMMU 1
|
11
qemu/configure
vendored
11
qemu/configure
vendored
@ -489,6 +489,8 @@ elif check_define __arm__ ; then
|
||||
cpu="arm"
|
||||
elif check_define __aarch64__ ; then
|
||||
cpu="aarch64"
|
||||
elif check_define __tricore__ ; then
|
||||
cpu="tricore"
|
||||
else
|
||||
cpu=$(uname -m)
|
||||
fi
|
||||
@ -528,6 +530,10 @@ case "$cpu" in
|
||||
cpu="sparc"
|
||||
supported_cpu="yes"
|
||||
;;
|
||||
tricore)
|
||||
cpu="tricore"
|
||||
supported_cpu="yes"
|
||||
;;
|
||||
*)
|
||||
# This will result in either an error or falling back to TCI later
|
||||
ARCH=unknown
|
||||
@ -852,7 +858,8 @@ QEMU_CFLAGS="$CPU_CFLAGS $QEMU_CFLAGS"
|
||||
default_target_list="aarch64-softmmu \
|
||||
arm-softmmu m68k-softmmu mips64el-softmmu mips64-softmmu mipsel-softmmu \
|
||||
mips-softmmu ppc64-softmmu ppc-softmmu sparc64-softmmu sparc-softmmu \
|
||||
x86_64-softmmu riscv32-softmmu riscv64-softmmu s390x-softmmu"
|
||||
x86_64-softmmu riscv32-softmmu riscv64-softmmu s390x-softmmu \
|
||||
tricore-softmmu"
|
||||
|
||||
if test x"$show_help" = x"yes" ; then
|
||||
cat << EOF
|
||||
@ -2747,6 +2754,8 @@ case "$target_name" in
|
||||
tilegx)
|
||||
;;
|
||||
tricore)
|
||||
TARGET_ARCH=tricore
|
||||
TARGET_BASE_ARCH=tricore
|
||||
;;
|
||||
unicore32)
|
||||
;;
|
||||
|
@ -794,6 +794,12 @@ struct TCGContext {
|
||||
TCGv NULL_QREG;
|
||||
/* Used to distinguish stores from bad addressing modes. */
|
||||
TCGv store_dummy;
|
||||
|
||||
// target/tricore/translate.c
|
||||
TCGv_i32 cpu_gpr_a[16];
|
||||
TCGv_i32 cpu_gpr_d[16];
|
||||
TCGv_i32 cpu_PSW_C, cpu_PSW_V, cpu_PSW_SV, cpu_PSW_AV, cpu_PSW_SAV;
|
||||
TCGv_i32 cpu_PC, cpu_PCXI, cpu_PSW, cpu_ICR;
|
||||
|
||||
// Used to store the start of current instrution.
|
||||
uint64_t pc_start;
|
||||
|
17
qemu/target/tricore/cpu-param.h
Normal file
17
qemu/target/tricore/cpu-param.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* TriCore cpu parameters for qemu.
|
||||
*
|
||||
* Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#ifndef TRICORE_CPU_PARAM_H
|
||||
#define TRICORE_CPU_PARAM_H 1
|
||||
|
||||
#define TARGET_LONG_BITS 32
|
||||
#define TARGET_PAGE_BITS 14
|
||||
#define TARGET_PHYS_ADDR_SPACE_BITS 32
|
||||
#define TARGET_VIRT_ADDR_SPACE_BITS 32
|
||||
#define NB_MMU_MODES 3
|
||||
|
||||
#endif
|
43
qemu/target/tricore/cpu-qom.h
Normal file
43
qemu/target/tricore/cpu-qom.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Modified for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
*/
|
||||
|
||||
#ifndef QEMU_TRICORE_CPU_QOM_H
|
||||
#define QEMU_TRICORE_CPU_QOM_H
|
||||
|
||||
#include "hw/core/cpu.h"
|
||||
|
||||
#define TYPE_TRICORE_CPU "tricore-cpu"
|
||||
|
||||
#define TRICORE_CPU(obj) ((TriCoreCPU *)obj)
|
||||
#define TRICORE_CPU_CLASS(klass) ((TriCoreCPUClass *)klass)
|
||||
#define TRICORE_CPU_GET_CLASS(obj) (&((TriCoreCPU *)obj)->cc)
|
||||
|
||||
typedef struct TriCoreCPUClass {
|
||||
/*< private >*/
|
||||
CPUClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
} TriCoreCPUClass;
|
||||
|
||||
|
||||
#endif /* QEMU_TRICORE_CPU_QOM_H */
|
205
qemu/target/tricore/cpu.c
Normal file
205
qemu/target/tricore/cpu.c
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* TriCore emulation for qemu: main translation routines.
|
||||
*
|
||||
* Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Modified for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "cpu-qom.h"
|
||||
#include "exec/exec-all.h"
|
||||
|
||||
#include <uc_priv.h>
|
||||
|
||||
static inline void set_feature(CPUTriCoreState *env, int feature)
|
||||
{
|
||||
env->features |= 1ULL << feature;
|
||||
}
|
||||
|
||||
static void tricore_cpu_set_pc(CPUState *cs, vaddr value)
|
||||
{
|
||||
TriCoreCPU *cpu = TRICORE_CPU(cs);
|
||||
CPUTriCoreState *env = &cpu->env;
|
||||
|
||||
env->PC = value & ~(target_ulong)1;
|
||||
}
|
||||
|
||||
static void tricore_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
|
||||
{
|
||||
TriCoreCPU *cpu = TRICORE_CPU(cs);
|
||||
CPUTriCoreState *env = &cpu->env;
|
||||
|
||||
env->PC = tb->pc;
|
||||
}
|
||||
|
||||
static void tricore_cpu_reset(CPUState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
TriCoreCPU *cpu = TRICORE_CPU(s);
|
||||
TriCoreCPUClass *tcc = TRICORE_CPU_GET_CLASS(cpu);
|
||||
CPUTriCoreState *env = &cpu->env;
|
||||
|
||||
tcc->parent_reset(dev);
|
||||
|
||||
memset(env, 0, offsetof(CPUTriCoreState, end_reset_fields));
|
||||
|
||||
cpu_state_reset(env);
|
||||
}
|
||||
|
||||
static bool tricore_cpu_has_work(CPUState *cs)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tricore_cpu_realizefn(CPUState *dev)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
TriCoreCPU *cpu = TRICORE_CPU(dev);
|
||||
CPUTriCoreState *env = &cpu->env;
|
||||
|
||||
cpu_exec_realizefn(cs);
|
||||
|
||||
/* Some features automatically imply others */
|
||||
if (tricore_feature(env, TRICORE_FEATURE_161)) {
|
||||
set_feature(env, TRICORE_FEATURE_16);
|
||||
}
|
||||
|
||||
if (tricore_feature(env, TRICORE_FEATURE_16)) {
|
||||
set_feature(env, TRICORE_FEATURE_131);
|
||||
}
|
||||
if (tricore_feature(env, TRICORE_FEATURE_131)) {
|
||||
set_feature(env, TRICORE_FEATURE_13);
|
||||
}
|
||||
cpu_reset(cs);
|
||||
}
|
||||
|
||||
|
||||
static void tricore_cpu_initfn(struct uc_struct *uc, CPUState *obj)
|
||||
{
|
||||
TriCoreCPU *cpu = TRICORE_CPU(obj);
|
||||
CPUTriCoreState *env = &cpu->env;
|
||||
|
||||
env->uc = uc;
|
||||
cpu_set_cpustate_pointers(cpu);
|
||||
}
|
||||
|
||||
static void tc1796_initfn(CPUState *obj)
|
||||
{
|
||||
TriCoreCPU *cpu = TRICORE_CPU(obj);
|
||||
|
||||
set_feature(&cpu->env, TRICORE_FEATURE_13);
|
||||
}
|
||||
|
||||
static void tc1797_initfn(CPUState *obj)
|
||||
{
|
||||
TriCoreCPU *cpu = TRICORE_CPU(obj);
|
||||
|
||||
set_feature(&cpu->env, TRICORE_FEATURE_131);
|
||||
}
|
||||
|
||||
static void tc27x_initfn(CPUState *obj)
|
||||
{
|
||||
TriCoreCPU *cpu = TRICORE_CPU(obj);
|
||||
|
||||
set_feature(&cpu->env, TRICORE_FEATURE_161);
|
||||
}
|
||||
|
||||
static void tricore_cpu_class_init(CPUClass *c)
|
||||
{
|
||||
TriCoreCPUClass *mcc = TRICORE_CPU_CLASS(c);
|
||||
CPUClass *cc = CPU_CLASS(c);
|
||||
|
||||
/* parent class is CPUClass, parent_reset() is cpu_common_reset(). */
|
||||
mcc->parent_reset = cc->reset;
|
||||
|
||||
cc->reset = tricore_cpu_reset;
|
||||
cc->has_work = tricore_cpu_has_work;
|
||||
cc->set_pc = tricore_cpu_set_pc;
|
||||
|
||||
cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb;
|
||||
cc->get_phys_page_debug = tricore_cpu_get_phys_page_debug;
|
||||
|
||||
cc->tlb_fill = tricore_cpu_tlb_fill;
|
||||
cc->tcg_initialize = tricore_tcg_init;
|
||||
}
|
||||
|
||||
#define DEFINE_TRICORE_CPU_TYPE(cpu_model, initfn) \
|
||||
{ \
|
||||
.parent = TYPE_TRICORE_CPU, \
|
||||
.initfn = initfn, \
|
||||
.name = TRICORE_CPU_TYPE_NAME(cpu_model), \
|
||||
}
|
||||
|
||||
struct TriCoreCPUInfo {
|
||||
const char *name;
|
||||
void (*initfn)(CPUState *obj);
|
||||
};
|
||||
|
||||
static struct TriCoreCPUInfo tricore_cpus_type_infos[] = {
|
||||
{ "tc1796", tc1796_initfn },
|
||||
{ "tc1797", tc1797_initfn },
|
||||
{ "tc27x", tc27x_initfn },
|
||||
};
|
||||
|
||||
TriCoreCPU *cpu_tricore_init(struct uc_struct *uc)
|
||||
{
|
||||
TriCoreCPU *cpu;
|
||||
CPUState *cs;
|
||||
CPUClass *cc;
|
||||
|
||||
cpu = calloc(1, sizeof(*cpu));
|
||||
if (cpu == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uc->cpu_model == INT_MAX) {
|
||||
uc->cpu_model = 2; // tc27x
|
||||
} else if (uc->cpu_model >= ARRAY_SIZE(tricore_cpus_type_infos)) {
|
||||
free(cpu);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cs = (CPUState *)cpu;
|
||||
cc = (CPUClass *)&cpu->cc;
|
||||
cs->cc = cc;
|
||||
cs->uc = uc;
|
||||
uc->cpu = cs;
|
||||
|
||||
cpu_class_init(uc, cc);
|
||||
|
||||
tricore_cpu_class_init(cc);
|
||||
|
||||
cpu_common_initfn(uc, cs);
|
||||
|
||||
tricore_cpu_initfn(uc, cs);
|
||||
|
||||
tricore_cpus_type_infos[uc->cpu_model].initfn(cs);
|
||||
|
||||
tricore_cpu_realizefn(cs);
|
||||
|
||||
// init address space
|
||||
cpu_address_space_init(cs, 0, cs->memory);
|
||||
|
||||
qemu_init_vcpu(cs);
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
410
qemu/target/tricore/cpu.h
Normal file
410
qemu/target/tricore/cpu.h
Normal file
@ -0,0 +1,410 @@
|
||||
/*
|
||||
* TriCore emulation for qemu: main CPU struct.
|
||||
*
|
||||
* Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Modified for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
*/
|
||||
|
||||
#ifndef TRICORE_CPU_H
|
||||
#define TRICORE_CPU_H
|
||||
|
||||
#include "cpu-qom.h"
|
||||
#include "exec/cpu-defs.h"
|
||||
#include "tricore-defs.h"
|
||||
|
||||
struct tricore_boot_info;
|
||||
|
||||
typedef struct tricore_def_t tricore_def_t;
|
||||
|
||||
// struct CPUTriCoreState {
|
||||
typedef struct CPUTriCoreState {
|
||||
/* GPR Register */
|
||||
uint32_t gpr_a[16];
|
||||
uint32_t gpr_d[16];
|
||||
/* CSFR Register */
|
||||
uint32_t PCXI;
|
||||
/* Frequently accessed PSW_USB bits are stored separately for efficiency.
|
||||
This contains all the other bits. Use psw_{read,write} to access
|
||||
the whole PSW. */
|
||||
uint32_t PSW;
|
||||
|
||||
/* PSW flag cache for faster execution
|
||||
*/
|
||||
uint32_t PSW_USB_C;
|
||||
uint32_t PSW_USB_V; /* Only if bit 31 set, then flag is set */
|
||||
uint32_t PSW_USB_SV; /* Only if bit 31 set, then flag is set */
|
||||
uint32_t PSW_USB_AV; /* Only if bit 31 set, then flag is set. */
|
||||
uint32_t PSW_USB_SAV; /* Only if bit 31 set, then flag is set. */
|
||||
|
||||
uint32_t PC;
|
||||
uint32_t SYSCON;
|
||||
uint32_t CPU_ID;
|
||||
uint32_t CORE_ID;
|
||||
uint32_t BIV;
|
||||
uint32_t BTV;
|
||||
uint32_t ISP;
|
||||
uint32_t ICR;
|
||||
uint32_t FCX;
|
||||
uint32_t LCX;
|
||||
uint32_t COMPAT;
|
||||
|
||||
/* Mem Protection Register */
|
||||
uint32_t DPR0_0L;
|
||||
uint32_t DPR0_0U;
|
||||
uint32_t DPR0_1L;
|
||||
uint32_t DPR0_1U;
|
||||
uint32_t DPR0_2L;
|
||||
uint32_t DPR0_2U;
|
||||
uint32_t DPR0_3L;
|
||||
uint32_t DPR0_3U;
|
||||
|
||||
uint32_t DPR1_0L;
|
||||
uint32_t DPR1_0U;
|
||||
uint32_t DPR1_1L;
|
||||
uint32_t DPR1_1U;
|
||||
uint32_t DPR1_2L;
|
||||
uint32_t DPR1_2U;
|
||||
uint32_t DPR1_3L;
|
||||
uint32_t DPR1_3U;
|
||||
|
||||
uint32_t DPR2_0L;
|
||||
uint32_t DPR2_0U;
|
||||
uint32_t DPR2_1L;
|
||||
uint32_t DPR2_1U;
|
||||
uint32_t DPR2_2L;
|
||||
uint32_t DPR2_2U;
|
||||
uint32_t DPR2_3L;
|
||||
uint32_t DPR2_3U;
|
||||
|
||||
uint32_t DPR3_0L;
|
||||
uint32_t DPR3_0U;
|
||||
uint32_t DPR3_1L;
|
||||
uint32_t DPR3_1U;
|
||||
uint32_t DPR3_2L;
|
||||
uint32_t DPR3_2U;
|
||||
uint32_t DPR3_3L;
|
||||
uint32_t DPR3_3U;
|
||||
|
||||
uint32_t CPR0_0L;
|
||||
uint32_t CPR0_0U;
|
||||
uint32_t CPR0_1L;
|
||||
uint32_t CPR0_1U;
|
||||
uint32_t CPR0_2L;
|
||||
uint32_t CPR0_2U;
|
||||
uint32_t CPR0_3L;
|
||||
uint32_t CPR0_3U;
|
||||
|
||||
uint32_t CPR1_0L;
|
||||
uint32_t CPR1_0U;
|
||||
uint32_t CPR1_1L;
|
||||
uint32_t CPR1_1U;
|
||||
uint32_t CPR1_2L;
|
||||
uint32_t CPR1_2U;
|
||||
uint32_t CPR1_3L;
|
||||
uint32_t CPR1_3U;
|
||||
|
||||
uint32_t CPR2_0L;
|
||||
uint32_t CPR2_0U;
|
||||
uint32_t CPR2_1L;
|
||||
uint32_t CPR2_1U;
|
||||
uint32_t CPR2_2L;
|
||||
uint32_t CPR2_2U;
|
||||
uint32_t CPR2_3L;
|
||||
uint32_t CPR2_3U;
|
||||
|
||||
uint32_t CPR3_0L;
|
||||
uint32_t CPR3_0U;
|
||||
uint32_t CPR3_1L;
|
||||
uint32_t CPR3_1U;
|
||||
uint32_t CPR3_2L;
|
||||
uint32_t CPR3_2U;
|
||||
uint32_t CPR3_3L;
|
||||
uint32_t CPR3_3U;
|
||||
|
||||
uint32_t DPM0;
|
||||
uint32_t DPM1;
|
||||
uint32_t DPM2;
|
||||
uint32_t DPM3;
|
||||
|
||||
uint32_t CPM0;
|
||||
uint32_t CPM1;
|
||||
uint32_t CPM2;
|
||||
uint32_t CPM3;
|
||||
|
||||
/* Memory Management Registers */
|
||||
uint32_t MMU_CON;
|
||||
uint32_t MMU_ASI;
|
||||
uint32_t MMU_TVA;
|
||||
uint32_t MMU_TPA;
|
||||
uint32_t MMU_TPX;
|
||||
uint32_t MMU_TFA;
|
||||
/* {1.3.1 only */
|
||||
uint32_t BMACON;
|
||||
uint32_t SMACON;
|
||||
uint32_t DIEAR;
|
||||
uint32_t DIETR;
|
||||
uint32_t CCDIER;
|
||||
uint32_t MIECON;
|
||||
uint32_t PIEAR;
|
||||
uint32_t PIETR;
|
||||
uint32_t CCPIER;
|
||||
/*} */
|
||||
/* Debug Registers */
|
||||
uint32_t DBGSR;
|
||||
uint32_t EXEVT;
|
||||
uint32_t CREVT;
|
||||
uint32_t SWEVT;
|
||||
uint32_t TR0EVT;
|
||||
uint32_t TR1EVT;
|
||||
uint32_t DMS;
|
||||
uint32_t DCX;
|
||||
uint32_t DBGTCR;
|
||||
uint32_t CCTRL;
|
||||
uint32_t CCNT;
|
||||
uint32_t ICNT;
|
||||
uint32_t M1CNT;
|
||||
uint32_t M2CNT;
|
||||
uint32_t M3CNT;
|
||||
/* Floating Point Registers */
|
||||
float_status fp_status;
|
||||
/* QEMU */
|
||||
int error_code;
|
||||
uint32_t hflags; /* CPU State */
|
||||
|
||||
const tricore_def_t *cpu_model;
|
||||
void *irq[8];
|
||||
struct QEMUTimer *timer; /* Internal timer */
|
||||
|
||||
/* Fields up to this point are cleared by a CPU reset */
|
||||
int end_reset_fields;
|
||||
|
||||
/* Fields from here on are preserved across CPU reset. */
|
||||
uint32_t features;
|
||||
|
||||
// Unicorn engine
|
||||
struct uc_struct *uc;
|
||||
} CPUTriCoreState;
|
||||
|
||||
/**
|
||||
* TriCoreCPU:
|
||||
* @env: #CPUTriCoreState
|
||||
*
|
||||
* A TriCore CPU.
|
||||
*/
|
||||
// TODO: Why is the type def needed? Without it the later typedef fails to find this... ?
|
||||
typedef struct TriCoreCPU {
|
||||
/*< private >*/
|
||||
CPUState parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
CPUNegativeOffsetState neg;
|
||||
CPUTriCoreState env;
|
||||
|
||||
struct TriCoreCPUClass cc;
|
||||
} TriCoreCPU;
|
||||
|
||||
hwaddr tricore_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||
void tricore_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
|
||||
|
||||
|
||||
#define MASK_PCXI_PCPN 0xff000000
|
||||
#define MASK_PCXI_PIE_1_3 0x00800000
|
||||
#define MASK_PCXI_PIE_1_6 0x00200000
|
||||
#define MASK_PCXI_UL 0x00400000
|
||||
#define MASK_PCXI_PCXS 0x000f0000
|
||||
#define MASK_PCXI_PCXO 0x0000ffff
|
||||
|
||||
#define MASK_PSW_USB 0xff000000
|
||||
#define MASK_USB_C 0x80000000
|
||||
#define MASK_USB_V 0x40000000
|
||||
#define MASK_USB_SV 0x20000000
|
||||
#define MASK_USB_AV 0x10000000
|
||||
#define MASK_USB_SAV 0x08000000
|
||||
#define MASK_PSW_PRS 0x00003000
|
||||
#define MASK_PSW_IO 0x00000c00
|
||||
#define MASK_PSW_IS 0x00000200
|
||||
#define MASK_PSW_GW 0x00000100
|
||||
#define MASK_PSW_CDE 0x00000080
|
||||
#define MASK_PSW_CDC 0x0000007f
|
||||
#define MASK_PSW_FPU_RM 0x3000000
|
||||
|
||||
#define MASK_SYSCON_PRO_TEN 0x2
|
||||
#define MASK_SYSCON_FCD_SF 0x1
|
||||
|
||||
#define MASK_CPUID_MOD 0xffff0000
|
||||
#define MASK_CPUID_MOD_32B 0x0000ff00
|
||||
#define MASK_CPUID_REV 0x000000ff
|
||||
|
||||
#define MASK_ICR_PIPN 0x00ff0000
|
||||
#define MASK_ICR_IE_1_3 0x00000100
|
||||
#define MASK_ICR_IE_1_6 0x00008000
|
||||
#define MASK_ICR_CCPN 0x000000ff
|
||||
|
||||
#define MASK_FCX_FCXS 0x000f0000
|
||||
#define MASK_FCX_FCXO 0x0000ffff
|
||||
|
||||
#define MASK_LCX_LCXS 0x000f0000
|
||||
#define MASK_LCX_LCX0 0x0000ffff
|
||||
|
||||
#define MASK_DBGSR_DE 0x1
|
||||
#define MASK_DBGSR_HALT 0x6
|
||||
#define MASK_DBGSR_SUSP 0x10
|
||||
#define MASK_DBGSR_PREVSUSP 0x20
|
||||
#define MASK_DBGSR_PEVT 0x40
|
||||
#define MASK_DBGSR_EVTSRC 0x1f00
|
||||
|
||||
#define TRICORE_HFLAG_KUU 0x3
|
||||
#define TRICORE_HFLAG_UM0 0x00002 /* user mode-0 flag */
|
||||
#define TRICORE_HFLAG_UM1 0x00001 /* user mode-1 flag */
|
||||
#define TRICORE_HFLAG_SM 0x00000 /* kernel mode flag */
|
||||
|
||||
enum tricore_features {
|
||||
TRICORE_FEATURE_13,
|
||||
TRICORE_FEATURE_131,
|
||||
TRICORE_FEATURE_16,
|
||||
TRICORE_FEATURE_161,
|
||||
};
|
||||
|
||||
static inline int tricore_feature(CPUTriCoreState *env, int feature)
|
||||
{
|
||||
return (env->features & (1ULL << feature)) != 0;
|
||||
}
|
||||
|
||||
/* TriCore Traps Classes*/
|
||||
enum {
|
||||
TRAPC_NONE = -1,
|
||||
TRAPC_MMU = 0,
|
||||
TRAPC_PROT = 1,
|
||||
TRAPC_INSN_ERR = 2,
|
||||
TRAPC_CTX_MNG = 3,
|
||||
TRAPC_SYSBUS = 4,
|
||||
TRAPC_ASSERT = 5,
|
||||
TRAPC_SYSCALL = 6,
|
||||
TRAPC_NMI = 7,
|
||||
TRAPC_IRQ = 8
|
||||
};
|
||||
|
||||
/* Class 0 TIN */
|
||||
enum {
|
||||
TIN0_VAF = 0,
|
||||
TIN0_VAP = 1,
|
||||
};
|
||||
|
||||
/* Class 1 TIN */
|
||||
enum {
|
||||
TIN1_PRIV = 1,
|
||||
TIN1_MPR = 2,
|
||||
TIN1_MPW = 3,
|
||||
TIN1_MPX = 4,
|
||||
TIN1_MPP = 5,
|
||||
TIN1_MPN = 6,
|
||||
TIN1_GRWP = 7,
|
||||
};
|
||||
|
||||
/* Class 2 TIN */
|
||||
enum {
|
||||
TIN2_IOPC = 1,
|
||||
TIN2_UOPC = 2,
|
||||
TIN2_OPD = 3,
|
||||
TIN2_ALN = 4,
|
||||
TIN2_MEM = 5,
|
||||
};
|
||||
|
||||
/* Class 3 TIN */
|
||||
enum {
|
||||
TIN3_FCD = 1,
|
||||
TIN3_CDO = 2,
|
||||
TIN3_CDU = 3,
|
||||
TIN3_FCU = 4,
|
||||
TIN3_CSU = 5,
|
||||
TIN3_CTYP = 6,
|
||||
TIN3_NEST = 7,
|
||||
};
|
||||
|
||||
/* Class 4 TIN */
|
||||
enum {
|
||||
TIN4_PSE = 1,
|
||||
TIN4_DSE = 2,
|
||||
TIN4_DAE = 3,
|
||||
TIN4_CAE = 4,
|
||||
TIN4_PIE = 5,
|
||||
TIN4_DIE = 6,
|
||||
};
|
||||
|
||||
/* Class 5 TIN */
|
||||
enum {
|
||||
TIN5_OVF = 1,
|
||||
TIN5_SOVF = 1,
|
||||
};
|
||||
|
||||
/* Class 6 TIN
|
||||
*
|
||||
* Is always TIN6_SYS
|
||||
*/
|
||||
|
||||
/* Class 7 TIN */
|
||||
enum {
|
||||
TIN7_NMI = 0,
|
||||
};
|
||||
|
||||
uint32_t psw_read(CPUTriCoreState *env);
|
||||
void psw_write(CPUTriCoreState *env, uint32_t val);
|
||||
int tricore_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n);
|
||||
int tricore_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n);
|
||||
|
||||
void fpu_set_state(CPUTriCoreState *env);
|
||||
|
||||
#define MMU_USER_IDX 2
|
||||
|
||||
void tricore_cpu_list(void);
|
||||
|
||||
#define cpu_list tricore_cpu_list
|
||||
|
||||
static inline int cpu_mmu_index(CPUTriCoreState *env, bool ifetch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef CPUTriCoreState CPUArchState;
|
||||
typedef TriCoreCPU ArchCPU;
|
||||
|
||||
#include "exec/cpu-all.h"
|
||||
|
||||
void cpu_state_reset(CPUTriCoreState *s);
|
||||
void tricore_tcg_init(struct uc_struct *uc);
|
||||
|
||||
static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, target_ulong *pc,
|
||||
target_ulong *cs_base, uint32_t *flags)
|
||||
{
|
||||
*pc = env->PC;
|
||||
*cs_base = 0;
|
||||
*flags = 0;
|
||||
}
|
||||
|
||||
#define TRICORE_CPU_TYPE_SUFFIX "-" TYPE_TRICORE_CPU
|
||||
#define TRICORE_CPU_TYPE_NAME(model) model TRICORE_CPU_TYPE_SUFFIX
|
||||
#define CPU_RESOLVING_TYPE TYPE_TRICORE_CPU
|
||||
|
||||
/* helpers.c */
|
||||
bool tricore_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
MMUAccessType access_type, int mmu_idx,
|
||||
bool probe, uintptr_t retaddr);
|
||||
|
||||
#endif /* TRICORE_CPU_H */
|
125
qemu/target/tricore/csfr.def
Normal file
125
qemu/target/tricore/csfr.def
Normal file
@ -0,0 +1,125 @@
|
||||
/* A(ll) access permited
|
||||
R(ead only) access
|
||||
E(nd init protected) access
|
||||
|
||||
A|R|E(offset, register, feature introducing reg)
|
||||
|
||||
NOTE: PSW is handled as a special case in gen_mtcr/mfcr */
|
||||
|
||||
A(0xfe00, PCXI, TRICORE_FEATURE_13)
|
||||
A(0xfe08, PC, TRICORE_FEATURE_13)
|
||||
A(0xfe14, SYSCON, TRICORE_FEATURE_13)
|
||||
R(0xfe18, CPU_ID, TRICORE_FEATURE_13)
|
||||
R(0xfe1c, CORE_ID, TRICORE_FEATURE_161)
|
||||
E(0xfe20, BIV, TRICORE_FEATURE_13)
|
||||
E(0xfe24, BTV, TRICORE_FEATURE_13)
|
||||
E(0xfe28, ISP, TRICORE_FEATURE_13)
|
||||
A(0xfe2c, ICR, TRICORE_FEATURE_13)
|
||||
A(0xfe38, FCX, TRICORE_FEATURE_13)
|
||||
A(0xfe3c, LCX, TRICORE_FEATURE_13)
|
||||
E(0x9400, COMPAT, TRICORE_FEATURE_131)
|
||||
/* memory protection register */
|
||||
A(0xC000, DPR0_0L, TRICORE_FEATURE_13)
|
||||
A(0xC004, DPR0_0U, TRICORE_FEATURE_13)
|
||||
A(0xC008, DPR0_1L, TRICORE_FEATURE_13)
|
||||
A(0xC00C, DPR0_1U, TRICORE_FEATURE_13)
|
||||
A(0xC010, DPR0_2L, TRICORE_FEATURE_13)
|
||||
A(0xC014, DPR0_2U, TRICORE_FEATURE_13)
|
||||
A(0xC018, DPR0_3L, TRICORE_FEATURE_13)
|
||||
A(0xC01C, DPR0_3U, TRICORE_FEATURE_13)
|
||||
A(0xC400, DPR1_0L, TRICORE_FEATURE_13)
|
||||
A(0xC404, DPR1_0U, TRICORE_FEATURE_13)
|
||||
A(0xC408, DPR1_1L, TRICORE_FEATURE_13)
|
||||
A(0xC40C, DPR1_1U, TRICORE_FEATURE_13)
|
||||
A(0xC410, DPR1_2L, TRICORE_FEATURE_13)
|
||||
A(0xC414, DPR1_2U, TRICORE_FEATURE_13)
|
||||
A(0xC418, DPR1_3L, TRICORE_FEATURE_13)
|
||||
A(0xC41C, DPR1_3U, TRICORE_FEATURE_13)
|
||||
A(0xC800, DPR2_0L, TRICORE_FEATURE_13)
|
||||
A(0xC804, DPR2_0U, TRICORE_FEATURE_13)
|
||||
A(0xC808, DPR2_1L, TRICORE_FEATURE_13)
|
||||
A(0xC80C, DPR2_1U, TRICORE_FEATURE_13)
|
||||
A(0xC810, DPR2_2L, TRICORE_FEATURE_13)
|
||||
A(0xC814, DPR2_2U, TRICORE_FEATURE_13)
|
||||
A(0xC818, DPR2_3L, TRICORE_FEATURE_13)
|
||||
A(0xC81C, DPR2_3U, TRICORE_FEATURE_13)
|
||||
A(0xCC00, DPR3_0L, TRICORE_FEATURE_13)
|
||||
A(0xCC04, DPR3_0U, TRICORE_FEATURE_13)
|
||||
A(0xCC08, DPR3_1L, TRICORE_FEATURE_13)
|
||||
A(0xCC0C, DPR3_1U, TRICORE_FEATURE_13)
|
||||
A(0xCC10, DPR3_2L, TRICORE_FEATURE_13)
|
||||
A(0xCC14, DPR3_2U, TRICORE_FEATURE_13)
|
||||
A(0xCC18, DPR3_3L, TRICORE_FEATURE_13)
|
||||
A(0xCC1C, DPR3_3U, TRICORE_FEATURE_13)
|
||||
A(0xD000, CPR0_0L, TRICORE_FEATURE_13)
|
||||
A(0xD004, CPR0_0U, TRICORE_FEATURE_13)
|
||||
A(0xD008, CPR0_1L, TRICORE_FEATURE_13)
|
||||
A(0xD00C, CPR0_1U, TRICORE_FEATURE_13)
|
||||
A(0xD010, CPR0_2L, TRICORE_FEATURE_13)
|
||||
A(0xD014, CPR0_2U, TRICORE_FEATURE_13)
|
||||
A(0xD018, CPR0_3L, TRICORE_FEATURE_13)
|
||||
A(0xD01C, CPR0_3U, TRICORE_FEATURE_13)
|
||||
A(0xD400, CPR1_0L, TRICORE_FEATURE_13)
|
||||
A(0xD404, CPR1_0U, TRICORE_FEATURE_13)
|
||||
A(0xD408, CPR1_1L, TRICORE_FEATURE_13)
|
||||
A(0xD40C, CPR1_1U, TRICORE_FEATURE_13)
|
||||
A(0xD410, CPR1_2L, TRICORE_FEATURE_13)
|
||||
A(0xD414, CPR1_2U, TRICORE_FEATURE_13)
|
||||
A(0xD418, CPR1_3L, TRICORE_FEATURE_13)
|
||||
A(0xD41C, CPR1_3U, TRICORE_FEATURE_13)
|
||||
A(0xD800, CPR2_0L, TRICORE_FEATURE_13)
|
||||
A(0xD804, CPR2_0U, TRICORE_FEATURE_13)
|
||||
A(0xD808, CPR2_1L, TRICORE_FEATURE_13)
|
||||
A(0xD80C, CPR2_1U, TRICORE_FEATURE_13)
|
||||
A(0xD810, CPR2_2L, TRICORE_FEATURE_13)
|
||||
A(0xD814, CPR2_2U, TRICORE_FEATURE_13)
|
||||
A(0xD818, CPR2_3L, TRICORE_FEATURE_13)
|
||||
A(0xD81C, CPR2_3U, TRICORE_FEATURE_13)
|
||||
A(0xDC00, CPR3_0L, TRICORE_FEATURE_13)
|
||||
A(0xDC04, CPR3_0U, TRICORE_FEATURE_13)
|
||||
A(0xDC08, CPR3_1L, TRICORE_FEATURE_13)
|
||||
A(0xDC0C, CPR3_1U, TRICORE_FEATURE_13)
|
||||
A(0xDC10, CPR3_2L, TRICORE_FEATURE_13)
|
||||
A(0xDC14, CPR3_2U, TRICORE_FEATURE_13)
|
||||
A(0xDC18, CPR3_3L, TRICORE_FEATURE_13)
|
||||
A(0xDC1C, CPR3_3U, TRICORE_FEATURE_13)
|
||||
A(0xE000, DPM0, TRICORE_FEATURE_13)
|
||||
A(0xE080, DPM1, TRICORE_FEATURE_13)
|
||||
A(0xE100, DPM2, TRICORE_FEATURE_13)
|
||||
A(0xE180, DPM3, TRICORE_FEATURE_13)
|
||||
A(0xE200, CPM0, TRICORE_FEATURE_13)
|
||||
A(0xE280, CPM1, TRICORE_FEATURE_13)
|
||||
A(0xE300, CPM2, TRICORE_FEATURE_13)
|
||||
A(0xE380, CPM3, TRICORE_FEATURE_13)
|
||||
/* memory management registers */
|
||||
A(0x8000, MMU_CON, TRICORE_FEATURE_13)
|
||||
A(0x8004, MMU_ASI, TRICORE_FEATURE_13)
|
||||
A(0x800C, MMU_TVA, TRICORE_FEATURE_13)
|
||||
A(0x8010, MMU_TPA, TRICORE_FEATURE_13)
|
||||
A(0x8014, MMU_TPX, TRICORE_FEATURE_13)
|
||||
A(0x8018, MMU_TFA, TRICORE_FEATURE_13)
|
||||
E(0x9004, BMACON, TRICORE_FEATURE_131)
|
||||
E(0x900C, SMACON, TRICORE_FEATURE_131)
|
||||
A(0x9020, DIEAR, TRICORE_FEATURE_131)
|
||||
A(0x9024, DIETR, TRICORE_FEATURE_131)
|
||||
A(0x9028, CCDIER, TRICORE_FEATURE_131)
|
||||
E(0x9044, MIECON, TRICORE_FEATURE_131)
|
||||
A(0x9210, PIEAR, TRICORE_FEATURE_131)
|
||||
A(0x9214, PIETR, TRICORE_FEATURE_131)
|
||||
A(0x9218, CCPIER, TRICORE_FEATURE_131)
|
||||
/* debug registers */
|
||||
A(0xFD00, DBGSR, TRICORE_FEATURE_13)
|
||||
A(0xFD08, EXEVT, TRICORE_FEATURE_13)
|
||||
A(0xFD0C, CREVT, TRICORE_FEATURE_13)
|
||||
A(0xFD10, SWEVT, TRICORE_FEATURE_13)
|
||||
A(0xFD20, TR0EVT, TRICORE_FEATURE_13)
|
||||
A(0xFD24, TR1EVT, TRICORE_FEATURE_13)
|
||||
A(0xFD40, DMS, TRICORE_FEATURE_13)
|
||||
A(0xFD44, DCX, TRICORE_FEATURE_13)
|
||||
A(0xFD48, DBGTCR, TRICORE_FEATURE_131)
|
||||
A(0xFC00, CCTRL, TRICORE_FEATURE_131)
|
||||
A(0xFC04, CCNT, TRICORE_FEATURE_131)
|
||||
A(0xFC08, ICNT, TRICORE_FEATURE_131)
|
||||
A(0xFC0C, M1CNT, TRICORE_FEATURE_131)
|
||||
A(0xFC10, M2CNT, TRICORE_FEATURE_131)
|
||||
A(0xFC14, M3CNT, TRICORE_FEATURE_131)
|
478
qemu/target/tricore/fpu_helper.c
Normal file
478
qemu/target/tricore/fpu_helper.c
Normal file
@ -0,0 +1,478 @@
|
||||
/*
|
||||
* TriCore emulation for qemu: fpu helper.
|
||||
*
|
||||
* Copyright (c) 2016 Bastian Koppelmann University of Paderborn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Modified for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/helper-proto.h"
|
||||
#include "fpu/softfloat.h"
|
||||
|
||||
#define QUIET_NAN 0x7fc00000
|
||||
#define ADD_NAN 0x7fc00001
|
||||
#define SQRT_NAN 0x7fc00004
|
||||
#define DIV_NAN 0x7fc00008
|
||||
#define MUL_NAN 0x7fc00002
|
||||
#define FPU_FS PSW_USB_C
|
||||
#define FPU_FI PSW_USB_V
|
||||
#define FPU_FV PSW_USB_SV
|
||||
#define FPU_FZ PSW_USB_AV
|
||||
#define FPU_FU PSW_USB_SAV
|
||||
|
||||
#define float32_sqrt_nan make_float32(SQRT_NAN)
|
||||
#define float32_quiet_nan make_float32(QUIET_NAN)
|
||||
|
||||
/* we don't care about input_denormal */
|
||||
static inline uint8_t f_get_excp_flags(CPUTriCoreState *env)
|
||||
{
|
||||
return get_float_exception_flags(&env->fp_status)
|
||||
& (float_flag_invalid
|
||||
| float_flag_overflow
|
||||
| float_flag_underflow
|
||||
| float_flag_output_denormal
|
||||
| float_flag_divbyzero
|
||||
| float_flag_inexact);
|
||||
}
|
||||
|
||||
static inline float32 f_maddsub_nan_result(float32 arg1, float32 arg2,
|
||||
float32 arg3, float32 result,
|
||||
uint32_t muladd_negate_c)
|
||||
{
|
||||
uint32_t aSign, bSign, cSign;
|
||||
uint32_t aExp, bExp, cExp;
|
||||
|
||||
if (float32_is_any_nan(arg1) || float32_is_any_nan(arg2) ||
|
||||
float32_is_any_nan(arg3)) {
|
||||
return QUIET_NAN;
|
||||
} else if (float32_is_infinity(arg1) && float32_is_zero(arg2)) {
|
||||
return MUL_NAN;
|
||||
} else if (float32_is_zero(arg1) && float32_is_infinity(arg2)) {
|
||||
return MUL_NAN;
|
||||
} else {
|
||||
aSign = arg1 >> 31;
|
||||
bSign = arg2 >> 31;
|
||||
cSign = arg3 >> 31;
|
||||
|
||||
aExp = (arg1 >> 23) & 0xff;
|
||||
bExp = (arg2 >> 23) & 0xff;
|
||||
cExp = (arg3 >> 23) & 0xff;
|
||||
|
||||
if (muladd_negate_c) {
|
||||
cSign ^= 1;
|
||||
}
|
||||
if (((aExp == 0xff) || (bExp == 0xff)) && (cExp == 0xff)) {
|
||||
if (aSign ^ bSign ^ cSign) {
|
||||
return ADD_NAN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
|
||||
{
|
||||
uint8_t some_excp = 0;
|
||||
set_float_exception_flags(0, &env->fp_status);
|
||||
|
||||
if (flags & float_flag_invalid) {
|
||||
env->FPU_FI = 1 << 31;
|
||||
some_excp = 1;
|
||||
}
|
||||
|
||||
if (flags & float_flag_overflow) {
|
||||
env->FPU_FV = 1 << 31;
|
||||
some_excp = 1;
|
||||
}
|
||||
|
||||
if (flags & float_flag_underflow || flags & float_flag_output_denormal) {
|
||||
env->FPU_FU = 1 << 31;
|
||||
some_excp = 1;
|
||||
}
|
||||
|
||||
if (flags & float_flag_divbyzero) {
|
||||
env->FPU_FZ = 1 << 31;
|
||||
some_excp = 1;
|
||||
}
|
||||
|
||||
if (flags & float_flag_inexact || flags & float_flag_output_denormal) {
|
||||
env->PSW |= 1 << 26;
|
||||
some_excp = 1;
|
||||
}
|
||||
|
||||
env->FPU_FS = some_excp;
|
||||
}
|
||||
|
||||
#define FADD_SUB(op) \
|
||||
uint32_t helper_f##op(CPUTriCoreState *env, uint32_t r1, uint32_t r2) \
|
||||
{ \
|
||||
float32 arg1 = make_float32(r1); \
|
||||
float32 arg2 = make_float32(r2); \
|
||||
uint32_t flags; \
|
||||
float32 f_result; \
|
||||
\
|
||||
f_result = float32_##op(arg2, arg1, &env->fp_status); \
|
||||
flags = f_get_excp_flags(env); \
|
||||
if (flags) { \
|
||||
/* If the output is a NaN, but the inputs aren't, \
|
||||
we return a unique value. */ \
|
||||
if ((flags & float_flag_invalid) \
|
||||
&& !float32_is_any_nan(arg1) \
|
||||
&& !float32_is_any_nan(arg2)) { \
|
||||
f_result = ADD_NAN; \
|
||||
} \
|
||||
f_update_psw_flags(env, flags); \
|
||||
} else { \
|
||||
env->FPU_FS = 0; \
|
||||
} \
|
||||
return (uint32_t)f_result; \
|
||||
}
|
||||
FADD_SUB(add)
|
||||
FADD_SUB(sub)
|
||||
|
||||
uint32_t helper_fmul(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
|
||||
{
|
||||
uint32_t flags;
|
||||
float32 arg1 = make_float32(r1);
|
||||
float32 arg2 = make_float32(r2);
|
||||
float32 f_result;
|
||||
|
||||
f_result = float32_mul(arg1, arg2, &env->fp_status);
|
||||
|
||||
flags = f_get_excp_flags(env);
|
||||
if (flags) {
|
||||
/* If the output is a NaN, but the inputs aren't,
|
||||
we return a unique value. */
|
||||
if ((flags & float_flag_invalid)
|
||||
&& !float32_is_any_nan(arg1)
|
||||
&& !float32_is_any_nan(arg2)) {
|
||||
f_result = MUL_NAN;
|
||||
}
|
||||
f_update_psw_flags(env, flags);
|
||||
} else {
|
||||
env->FPU_FS = 0;
|
||||
}
|
||||
return (uint32_t)f_result;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Target TriCore QSEED.F significand Lookup Table
|
||||
*
|
||||
* The QSEED.F output significand depends on the least-significant
|
||||
* exponent bit and the 6 most-significant significand bits.
|
||||
*
|
||||
* IEEE 754 float datatype
|
||||
* partitioned into Sign (S), Exponent (E) and Significand (M):
|
||||
*
|
||||
* S E E E E E E E E M M M M M M ...
|
||||
* | | |
|
||||
* +------+------+-------+-------+
|
||||
* | |
|
||||
* for lookup table
|
||||
* calculating index for
|
||||
* output E output M
|
||||
*
|
||||
* This lookup table was extracted by analyzing QSEED output
|
||||
* from the real hardware
|
||||
*/
|
||||
static const uint8_t target_qseed_significand_table[128] = {
|
||||
253, 252, 245, 244, 239, 238, 231, 230, 225, 224, 217, 216,
|
||||
211, 210, 205, 204, 201, 200, 195, 194, 189, 188, 185, 184,
|
||||
179, 178, 175, 174, 169, 168, 165, 164, 161, 160, 157, 156,
|
||||
153, 152, 149, 148, 145, 144, 141, 140, 137, 136, 133, 132,
|
||||
131, 130, 127, 126, 123, 122, 121, 120, 117, 116, 115, 114,
|
||||
111, 110, 109, 108, 103, 102, 99, 98, 93, 92, 89, 88, 83,
|
||||
82, 79, 78, 75, 74, 71, 70, 67, 66, 63, 62, 59, 58, 55,
|
||||
54, 53, 52, 49, 48, 45, 44, 43, 42, 39, 38, 37, 36, 33,
|
||||
32, 31, 30, 27, 26, 25, 24, 23, 22, 19, 18, 17, 16, 15,
|
||||
14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2
|
||||
};
|
||||
|
||||
uint32_t helper_qseed(CPUTriCoreState *env, uint32_t r1)
|
||||
{
|
||||
uint32_t arg1, S, E, M, E_minus_one, m_idx;
|
||||
uint32_t new_E, new_M, new_S, result;
|
||||
|
||||
arg1 = make_float32(r1);
|
||||
|
||||
/* fetch IEEE-754 fields S, E and the uppermost 6-bit of M */
|
||||
S = extract32(arg1, 31, 1);
|
||||
E = extract32(arg1, 23, 8);
|
||||
M = extract32(arg1, 17, 6);
|
||||
|
||||
if (float32_is_any_nan(arg1)) {
|
||||
result = float32_quiet_nan;
|
||||
} else if (float32_is_zero_or_denormal(arg1)) {
|
||||
if (float32_is_neg(arg1)) {
|
||||
result = float32_infinity | (1 << 31);
|
||||
} else {
|
||||
result = float32_infinity;
|
||||
}
|
||||
} else if (float32_is_neg(arg1)) {
|
||||
result = float32_sqrt_nan;
|
||||
} else if (float32_is_infinity(arg1)) {
|
||||
result = float32_zero;
|
||||
} else {
|
||||
E_minus_one = E - 1;
|
||||
m_idx = ((E_minus_one & 1) << 6) | M;
|
||||
new_S = S;
|
||||
new_E = 0xBD - E_minus_one / 2;
|
||||
new_M = target_qseed_significand_table[m_idx];
|
||||
|
||||
result = 0;
|
||||
result = deposit32(result, 31, 1, new_S);
|
||||
result = deposit32(result, 23, 8, new_E);
|
||||
result = deposit32(result, 15, 8, new_M);
|
||||
}
|
||||
|
||||
if (float32_is_signaling_nan(arg1, &env->fp_status)
|
||||
|| result == float32_sqrt_nan) {
|
||||
env->FPU_FI = 1 << 31;
|
||||
env->FPU_FS = 1;
|
||||
} else {
|
||||
env->FPU_FS = 0;
|
||||
}
|
||||
|
||||
return (uint32_t) result;
|
||||
}
|
||||
|
||||
uint32_t helper_fdiv(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
|
||||
{
|
||||
uint32_t flags;
|
||||
float32 arg1 = make_float32(r1);
|
||||
float32 arg2 = make_float32(r2);
|
||||
float32 f_result;
|
||||
|
||||
f_result = float32_div(arg1, arg2 , &env->fp_status);
|
||||
|
||||
flags = f_get_excp_flags(env);
|
||||
if (flags) {
|
||||
/* If the output is a NaN, but the inputs aren't,
|
||||
we return a unique value. */
|
||||
if ((flags & float_flag_invalid)
|
||||
&& !float32_is_any_nan(arg1)
|
||||
&& !float32_is_any_nan(arg2)) {
|
||||
f_result = DIV_NAN;
|
||||
}
|
||||
f_update_psw_flags(env, flags);
|
||||
} else {
|
||||
env->FPU_FS = 0;
|
||||
}
|
||||
|
||||
return (uint32_t)f_result;
|
||||
}
|
||||
|
||||
uint32_t helper_fmadd(CPUTriCoreState *env, uint32_t r1,
|
||||
uint32_t r2, uint32_t r3)
|
||||
{
|
||||
uint32_t flags;
|
||||
float32 arg1 = make_float32(r1);
|
||||
float32 arg2 = make_float32(r2);
|
||||
float32 arg3 = make_float32(r3);
|
||||
float32 f_result;
|
||||
|
||||
f_result = float32_muladd(arg1, arg2, arg3, 0, &env->fp_status);
|
||||
|
||||
flags = f_get_excp_flags(env);
|
||||
if (flags) {
|
||||
if (flags & float_flag_invalid) {
|
||||
arg1 = float32_squash_input_denormal(arg1, &env->fp_status);
|
||||
arg2 = float32_squash_input_denormal(arg2, &env->fp_status);
|
||||
arg3 = float32_squash_input_denormal(arg3, &env->fp_status);
|
||||
f_result = f_maddsub_nan_result(arg1, arg2, arg3, f_result, 0);
|
||||
}
|
||||
f_update_psw_flags(env, flags);
|
||||
} else {
|
||||
env->FPU_FS = 0;
|
||||
}
|
||||
return (uint32_t)f_result;
|
||||
}
|
||||
|
||||
uint32_t helper_fmsub(CPUTriCoreState *env, uint32_t r1,
|
||||
uint32_t r2, uint32_t r3)
|
||||
{
|
||||
uint32_t flags;
|
||||
float32 arg1 = make_float32(r1);
|
||||
float32 arg2 = make_float32(r2);
|
||||
float32 arg3 = make_float32(r3);
|
||||
float32 f_result;
|
||||
|
||||
f_result = float32_muladd(arg1, arg2, arg3, float_muladd_negate_product,
|
||||
&env->fp_status);
|
||||
|
||||
flags = f_get_excp_flags(env);
|
||||
if (flags) {
|
||||
if (flags & float_flag_invalid) {
|
||||
arg1 = float32_squash_input_denormal(arg1, &env->fp_status);
|
||||
arg2 = float32_squash_input_denormal(arg2, &env->fp_status);
|
||||
arg3 = float32_squash_input_denormal(arg3, &env->fp_status);
|
||||
|
||||
f_result = f_maddsub_nan_result(arg1, arg2, arg3, f_result, 1);
|
||||
}
|
||||
f_update_psw_flags(env, flags);
|
||||
} else {
|
||||
env->FPU_FS = 0;
|
||||
}
|
||||
return (uint32_t)f_result;
|
||||
}
|
||||
|
||||
uint32_t helper_fcmp(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
|
||||
{
|
||||
uint32_t result, flags;
|
||||
float32 arg1 = make_float32(r1);
|
||||
float32 arg2 = make_float32(r2);
|
||||
|
||||
set_flush_inputs_to_zero(0, &env->fp_status);
|
||||
|
||||
result = 1 << (float32_compare_quiet(arg1, arg2, &env->fp_status) + 1);
|
||||
result |= float32_is_denormal(arg1) << 4;
|
||||
result |= float32_is_denormal(arg2) << 5;
|
||||
|
||||
flags = f_get_excp_flags(env);
|
||||
if (flags) {
|
||||
f_update_psw_flags(env, flags);
|
||||
} else {
|
||||
env->FPU_FS = 0;
|
||||
}
|
||||
|
||||
set_flush_inputs_to_zero(1, &env->fp_status);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t helper_ftoi(CPUTriCoreState *env, uint32_t arg)
|
||||
{
|
||||
float32 f_arg = make_float32(arg);
|
||||
int32_t result, flags;
|
||||
|
||||
result = float32_to_int32(f_arg, &env->fp_status);
|
||||
|
||||
flags = f_get_excp_flags(env);
|
||||
if (flags) {
|
||||
if (float32_is_any_nan(f_arg)) {
|
||||
result = 0;
|
||||
}
|
||||
f_update_psw_flags(env, flags);
|
||||
} else {
|
||||
env->FPU_FS = 0;
|
||||
}
|
||||
return (uint32_t)result;
|
||||
}
|
||||
|
||||
uint32_t helper_itof(CPUTriCoreState *env, uint32_t arg)
|
||||
{
|
||||
float32 f_result;
|
||||
uint32_t flags;
|
||||
f_result = int32_to_float32(arg, &env->fp_status);
|
||||
|
||||
flags = f_get_excp_flags(env);
|
||||
if (flags) {
|
||||
f_update_psw_flags(env, flags);
|
||||
} else {
|
||||
env->FPU_FS = 0;
|
||||
}
|
||||
return (uint32_t)f_result;
|
||||
}
|
||||
|
||||
uint32_t helper_utof(CPUTriCoreState *env, uint32_t arg)
|
||||
{
|
||||
float32 f_result;
|
||||
uint32_t flags;
|
||||
|
||||
f_result = uint32_to_float32(arg, &env->fp_status);
|
||||
|
||||
flags = f_get_excp_flags(env);
|
||||
if (flags) {
|
||||
f_update_psw_flags(env, flags);
|
||||
} else {
|
||||
env->FPU_FS = 0;
|
||||
}
|
||||
return (uint32_t)f_result;
|
||||
}
|
||||
|
||||
uint32_t helper_ftoiz(CPUTriCoreState *env, uint32_t arg)
|
||||
{
|
||||
float32 f_arg = make_float32(arg);
|
||||
uint32_t result;
|
||||
int32_t flags;
|
||||
|
||||
result = float32_to_int32_round_to_zero(f_arg, &env->fp_status);
|
||||
|
||||
flags = f_get_excp_flags(env);
|
||||
if (flags & float_flag_invalid) {
|
||||
flags &= ~float_flag_inexact;
|
||||
if (float32_is_any_nan(f_arg)) {
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags) {
|
||||
f_update_psw_flags(env, flags);
|
||||
} else {
|
||||
env->FPU_FS = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t helper_ftouz(CPUTriCoreState *env, uint32_t arg)
|
||||
{
|
||||
float32 f_arg = make_float32(arg);
|
||||
uint32_t result;
|
||||
int32_t flags;
|
||||
|
||||
result = float32_to_uint32_round_to_zero(f_arg, &env->fp_status);
|
||||
|
||||
flags = f_get_excp_flags(env);
|
||||
if (flags & float_flag_invalid) {
|
||||
flags &= ~float_flag_inexact;
|
||||
if (float32_is_any_nan(f_arg)) {
|
||||
result = 0;
|
||||
}
|
||||
} else if (float32_lt_quiet(f_arg, 0, &env->fp_status)) {
|
||||
flags = float_flag_invalid;
|
||||
result = 0;
|
||||
}
|
||||
|
||||
if (flags) {
|
||||
f_update_psw_flags(env, flags);
|
||||
} else {
|
||||
env->FPU_FS = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void helper_updfl(CPUTriCoreState *env, uint32_t arg)
|
||||
{
|
||||
env->FPU_FS = extract32(arg, 7, 1) & extract32(arg, 15, 1);
|
||||
env->FPU_FI = (extract32(arg, 6, 1) & extract32(arg, 14, 1)) << 31;
|
||||
env->FPU_FV = (extract32(arg, 5, 1) & extract32(arg, 13, 1)) << 31;
|
||||
env->FPU_FZ = (extract32(arg, 4, 1) & extract32(arg, 12, 1)) << 31;
|
||||
env->FPU_FU = (extract32(arg, 3, 1) & extract32(arg, 11, 1)) << 31;
|
||||
/* clear FX and RM */
|
||||
env->PSW &= ~(extract32(arg, 10, 1) << 26);
|
||||
env->PSW |= (extract32(arg, 2, 1) & extract32(arg, 10, 1)) << 26;
|
||||
|
||||
fpu_set_state(env);
|
||||
}
|
162
qemu/target/tricore/helper.c
Normal file
162
qemu/target/tricore/helper.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Modified for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "fpu/softfloat-helpers.h"
|
||||
|
||||
enum {
|
||||
TLBRET_DIRTY = -4,
|
||||
TLBRET_INVALID = -3,
|
||||
TLBRET_NOMATCH = -2,
|
||||
TLBRET_BADADDR = -1,
|
||||
TLBRET_MATCH = 0
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
static int get_physical_address(CPUTriCoreState *env, hwaddr *physical,
|
||||
int *prot, target_ulong address,
|
||||
MMUAccessType access_type, int mmu_idx)
|
||||
{
|
||||
int ret = TLBRET_MATCH;
|
||||
|
||||
*physical = address & 0xFFFFFFFF;
|
||||
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
hwaddr tricore_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||
{
|
||||
TriCoreCPU *cpu = TRICORE_CPU(cs);
|
||||
hwaddr phys_addr;
|
||||
int prot;
|
||||
int mmu_idx = cpu_mmu_index(&cpu->env, false);
|
||||
|
||||
if (get_physical_address(&cpu->env, &phys_addr, &prot, addr,
|
||||
MMU_DATA_LOAD, mmu_idx)) {
|
||||
return -1;
|
||||
}
|
||||
return phys_addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TODO: Add exeption support*/
|
||||
static void raise_mmu_exception(CPUTriCoreState *env, target_ulong address,
|
||||
int rw, int tlb_error)
|
||||
{
|
||||
}
|
||||
|
||||
bool tricore_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
||||
MMUAccessType rw, int mmu_idx,
|
||||
bool probe, uintptr_t retaddr)
|
||||
{
|
||||
TriCoreCPU *cpu = TRICORE_CPU(cs);
|
||||
CPUTriCoreState *env = &cpu->env;
|
||||
hwaddr physical;
|
||||
int prot;
|
||||
int ret = 0;
|
||||
|
||||
rw &= 1;
|
||||
ret = get_physical_address(env, &physical, &prot,
|
||||
address, rw, mmu_idx);
|
||||
|
||||
// qemu_log_mask(CPU_LOG_MMU, "%s address=" TARGET_FMT_lx " ret %d physical "
|
||||
// TARGET_FMT_plx " prot %d\n",
|
||||
// __func__, (target_ulong)address, ret, physical, prot);
|
||||
|
||||
if (ret == TLBRET_MATCH) {
|
||||
tlb_set_page(cs, address & TARGET_PAGE_MASK,
|
||||
physical & TARGET_PAGE_MASK, prot | PAGE_EXEC,
|
||||
mmu_idx, TARGET_PAGE_SIZE);
|
||||
return true;
|
||||
} else {
|
||||
assert(ret < 0);
|
||||
if (probe) {
|
||||
return false;
|
||||
}
|
||||
raise_mmu_exception(env, address, rw, ret);
|
||||
cpu_loop_exit_restore(cs, retaddr);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void tricore_cpu_list_entry(gpointer data, gpointer user_data)
|
||||
{
|
||||
ObjectClass *oc = data;
|
||||
const char *typename;
|
||||
char *name;
|
||||
|
||||
typename = object_class_get_name(oc);
|
||||
name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_TRICORE_CPU));
|
||||
qemu_printf(" %s\n", name);
|
||||
g_free(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
void tricore_cpu_list(void)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
list = object_class_get_list_sorted(TYPE_TRICORE_CPU, false);
|
||||
qemu_printf("Available CPUs:\n");
|
||||
g_slist_foreach(list, tricore_cpu_list_entry, NULL);
|
||||
g_slist_free(list);
|
||||
}
|
||||
#endif
|
||||
|
||||
void fpu_set_state(CPUTriCoreState *env)
|
||||
{
|
||||
set_float_rounding_mode(env->PSW & MASK_PSW_FPU_RM, &env->fp_status);
|
||||
set_flush_inputs_to_zero(1, &env->fp_status);
|
||||
set_flush_to_zero(1, &env->fp_status);
|
||||
set_default_nan_mode(1, &env->fp_status);
|
||||
}
|
||||
|
||||
uint32_t psw_read(CPUTriCoreState *env)
|
||||
{
|
||||
/* clear all USB bits */
|
||||
env->PSW &= 0x6ffffff;
|
||||
/* now set them from the cache */
|
||||
env->PSW |= ((env->PSW_USB_C != 0) << 31);
|
||||
env->PSW |= ((env->PSW_USB_V & (1 << 31)) >> 1);
|
||||
env->PSW |= ((env->PSW_USB_SV & (1 << 31)) >> 2);
|
||||
env->PSW |= ((env->PSW_USB_AV & (1 << 31)) >> 3);
|
||||
env->PSW |= ((env->PSW_USB_SAV & (1 << 31)) >> 4);
|
||||
|
||||
return env->PSW;
|
||||
}
|
||||
|
||||
void psw_write(CPUTriCoreState *env, uint32_t val)
|
||||
{
|
||||
env->PSW_USB_C = (val & MASK_USB_C);
|
||||
env->PSW_USB_V = (val & MASK_USB_V) << 1;
|
||||
env->PSW_USB_SV = (val & MASK_USB_SV) << 2;
|
||||
env->PSW_USB_AV = (val & MASK_USB_AV) << 3;
|
||||
env->PSW_USB_SAV = (val & MASK_USB_SAV) << 4;
|
||||
env->PSW = val;
|
||||
|
||||
fpu_set_state(env);
|
||||
}
|
163
qemu/target/tricore/helper.h
Normal file
163
qemu/target/tricore/helper.h
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Modified for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
*/
|
||||
|
||||
DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64)
|
||||
DEF_HELPER_6(uc_traceopcode, void, ptr, i64, i64, i32, ptr, i64)
|
||||
|
||||
/* Arithmetic */
|
||||
DEF_HELPER_3(add_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(add64_ssov, i64, env, i64, i64)
|
||||
DEF_HELPER_3(add_suov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(add_h_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(add_h_suov, i32, env, i32, i32)
|
||||
DEF_HELPER_4(addr_h_ssov, i32, env, i64, i32, i32)
|
||||
DEF_HELPER_4(addsur_h_ssov, i32, env, i64, i32, i32)
|
||||
DEF_HELPER_3(sub_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(sub64_ssov, i64, env, i64, i64)
|
||||
DEF_HELPER_3(sub_suov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(sub_h_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(sub_h_suov, i32, env, i32, i32)
|
||||
DEF_HELPER_4(subr_h_ssov, i32, env, i64, i32, i32)
|
||||
DEF_HELPER_4(subadr_h_ssov, i32, env, i64, i32, i32)
|
||||
DEF_HELPER_3(mul_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(mul_suov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(sha_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_3(absdif_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_4(madd32_ssov, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_4(madd32_suov, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_4(madd64_ssov, i64, env, i32, i64, i32)
|
||||
DEF_HELPER_5(madd64_q_ssov, i64, env, i64, i32, i32, i32)
|
||||
DEF_HELPER_3(madd32_q_add_ssov, i32, env, i64, i64)
|
||||
DEF_HELPER_5(maddr_q_ssov, i32, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_4(madd64_suov, i64, env, i32, i64, i32)
|
||||
DEF_HELPER_4(msub32_ssov, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msub32_suov, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_4(msub64_ssov, i64, env, i32, i64, i32)
|
||||
DEF_HELPER_5(msub64_q_ssov, i64, env, i64, i32, i32, i32)
|
||||
DEF_HELPER_3(msub32_q_sub_ssov, i32, env, i64, i64)
|
||||
DEF_HELPER_5(msubr_q_ssov, i32, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_4(msub64_suov, i64, env, i32, i64, i32)
|
||||
DEF_HELPER_3(absdif_h_ssov, i32, env, i32, i32)
|
||||
DEF_HELPER_2(abs_ssov, i32, env, i32)
|
||||
DEF_HELPER_2(abs_h_ssov, i32, env, i32)
|
||||
/* hword/byte arithmetic */
|
||||
DEF_HELPER_2(abs_b, i32, env, i32)
|
||||
DEF_HELPER_2(abs_h, i32, env, i32)
|
||||
DEF_HELPER_3(absdif_b, i32, env, i32, i32)
|
||||
DEF_HELPER_3(absdif_h, i32, env, i32, i32)
|
||||
DEF_HELPER_4(addr_h, i32, env, i64, i32, i32)
|
||||
DEF_HELPER_4(addsur_h, i32, env, i64, i32, i32)
|
||||
DEF_HELPER_5(maddr_q, i32, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_3(add_b, i32, env, i32, i32)
|
||||
DEF_HELPER_3(add_h, i32, env, i32, i32)
|
||||
DEF_HELPER_3(sub_b, i32, env, i32, i32)
|
||||
DEF_HELPER_3(sub_h, i32, env, i32, i32)
|
||||
DEF_HELPER_4(subr_h, i32, env, i64, i32, i32)
|
||||
DEF_HELPER_4(subadr_h, i32, env, i64, i32, i32)
|
||||
DEF_HELPER_5(msubr_q, i32, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(eq_b, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(eq_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(eqany_b, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(eqany_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(lt_b, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(lt_bu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(lt_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(lt_hu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(max_b, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(max_bu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(max_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(max_hu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(ixmax, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_FLAGS_2(ixmax_u, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_FLAGS_2(min_b, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(min_bu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(min_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(min_hu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(ixmin, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_FLAGS_2(ixmin_u, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
/* count leading ... */
|
||||
DEF_HELPER_FLAGS_1(clo_h, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||
DEF_HELPER_FLAGS_1(clz_h, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||
DEF_HELPER_FLAGS_1(cls_h, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||
/* sh */
|
||||
DEF_HELPER_FLAGS_2(sh, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(sh_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_3(sha, i32, env, i32, i32)
|
||||
DEF_HELPER_2(sha_h, i32, i32, i32)
|
||||
/* merge/split/parity */
|
||||
DEF_HELPER_FLAGS_2(bmerge, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_1(bsplit, TCG_CALL_NO_RWG_SE, i64, i32)
|
||||
DEF_HELPER_FLAGS_1(parity, TCG_CALL_NO_RWG_SE, i32, i32)
|
||||
/* float */
|
||||
DEF_HELPER_FLAGS_4(pack, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32)
|
||||
DEF_HELPER_1(unpack, i64, i32)
|
||||
DEF_HELPER_3(fadd, i32, env, i32, i32)
|
||||
DEF_HELPER_3(fsub, i32, env, i32, i32)
|
||||
DEF_HELPER_3(fmul, i32, env, i32, i32)
|
||||
DEF_HELPER_3(fdiv, i32, env, i32, i32)
|
||||
DEF_HELPER_4(fmadd, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_4(fmsub, i32, env, i32, i32, i32)
|
||||
DEF_HELPER_3(fcmp, i32, env, i32, i32)
|
||||
DEF_HELPER_2(qseed, i32, env, i32)
|
||||
DEF_HELPER_2(ftoi, i32, env, i32)
|
||||
DEF_HELPER_2(itof, i32, env, i32)
|
||||
DEF_HELPER_2(utof, i32, env, i32)
|
||||
DEF_HELPER_2(ftoiz, i32, env, i32)
|
||||
DEF_HELPER_2(ftouz, i32, env, i32)
|
||||
DEF_HELPER_2(updfl, void, env, i32)
|
||||
/* dvinit */
|
||||
DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32)
|
||||
DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32)
|
||||
DEF_HELPER_3(dvinit_h_13, i64, env, i32, i32)
|
||||
DEF_HELPER_3(dvinit_h_131, i64, env, i32, i32)
|
||||
DEF_HELPER_FLAGS_2(dvadj, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_FLAGS_2(dvstep, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_FLAGS_2(dvstep_u, TCG_CALL_NO_RWG_SE, i64, i64, i32)
|
||||
DEF_HELPER_3(divide, i64, env, i32, i32)
|
||||
DEF_HELPER_3(divide_u, i64, env, i32, i32)
|
||||
/* mulh */
|
||||
DEF_HELPER_FLAGS_5(mul_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_5(mulm_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_5(mulr_h, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32, i32)
|
||||
/* crc32 */
|
||||
DEF_HELPER_FLAGS_2(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32)
|
||||
/* CSA */
|
||||
DEF_HELPER_2(call, void, env, i32)
|
||||
DEF_HELPER_1(ret, void, env)
|
||||
DEF_HELPER_2(bisr, void, env, i32)
|
||||
DEF_HELPER_1(rfe, void, env)
|
||||
DEF_HELPER_1(rfm, void, env)
|
||||
DEF_HELPER_2(ldlcx, void, env, i32)
|
||||
DEF_HELPER_2(lducx, void, env, i32)
|
||||
DEF_HELPER_2(stlcx, void, env, i32)
|
||||
DEF_HELPER_2(stucx, void, env, i32)
|
||||
DEF_HELPER_1(svlcx, void, env)
|
||||
DEF_HELPER_1(svucx, void, env)
|
||||
DEF_HELPER_1(rslcx, void, env)
|
||||
/* Address mode helper */
|
||||
DEF_HELPER_1(br_update, i32, i32)
|
||||
DEF_HELPER_2(circ_update, i32, i32, i32)
|
||||
/* PSW cache helper */
|
||||
DEF_HELPER_2(psw_write, void, env, i32)
|
||||
DEF_HELPER_1(psw_read, i32, env)
|
||||
/* Exceptions */
|
||||
DEF_HELPER_3(raise_exception_sync, noreturn, env, i32, i32)
|
2795
qemu/target/tricore/op_helper.c
Normal file
2795
qemu/target/tricore/op_helper.c
Normal file
File diff suppressed because it is too large
Load Diff
9374
qemu/target/tricore/translate.c
Normal file
9374
qemu/target/tricore/translate.c
Normal file
File diff suppressed because it is too large
Load Diff
23
qemu/target/tricore/tricore-defs.h
Normal file
23
qemu/target/tricore/tricore-defs.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QEMU_TRICORE_DEFS_H
|
||||
#define QEMU_TRICORE_DEFS_H
|
||||
|
||||
#define TRICORE_TLB_MAX 128
|
||||
|
||||
#endif /* QEMU_TRICORE_DEFS_H */
|
1474
qemu/target/tricore/tricore-opcodes.h
Normal file
1474
qemu/target/tricore/tricore-opcodes.h
Normal file
File diff suppressed because it is too large
Load Diff
270
qemu/target/tricore/unicorn.c
Normal file
270
qemu/target/tricore/unicorn.c
Normal file
@ -0,0 +1,270 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015 */
|
||||
|
||||
/*
|
||||
Created for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
*/
|
||||
|
||||
#include "qemu/typedefs.h"
|
||||
#include "unicorn/unicorn.h"
|
||||
#include "sysemu/cpus.h"
|
||||
#include "sysemu/tcg.h"
|
||||
#include "cpu.h"
|
||||
#include "uc_priv.h"
|
||||
#include "unicorn_common.h"
|
||||
#include "unicorn.h"
|
||||
|
||||
TriCoreCPU *cpu_tricore_init(struct uc_struct *uc);
|
||||
|
||||
void tricore_set_pc(struct uc_struct *uc, uint64_t address)
|
||||
{
|
||||
((CPUTriCoreState *)uc->cpu->env_ptr)->PC = address;
|
||||
}
|
||||
|
||||
void tricore_reg_reset(struct uc_struct *uc)
|
||||
{
|
||||
CPUTriCoreState *env;
|
||||
(void)uc;
|
||||
|
||||
env = uc->cpu->env_ptr;
|
||||
memset(env->gpr_a, 0, sizeof(env->gpr_a));
|
||||
memset(env->gpr_d, 0, sizeof(env->gpr_d));
|
||||
|
||||
env->PC = 0;
|
||||
}
|
||||
|
||||
static void reg_read(CPUTriCoreState *env, unsigned int regid, void *value)
|
||||
{
|
||||
if (regid >= UC_TRICORE_REG_A0 && regid <= UC_TRICORE_REG_A9)
|
||||
*(int32_t *)value = env->gpr_a[regid - UC_TRICORE_REG_A0];
|
||||
if (regid >= UC_TRICORE_REG_A12 && regid <= UC_TRICORE_REG_A15)
|
||||
*(int32_t *)value = env->gpr_a[regid - UC_TRICORE_REG_A0];
|
||||
else if (regid >= UC_TRICORE_REG_D0 && regid <= UC_TRICORE_REG_D15)
|
||||
*(int32_t *)value = env->gpr_d[regid - UC_TRICORE_REG_D0];
|
||||
else {
|
||||
switch (regid) {
|
||||
// case UC_TRICORE_REG_SP:
|
||||
case UC_TRICORE_REG_A10:
|
||||
*(int32_t *)value = env->gpr_a[10];
|
||||
break;
|
||||
// case UC_TRICORE_REG_LR:
|
||||
case UC_TRICORE_REG_A11:
|
||||
*(int32_t *)value = env->gpr_a[11];
|
||||
break;
|
||||
case UC_TRICORE_REG_PC:
|
||||
*(int32_t *)value = env->PC;
|
||||
break;
|
||||
case UC_TRICORE_REG_PCXI:
|
||||
*(int32_t *)value = env->PCXI;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW:
|
||||
*(int32_t *)value = env->PSW;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW_USB_C:
|
||||
*(int32_t *)value = env->PSW_USB_C;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW_USB_V:
|
||||
*(int32_t *)value = env->PSW_USB_V;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW_USB_SV:
|
||||
*(int32_t *)value = env->PSW_USB_SV;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW_USB_AV:
|
||||
*(int32_t *)value = env->PSW_USB_AV;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW_USB_SAV:
|
||||
*(int32_t *)value = env->PSW_USB_SAV;
|
||||
break;
|
||||
case UC_TRICORE_REG_SYSCON:
|
||||
*(int32_t *)value = env->SYSCON;
|
||||
break;
|
||||
case UC_TRICORE_REG_CPU_ID:
|
||||
*(int32_t *)value = env->CPU_ID;
|
||||
break;
|
||||
case UC_TRICORE_REG_BIV:
|
||||
*(int32_t *)value = env->BIV;
|
||||
break;
|
||||
case UC_TRICORE_REG_BTV:
|
||||
*(int32_t *)value = env->BTV;
|
||||
break;
|
||||
case UC_TRICORE_REG_ISP:
|
||||
*(int32_t *)value = env->ISP;
|
||||
break;
|
||||
case UC_TRICORE_REG_ICR:
|
||||
*(int32_t *)value = env->ICR;
|
||||
break;
|
||||
case UC_TRICORE_REG_FCX:
|
||||
*(int32_t *)value = env->FCX;
|
||||
break;
|
||||
case UC_TRICORE_REG_LCX:
|
||||
*(int32_t *)value = env->LCX;
|
||||
break;
|
||||
case UC_TRICORE_REG_COMPAT:
|
||||
*(int32_t *)value = env->COMPAT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int tricore_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals,
|
||||
int count)
|
||||
{
|
||||
CPUTriCoreState *env = &(TRICORE_CPU(uc->cpu)->env);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned int regid = regs[i];
|
||||
void *value = vals[i];
|
||||
reg_read(env, regid, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tricore_context_reg_read(struct uc_context *uc, unsigned int *regs,
|
||||
void **vals, int count)
|
||||
{
|
||||
CPUTriCoreState *env = (CPUTriCoreState *)uc->data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned int regid = regs[i];
|
||||
void *value = vals[i];
|
||||
reg_read(env, regid, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void reg_write(CPUTriCoreState *env, unsigned int regid,
|
||||
const void *value)
|
||||
{
|
||||
if (regid >= UC_TRICORE_REG_A0 && regid <= UC_TRICORE_REG_A9)
|
||||
env->gpr_a[regid - UC_TRICORE_REG_A0] = *(int32_t *)value;
|
||||
if (regid >= UC_TRICORE_REG_A12 && regid <= UC_TRICORE_REG_A15)
|
||||
env->gpr_a[regid - UC_TRICORE_REG_A0] = *(int32_t *)value;
|
||||
else if (regid >= UC_TRICORE_REG_D0 && regid <= UC_TRICORE_REG_D15)
|
||||
env->gpr_d[regid - UC_TRICORE_REG_D0] = *(int32_t *)value;
|
||||
else {
|
||||
switch (regid) {
|
||||
// case UC_TRICORE_REG_SP:
|
||||
case UC_TRICORE_REG_A10:
|
||||
env->gpr_a[10] = *(int32_t *)value;
|
||||
break;
|
||||
// case UC_TRICORE_REG_LR:
|
||||
case UC_TRICORE_REG_A11:
|
||||
env->gpr_a[11] = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_PC:
|
||||
env->PC = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_PCXI:
|
||||
env->PCXI = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW:
|
||||
env->PSW = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW_USB_C:
|
||||
env->PSW_USB_C = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW_USB_V:
|
||||
env->PSW_USB_V = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW_USB_SV:
|
||||
env->PSW_USB_SV = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW_USB_AV:
|
||||
env->PSW_USB_AV = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_PSW_USB_SAV:
|
||||
env->PSW_USB_SAV = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_SYSCON:
|
||||
env->SYSCON = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_CPU_ID:
|
||||
env->CPU_ID = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_BIV:
|
||||
env->BIV = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_BTV:
|
||||
env->BTV = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_ISP:
|
||||
env->ISP = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_ICR:
|
||||
env->ICR = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_FCX:
|
||||
env->FCX = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_LCX:
|
||||
env->LCX = *(int32_t *)value;
|
||||
break;
|
||||
case UC_TRICORE_REG_COMPAT:
|
||||
env->COMPAT = *(int32_t *)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int tricore_reg_write(struct uc_struct *uc, unsigned int *regs,
|
||||
void *const *vals, int count)
|
||||
{
|
||||
CPUTriCoreState *env = &(TRICORE_CPU(uc->cpu)->env);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned int regid = regs[i];
|
||||
void *value = vals[i];
|
||||
reg_write(env, regid, value);
|
||||
if (regid == UC_TRICORE_REG_PC) {
|
||||
// force to quit execution and flush TB
|
||||
uc->quit_request = true;
|
||||
uc_emu_stop(uc);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tricore_context_reg_write(struct uc_context *uc, unsigned int *regs,
|
||||
void *const *vals, int count)
|
||||
{
|
||||
CPUTriCoreState *env = (CPUTriCoreState *)uc->data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned int regid = regs[i];
|
||||
const void *value = vals[i];
|
||||
reg_write(env, regid, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tricore_cpus_init(struct uc_struct *uc, const char *cpu_model)
|
||||
{
|
||||
TriCoreCPU *cpu;
|
||||
|
||||
cpu = cpu_tricore_init(uc);
|
||||
if (cpu == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tricore_uc_init(struct uc_struct *uc)
|
||||
{
|
||||
uc->reg_read = tricore_reg_read;
|
||||
uc->reg_write = tricore_reg_write;
|
||||
uc->reg_reset = tricore_reg_reset;
|
||||
uc->set_pc = tricore_set_pc;
|
||||
uc->cpus_init = tricore_cpus_init;
|
||||
uc->cpu_context_size = offsetof(CPUTriCoreState, end_reset_fields);
|
||||
uc_common_init(uc);
|
||||
}
|
27
qemu/target/tricore/unicorn.h
Normal file
27
qemu/target/tricore/unicorn.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015 */
|
||||
|
||||
/*
|
||||
Modified for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
*/
|
||||
|
||||
#ifndef UC_QEMU_TARGET_TRICORE_H
|
||||
#define UC_QEMU_TARGET_TRICORE_H
|
||||
|
||||
// functions to read & write registers
|
||||
int tricore_reg_read(struct uc_struct *uc, unsigned int *regs, void **vals,
|
||||
int count);
|
||||
int tricore_reg_write(struct uc_struct *uc, unsigned int *regs,
|
||||
void *const *vals, int count);
|
||||
|
||||
int tricore_context_reg_read(struct uc_context *uc, unsigned int *regs,
|
||||
void **vals, int count);
|
||||
int tricore_context_reg_write(struct uc_context *uc, unsigned int *regs,
|
||||
void *const *vals, int count);
|
||||
|
||||
void tricore_reg_reset(struct uc_struct *uc);
|
||||
|
||||
void tricore_uc_init(struct uc_struct *uc);
|
||||
|
||||
#endif
|
1289
qemu/tricore.h
Normal file
1289
qemu/tricore.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -89,6 +89,9 @@ endif
|
||||
ifneq (,$(findstring m68k,$(UNICORN_ARCHS)))
|
||||
SOURCES += sample_m68k.c
|
||||
endif
|
||||
ifneq (,$(findstring tricore,$(UNICORN_ARCHS)))
|
||||
SOURCES += sample_tricore.c
|
||||
endif
|
||||
|
||||
BINS = $(SOURCES:.c=$(BIN_EXT))
|
||||
OBJS = $(SOURCES:.c=.o)
|
||||
|
100
samples/sample_tricore.c
Normal file
100
samples/sample_tricore.c
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
Created for Unicorn Engine by Eric Poole <eric.poole@aptiv.com>, 2022
|
||||
Copyright 2022 Aptiv
|
||||
*/
|
||||
|
||||
/* Sample code to demonstrate how to emulate TriCore code */
|
||||
|
||||
#include <unicorn/unicorn.h>
|
||||
#include <string.h>
|
||||
|
||||
// code to be emulated
|
||||
#define CODE "\x82\x11\xbb\x00\x00\x08" // mov d0, #0x1; mov.u d0, #0x8000
|
||||
|
||||
// memory address where emulation starts
|
||||
#define ADDRESS 0x10000
|
||||
|
||||
static void hook_block(uc_engine *uc, uint64_t address, uint32_t size,
|
||||
void *user_data)
|
||||
{
|
||||
printf(">>> Tracing basic block at 0x%" PRIx64 ", block size = 0x%x\n",
|
||||
address, size);
|
||||
}
|
||||
|
||||
static void hook_code(uc_engine *uc, uint64_t address, uint32_t size,
|
||||
void *user_data)
|
||||
{
|
||||
printf(">>> Tracing instruction at 0x%" PRIx64
|
||||
", instruction size = 0x%x\n",
|
||||
address, size);
|
||||
}
|
||||
|
||||
static void test_tricore(void)
|
||||
{
|
||||
uc_engine *uc;
|
||||
uc_err err;
|
||||
uc_hook trace1, trace2;
|
||||
|
||||
uint32_t d0 = 0x0; // d0 register
|
||||
|
||||
printf("Emulate TriCore code\n");
|
||||
|
||||
// Initialize emulator in TriCore mode
|
||||
err = uc_open(UC_ARCH_TRICORE, UC_MODE_LITTLE_ENDIAN, &uc);
|
||||
if (err) {
|
||||
printf("Failed on uc_open() with error returned: %u (%s)\n", err,
|
||||
uc_strerror(err));
|
||||
return;
|
||||
}
|
||||
|
||||
// map 2MB memory for this emulation
|
||||
uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL);
|
||||
|
||||
// write machine code to be emulated to memory
|
||||
uc_mem_write(uc, ADDRESS, CODE, sizeof(CODE) - 1);
|
||||
|
||||
// tracing all basic blocks with customized callback
|
||||
uc_hook_add(uc, &trace1, UC_HOOK_BLOCK, hook_block, NULL, 1, 0);
|
||||
|
||||
// tracing one instruction at ADDRESS with customized callback
|
||||
uc_hook_add(uc, &trace2, UC_HOOK_CODE, hook_code, NULL, ADDRESS,
|
||||
ADDRESS + sizeof(CODE) - 1);
|
||||
|
||||
// emulate machine code in infinite time (last param = 0), or when
|
||||
// finishing all the code.
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(CODE) - 1, 0, 0);
|
||||
if (err) {
|
||||
printf("Failed on uc_emu_start() with error returned: %u\n", err);
|
||||
}
|
||||
|
||||
// now print out some registers
|
||||
printf(">>> Emulation done. Below is the CPU context\n");
|
||||
|
||||
uc_reg_read(uc, UC_TRICORE_REG_D0, &d0);
|
||||
printf(">>> d0 = 0x%x\n", d0);
|
||||
|
||||
uc_close(uc);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
// dynamically load shared library
|
||||
#ifdef DYNLOAD
|
||||
if (!uc_dyn_load(NULL, 0)) {
|
||||
printf("Error dynamically loading shared library.\n");
|
||||
printf("Please check that unicorn.dll/unicorn.so is available as well "
|
||||
"as\n");
|
||||
printf("any other dependent dll/so files.\n");
|
||||
printf("The easiest way is to place them in the same directory as this "
|
||||
"app.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
test_tricore();
|
||||
#ifdef DYNLOAD
|
||||
uc_dyn_free();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
14
symbols.sh
14
symbols.sh
@ -6274,7 +6274,19 @@ tcg_s390_program_interrupt \
|
||||
tcg_s390_data_exception \
|
||||
"
|
||||
|
||||
ARCHS="x86_64 arm aarch64 riscv32 riscv64 mips mipsel mips64 mips64el sparc sparc64 m68k ppc ppc64 s390x"
|
||||
tricore_SYMBOLS="
|
||||
helper_fadd \
|
||||
helper_fsub \
|
||||
helper_fmul \
|
||||
helper_fdiv \
|
||||
helper_fmadd \
|
||||
helper_fmsub \
|
||||
helper_pack \
|
||||
gen_intermediate_code \
|
||||
restore_state_to_opc \
|
||||
"
|
||||
|
||||
ARCHS="x86_64 arm aarch64 riscv32 riscv64 mips mipsel mips64 mips64el sparc sparc64 m68k ppc ppc64 s390x tricore"
|
||||
|
||||
for arch in $ARCHS; do
|
||||
|
||||
|
6
tests/unit/test_tricore.c
Normal file
6
tests/unit/test_tricore.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "unicorn_test.h"
|
||||
|
||||
const uint64_t code_start = 0x1000;
|
||||
const uint64_t code_len = 0x4000;
|
||||
|
||||
TEST_LIST = {{NULL, NULL}};
|
25
uc.c
25
uc.c
@ -24,6 +24,7 @@
|
||||
#include "qemu/target/ppc/unicorn.h"
|
||||
#include "qemu/target/riscv/unicorn.h"
|
||||
#include "qemu/target/s390x/unicorn.h"
|
||||
#include "qemu/target/tricore/unicorn.h"
|
||||
|
||||
#include "qemu/include/qemu/queue.h"
|
||||
#include "qemu-common.h"
|
||||
@ -167,6 +168,10 @@ bool uc_arch_supported(uc_arch arch)
|
||||
#ifdef UNICORN_HAS_S390X
|
||||
case UC_ARCH_S390X:
|
||||
return true;
|
||||
#endif
|
||||
#ifdef UNICORN_HAS_TRICORE
|
||||
case UC_ARCH_TRICORE:
|
||||
return true;
|
||||
#endif
|
||||
/* Invalid or disabled arch */
|
||||
default:
|
||||
@ -384,6 +389,15 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **result)
|
||||
}
|
||||
uc->init_arch = s390_uc_init;
|
||||
break;
|
||||
#endif
|
||||
#ifdef UNICORN_HAS_TRICORE
|
||||
case UC_ARCH_TRICORE:
|
||||
if ((mode & ~UC_MODE_TRICORE_MASK)) {
|
||||
free(uc);
|
||||
return UC_ERR_MODE;
|
||||
}
|
||||
uc->init_arch = tricore_uc_init;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -798,6 +812,11 @@ uc_err uc_emu_start(uc_engine *uc, uint64_t begin, uint64_t until,
|
||||
case UC_ARCH_S390X:
|
||||
uc_reg_write(uc, UC_S390X_REG_PC, &begin);
|
||||
break;
|
||||
#endif
|
||||
#ifdef UNICORN_HAS_TRICORE
|
||||
case UC_ARCH_TRICORE:
|
||||
uc_reg_write(uc, UC_TRICORE_REG_PC, &begin);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1960,6 +1979,12 @@ static void find_context_reg_rw_function(uc_arch arch, uc_mode mode,
|
||||
rw->context_reg_read = s390_context_reg_read;
|
||||
rw->context_reg_write = s390_context_reg_write;
|
||||
break;
|
||||
#endif
|
||||
#ifdef UNICORN_HAS_TRICORE
|
||||
case UC_ARCH_TRICORE:
|
||||
rw->context_reg_read = tricore_context_reg_read;
|
||||
rw->context_reg_write = tricore_context_reg_write;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user