Merge "Removed OVP-related (source) files/code (backend discarded)."
This commit is contained in:
@ -30,9 +30,8 @@ include(doxygen)
|
|||||||
#### Backend selection ####
|
#### Backend selection ####
|
||||||
OPTION( BUILD_BOCHS "Build Bochs Variant?" ON)
|
OPTION( BUILD_BOCHS "Build Bochs Variant?" ON)
|
||||||
OPTION( BUILD_GEM5 "Build gem5 Variant?" OFF)
|
OPTION( BUILD_GEM5 "Build gem5 Variant?" OFF)
|
||||||
OPTION( BUILD_OVP "Build OVP Variant?" OFF)
|
|
||||||
OPTION( BUILD_QEMU "Build QEMU Variant?" OFF)
|
OPTION( BUILD_QEMU "Build QEMU Variant?" OFF)
|
||||||
OPTION( BUILD_T32 "Build Lauterbach Trace32 Variant?" OFF)
|
OPTION( BUILD_T32 "Build Lauterbach Trace32 Variant?" OFF)
|
||||||
|
|
||||||
OPTION( BUILD_X86 "Build for x86 guests?" ON)
|
OPTION( BUILD_X86 "Build for x86 guests?" ON)
|
||||||
OPTION( BUILD_ARM "Build for ARM guests?" OFF)
|
OPTION( BUILD_ARM "Build for ARM guests?" OFF)
|
||||||
@ -47,8 +46,6 @@ if(BUILD_BOCHS)
|
|||||||
elseif(BUILD_GEM5)
|
elseif(BUILD_GEM5)
|
||||||
include_directories(simulators/gem5/src simulators/gem5/build/ARM)
|
include_directories(simulators/gem5/src simulators/gem5/build/ARM)
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -DTRACING_ON")
|
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -DTRACING_ON")
|
||||||
elseif(BUILD_OVP)
|
|
||||||
add_subdirectory(simulators/ovp)
|
|
||||||
elseif(BUILD_QEMU)
|
elseif(BUILD_QEMU)
|
||||||
include_directories(simulators)
|
include_directories(simulators)
|
||||||
elseif(BUILD_T32)
|
elseif(BUILD_T32)
|
||||||
@ -73,7 +70,6 @@ add_subdirectory(src)
|
|||||||
#### Backend-related build system stuff
|
#### Backend-related build system stuff
|
||||||
include(bochs)
|
include(bochs)
|
||||||
include(gem5)
|
include(gem5)
|
||||||
include(ovp)
|
|
||||||
include(qemu)
|
include(qemu)
|
||||||
include(t32)
|
include(t32)
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
#### OVP-specific stuff
|
|
||||||
if(BUILD_OVP)
|
|
||||||
message(STATUS "[${PROJECT_NAME}] Building OVP variant ...")
|
|
||||||
SET(VARIANT ovp)
|
|
||||||
endif(BUILD_OVP)
|
|
||||||
@ -11,21 +11,31 @@ fail: Fail* parent directory, containing all source & configuration files (${FA
|
|||||||
|-scripts: python/shell scripts for Fail*-compilation and experiment distribution
|
|-scripts: python/shell scripts for Fail*-compilation and experiment distribution
|
||||||
|-simulators: parent directory of simulators supported by Fail* (may still be WIP)
|
|-simulators: parent directory of simulators supported by Fail* (may still be WIP)
|
||||||
|-bochs: source files of the (modified) Bochs x86 simulator backend
|
|-bochs: source files of the (modified) Bochs x86 simulator backend
|
||||||
|-ovp: source files of the Open Virtual Platform simulator backend
|
|-gem5: source files of the gem5 simulator backend
|
||||||
|
|-debuggers: parent directory of debuggers supported by Fail* (may still be WIP)
|
||||||
|
|-gdb: source files related to the GNU gdb debugger
|
||||||
|
|-t32: source files related to the Lauterbach T32 debugger
|
||||||
|-src: C/C++/AspectC++ source files related to Fail*, experiments and plugins
|
|-src: C/C++/AspectC++ source files related to Fail*, experiments and plugins
|
||||||
|-core: core source files forming the Fail* framework
|
|-core: core source files forming the Fail* framework
|
||||||
|-util: utility classes and miscellaneous helper functions
|
|-util: utility classes and miscellaneous helper functions
|
||||||
|-config: CMake configuration files, defining the Fail* components and variant
|
|-config: CMake configuration files, defining the Fail* components and variant
|
||||||
|-sal: source file forming the Simulator Abstraction Layer (backend-interface)
|
|-sal: source file forming the Simulator Abstraction Layer (backend-interface)
|
||||||
|-bochs: backend source files to the Bochs simulator
|
|-bochs: backend source files of the Bochs simulator
|
||||||
|-ovp: backend source files to the Open Virtual Platform simulator
|
|-gem5: backend source files of the gem5 simulator
|
||||||
|
|-qemu: backend source files of the QEMU simulator
|
||||||
|
|-t32: backend source files of the Lauterbach T32 debugger
|
||||||
|
|-arm: ARM-specific platform source files
|
||||||
|
|-x86: x86-specific platform source files
|
||||||
|
|-perf: performance-related source files (extensions); speeds up
|
||||||
|
Fail* <-> simulator interaction (e.g., when using breakpoints)
|
||||||
|-cpn: campaign- (and therefore server-)related source files
|
|-cpn: campaign- (and therefore server-)related source files
|
||||||
|-efw: experiment-framework- (and therefore client-)related source files
|
|-efw: experiment-framework- (and therefore client-)related source files
|
||||||
|-comm: communication related source files (these files are used by cpn and efw)
|
|-comm: communication related source files (these files are used by cpn and efw), incl.
|
||||||
|-msg: Google protobuf message definitions used for communication purposes
|
protobuf message definitions used for communication purposes
|
||||||
|-experiments: experiment code files (within a new dir) need to be located here
|
|-experiments: experiment code files (within a new dir) need to be located here
|
||||||
|-plugins: plugin code files (within a new dir) need to be located here
|
|-plugins: plugin code files (within a new dir) need to be located here
|
||||||
|-[build]: recommended location of your build-tree, generated files will be placed here
|
|-tools: Fail*-related tools, e.g., for tracing or fault-space pruning
|
||||||
|
|-[build]: recommended location of your build-tree, generated files will be placed here
|
||||||
|
|
||||||
|
|
||||||
Some additional useful notes:
|
Some additional useful notes:
|
||||||
@ -40,8 +50,8 @@ Some additional useful notes:
|
|||||||
- CMake invokes the compiler with the following include directories:
|
- CMake invokes the compiler with the following include directories:
|
||||||
* ${FAIL_DIR}/src/core
|
* ${FAIL_DIR}/src/core
|
||||||
* ${BUILD_DIR}/src/core
|
* ${BUILD_DIR}/src/core
|
||||||
When compiling the Bochs variant the following directory is added, too:
|
When compiling the $SIMULATOR variant the following directory is added, too:
|
||||||
* ${FAIL_DIR}/simulators/bochs
|
* ${FAIL_DIR}/simulators/$SIMULATOR
|
||||||
These definitions simplify and shorten the include paths.
|
These definitions simplify and shorten the include paths.
|
||||||
|
|
||||||
=========================================================================================
|
=========================================================================================
|
||||||
|
|||||||
@ -184,25 +184,6 @@ Comparison IPS numbers are shown in the default "bochsrc". Headless bochsrc conf
|
|||||||
all aspects disabled, guest system executes endless loop, host CPU Xeon X5470 (3.33GHz):
|
all aspects disabled, guest system executes endless loop, host CPU Xeon X5470 (3.33GHz):
|
||||||
IPS: 66124283 average = 66964789
|
IPS: 66124283 average = 66964789
|
||||||
|
|
||||||
Building OVP for ARM Cortex-M3:
|
|
||||||
**********************************************************************
|
|
||||||
|
|
||||||
For the first time:
|
|
||||||
------------------------------------------------------------
|
|
||||||
1. Get a license from http://www.ovpworld.org/
|
|
||||||
2. Download the following files:
|
|
||||||
- Downloads -> Main OVP Download including OVPsim Simulator
|
|
||||||
- Downloads -> ARM -> ARM OVP Cortex-M Profile Model
|
|
||||||
-> Self contained ARM Cortex-M examples
|
|
||||||
-> ARM GNU GCC and GDB tools
|
|
||||||
3. Install OVP by running the self-extracting archives.
|
|
||||||
4. Get Sourcery CodeBench Lite Edition from
|
|
||||||
http://www.mentor.com/embedded-software/codesourcery
|
|
||||||
(ARM processors -> EABI release)
|
|
||||||
5. Install the self-extracting archive, or use the installation in
|
|
||||||
/fs/proj/compiler/codesourcery-arm-eabi (DO, ios/kos)
|
|
||||||
TODO: Source setup.sh, setupImperas ...
|
|
||||||
TODO: Fix Hard-coded paths
|
|
||||||
|
|
||||||
Building gem5:
|
Building gem5:
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|||||||
20
doc/todo.txt
20
doc/todo.txt
@ -117,7 +117,7 @@ Buildsystem:
|
|||||||
(verwendeter Compiler, Installationsverzeichnis, ...), den Rest in einem
|
(verwendeter Compiler, Installationsverzeichnis, ...), den Rest in einem
|
||||||
brauchbaren Konfigurationswerkzeug mit Ausdrucksmöglichkeiten für
|
brauchbaren Konfigurationswerkzeug mit Ausdrucksmöglichkeiten für
|
||||||
Merkmalmodelle, Abhängigkeiten, Mehrfachauswahl etc. (kconfig?)
|
Merkmalmodelle, Abhängigkeiten, Mehrfachauswahl etc. (kconfig?)
|
||||||
* Bochs / OVP / Gem5 sind Alternativen, nicht beide anschaltbar
|
* Bochs / T32 / Gem5 sind Alternativen, nicht beide anschaltbar
|
||||||
-> Cmake-Combo-Box (ggf. noch an anderen Stellen einsetzbar)
|
-> Cmake-Combo-Box (ggf. noch an anderen Stellen einsetzbar)
|
||||||
http://www.kitware.com/blog/home/post/82
|
http://www.kitware.com/blog/home/post/82
|
||||||
- Hinzufügen eines neuen Experiments konkreter dokumentieren (how-to-build.txt?)
|
- Hinzufügen eines neuen Experiments konkreter dokumentieren (how-to-build.txt?)
|
||||||
@ -218,21 +218,3 @@ Theorie TODO
|
|||||||
==========================================================================================
|
==========================================================================================
|
||||||
- Problem Fork von FI Tools -> Merging eklig.
|
- Problem Fork von FI Tools -> Merging eklig.
|
||||||
-> Liste mit konkreten Beispielen
|
-> Liste mit konkreten Beispielen
|
||||||
|
|
||||||
|
|
||||||
==========================================================================================
|
|
||||||
FailOVP-Bausteine TODO
|
|
||||||
==========================================================================================
|
|
||||||
Wer gerade an was arbeitet, steht in Klammern hinter dem TODO.
|
|
||||||
|
|
||||||
Abstraktionen:
|
|
||||||
- save/restore implementieren -> Speicher-, Register-, Timer-, ??- Zustaende
|
|
||||||
|
|
||||||
Sonstiges:
|
|
||||||
- Sections aus ELF Datei extrahieren, entsprechende Speicherbereiche (generisch) anlegen (rz)
|
|
||||||
- Symbole aus ELF extrahieren -> Adressen von globalen Objekten/Funktionen in Experimenten angeben (rz)
|
|
||||||
- Prozessormodell per cmake cleanen und neu bauen (mh)
|
|
||||||
- CiAO ELF in OVP ausfuehren
|
|
||||||
|
|
||||||
Erledigt:
|
|
||||||
-
|
|
||||||
|
|||||||
@ -1,56 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
# PreDefined environment variables (setupImperas)
|
|
||||||
# IMPERAS_HOME
|
|
||||||
# IMPERAS_ARCA
|
|
||||||
|
|
||||||
# And the variables set in Imperas/bin/Makefile.include
|
|
||||||
# IMPERAS_LIB
|
|
||||||
# IMPERAS_BIN
|
|
||||||
# IMPERAS_VMISTUBS
|
|
||||||
# IMPERAS_VMIINC
|
|
||||||
# SHRSUF
|
|
||||||
#
|
|
||||||
#TODO test ist IMPERAS_HOME is set.
|
|
||||||
|
|
||||||
|
|
||||||
message(STATUS "Imperas Home: $ENV{IMPERAS_HOME}")
|
|
||||||
message(STATUS "Imperas License: $ENV{IMPERASD_LICENSE_FILE}")
|
|
||||||
|
|
||||||
|
|
||||||
message(STATUS "Arch: $ENV{IMPERAS_ARCH}")
|
|
||||||
#message(STATUS "VLNV: $ENV{IMPERAS_VLNV}")
|
|
||||||
#set(IMPERAS_LIB $ENV{IMPERAS_HOME}/lib/$ENV{IMPERAS_ARCH})
|
|
||||||
|
|
||||||
set(IMPERAS_BIN $ENV{IMPERAS_HOME}/bin/$ENV{IMPERAS_ARCH})
|
|
||||||
set(IMPERAS_VMISTUBS ${IMPERAS_BIN}/vmiStubs.a)
|
|
||||||
set(IMPERAS_VMIINC
|
|
||||||
-I$ENV{IMPERAS_HOME}/ImpPublic/include/host
|
|
||||||
)
|
|
||||||
|
|
||||||
## This is needed when building a shared library
|
|
||||||
set(HOST_LDFLAGS "-Wl,--version-script=$ENV{IMPERAS_HOME}/ImperasLib/source/buildutils/version.script")
|
|
||||||
|
|
||||||
## This is needed by a platform executable
|
|
||||||
set(SIM_LDFLAGS $ENV{IMPERAS_HOME}/bin/$ENV{IMPERAS_ARCH}/libRuntimeLoader.so)
|
|
||||||
|
|
||||||
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR})
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/src/core)
|
|
||||||
include_directories(${CMAKE_BINARY_DIR})
|
|
||||||
include_directories(${CMAKE_BINARY_DIR}/src/core)
|
|
||||||
include_directories($ENV{IMPERAS_HOME}/ImpPublic/include/host)
|
|
||||||
|
|
||||||
#add_subdirectory(ovpworld.org/mmc/flakyMemory/1.0/model)
|
|
||||||
add_subdirectory(cortexM3)
|
|
||||||
add_subdirectory(statusmsg)
|
|
||||||
|
|
||||||
include(ExternalProject)
|
|
||||||
#### Put resulting (model) library file in <your_build_dir>/lib ####
|
|
||||||
ExternalProject_Add(
|
|
||||||
OVParmmModel
|
|
||||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/armmModel
|
|
||||||
INSTALL_COMMAND ""
|
|
||||||
CMAKE_ARGS -DFAIL_BASE=${CMAKE_SOURCE_DIR} -DLIBRARY_OUTPUT_PATH=${LIBRARY_OUTPUT_PATH}
|
|
||||||
)
|
|
||||||
|
|
||||||
@ -1,144 +0,0 @@
|
|||||||
#ifndef _OVPCpu_HPP_
|
|
||||||
#define _OVPCpu_HPP_
|
|
||||||
|
|
||||||
#include "icm/icmCpuManager.hpp"
|
|
||||||
#include "sal/Register.hpp"
|
|
||||||
#include "OVPPlatform.hpp"
|
|
||||||
|
|
||||||
extern OVPPlatform ovpplatform;
|
|
||||||
|
|
||||||
|
|
||||||
using namespace icmCpuManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \class OVPCpu
|
|
||||||
* Abstract class which contains methods OVP platforms must implement.
|
|
||||||
* As there is the possibility to create different platforms this class
|
|
||||||
* is an interface for the OVPPlatform.
|
|
||||||
*/
|
|
||||||
class OVPCpu {
|
|
||||||
protected:
|
|
||||||
icmPlatform *platform;
|
|
||||||
icmProcessorObject *cpu;
|
|
||||||
icmAttrListObject *attrList;
|
|
||||||
icmProcessorP processorP;
|
|
||||||
|
|
||||||
// for MMC
|
|
||||||
icmMmcObject *mmcInstr;
|
|
||||||
icmMmcObject *mmcData;
|
|
||||||
icmBusObject *instrBus;
|
|
||||||
icmBusObject *dataBus;
|
|
||||||
icmBusObject *mainBus;
|
|
||||||
icmMemoryObject *icmMem0;
|
|
||||||
icmMemoryObject *icmMem1;
|
|
||||||
icmMemoryObject *icmMem2;
|
|
||||||
|
|
||||||
icmRegInfoP rid_sp;
|
|
||||||
|
|
||||||
public:
|
|
||||||
unsigned char *mem;
|
|
||||||
Int16 *textmem;
|
|
||||||
size_t offset;
|
|
||||||
size_t memSize;
|
|
||||||
size_t textOffset;
|
|
||||||
size_t textMemSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize platform.
|
|
||||||
* @param gdb set if GDB functionality should be enabled
|
|
||||||
*/
|
|
||||||
virtual void init(bool) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simulate the platform
|
|
||||||
* @param app Name/Path to the application to run
|
|
||||||
*/
|
|
||||||
virtual int startSimulation(const char*) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a full MMC to have memory control.
|
|
||||||
* @param vlnRoot Path to OVP model. Default: 0 -> default OVP path will be taken
|
|
||||||
*/
|
|
||||||
virtual void createFullMMC(const char *) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set general purpose register in SAL
|
|
||||||
*/
|
|
||||||
virtual void makeGPRegister() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set status register in SAL
|
|
||||||
*/
|
|
||||||
virtual void makeSTRegister() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set program counter register in SAL
|
|
||||||
*/
|
|
||||||
virtual void makePCRegister() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create local mirrored memory to handle memory manipulations
|
|
||||||
* during the memory callback
|
|
||||||
* @param sizeText Size of the text segment
|
|
||||||
* @param offText Address the text segment starts
|
|
||||||
* @param sizeMem Size of the other segments
|
|
||||||
* @param offMem Address the other segments start
|
|
||||||
*/
|
|
||||||
virtual void makeCallbackMemory(size_t sizeText, size_t offText, size_t sizeMem, size_t offMem) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves cpu status in file at given path
|
|
||||||
* @param path path to store file
|
|
||||||
*/
|
|
||||||
virtual void save(const string& path) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restore cpu status from file at given path
|
|
||||||
* @param path path to store file
|
|
||||||
*/
|
|
||||||
virtual void restore(const string& path) = 0;
|
|
||||||
/**
|
|
||||||
* Returns the private icmProcessorObject pointer needed for some OVP action
|
|
||||||
* @return icmProcessorObject
|
|
||||||
*/
|
|
||||||
|
|
||||||
icmProcessorObject *getProcessor() {
|
|
||||||
return cpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the private ProcessorP struct needed for some OVP action
|
|
||||||
* @return ProcessorP
|
|
||||||
*/
|
|
||||||
icmProcessorP getProcessorP() {
|
|
||||||
return processorP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the pointer to the stack pointer register
|
|
||||||
* @param reg icmRegInfoP of the stack pointer register
|
|
||||||
*/
|
|
||||||
void setSPReg(icmRegInfoP reg) {
|
|
||||||
rid_sp = reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the private stack pointer register pointer
|
|
||||||
* @return stack pointer register
|
|
||||||
*/
|
|
||||||
icmRegInfoP getSPReg() {
|
|
||||||
return rid_sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fills the callback memory with program data. This function
|
|
||||||
* must be called after the application is loaded to local memory
|
|
||||||
* and before the start of the simulation.
|
|
||||||
*/
|
|
||||||
void fillCallbackMemory() {
|
|
||||||
mainBus->read(offset, mem, memSize, cpu);
|
|
||||||
mainBus->read(textOffset, textmem, textMemSize, cpu);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
#include "OVPCpu.hpp"
|
|
||||||
#include "OVPStatusRegister.hpp"
|
|
||||||
#include "OVPPlatform.hpp"
|
|
||||||
#include "sal/Register.hpp"
|
|
||||||
#include "sal/SALInst.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
OVPPlatform ovpplatform;
|
|
||||||
|
|
||||||
// current CPU
|
|
||||||
OVPCpu *platform;
|
|
||||||
icmProcessorObject *processor;
|
|
||||||
icmProcessorP cpuP;
|
|
||||||
|
|
||||||
void OVPPlatform::setCpu(void *ovpcpu) {
|
|
||||||
platform = (OVPCpu *)ovpcpu;
|
|
||||||
processor = platform->getProcessor();
|
|
||||||
cpuP = processor->getProcessorP();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OVPPlatform::setRegisterData(void * link, unsigned int val) {
|
|
||||||
icmWriteRegInfoValue(cpuP, (icmRegInfoP)link, (void *) &val);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int OVPPlatform::getRegisterData(void *link) {
|
|
||||||
unsigned int res;
|
|
||||||
|
|
||||||
icmReadRegInfoValue(cpuP, (icmRegInfoP)link, (void *)&res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t OVPPlatform::getPC() {
|
|
||||||
return (uint32_t) processor->getPC();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OVPPlatform::setPC(uint32_t val) {
|
|
||||||
processor->setPC(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t OVPPlatform::getSP() {
|
|
||||||
uint32_t res;
|
|
||||||
void *buf = &res;
|
|
||||||
|
|
||||||
icmReadRegInfoValue(cpuP, platform->getSPReg(), buf);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void OVPPlatform::save(const string& path) {
|
|
||||||
platform->save(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OVPPlatform::restore(const string& path) {
|
|
||||||
platform->restore(path);
|
|
||||||
}
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
#ifndef __OVPPLATFORM_HPP__
|
|
||||||
#define __OVPPLATFORM_HPP__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \class OVPPlatform
|
|
||||||
* OVPPlatform is the layer/interface which connects SAL and the OVP platform.
|
|
||||||
*/
|
|
||||||
class OVPPlatform {
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* The current OVP platform has to set a pointer to itself so that
|
|
||||||
* OVPPlatform can execute OVP functions using the correct platform
|
|
||||||
* @param ovpcpu void ptr to the OVPCpu object
|
|
||||||
*/
|
|
||||||
void setCpu(void *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set value to a register
|
|
||||||
* @param link Pointer to the OVP register
|
|
||||||
* @param val Value the register is set to
|
|
||||||
*/
|
|
||||||
void setRegisterData(void *, unsigned int);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves value from a register
|
|
||||||
* @param link Pointer to the OVP register
|
|
||||||
* @return value of the register
|
|
||||||
*/
|
|
||||||
unsigned int getRegisterData(void *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the program counter
|
|
||||||
* @return current program counter
|
|
||||||
*/
|
|
||||||
uint32_t getPC();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the program counter
|
|
||||||
*/
|
|
||||||
void setPC(uint32_t);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the stack pointer
|
|
||||||
* @return current stack pointer
|
|
||||||
*/
|
|
||||||
uint32_t getSP();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save cpu status
|
|
||||||
*/
|
|
||||||
void save(const string&);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restore cpu status
|
|
||||||
*/
|
|
||||||
void restore(const string&);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
#ifndef __OVP_STATUS_REGISTER_HPP__
|
|
||||||
#define __OVP_STATUS_REGISTER_HPP__
|
|
||||||
|
|
||||||
#include "sal/ovp/OVPRegister.hpp"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \class OVPStatusRegister
|
|
||||||
* Abstract class for status register implementation
|
|
||||||
*/
|
|
||||||
class OVPStatusRegister : public fail::OVPRegister {
|
|
||||||
protected:
|
|
||||||
|
|
||||||
public:
|
|
||||||
OVPStatusRegister(uint32_t width, void *link)
|
|
||||||
: fail::OVPRegister(width, 32, link, fail::RT_ST) { }
|
|
||||||
~OVPStatusRegister() {}
|
|
||||||
|
|
||||||
virtual bool getSignFlag() const = 0;
|
|
||||||
virtual bool getZeroFlag() const = 0;
|
|
||||||
virtual bool getCarryFlag() const = 0;
|
|
||||||
virtual bool getOverflowFlag() const = 0;
|
|
||||||
|
|
||||||
virtual void setSignFlag(bool) = 0;
|
|
||||||
virtual void setZeroFlag(bool) = 0;
|
|
||||||
virtual void setCarryFlag(bool) = 0;
|
|
||||||
virtual void setOverflowFlag(bool) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invert bit at specific position of status register
|
|
||||||
* @param pos position of bit to invert
|
|
||||||
*/
|
|
||||||
/* void invertBit(int pos) {
|
|
||||||
size_t val;
|
|
||||||
size_t chpos = 1 << pos;
|
|
||||||
|
|
||||||
icmReadRegInfoValue(cpuP, cpsr, (void *)&val);
|
|
||||||
|
|
||||||
// get bit
|
|
||||||
bool bit = (val >> pos) & 0x1;
|
|
||||||
|
|
||||||
if(bit == 0) {
|
|
||||||
chpos = ~chpos;
|
|
||||||
val = val & chpos;
|
|
||||||
} else {
|
|
||||||
val = val | chpos;
|
|
||||||
}
|
|
||||||
|
|
||||||
}*/
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __OVP_STATUS_REGISTER_HPP__
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
Env setzen: . ./setImperas.sh
|
|
||||||
|
|
||||||
64 bit Systeme brauchen ia32-libs
|
|
||||||
evtl unter Ubuntu: ln -s /usr/lib32/libstdc++.so.6 /usr/lib32/libstdc++.so
|
|
||||||
|
|
||||||
License Server in Env-Variable:
|
|
||||||
export IMPERASD_LICENSE_FILE=@faui49.informatik.uni-erlangen.de
|
|
||||||
@ -1,98 +0,0 @@
|
|||||||
Project(OVPCM3_Model)
|
|
||||||
cmake_minimum_required(VERSION 2.8)
|
|
||||||
|
|
||||||
|
|
||||||
message(STATUS "Imperas Home: $ENV{IMPERAS_HOME}")
|
|
||||||
message(STATUS "Imperas License: $ENV{IMPERASD_LICENSE_FILE}")
|
|
||||||
|
|
||||||
|
|
||||||
message(STATUS "Arch: $ENV{IMPERAS_ARCH}")
|
|
||||||
set(IMPERAS_BIN $ENV{IMPERAS_HOME}/bin/$ENV{IMPERAS_ARCH})
|
|
||||||
set(IMPERAS_VMISTUBS ${IMPERAS_BIN}/vmiStubs.a)
|
|
||||||
set(IMPERAS_VMIINC
|
|
||||||
-I$ENV{IMPERAS_HOME}/ImpPublic/include/host
|
|
||||||
)
|
|
||||||
|
|
||||||
## This is needed when building a shared library
|
|
||||||
set(HOST_LDFLAGS "-Wl,--version-script=$ENV{IMPERAS_HOME}/ImperasLib/source/buildutils/version.script")
|
|
||||||
|
|
||||||
## This is needed by a platform executable
|
|
||||||
set(SIM_LDFLAGS $ENV{IMPERAS_HOME}/bin/$ENV{IMPERAS_ARCH}/libRuntimeLoader.so)
|
|
||||||
|
|
||||||
message(STATUS "Fail* base dir included: ${FAIL_BASE}")
|
|
||||||
message(STATUS "Library output path: ${LIBRARY_OUTPUT_PATH}")
|
|
||||||
include_directories(${FAIL_BASE})
|
|
||||||
include_directories($ENV{IMPERAS_HOME}/ImpPublic/include/host)
|
|
||||||
|
|
||||||
set(CMAKE_C_COMPILER "gcc")
|
|
||||||
set(CMAKE_CXX_COMPILER "g++")
|
|
||||||
|
|
||||||
#### Put resulting (model) library file in <your_build_dir>/lib ####
|
|
||||||
|
|
||||||
set(SRCS
|
|
||||||
failSALlink.cc
|
|
||||||
armAttributeEntriesThumb16.h
|
|
||||||
armAttributeEntriesThumb32.h
|
|
||||||
armBitMacros.h
|
|
||||||
armBus.c
|
|
||||||
armConfig.h
|
|
||||||
armDebug.h
|
|
||||||
armDecodeEntriesThumb16.h
|
|
||||||
armDecodeEntriesThumb32.h
|
|
||||||
armDecode.h
|
|
||||||
armDecodeThumb.h
|
|
||||||
armDecodeTypes.h
|
|
||||||
armDisassembleFormats.h
|
|
||||||
armDisassemble.h
|
|
||||||
armEmit.h
|
|
||||||
armExceptions.h
|
|
||||||
armExceptionTypes.h
|
|
||||||
armFPConstants.h
|
|
||||||
armFunctions.h
|
|
||||||
armInfo.c
|
|
||||||
armmAttrs.c
|
|
||||||
armmConfigList.c
|
|
||||||
armmDebug.c
|
|
||||||
armmDecode.c
|
|
||||||
armmDecodeThumb.c
|
|
||||||
armmDisassemble.c
|
|
||||||
armmDoc.c
|
|
||||||
armmDoc.h
|
|
||||||
armmEmit.c
|
|
||||||
armMessage.h
|
|
||||||
armmExceptions.c
|
|
||||||
armmMain.c
|
|
||||||
armmMorphFunctions.c
|
|
||||||
armmMorphTable.c
|
|
||||||
armMode.h
|
|
||||||
armMorphEntries.h
|
|
||||||
armMorphFunctions.h
|
|
||||||
armMorph.h
|
|
||||||
armmParameters.c
|
|
||||||
armmParameters.h
|
|
||||||
armmSemiHost.c
|
|
||||||
armmSys.c
|
|
||||||
armmUtils.c
|
|
||||||
armmVFP.c
|
|
||||||
armmVM.c
|
|
||||||
armRegisters.h
|
|
||||||
armStructure.h
|
|
||||||
armSys.h
|
|
||||||
armSysRegisters.h
|
|
||||||
armTypeRefs.h
|
|
||||||
armUtils.h
|
|
||||||
armVariant.h
|
|
||||||
armVFP.h
|
|
||||||
armVM.h
|
|
||||||
)
|
|
||||||
add_definitions("-m32 ${IMPERAS_VMIINC}")
|
|
||||||
message(STATUS "armmModel ld flags: ${HOST_LDFLAGS}")
|
|
||||||
add_library(armmModel SHARED ${SRCS})
|
|
||||||
|
|
||||||
|
|
||||||
#add_dependencies(armmModel SAL)
|
|
||||||
set_target_properties(armmModel PROPERTIES LINK_FLAGS "${HOST_LDFLAGS} -m32")# -L${CMAKE_BINARY_DIR}/lib -lSAL")
|
|
||||||
|
|
||||||
#target_link_libraries(armmModel ${IMPERAS_VMISTUBS} ${LIBRARY_OUTPUT_PATH}/libSAL.a)
|
|
||||||
target_link_libraries(armmModel ${IMPERAS_VMISTUBS})
|
|
||||||
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
IMPERAS_HOME := $(shell getpath.exe "$(IMPERAS_HOME)")
|
|
||||||
|
|
||||||
LDFLAGS+=-lm
|
|
||||||
|
|
||||||
include $(IMPERAS_HOME)/ImperasLib/source/buildutils/Makefile.host
|
|
||||||
@ -1,245 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_ATTRIBUTE_ENTRIES_THUMB16_H
|
|
||||||
#define ARM_ATTRIBUTE_ENTRIES_THUMB16_H
|
|
||||||
|
|
||||||
#include "armDisassembleFormats.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like ADC
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_ADC(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_IT, r1:R3_0, r2:R3_3}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like ADD (1)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_ADD1(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_IT, r1:R3_0, r2:R3_3, cs:CS_U_3_6}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like ADD (2)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_ADD2(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_IT, r1:R3_8, cs:CS_U_8_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like ADD (3)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_ADD3(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_IT, r1:R3_0, r2:R3_3, r3:R3_6}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like ADD (4)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_ADD4(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_0H7, r2:R4_3H6}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like ADD (5)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_ADD5(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R3_8, r2:R_PC, cs:CS_U_8_0x4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like ADD (6)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_ADD6(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R3_8, r2:R_SP, cs:CS_U_8_0x4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like ADD (7)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_ADD7(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R_SP, cs:CS_U_7_0x4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like ASR (1)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_ASR1(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _SS) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_IT, r1:R3_0, r2:R3_3, cs:CS_U_5_6, ss:_SS}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like ASR (2)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_ASR2(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _SS) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_IT, r1:R3_0, r2:R3_3, ss:_SS}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like MOV (2)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_MOV2(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_IT, r1:R3_0, r2:R3_3, cs:CS_U_5_6, ss:SS_LSL}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like CMP (1)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_CMP1(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_I, r1:R3_8, cs:CS_U_8_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like CMP (2)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_CMP2(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_I, r1:R3_0, r2:R3_3}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like CMP (3)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_CMP3(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_I, r1:R4_0H7, r2:R4_3H6}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like B (1)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_B1(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_T, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, cond:CO_8, ts:TC_S8}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like B (2)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_B2(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_T, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, ts:TC_S11}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like BLX (2)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_BLX2(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_3H6}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like SXTH
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_SXTH(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R3_0, r2:R3_3}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like BKPT
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_BKPT(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_XIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, cs:CS_U_8_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like SETEND
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_SETEND(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_ENDIAN, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, cs:CS_U_1_3}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like CPS
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_CPS(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_FLAGS_OPT_MODE, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, imod:IS_4, aif:AIF_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like CBNZ
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_CBNZ(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_T, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R3_0, ts:TC_U9_7_3}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like LDMIA
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_LDMIA(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _RLIST, _INC, _UA45, _UA67) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_RLIST, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R3_8, wb:WB_1_NB, rList:_RLIST, incDec:_INC, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like LDR (1)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_LDR1(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R3_0, r2:R3_3, cs:CS_U_5_6_SZ, sz:_SZ, xs:_XS, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like LDR (2)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_LDR2(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_R3, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R3_0, r2:R3_3, r3:R3_6, sz:_SZ, xs:_XS, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like LDR (3)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_LDR3(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R3_8, r2:R_PC, cs:CS_U_8_0_SZ, sz:_SZ, xs:_XS, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like LDR (4)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_LDR4(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R3_8, r2:R_SP, cs:CS_U_8_0_SZ, sz:_SZ, xs:_XS, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like POP
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_POP(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _RLIST, _INC, _UA45, _UA67) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_RLIST, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R_SP, pi:PI_1, wb:WB_1, rList:_RLIST, incDec:_INC, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like STMIA
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_STMIA(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _RLIST, _INC, _UA45, _UA67) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_R1_RLIST_T, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R3_8, pi:PI_1, wb:WB_1, rList:_RLIST, incDec:_INC, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like IT
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_IT(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_ITC, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, cs:CS_U_4_4, it:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like NOP
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_NOP(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_NONE, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like BL_H10
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_BL_H10(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_SIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, cs:CS_S_11_0S12}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 16-bit Thumb instructions like BL_H11
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_BL_H11(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT16_##_NAME] = {opcode:_OPCODE, format:FMT_UIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, cs:CS_U_11_0S1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entry for undecoded 16-bit Thumb instruction
|
|
||||||
//
|
|
||||||
#define ATTR_SET_16_UNDECODED(_NAME) \
|
|
||||||
[TT16_##_NAME] = {type:ARM_IT_LAST}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,635 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_ATTRIBUTE_ENTRIES_THUMB32_H
|
|
||||||
#define ARM_ATTRIBUTE_ENTRIES_THUMB32_H
|
|
||||||
|
|
||||||
#include "armDisassembleFormats.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like AND
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_AND(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##_IMM] = {opcode:_OPCODE, format:FMT_R1_R2_UIMM, type:ARM_IT_##_NAME##_IMM, support:_SUPPORT, isar:_ISAR, f:SF_20_V, r1:R4_8, r2:R4_16, r3:0, cs:CS_MI, ss:0 }, \
|
|
||||||
[TT32_##_NAME##_RM_SHFT_IMM] = {opcode:_OPCODE, format:FMT_R1_R2_R3_SHIFT_SIMM, type:ARM_IT_##_NAME##_RM_SHFT_IMM, support:_SUPPORT, isar:_ISAR, f:SF_20_V, r1:R4_8, r2:R4_16, r3:R4_0, cs:CS_PI5, ss:SS2_4 }, \
|
|
||||||
[TT32_##_NAME##_RM_RRX] = {opcode:_OPCODE, format:FMT_R1_R2_R3_SHIFT, type:ARM_IT_##_NAME##_RM_RRX, support:_SUPPORT, isar:_ISAR, f:SF_20_V, r1:R4_8, r2:R4_16, r3:R4_0, cs:CS_NA, ss:SS_RRX}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like TST
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_TST(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##_IMM] = {opcode:_OPCODE, format:FMT_R1_UIMM, type:ARM_IT_##_NAME##_IMM, support:_SUPPORT, isar:_ISAR, f:SF_I, r1:R4_16, r2:0, cs:CS_MI, ss:0 }, \
|
|
||||||
[TT32_##_NAME##_RM_SHFT_IMM] = {opcode:_OPCODE, format:FMT_R1_R2_SHIFT_SIMM, type:ARM_IT_##_NAME##_RM_SHFT_IMM, support:_SUPPORT, isar:_ISAR, f:SF_I, r1:R4_16, r2:R4_0, cs:CS_PI5, ss:SS2_4 }, \
|
|
||||||
[TT32_##_NAME##_RM_RRX] = {opcode:_OPCODE, format:FMT_R1_R2_SHIFT, type:ARM_IT_##_NAME##_RM_RRX, support:_SUPPORT, isar:_ISAR, f:SF_I, r1:R4_16, r2:R4_0, cs:CS_NA, ss:SS_RRX}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like MOV
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MOV(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##_IMM] = {opcode:_OPCODE, format:FMT_R1_UIMM, type:ARM_IT_##_NAME##_IMM, support:_SUPPORT, isar:_ISAR, f:SF_20_V, r1:R4_8, r2:0, cs:CS_MI, ss:0 }, \
|
|
||||||
[TT32_##_NAME##_RM_SHFT_IMM] = {opcode:_OPCODE, format:FMT_R1_R2_SHIFT_SIMM, type:ARM_IT_##_NAME##_RM_SHFT_IMM, support:_SUPPORT, isar:_ISAR, f:SF_20_V, r1:R4_8, r2:R4_0, cs:CS_PI5, ss:SS2_4 }, \
|
|
||||||
[TT32_##_NAME##_RM_RRX] = {opcode:_OPCODE, format:FMT_R1_R2_SHIFT, type:ARM_IT_##_NAME##_RM_RRX, support:_SUPPORT, isar:_ISAR, f:SF_20_V, r1:R4_8, r2:R4_0, cs:CS_NA, ss:SS_RRX}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like PKHBT
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_PKHBT(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3_SHIFT_SIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, cs:CS_PI5, ss:SS2_4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like ADD (plain binary immediate)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_ADD_PI(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_UIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, cs:CS_PI12}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like MOV (plain binary immediate)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MOV_PI(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_UIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_8, cs:CS_PI16}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SSAT
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SSAT(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_WIDTH_R2_SHIFT_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, cs:CS_PI5, ss:SS2_20, w:WS_WIDTH5M1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SSAT16
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SSAT16(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_WIDTH_R2, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, w:WS_WIDTH4M1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like USAT
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_USAT(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_WIDTH_R2_SHIFT_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, cs:CS_PI5, ss:SS2_20, w:WS_WIDTH5}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like USAT16
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_USAT16(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_WIDTH_R2, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, w:WS_WIDTH4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SBFX
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SBFX(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_LSB_WIDTH, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, cs:CS_PI5, w:WS_WIDTH5M1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like BFI
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_BFI(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_LSB_WIDTH, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, cs:CS_PI5, w:WS_MSB}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like BFC
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_BFC(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_LSB_WIDTH, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_8, cs:CS_PI5, w:WS_MSB}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like LSL
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_LSL(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_20_V, r1:R4_8, r2:R4_16, r3:R4_0, ss:SS2_21}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SXTAH
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SXTAH(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3_SHIFT_SIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, cs:CS_U_2_4x8, ss:SS_ROR}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SXTH
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SXTH(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_SHIFT_SIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_0, cs:CS_U_2_4x8, ss:SS_ROR}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb parallel add/subtract instructions
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_PAS(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_S##_NAME] = {opcode:"s" _OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_S##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}, \
|
|
||||||
[TT32_Q##_NAME] = {opcode:"q" _OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_Q##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}, \
|
|
||||||
[TT32_SH##_NAME] = {opcode:"sh"_OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_SH##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}, \
|
|
||||||
[TT32_U##_NAME] = {opcode:"u" _OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_U##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}, \
|
|
||||||
[TT32_UQ##_NAME] = {opcode:"uq"_OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_UQ##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}, \
|
|
||||||
[TT32_UH##_NAME] = {opcode:"uh"_OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_UH##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like QADD
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_QADD(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_0, r3:R4_16}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like CLZ
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_CLZ(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SEL
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SEL(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like MLA
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MLA(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, r4:R4_12}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SMLAL
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SMLAL(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_8, r3:R4_16, r4:R4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like MUL
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MUL(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SMLA<x><y>
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SMLA_XY(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##BB] = {opcode:_OPCODE"bb", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##BB, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, r4:R4_12}, \
|
|
||||||
[TT32_##_NAME##BT] = {opcode:_OPCODE"bt", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##BT, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, r4:R4_12}, \
|
|
||||||
[TT32_##_NAME##TB] = {opcode:_OPCODE"tb", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##TB, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, r4:R4_12}, \
|
|
||||||
[TT32_##_NAME##TT] = {opcode:_OPCODE"tt", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##TT, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, r4:R4_12}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SMUL<x><y>
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SMUL_XY(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##BB] = {opcode:_OPCODE"bb", format:FMT_R1_R2_R3, type:ARM_IT_##_NAME##BB, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}, \
|
|
||||||
[TT32_##_NAME##BT] = {opcode:_OPCODE"bt", format:FMT_R1_R2_R3, type:ARM_IT_##_NAME##BT, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}, \
|
|
||||||
[TT32_##_NAME##TB] = {opcode:_OPCODE"tb", format:FMT_R1_R2_R3, type:ARM_IT_##_NAME##TB, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}, \
|
|
||||||
[TT32_##_NAME##TT] = {opcode:_OPCODE"tt", format:FMT_R1_R2_R3, type:ARM_IT_##_NAME##TT, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SMLAL<x><y>
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SMLAL_XY(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##BB] = {opcode:_OPCODE"bb", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##BB, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_8, r3:R4_16, r4:R4_0}, \
|
|
||||||
[TT32_##_NAME##BT] = {opcode:_OPCODE"bt", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##BT, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_8, r3:R4_16, r4:R4_0}, \
|
|
||||||
[TT32_##_NAME##TB] = {opcode:_OPCODE"tb", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##TB, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_8, r3:R4_16, r4:R4_0}, \
|
|
||||||
[TT32_##_NAME##TT] = {opcode:_OPCODE"tt", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##TT, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_8, r3:R4_16, r4:R4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SMLAD<x>
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SMLAD(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, r4:R4_12}, \
|
|
||||||
[TT32_##_NAME##X] = {opcode:_OPCODE"x", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##X, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, r4:R4_12}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SMUAD<x>
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SMUAD(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}, \
|
|
||||||
[TT32_##_NAME##X] = {opcode:_OPCODE"x", format:FMT_R1_R2_R3, type:ARM_IT_##_NAME##X, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for DSP instructions like SMLAW<y>
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SMLAW(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##B] = {opcode:_OPCODE"b", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##B, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, r4:R4_12}, \
|
|
||||||
[TT32_##_NAME##T] = {opcode:_OPCODE"t", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##T, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, r4:R4_12}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for DSP instructions like SMULW<y>
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SMULW(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##B] = {opcode:_OPCODE"b", format:FMT_R1_R2_R3, type:ARM_IT_##_NAME##B, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}, \
|
|
||||||
[TT32_##_NAME##T] = {opcode:_OPCODE"t", format:FMT_R1_R2_R3, type:ARM_IT_##_NAME##T, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like SMMLA
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SMMLA(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, r4:R4_12}, \
|
|
||||||
[TT32_##_NAME##R] = {opcode:_OPCODE"r", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##R, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0, r4:R4_12}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like SMMUL
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SMMUL(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}, \
|
|
||||||
[TT32_##_NAME##R] = {opcode:_OPCODE"r", format:FMT_R1_R2_R3, type:ARM_IT_##_NAME##R, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_16, r3:R4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SMLALD<x>
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SMLALD(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_8, r3:R4_16, r4:R4_0}, \
|
|
||||||
[TT32_##_NAME##X] = {opcode:_OPCODE"x", format:FMT_R1_R2_R3_R4, type:ARM_IT_##_NAME##X, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_8, r3:R4_16, r4:R4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like B (1)
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_B1(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_T, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, cond:CO_22, ts:TC_S20_T2}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like BL
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_BL(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_T, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, ts:TC_S24_T2}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like BLX
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_BLX(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_T, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, ts:TC_S24_T4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like BXJ
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_BXJ(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_16}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like MSR
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MSR(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_SR_R1, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_16, cs:CS_U_8_0, mask:MSRMASK_10}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like MRS
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MRS(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_SR, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, cs:CS_U_8_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like DSB
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_DSB(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_LIM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, cs:CS_U_4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SUBS_PC_LR
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SUBS_PC_LR(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_SIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, f:SF_V, r1:R_PC, r2:R_LR, cs:CS_U_8_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like CPS
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_CPS(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_FLAGS_OPT_MODE, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, cs:CS_U_5_0, imod:IS_9, m:1, aif:AIF_5}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like NOP
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_NOP(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_NONE, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like DBG
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_DBG(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_UIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, cs:CS_U_4_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like SRS
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SRS(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _INCDEC, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_WB_UIMM, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R_SP, cs:CS_U_5_0, wb:WB_21, incDec:_INCDEC, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like RFE
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_RFE(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _INCDEC, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_WB, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_16, wb:WB_21, incDec:_INCDEC, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like LDM
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_LDM(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _INCDEC, _RLIST, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_RLIST, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_16, wb:WB_21, rList:_RLIST, incDec:_INCDEC, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like POPM
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_POPM(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _INCDEC, _RLIST, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_RLIST, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_16, wb:WB_21, rList:_RLIST, incDec:_INCDEC, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like LDRD_IMM
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_LDRD_IMM(_NAME, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R4_ADDR_R2_SIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, r4:R4_8, cs:CS_U_8_0x4_U, sz:_SZ, xs:_XS, pi:PI_24, wb:WB_21, ua45:_UA45, ua67:_UA67, u:US_23}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like LDREX
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_LDREX(_NAME, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_SIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, cs:CS_U_8_0_SZ, sz:_SZ, xs:_XS, ua45:_UA45, ua67:_UA67, ea:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like LDREXB
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_LDREXB(_NAME, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_SIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, sz:_SZ, xs:_XS, ua45:_UA45, ua67:_UA67, ea:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like LDREXD
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_LDREXD(_NAME, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R4_ADDR_R2_SIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, r4:R4_8, sz:_SZ, xs:_XS, ua45:_UA45, ua67:_UA67, ea:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like STREX
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_STREX(_NAME, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_ADDR_R3_SIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_8, r2:R4_12, r3:R4_16, cs:CS_U_8_0_SZ, sz:_SZ, xs:_XS, ua45:_UA45, ua67:_UA67, ea:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like STREXB
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_STREXB(_NAME, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_ADDR_R3_SIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_0, r2:R4_12, r3:R4_16, sz:_SZ, xs:_XS, ua45:_UA45, ua67:_UA67, ea:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like STREXD
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_STREXD(_NAME, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_R4_ADDR_R3_SIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_0, r2:R4_12, r3:R4_16, r4:R4_8, sz:_SZ, xs:_XS, ua45:_UA45, ua67:_UA67, ea:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like TBB
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_TBB(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:ADDR_R1_R2_SZSHIFT, type:ARM_IT_##_TYPE, support:_SUPPORT, isar:_ISAR, r1:R4_16, r2:R4_0, sz:_SZ, xs:_XS, ua45:_UA45, ua67:_UA67}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like LDR
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_LDR(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME##_IMM1] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_SIMM, type:ARM_IT_##_TYPE##_IMM, support:_SUPPORT, isar:ARM_ISAR_NA, r1:R4_12, r2:R4_16, r3:0, cs:CS_U_12_0, ss:0, sz:_SZ, xs:_XS, tl:0, pi:0, wb:0, ua45:_UA45, ua67:_UA67, u:0 }, \
|
|
||||||
[TT32_##_NAME##_IMM2] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_SIMM, type:ARM_IT_##_TYPE##_IMM, support:_SUPPORT, isar:ARM_ISAR_NA, r1:R4_12, r2:R4_16, r3:0, cs:CS_U_8_0_U, ss:0, sz:_SZ, xs:_XS, tl:0, pi:PI_10, wb:WB_8, ua45:_UA45, ua67:_UA67, u:US_9 }, \
|
|
||||||
[TT32_##_NAME##_IMM3] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_SIMM, type:ARM_IT_##_TYPE##_IMM, support:_SUPPORT, isar:ARM_ISAR_NA, r1:R4_12, r2:R4_16, r3:0, cs:CS_U_12_0_U, ss:0, sz:_SZ, xs:_XS, tl:0, pi:0, wb:0, ua45:_UA45, ua67:_UA67, u:US_23}, \
|
|
||||||
[TT32_##_NAME##_RM] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_R3, type:ARM_IT_##_TYPE##_RM, support:_SUPPORT, isar:ARM_ISAR_NA, r1:R4_12, r2:R4_16, r3:R4_0, cs:0, ss:0, sz:_SZ, xs:_XS, tl:0, pi:0, wb:0, ua45:_UA45, ua67:_UA67, u:0 }, \
|
|
||||||
[TT32_##_NAME##_RM_SHFT_IMM] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_R3_SHIFT_SIMM, type:ARM_IT_##_TYPE##_RM_SHFT_IMM, support:_SUPPORT, isar:ARM_ISAR_NA, r1:R4_12, r2:R4_16, r3:R4_0, cs:CS_U_2_4, ss:SS_LSL, sz:_SZ, xs:_XS, tl:0, pi:0, wb:0, ua45:_UA45, ua67:_UA67, u:0 }, \
|
|
||||||
[TT32_##_NAME##T_IMM] = {opcode:_OPCODE, format:FMT_R1_ADDR_R2_SIMM, type:ARM_IT_##_TYPE##T_IMM, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, r3:0, cs:CS_U_8_0_U, ss:0, sz:_SZ, xs:_XS, tl:1, pi:PI_10, wb:WB_8, ua45:_UA45, ua67:_UA67, u:US_9 }
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like PLD
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_PLD(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE, _SZ, _XS, _UA45, _UA67) \
|
|
||||||
[TT32_##_NAME##_IMM1] = {opcode:_OPCODE, format:FMT_ADDR_R1_SIMM, type:ARM_IT_##_TYPE##_IMM, support:_SUPPORT, isar:_ISAR, r1:R4_16, r2:0, cs:CS_U_12_0, ss:0, sz:_SZ, xs:_XS, pi:0, wb:0, ua45:_UA45, ua67:_UA67, u:0 }, \
|
|
||||||
[TT32_##_NAME##_IMM2] = {opcode:_OPCODE, format:FMT_ADDR_R1_SIMM, type:ARM_IT_##_TYPE##_IMM, support:_SUPPORT, isar:_ISAR, r1:R4_16, r2:0, cs:CS_U_8_0_U, ss:0, sz:_SZ, xs:_XS, pi:PI_10, wb:WB_8, ua45:_UA45, ua67:_UA67, u:US_9 }, \
|
|
||||||
[TT32_##_NAME##_IMM3] = {opcode:_OPCODE, format:FMT_ADDR_R1_SIMM, type:ARM_IT_##_TYPE##_IMM, support:_SUPPORT, isar:_ISAR, r1:R4_16, r2:0, cs:CS_U_12_0_U, ss:0, sz:_SZ, xs:_XS, pi:0, wb:0, ua45:_UA45, ua67:_UA67, u:US_23}, \
|
|
||||||
[TT32_##_NAME##_RM] = {opcode:_OPCODE, format:FMT_ADDR_R1_R2, type:ARM_IT_##_TYPE##_RM, support:_SUPPORT, isar:_ISAR, r1:R4_16, r2:R4_0, cs:0, ss:0, sz:_SZ, xs:_XS, pi:0, wb:0, ua45:_UA45, ua67:_UA67, u:0 }, \
|
|
||||||
[TT32_##_NAME##_RM_SHFT_IMM] = {opcode:_OPCODE, format:FMT_ADDR_R1_R2_SHIFT_SIMM, type:ARM_IT_##_TYPE##_RM_SHFT_IMM, support:_SUPPORT, isar:_ISAR, r1:R4_16, r2:R4_0, cs:CS_U_2_4, ss:SS_LSL, sz:_SZ, xs:_XS, pi:0, wb:0, ua45:_UA45, ua67:_UA67, u:0 }
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like UHINTH
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_UHINTH(_NAME, _TYPE, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_NONE, type:ARM_IT_NOP, support:_SUPPORT, isar:_ISAR}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb undefined instructions
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_UND(_NAME, _SUPPORT, _ISAR) \
|
|
||||||
[TT32_##_NAME] = {type:ARM_IT_LAST, support:_SUPPORT, isar:_ISAR}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like CDP
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_CDP(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_CPNUM_COP1_CR1_CR2_CR3_COP2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, cond:CO_28, r1:R4_12, r2:R4_16, r3:R4_0, cpNum:1, cpOp1:COP_4_20, cpOp2:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like CDP2
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_CDP2(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_CPNUM_COP1_CR1_CR2_CR3_COP2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, r3:R4_0, cpNum:1, cpOp1:COP_4_20, cpOp2:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like LDC
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_LDC(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##_IMM] = {opcode:_OPCODE, format:FMT_CPNUM_CR1_SIMM, type:ARM_IT_##_NAME##_IMM, support:_SUPPORT, isar:_ISAR, cond:CO_28, r1:R4_12, r2:R4_16, cs:CS_U_8_0x4_U, pi:PI_24, wb:WB_21, ll:1, cpNum:1, u:US_23}, \
|
|
||||||
[TT32_##_NAME##_UNINDEXED] = {opcode:_OPCODE, format:FMT_CPNUM_CR1_UNINDEXED, type:ARM_IT_##_NAME##_UNINDEXED, support:_SUPPORT, isar:_ISAR, cond:CO_28, r1:R4_12, r2:R4_16, cs:CS_U_8_0, pi:PI_24, wb:WB_21, ll:1, cpNum:1, u:0 }
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like LDC2
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_LDC2(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##_IMM] = {opcode:_OPCODE, format:FMT_CPNUM_CR1_SIMM, type:ARM_IT_##_NAME##_IMM, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, cs:CS_U_8_0x4_U, pi:PI_24, wb:WB_21, ll:1, cpNum:1, u:US_23}, \
|
|
||||||
[TT32_##_NAME##_UNINDEXED] = {opcode:_OPCODE, format:FMT_CPNUM_CR1_UNINDEXED, type:ARM_IT_##_NAME##_UNINDEXED, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, cs:CS_U_8_0, pi:PI_24, wb:WB_21, ll:1, cpNum:1, u:0 }
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like MCR
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MCR(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_CPNUM_COP1_R1_CR2_CR3_COP2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, cond:CO_28, r1:R4_12, r2:R4_16, r3:R4_0, cpNum:1, cpOp1:COP_3_21, cpOp2:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like MCR2
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MCR2(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_CPNUM_COP1_R1_CR2_CR3_COP2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, r3:R4_0, cpNum:1, cpOp1:COP_3_21, cpOp2:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like MRC
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MRC(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_CPNUM_COP1_R1F_CR2_CR3_COP2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, cond:CO_28, r1:R4_12, r2:R4_16, r3:R4_0, cpNum:1, cpOp1:COP_3_21, cpOp2:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for 32-bit Thumb instructions like MRC2
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MRC2(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_CPNUM_COP1_R1F_CR2_CR3_COP2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, r3:R4_0, cpNum:1, cpOp1:COP_3_21, cpOp2:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like MCRR
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MCRR(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_CPNUM_COP1_R1_R2_CR3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, cond:CO_28, r1:R4_12, r2:R4_16, r3:R4_0, cpNum:1, cpOp1:COP_4_4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like MCRR2
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_MCRR2(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_CPNUM_COP1_R1_R2_CR3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, r3:R4_0, cpNum:1, cpOp1:COP_4_4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like VMRS
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VMRS(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_FPSCR, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like VMSR
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VMSR(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_FPSCR_R1, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like VMOVRS
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VMOVRS(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_S2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:V_16_7}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like VMOVSR
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VMOVSR(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_S1_R2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:V_16_7, r2:R4_12}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions VMOVZR
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VMOVZR(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_Z1_R2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:V_7_16, r2:R4_12, index:IDX_21}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions VMOVRZ
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VMOVRZ(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME ] = {opcode:_OPCODE, format:FMT_R1_Z2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:V_7_16, index:IDX_21}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like VMOVRRD
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VMOVRRD(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_D3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, r3:V_5_0}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like VMOVDRR
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VMOVDRR(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_D1_R2_R3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:V_5_0, r2:R4_12, r3:R4_16}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like VMOVRRSS
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VMOVRRSS(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_R1_R2_SS3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:R4_12, r2:R4_16, r3:V_0_5}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for instructions like VMOVSSRR
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VMOVSSRR(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_SS1_R2_R3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, r1:V_0_5, r2:R4_12, r3:R4_16}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for SIMD/VFP load/store multiple instructions w/ 1 arm reg and a reg list (initial reg + number of consecutive regs)
|
|
||||||
// D/S versions
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SDFP_LDSTM(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##_D] = {opcode:_OPCODE, format:FMT_R1_SIMD_RL, type:ARM_IT_##_NAME##_D, support:_SUPPORT, isar:_ISAR, r1:R4_16, r2:V_22_12, nregs:NREG_7_1, incDec:ID_U_P, wb:WB_21, ua67:ARM_UA_DABORT}, \
|
|
||||||
[TT32_##_NAME##_S] = {opcode:_OPCODE, format:FMT_R1_VFP_RL, type:ARM_IT_##_NAME##_S, support:_SUPPORT, isar:_ISAR, r1:R4_16, r2:V_12_22, nregs:NREG_8_0, incDec:ID_U_P, wb:WB_21, ua67:ARM_UA_DABORT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for SIMD/VFP load/store instructions w/ 1 reg and 1 arm reg and an immediate
|
|
||||||
// D/S versions
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SDFP_LDST(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##_D] = {opcode:_OPCODE, format:FMT_D1_ADDR_R2_SIMM, type:ARM_IT_##_NAME##_D, support:_SUPPORT, isar:_ISAR, r1:V_22_12, r2:R4_16, cs:CS_U_8_0x4_U, u:US_23, ua67:ARM_UA_DABORT}, \
|
|
||||||
[TT32_##_NAME##_S] = {opcode:_OPCODE, format:FMT_S1_ADDR_R2_SIMM, type:ARM_IT_##_NAME##_S, support:_SUPPORT, isar:_ISAR, r1:V_12_22, r2:R4_16, cs:CS_U_8_0x4_U, u:US_23, ua67:ARM_UA_DABORT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for SIMD/VFP push/pop instructions w/ arm reg SP and a reg list (initial reg + number of consecutive regs)
|
|
||||||
// D/S versions
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_SDFP_PUSH(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME##_D] = {opcode:_OPCODE, format:FMT_SIMD_RL, type:ARM_IT_##_NAME##_D, support:_SUPPORT, isar:_ISAR, r1:R4_16, r2:V_22_12, nregs:NREG_7_1, incDec:ID_U_P_IMP, wb:WB_21, ua67:ARM_UA_DABORT}, \
|
|
||||||
[TT32_##_NAME##_S] = {opcode:_OPCODE, format:FMT_VFP_RL, type:ARM_IT_##_NAME##_S, support:_SUPPORT, isar:_ISAR, r1:R4_16, r2:V_12_22, nregs:NREG_8_0, incDec:ID_U_P_IMP, wb:WB_21, ua67:ARM_UA_DABORT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for VFP data processing instructions w/ 3 regs same length:
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VFP_RRR(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_S1_S2_S3, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, dt1:ARM_SDFPT_F32, r1:V_12_22, r2:V_16_7, r3:V_0_5}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for VFP data processing instructions w/ 2 regs same length:
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VFP_RR(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_S1_S2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, dt1:ARM_SDFPT_F32, r1:V_12_22, r2:V_0_5}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for VFP data processing instructions w/ 1 reg and modified immediate:
|
|
||||||
// Note: immediate value 'abcdefgh' is in c (for disassembly purposes). Must still be converted to modified imm value at morph time
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VFP_RI(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_S1_SDFP_MI, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, dt1:ARM_SDFPT_F32, r1:V_12_22, sdfpMI:SDFP_MI_VFP_S}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for VFP data processing instructions w/ 2 regs same length:
|
|
||||||
// S version only 2 dt1 sizes specified
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VFP_RR_S_S2(_NAME, _SUPPORT, _ISAR, _OPCODE, _S1, _S2) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_S1_S2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, dt1:ARM_SDFPT_F##_S1, dt2:ARM_SDFPT_F##_S2, r1:V_12_22, r2:V_0_5}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for VFP data processing instructions w/ 1 reg and implied immediate 0.0 value
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VFP_R0(_NAME, _SUPPORT, _ISAR, _OPCODE) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_S1_F0, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, dt1:ARM_SDFPT_F32, r1:V_12_22, r2:V_0_5}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for VFP data processing instructions w/ 2 regs SS: Type for dt2 specified
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VFP_LS_T(_NAME, _SUPPORT, _ISAR, _OPCODE, _T) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_S1_S2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, dt1:ARM_SDFPT_F32, dt2:ARM_SDFPT##_T##32, r1:V_12_22, r2:V_0_5}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for VFP data processing instructions w/ 2 regs SS: Type for dt1 specified
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VFP_NS_T(_NAME, _SUPPORT, _ISAR, _OPCODE, _T) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_S1_S2, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, dt1:ARM_SDFPT##_T##32, dt2:ARM_SDFPT_F32, r1:V_12_22, r2:V_0_5}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute entries for VFP data processing instructions w/ 1 reg and an immediate:
|
|
||||||
// 2 ftypes with sizes specified A modifier for the constant specified
|
|
||||||
//
|
|
||||||
#define ATTR_SET_32_VFP_RI_T2C(_NAME, _SUPPORT, _ISAR, _OPCODE, _TS1, _TS2, _C) \
|
|
||||||
[TT32_##_NAME] = {opcode:_OPCODE, format:FMT_S1_S2_UIMM, type:ARM_IT_##_NAME, support:_SUPPORT, isar:_ISAR, dt1:ARM_SDFPT##_TS1, dt2:ARM_SDFPT##_TS2, r1:V_12_22, r2:V_12_22, cs:CS_U_5_0_5M##_C}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_BIT_MACROS_H
|
|
||||||
#define ARM_BIT_MACROS_H
|
|
||||||
|
|
||||||
//
|
|
||||||
// mask the argument _ARG to be _BITS bits wide
|
|
||||||
//
|
|
||||||
#define WIDTH(_BITS, _ARG) ((_ARG)&((1<<(_BITS))-1))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiMessage.h"
|
|
||||||
#include "vmi/vmiRt.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armFunctions.h"
|
|
||||||
|
|
||||||
static vmiBusPort busPorts[] = {
|
|
||||||
{"INSTRUCTION", vmi_BP_MASTER, vmi_DOM_CODE, 32, 1 },
|
|
||||||
{"DATA" , vmi_BP_MASTER, vmi_DOM_DATA, 32, 0 },
|
|
||||||
{ 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the next bus port
|
|
||||||
//
|
|
||||||
VMI_BUS_PORT_SPECS_FN(armGetBusPortSpec) {
|
|
||||||
if (!prev) {
|
|
||||||
return busPorts;
|
|
||||||
}
|
|
||||||
prev++;
|
|
||||||
if (prev->name) {
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_CONFIG_H
|
|
||||||
#define ARM_CONFIG_H
|
|
||||||
|
|
||||||
// basic number types
|
|
||||||
#include "hostapi/impTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armSysRegisters.h"
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
#include "armVariant.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Use this to define a write mask entry in the structure below
|
|
||||||
//
|
|
||||||
#define SCS_MASK_DECL(_N) union { \
|
|
||||||
Uns32 value32; \
|
|
||||||
SCS_REG_STRUCT_DECL(_N) fields; \
|
|
||||||
} _N
|
|
||||||
|
|
||||||
//
|
|
||||||
// This structure hold configuration information about an ARM variant
|
|
||||||
//
|
|
||||||
typedef struct armConfigS {
|
|
||||||
|
|
||||||
// name of configuration
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
// configuration not held in system registers
|
|
||||||
armArchitecture arch :16; // specific ISA supported
|
|
||||||
Uns32 numInterrupts :16; // number of external interrupt lines
|
|
||||||
Uns32 ERG : 4; // exclusives reservation granule
|
|
||||||
Bool rotateUnaligned: 1; // rotate unaligned LDR/LDRT/SWP?
|
|
||||||
Bool align64as32 : 1; // align 64-bit load/store on 32-bit
|
|
||||||
Bool STRoffsetPC12 : 1; // STR/STM store PC with offset 12?
|
|
||||||
Uns32 priorityBitsM1 : 3; // number of priority bits, minus 1
|
|
||||||
|
|
||||||
// default values for system registers
|
|
||||||
struct {
|
|
||||||
SCS_REG_DECL(ICTR);
|
|
||||||
SCS_REG_DECL(ACTLR);
|
|
||||||
SCS_REG_DECL(CPUID);
|
|
||||||
SCS_REG_DECL(CPACR);
|
|
||||||
SCS_REG_DECL(SYST_CALIB);
|
|
||||||
SCS_REG_DECL(ID_PFR0);
|
|
||||||
SCS_REG_DECL(ID_PFR1);
|
|
||||||
SCS_REG_DECL(ID_DFR0);
|
|
||||||
SCS_REG_DECL(ID_AFR0);
|
|
||||||
SCS_REG_DECL(ID_MMFR0);
|
|
||||||
SCS_REG_DECL(ID_MMFR1);
|
|
||||||
SCS_REG_DECL(ID_MMFR2);
|
|
||||||
SCS_REG_DECL(ID_MMFR3);
|
|
||||||
SCS_REG_DECL(ID_ISAR0);
|
|
||||||
SCS_REG_DECL(ID_ISAR1);
|
|
||||||
SCS_REG_DECL(ID_ISAR2);
|
|
||||||
SCS_REG_DECL(ID_ISAR3);
|
|
||||||
SCS_REG_DECL(ID_ISAR4);
|
|
||||||
SCS_REG_DECL(ID_ISAR5);
|
|
||||||
SCS_REG_DECL(MVFR0);
|
|
||||||
SCS_REG_DECL(MVFR1);
|
|
||||||
SCS_REG_DECL(MPU_TYPE);
|
|
||||||
} regDefaults;
|
|
||||||
|
|
||||||
// write masks for system registers
|
|
||||||
struct {
|
|
||||||
SCS_MASK_DECL(CPACR);
|
|
||||||
} regMasks;
|
|
||||||
|
|
||||||
} armConfig;
|
|
||||||
|
|
||||||
DEFINE_CS(armConfig);
|
|
||||||
|
|
||||||
//
|
|
||||||
// This specifies configuration information for each supported variant
|
|
||||||
//
|
|
||||||
extern const struct armConfigS armConfigTable[];
|
|
||||||
|
|
||||||
//
|
|
||||||
// Predicates for system features
|
|
||||||
//
|
|
||||||
|
|
||||||
// is MPU enabled?
|
|
||||||
#define MPU_ENABLED(_A) SCS_FIELD(_A, MPU_CONTROL, ENABLE)
|
|
||||||
|
|
||||||
// is MPU unified?
|
|
||||||
#define MPU_UNIFIED(_A) (!SCS_FIELD(_A, MPU_TYPE, SEPARATE))
|
|
||||||
|
|
||||||
// is MPU present?
|
|
||||||
#define MPU_PRESENT(_A) SCS_FIELD(_A, MPU_TYPE, DREGION)
|
|
||||||
#define MPUS_PRESENT(_A) (MPU_PRESENT(_A) && !MPU_UNIFIED(_A))
|
|
||||||
|
|
||||||
|
|
||||||
// is alignment checking enabled?
|
|
||||||
#define ALIGN_ENABLED(_A) SCS_FIELD(_A, CCR, UNALIGN_TRP)
|
|
||||||
#define DO_UNALIGNED(_A) !ALIGN_ENABLED(_A)
|
|
||||||
|
|
||||||
// is Jazelle present?
|
|
||||||
#define JAZELLE_PRESENT(_A) ARM_SUPPORT((_A)->configInfo.arch, ARM_J)
|
|
||||||
|
|
||||||
// get number of priority bits supported
|
|
||||||
#define PRIORITY_BITS(_A) ((_A)->configInfo.priorityBitsM1+1)
|
|
||||||
|
|
||||||
// get number of interrupt lines
|
|
||||||
#define NUM_INTERRUPTS(_A) ((_A)->configInfo.numInterrupts)
|
|
||||||
|
|
||||||
// is FPU present?
|
|
||||||
#define FPU_PRESENT(_A) SCS_FIELD((_A), MVFR0, A_SIMD_Registers)
|
|
||||||
|
|
||||||
// is DSP present?
|
|
||||||
#define DSP_PRESENT(_A) (SCS_FIELD((_A), ID_ISAR3, SIMD_instrs)>2)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_DEBUG_H
|
|
||||||
#define ARM_DEBUG_H
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add programmer's view of all system registers
|
|
||||||
//
|
|
||||||
void armAddSysRegistersView(armP arm, vmiViewObjectP processorObject);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_DECODE_H
|
|
||||||
#define ARM_DECODE_H
|
|
||||||
|
|
||||||
// basic number types
|
|
||||||
#include "hostapi/impTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armDecodeTypes.h"
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode the instruction at the passed address. The 'info' structure is filled
|
|
||||||
// with details of the instruction.
|
|
||||||
//
|
|
||||||
void armDecode(armP arm, Uns32 thisPC, armInstructionInfoP info);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the size of the instruction at the passed address and the mode
|
|
||||||
//
|
|
||||||
Uns32 armGetInstructionSizeMode(armP arm, Uns32 thisPC, Bool isThumb);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the size of the instruction at the passed address
|
|
||||||
//
|
|
||||||
Uns32 armGetInstructionSize(armP arm, Uns32 thisPC);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,138 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_DECODE_ENTRIES_THUMB16_H
|
|
||||||
#define ARM_DECODE_ENTRIES_THUMB16_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiDecode.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// This macro adds a decode table entry for a 16-bit Thumb instruction class
|
|
||||||
//
|
|
||||||
#define DECODE_TT16(_PRIORITY, _NAME, _PATTERN) \
|
|
||||||
{type:TT16_##_NAME, priority:_PRIORITY, name:#_NAME"_T", pattern:_PATTERN}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like ADC
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_ADC(_NAME, _OP) \
|
|
||||||
DECODE_TT16(1, _NAME, "|"_OP"|...|...|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like ADD (1)
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_ADD1(_NAME, _OP) \
|
|
||||||
DECODE_TT16(0, _NAME, "|"_OP"|...|...|...|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like ADD (2)
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_ADD2(_NAME, _OP) \
|
|
||||||
DECODE_TT16(0, _NAME, "|"_OP"|...|........|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like ADD (4)
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_ADD4(_NAME, _OP) \
|
|
||||||
DECODE_TT16(1, _NAME, "|"_OP"|...|...|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like ADD (7)
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_ADD7(_NAME, _OP) \
|
|
||||||
DECODE_TT16(0, _NAME, "|"_OP"|.......|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like ASR (1)
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_ASR1(_NAME, _OP) \
|
|
||||||
DECODE_TT16(0, _NAME, "|"_OP"|.....|...|...|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like B (1)
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_B1(_NAME, _OP) \
|
|
||||||
DECODE_TT16(0, _NAME, "|1101|" _OP "|........|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like B (2)
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_B2(_NAME, _OP) \
|
|
||||||
DECODE_TT16(0, _NAME, "|111|" _OP "...........|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like BLX (2)
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_BLX2(_NAME, _OP) \
|
|
||||||
DECODE_TT16(0, _NAME, "|"_OP"|....|...|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for undefined 16-bit Thumb instructions like SWI
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_SWI(_NAME, _OP) \
|
|
||||||
DECODE_TT16(1, _NAME, "|1101|" _OP "|........|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like BKPT
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_BKPT(_NAME, _OP) \
|
|
||||||
DECODE_TT16(1, _NAME, "1011|"_OP"|.....|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like POP
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_POP(_NAME, _OP) \
|
|
||||||
DECODE_TT16(0, _NAME, "|"_OP"|.|........|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb instructions like IT
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_IT(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT16(0, _NAME, "|1011|1111|" _OP1 "|" _OP2 "|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb hint instructions like NOP
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_HINT1(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT16(1, _NAME, "|1011|1111|" _OP1 "|" _OP2 "|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 16-bit Thumb hint instructions like YIELD
|
|
||||||
//
|
|
||||||
#define DECODE_SET_16_HINT2(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT16(2, _NAME, "|1011|1111|" _OP1 "|" _OP2 "|")
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,390 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_DECODE_ENTRIES_THUMB32_H
|
|
||||||
#define ARM_DECODE_ENTRIES_THUMB32_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiDecode.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// This macro adds a decode table entry for a 32-bit Thumb instruction class
|
|
||||||
//
|
|
||||||
#define DECODE_TT32(_PRIORITY, _NAME, _PATTERN) \
|
|
||||||
{type:TT32_##_NAME, priority:_PRIORITY, name:#_NAME"_T", pattern:_PATTERN}
|
|
||||||
|
|
||||||
//
|
|
||||||
// This macro adds an undefined instruction decode table entry for a 32-bit Thumb instruction class
|
|
||||||
//
|
|
||||||
#define DECODE_LAST(_PRIORITY, _PATTERN) \
|
|
||||||
{type:TT_LAST, priority:_PRIORITY, name:"LAST_T", pattern:_PATTERN}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like AND
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_AND(_NAME, _OP) \
|
|
||||||
DECODE_TT32(0, _NAME##_IMM, "|111|10.0|" _OP "|.|....|0...|....|........"), \
|
|
||||||
DECODE_TT32(0, _NAME##_RM_SHFT_IMM, "|111|0101|" _OP "|.|....|....|....|........"), \
|
|
||||||
DECODE_TT32(1, _NAME##_RM_RRX, "|111|0101|" _OP "|.|....|.000|....|0011....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like TST
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_TST(_NAME, _OP) \
|
|
||||||
DECODE_TT32(2, _NAME##_IMM, "|111|10.0|" _OP "|1|....|0...|1111|........"), \
|
|
||||||
DECODE_TT32(2, _NAME##_RM_SHFT_IMM, "|111|0101|" _OP "|1|....|....|1111|........"), \
|
|
||||||
DECODE_TT32(3, _NAME##_RM_RRX, "|111|0101|" _OP "|1|....|.000|1111|0011....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like MOV
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_MOV(_NAME, _OP) \
|
|
||||||
DECODE_TT32(2, _NAME##_IMM, "|111|10.0|" _OP "|.|1111|0...|....|........"), \
|
|
||||||
DECODE_TT32(2, _NAME##_RM_SHFT_IMM, "|111|0101|" _OP "|.|1111|....|....|........"), \
|
|
||||||
DECODE_TT32(3, _NAME##_RM_RRX, "|111|0101|" _OP "|.|1111|.000|....|0011....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like PKHBT
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_PKHBT(_NAME, _OP) \
|
|
||||||
DECODE_TT32(0, _NAME, "|111|01|01|0110|0|....|....|....|.." _OP "0|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like ADD (plain binary immediate)
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_ADD_PI(_NAME, _OP) \
|
|
||||||
DECODE_TT32(0, _NAME, "|111|10|.1|" _OP "|....|0|...|....|........")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like ADR (plain binary immediate)
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_ADR_PI(_NAME, _OP) \
|
|
||||||
DECODE_TT32(1, _NAME, "|111|10|.1|" _OP "|1111|0|...|....|........")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like SSAT16
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SSAT16(_NAME, _OP) \
|
|
||||||
DECODE_TT32(1, _NAME, "|111|10|.1|" _OP "|....|0|000|....|00......")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like LSL
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_LSL(_NAME, _OP1, _OP2, _OP3) \
|
|
||||||
DECODE_TT32(0, _NAME, "|111|1101|0|" _OP1 "|" _OP3 "|1111|....|" _OP2 "|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like SXTH
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SXTH(_NAME, _OP1, _OP2, _OP3) \
|
|
||||||
DECODE_TT32(1, _NAME, "|111|1101|0|" _OP1 "|" _OP3 "|1111|....|" _OP2 "|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for parallel add/subtract instructions
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_PAS(_NAME, _OP) \
|
|
||||||
DECODE_TT32(0, S##_NAME, "111|1101|01|" _OP "|....|1111|....|0000|....|"), \
|
|
||||||
DECODE_TT32(0, Q##_NAME, "111|1101|01|" _OP "|....|1111|....|0001|....|"), \
|
|
||||||
DECODE_TT32(0, SH##_NAME, "111|1101|01|" _OP "|....|1111|....|0010|....|"), \
|
|
||||||
DECODE_TT32(0, U##_NAME, "111|1101|01|" _OP "|....|1111|....|0100|....|"), \
|
|
||||||
DECODE_TT32(0, UQ##_NAME, "111|1101|01|" _OP "|....|1111|....|0101|....|"), \
|
|
||||||
DECODE_TT32(0, UH##_NAME, "111|1101|01|" _OP "|....|1111|....|0110|....|")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like MLA
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_MLA(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(0, _NAME, "|111|1101|1|" _OP1 "|....|....|....|" _OP2 "|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like MUL
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_MUL(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(1, _NAME, "|111|1101|1|" _OP1 "|....|1111|....|" _OP2 "|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb DSP instructions like SMLA<x><y>
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SMLA_XY(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(0, _NAME##BB, "|111|1101|1|" _OP1 "|....|....|....|" _OP2 "00|...."), \
|
|
||||||
DECODE_TT32(0, _NAME##BT, "|111|1101|1|" _OP1 "|....|....|....|" _OP2 "01|...."), \
|
|
||||||
DECODE_TT32(0, _NAME##TB, "|111|1101|1|" _OP1 "|....|....|....|" _OP2 "10|...."), \
|
|
||||||
DECODE_TT32(0, _NAME##TT, "|111|1101|1|" _OP1 "|....|....|....|" _OP2 "11|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb DSP instructions like SMUL<x><y>
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SMUL_XY(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(1, _NAME##BB, "|111|1101|1|" _OP1 "|....|1111|....|" _OP2 "00|...."), \
|
|
||||||
DECODE_TT32(1, _NAME##BT, "|111|1101|1|" _OP1 "|....|1111|....|" _OP2 "01|...."), \
|
|
||||||
DECODE_TT32(1, _NAME##TB, "|111|1101|1|" _OP1 "|....|1111|....|" _OP2 "10|...."), \
|
|
||||||
DECODE_TT32(1, _NAME##TT, "|111|1101|1|" _OP1 "|....|1111|....|" _OP2 "11|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb DSP instructions like SMLAD<x>
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SMLAD(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(0, _NAME, "|111|1101|1|" _OP1 "|....|....|....|" _OP2 "0|...."), \
|
|
||||||
DECODE_TT32(0, _NAME##X, "|111|1101|1|" _OP1 "|....|....|....|" _OP2 "1|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb DSP instructions like SMUAD<x>
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SMUAD(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(1, _NAME, "|111|1101|1|" _OP1 "|....|1111|....|" _OP2 "0|...."), \
|
|
||||||
DECODE_TT32(1, _NAME##X, "|111|1101|1|" _OP1 "|....|1111|....|" _OP2 "1|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb DSP instructions like SMLAW<y>
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SMLAW(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(0, _NAME##B, "|111|1101|1|" _OP1 "|....|....|....|" _OP2 "0|...."), \
|
|
||||||
DECODE_TT32(0, _NAME##T, "|111|1101|1|" _OP1 "|....|....|....|" _OP2 "1|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb DSP instructions like SMULW<y>
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SMULW(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(1, _NAME##B, "|111|1101|1|" _OP1 "|....|1111|....|" _OP2 "0|...."), \
|
|
||||||
DECODE_TT32(1, _NAME##T, "|111|1101|1|" _OP1 "|....|1111|....|" _OP2 "1|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb DSP instructions like SMMLA
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SMMLA(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(0, _NAME, "|111|1101|1|" _OP1 "|....|....|....|" _OP2 "0|...."), \
|
|
||||||
DECODE_TT32(0, _NAME##R, "|111|1101|1|" _OP1 "|....|....|....|" _OP2 "1|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb DSP instructions like SMMUL
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SMMUL(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(1, _NAME, "|111|1101|1|" _OP1 "|....|1111|....|" _OP2 "0|...."), \
|
|
||||||
DECODE_TT32(1, _NAME##R, "|111|1101|1|" _OP1 "|....|1111|....|" _OP2 "1|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like BFC
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_BFC(_NAME, _OP) \
|
|
||||||
DECODE_TT32(1, _NAME, "|111|10|.1|" _OP "|1111|0|...|....|........")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like B (1)
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_B1(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(0, _NAME, "|111|10|...........|1|" _OP1 "|..........." _OP2)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb undefined instructions
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_UNDEF(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(1, _NAME, "|111|10|" _OP2 "|....|1|" _OP1 "|....|........")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like MSR
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_MSR(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(2, _NAME, "|111|10|" _OP2 "|....|1|" _OP1 "|....|........")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb hint instructions like NOP
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_HINT1(_NAME, _OP1, _OP2, _OP3) \
|
|
||||||
DECODE_TT32(3, _NAME, "|111|10|" _OP2 "|....|1|" _OP1 "|.000|" _OP3)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb hint instructions like YIELD
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_HINT2(_NAME, _OP1, _OP2, _OP3) \
|
|
||||||
DECODE_TT32(4, _NAME, "|111|10|" _OP2 "|....|1|" _OP1 "|.000|" _OP3)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like CLREX
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_CLREX(_NAME, _OP) \
|
|
||||||
DECODE_TT32(2, _NAME, "|111|10|0111011|....|10.0|....|" _OP "|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like SRS
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SRS(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(1, _NAME, "|111|0100|" _OP1 "|0|" _OP2 "|................")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like POPM
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_POPM(_NAME, _OP1, _OP2) \
|
|
||||||
DECODE_TT32(2, _NAME, "|111|0100|" _OP1 "|0|" _OP2 "|................")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like LDRD_IMM
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_LDRD_IMM(_NAME, _OP1, _OP2, _OP3) \
|
|
||||||
DECODE_TT32(0, _NAME, "|111|0100|" _OP1 "|1|" _OP2 "|....|........" _OP3 "....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like LDREX
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_LDREX(_NAME, _OP1, _OP2, _OP3) \
|
|
||||||
DECODE_TT32(1, _NAME, "|111|0100|" _OP1 "|1|" _OP2 "|....|........" _OP3 "....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like LDR
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_LDR(_NAME, _SIGN, _SZ) \
|
|
||||||
DECODE_TT32(0, _NAME##_IMM1, "|111|1100|" _SIGN "1|" _SZ "|1|....|....|......|......"), \
|
|
||||||
DECODE_TT32(1, _NAME##_IMM2, "|111|1100|" _SIGN "0|" _SZ "|1|....|....|1..1..|......"), \
|
|
||||||
DECODE_TT32(1, _NAME##_IMM2, "|111|1100|" _SIGN "0|" _SZ "|1|....|....|1100..|......"), \
|
|
||||||
DECODE_TT32(3, _NAME##_IMM3, "|111|1100|" _SIGN "0|" _SZ "|1|1111|....|......|......"), \
|
|
||||||
DECODE_TT32(2, _NAME##_RM, "|111|1100|" _SIGN "0|" _SZ "|1|....|....|000000|00...."), \
|
|
||||||
DECODE_TT32(1, _NAME##_RM_SHFT_IMM, "|111|1100|" _SIGN "0|" _SZ "|1|....|....|000000|......"), \
|
|
||||||
DECODE_TT32(1, _NAME##T_IMM, "|111|1100|" _SIGN "0|" _SZ "|1|....|....|1110..|......")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like STR
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_STR(_NAME, _SIGN, _SZ) \
|
|
||||||
DECODE_TT32(0, _NAME##_IMM1, "|111|1100|" _SIGN "1|" _SZ "|0|....|....|......|......"), \
|
|
||||||
DECODE_TT32(1, _NAME##_IMM2, "|111|1100|" _SIGN "0|" _SZ "|0|....|....|1..1..|......"), \
|
|
||||||
DECODE_TT32(1, _NAME##_IMM2, "|111|1100|" _SIGN "0|" _SZ "|0|....|....|1100..|......"), \
|
|
||||||
DECODE_TT32(3, _NAME##_IMM3, "|111|1100|" _SIGN "0|" _SZ "|0|1111|....|......|......"), \
|
|
||||||
DECODE_TT32(2, _NAME##_RM, "|111|1100|" _SIGN "0|" _SZ "|0|....|....|000000|00...."), \
|
|
||||||
DECODE_TT32(1, _NAME##_RM_SHFT_IMM, "|111|1100|" _SIGN "0|" _SZ "|0|....|....|000000|......"), \
|
|
||||||
DECODE_TT32(1, _NAME##T_IMM, "|111|1100|" _SIGN "0|" _SZ "|0|....|....|1110..|......")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like PLD
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_PLD(_NAME, _SIGN, _SZ) \
|
|
||||||
DECODE_TT32(5, _NAME##_IMM1, "|111|1100|" _SIGN "1|" _SZ "|1|....|1111|......|......"), \
|
|
||||||
DECODE_TT32(6, _NAME##_IMM2, "|111|1100|" _SIGN "0|" _SZ "|1|....|1111|1100..|......"), \
|
|
||||||
DECODE_TT32(8, _NAME##_IMM3, "|111|1100|" _SIGN "0|" _SZ "|1|1111|1111|......|......"), \
|
|
||||||
DECODE_TT32(7, _NAME##_RM, "|111|1100|" _SIGN "0|" _SZ "|1|....|1111|000000|00...."), \
|
|
||||||
DECODE_TT32(6, _NAME##_RM_SHFT_IMM, "|111|1100|" _SIGN "0|" _SZ "|1|....|1111|000000|......")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like UHINTH
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_UHINTH(_NAME, _SZ) \
|
|
||||||
DECODE_TT32(4, _NAME, "|111|1100|..|" _SZ "|1|....|1111|......|......")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like CDP
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_CDP(_NAME) \
|
|
||||||
DECODE_TT32(0, _NAME, "....|1110|....|....|....|....|...|0|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like CDP2
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_CDP2(_NAME) \
|
|
||||||
DECODE_TT32(1, _NAME, "1111|1110|....|....|....|....|...|0|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like LDC
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_LDC(_NAME, _OP) \
|
|
||||||
DECODE_TT32(0, _NAME##_IMM, "....|110|...." _OP "|....|....|....|........"), \
|
|
||||||
DECODE_TT32(1, _NAME##_UNINDEXED, "....|110|0..0" _OP "|....|....|....|........")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like LDC2
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_LDC2(_NAME, _OP) \
|
|
||||||
DECODE_TT32(2, _NAME##_IMM, "1111|110|...." _OP "|....|....|....|........"), \
|
|
||||||
DECODE_TT32(3, _NAME##_UNINDEXED, "1111|110|0..0" _OP "|....|....|....|........")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like MCR
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_MCR(_NAME, _OP) \
|
|
||||||
DECODE_TT32(0, _NAME, "....|1110|...|" _OP "|....|....|....|...|1|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb instructions like MCR2
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_MCR2(_NAME, _OP) \
|
|
||||||
DECODE_TT32(1, _NAME, "1111|1110|...|" _OP "|....|....|....|...|1|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb DSP instructions like MCRR
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_MCRR(_NAME, _OP) \
|
|
||||||
DECODE_TT32(4, _NAME, "....|1100010" _OP "|....|....|....|....|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for 32-bit Thumb DSP instructions like MCRR2
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_MCRR2(_NAME, _OP) \
|
|
||||||
DECODE_TT32(5, _NAME, "1111|1100010" _OP "|....|....|....|....|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for VFP/SIMD instructions like VMRS
|
|
||||||
// Note - When bit 28=1 manual states this is an undefined instruction so extra
|
|
||||||
// decode is added. Without it this decodes as MRC and gives NOCP fault.
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_VMRS(_NAME, _OPL, _OPC, _OPA, _OPB) \
|
|
||||||
DECODE_TT32(2, _NAME, "1110|1110" _OPA _OPL "|....|....|101" _OPC "|." _OPB "1|...."), \
|
|
||||||
DECODE_LAST(2, "1111|1110" _OPA _OPL "|....|....|101" _OPC "|." _OPB "1|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for VFP instructions like VMOVRRD
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_VMOVRRD(_NAME, _OPL, _OPC, _OP) \
|
|
||||||
DECODE_TT32(6, _NAME, "1110|1100|010" _OPL "........|101" _OPC _OP "|...."), \
|
|
||||||
DECODE_LAST(6, "1111|1100|010" _OPL "........|101" _OPC _OP "|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for SIMD/VFP load/store instructions
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SDFP_LDST(_NAME, _OP) \
|
|
||||||
DECODE_TT32(4, _NAME##_D, "1110|110" _OP "|....|....|1011|....|...."), \
|
|
||||||
DECODE_TT32(4, _NAME##_S, "1110|110" _OP "|....|....|1010|....|...."), \
|
|
||||||
DECODE_LAST(6, "1111|110" _OP "|....|....|101.|....|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for SIMD/VFP PUSH/POP instructions
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_SDFP_PUSH_POP(_NAME, _OP) \
|
|
||||||
DECODE_TT32(5, _NAME##_D, "1110|110" _OP "|1101|....|1011|....|...."), \
|
|
||||||
DECODE_TT32(5, _NAME##_S, "1110|110" _OP "|1101|....|1010|....|....")
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode entries for VFP instructions S version only
|
|
||||||
//
|
|
||||||
#define DECODE_SET_32_VFP_S(_NAME, _OP1, _OP2, _OP3) \
|
|
||||||
DECODE_TT32(2, _NAME, "1110|1110|" _OP1 _OP2 "|....|1010|" _OP3 ".0|...."), \
|
|
||||||
DECODE_LAST(3, "1111|1110|" _OP1 _OP2 "|....|1010|" _OP3 ".0|....")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_DECODE_THUMB_H
|
|
||||||
#define ARM_DECODE_THUMB_H
|
|
||||||
|
|
||||||
// basic number types
|
|
||||||
#include "hostapi/impTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armDecodeTypes.h"
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return size in bytes of Thumb instruction at the passed address
|
|
||||||
//
|
|
||||||
Uns32 armGetThumbInstructionSize(armP arm, Uns32 thisPC);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode the Thumb instruction at the passed address. The 'info' structure is
|
|
||||||
// filled with details of the instruction.
|
|
||||||
//
|
|
||||||
void armDecodeThumb(armP arm, Uns32 thisPC, armInstructionInfoP info);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,762 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_DECODE_TYPES_H
|
|
||||||
#define ARM_DECODE_TYPES_H
|
|
||||||
|
|
||||||
// basic number types
|
|
||||||
#include "hostapi/impTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armVariant.h"
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction type for an instruction with a single variant
|
|
||||||
//
|
|
||||||
#define ITYPE_SINGLE(_NAME) \
|
|
||||||
ARM_IT_##_NAME
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for normal instructions like ADC
|
|
||||||
//
|
|
||||||
#define ITYPE_SET_ADC(_NAME) \
|
|
||||||
ARM_IT_##_NAME##_IMM, \
|
|
||||||
ARM_IT_##_NAME##_RM, \
|
|
||||||
ARM_IT_##_NAME##_RM_SHFT_IMM, \
|
|
||||||
ARM_IT_##_NAME##_RM_RRX, \
|
|
||||||
ARM_IT_##_NAME##_IT, \
|
|
||||||
ARM_IT_##_NAME##_RT
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for normal instructions like LDC
|
|
||||||
//
|
|
||||||
#define ITYPE_SET_LDC(_NAME) \
|
|
||||||
ARM_IT_##_NAME##_IMM, \
|
|
||||||
ARM_IT_##_NAME##_UNINDEXED
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for normal instructions like LDR
|
|
||||||
//
|
|
||||||
#define ITYPE_SET_LDR(_NAME) \
|
|
||||||
ARM_IT_##_NAME##_IMM, \
|
|
||||||
ARM_IT_##_NAME##_RM, \
|
|
||||||
ARM_IT_##_NAME##_RM_SHFT_IMM
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for normal instructions like LDRH
|
|
||||||
//
|
|
||||||
#define ITYPE_SET_LDRH(_NAME) \
|
|
||||||
ARM_IT_##_NAME##_IMM, \
|
|
||||||
ARM_IT_##_NAME##_RM \
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for normal instructions like MOV
|
|
||||||
//
|
|
||||||
#define ITYPE_SET_MOV(_NAME) \
|
|
||||||
ARM_IT_##_NAME##_IMM, \
|
|
||||||
ARM_IT_##_NAME##_RM, \
|
|
||||||
ARM_IT_##_NAME##_RM_SHFT_IMM, \
|
|
||||||
ARM_IT_##_NAME##_RM_SHFT_RS, \
|
|
||||||
ARM_IT_##_NAME##_RM_RRX, \
|
|
||||||
ARM_IT_##_NAME##_RM_SHFT_RST
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for DSP instructions like SMLA<x><y>
|
|
||||||
//
|
|
||||||
#define ITYPE_SET_SMLA_XY(_NAME) \
|
|
||||||
ARM_IT_##_NAME##BB, \
|
|
||||||
ARM_IT_##_NAME##BT, \
|
|
||||||
ARM_IT_##_NAME##TB, \
|
|
||||||
ARM_IT_##_NAME##TT
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for DSP instructions like SMLAW<y>
|
|
||||||
//
|
|
||||||
#define ITYPE_SET_SMLAW_Y(_NAME) \
|
|
||||||
ARM_IT_##_NAME##B, \
|
|
||||||
ARM_IT_##_NAME##T
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for normal instructions like PLD
|
|
||||||
//
|
|
||||||
#define ITYPE_SET_PLD(_NAME) \
|
|
||||||
ARM_IT_##_NAME##_IMM, \
|
|
||||||
ARM_IT_##_NAME##_RM, \
|
|
||||||
ARM_IT_##_NAME##_RM_SHFT_IMM
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for parallel add/subtract Media instructions
|
|
||||||
//
|
|
||||||
#define ITYPE_SET_PAS(_NAME) \
|
|
||||||
ARM_IT_S##_NAME, \
|
|
||||||
ARM_IT_Q##_NAME, \
|
|
||||||
ARM_IT_SH##_NAME, \
|
|
||||||
ARM_IT_U##_NAME, \
|
|
||||||
ARM_IT_UQ##_NAME, \
|
|
||||||
ARM_IT_UH##_NAME
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for Media instructions with optional argument exchange
|
|
||||||
//
|
|
||||||
#define ITYPE_MEDIA_X(_NAME) \
|
|
||||||
ARM_IT_##_NAME, \
|
|
||||||
ARM_IT_##_NAME##X
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for Media instructions with optional result rounding
|
|
||||||
//
|
|
||||||
#define ITYPE_MEDIA_R(_NAME) \
|
|
||||||
ARM_IT_##_NAME, \
|
|
||||||
ARM_IT_##_NAME##R
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction types for VFP instructions with D and S variants
|
|
||||||
//
|
|
||||||
#define ITYPE_VFP_DS(_NAME) \
|
|
||||||
ARM_IT_##_NAME##_D, \
|
|
||||||
ARM_IT_##_NAME##_S
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction type enumeration
|
|
||||||
//
|
|
||||||
typedef enum armInstructionTypeE {
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ARM INSTRUCTIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// data processing instructions
|
|
||||||
ITYPE_SET_ADC (ADC),
|
|
||||||
ITYPE_SET_ADC (ADD),
|
|
||||||
ITYPE_SET_ADC (AND),
|
|
||||||
ITYPE_SET_ADC (BIC),
|
|
||||||
ITYPE_SET_ADC (EOR),
|
|
||||||
ITYPE_SET_MOV (MOV),
|
|
||||||
ITYPE_SET_ADC (MUL),
|
|
||||||
ITYPE_SET_MOV (MVN),
|
|
||||||
ITYPE_SET_MOV (NEG),
|
|
||||||
ITYPE_SET_ADC (ORN),
|
|
||||||
ITYPE_SET_ADC (ORR),
|
|
||||||
ITYPE_SET_ADC (RSB),
|
|
||||||
ITYPE_SET_ADC (RSC),
|
|
||||||
ITYPE_SET_ADC (SBC),
|
|
||||||
ITYPE_SET_ADC (SUB),
|
|
||||||
|
|
||||||
// ARMv6T2 move instructions
|
|
||||||
ITYPE_SINGLE (MOVT),
|
|
||||||
ITYPE_SINGLE (MOVW),
|
|
||||||
|
|
||||||
// multiply instructions
|
|
||||||
ITYPE_SINGLE (MLA ),
|
|
||||||
ITYPE_SINGLE (MLS ),
|
|
||||||
ITYPE_SINGLE (MUL ),
|
|
||||||
ITYPE_SINGLE (SMLAL),
|
|
||||||
ITYPE_SINGLE (SMULL),
|
|
||||||
ITYPE_SINGLE (UMAAL),
|
|
||||||
ITYPE_SINGLE (UMLAL),
|
|
||||||
ITYPE_SINGLE (UMULL),
|
|
||||||
|
|
||||||
// compare instructions
|
|
||||||
ITYPE_SET_ADC (CMN),
|
|
||||||
ITYPE_SET_ADC (CMP),
|
|
||||||
ITYPE_SET_ADC (TEQ),
|
|
||||||
ITYPE_SET_ADC (TST),
|
|
||||||
|
|
||||||
// branch instructions
|
|
||||||
ITYPE_SINGLE (B ),
|
|
||||||
ITYPE_SINGLE (BL ),
|
|
||||||
ITYPE_SINGLE (BLX2),
|
|
||||||
ITYPE_SINGLE (BX ),
|
|
||||||
|
|
||||||
// miscellaneous instructions
|
|
||||||
ITYPE_SINGLE (BKPT),
|
|
||||||
ITYPE_SINGLE (CLZ ),
|
|
||||||
ITYPE_SINGLE (SWI ),
|
|
||||||
|
|
||||||
// load and store instructions
|
|
||||||
ITYPE_SET_LDR (LDR ),
|
|
||||||
ITYPE_SET_LDR (LDRB ),
|
|
||||||
ITYPE_SET_LDR (LDRBT),
|
|
||||||
ITYPE_SET_LDRH (LDRH ),
|
|
||||||
ITYPE_SET_LDRH (LDRSB),
|
|
||||||
ITYPE_SET_LDRH (LDRSH),
|
|
||||||
ITYPE_SET_LDR (LDRT ),
|
|
||||||
ITYPE_SET_LDR (STR ),
|
|
||||||
ITYPE_SET_LDR (STRB ),
|
|
||||||
ITYPE_SET_LDR (STRBT),
|
|
||||||
ITYPE_SET_LDRH (STRH ),
|
|
||||||
ITYPE_SET_LDR (STRT ),
|
|
||||||
|
|
||||||
// load and store multiple instructions
|
|
||||||
ITYPE_SINGLE (LDM1),
|
|
||||||
ITYPE_SINGLE (STM1),
|
|
||||||
|
|
||||||
// ARMv6T2 load and store instructions
|
|
||||||
ITYPE_SET_LDRH (LDRHT ),
|
|
||||||
ITYPE_SET_LDRH (LDRSBT),
|
|
||||||
ITYPE_SET_LDRH (LDRSHT),
|
|
||||||
ITYPE_SET_LDRH (STRHT ),
|
|
||||||
|
|
||||||
// synchronization primitives
|
|
||||||
ITYPE_SINGLE (LDREX ),
|
|
||||||
ITYPE_SINGLE (LDREXB),
|
|
||||||
ITYPE_SINGLE (LDREXH),
|
|
||||||
ITYPE_SINGLE (STREX ),
|
|
||||||
ITYPE_SINGLE (STREXB),
|
|
||||||
ITYPE_SINGLE (STREXH),
|
|
||||||
|
|
||||||
// coprocessor instructions
|
|
||||||
ITYPE_SINGLE (CDP ),
|
|
||||||
ITYPE_SINGLE (CDP2),
|
|
||||||
ITYPE_SET_LDC (LDC ),
|
|
||||||
ITYPE_SET_LDC (LDC2),
|
|
||||||
ITYPE_SINGLE (MCR ),
|
|
||||||
ITYPE_SINGLE (MCR2),
|
|
||||||
ITYPE_SINGLE (MRC ),
|
|
||||||
ITYPE_SINGLE (MRC2),
|
|
||||||
ITYPE_SET_LDC (STC ),
|
|
||||||
ITYPE_SET_LDC (STC2),
|
|
||||||
|
|
||||||
// status register access instructions
|
|
||||||
ITYPE_SINGLE (MRS),
|
|
||||||
ITYPE_SINGLE (MSR),
|
|
||||||
|
|
||||||
// hints
|
|
||||||
ITYPE_SINGLE (NOP ),
|
|
||||||
ITYPE_SINGLE (YIELD),
|
|
||||||
ITYPE_SINGLE (WFE ),
|
|
||||||
ITYPE_SINGLE (WFI ),
|
|
||||||
ITYPE_SINGLE (SEV ),
|
|
||||||
ITYPE_SINGLE (DBG ),
|
|
||||||
|
|
||||||
// ARMv6 miscellaneous instructions
|
|
||||||
ITYPE_SINGLE (CPS ),
|
|
||||||
ITYPE_SINGLE (CLREX ),
|
|
||||||
ITYPE_SINGLE (DSB ),
|
|
||||||
ITYPE_SINGLE (ISB ),
|
|
||||||
|
|
||||||
// ARMv7 hint instructions
|
|
||||||
ITYPE_SET_PLD (PLD),
|
|
||||||
ITYPE_SET_PLD (PLI),
|
|
||||||
ITYPE_SINGLE (DMB),
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DSP INSTRUCTIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// data processing instructions
|
|
||||||
ITYPE_SINGLE (QADD ),
|
|
||||||
ITYPE_SINGLE (QDADD),
|
|
||||||
ITYPE_SINGLE (QDSUB),
|
|
||||||
ITYPE_SINGLE (QSUB ),
|
|
||||||
|
|
||||||
// multiply instructions
|
|
||||||
ITYPE_SET_SMLA_XY (SMLA ),
|
|
||||||
ITYPE_SET_SMLA_XY (SMLAL),
|
|
||||||
ITYPE_SET_SMLAW_Y (SMLAW),
|
|
||||||
ITYPE_SET_SMLA_XY (SMUL ),
|
|
||||||
ITYPE_SET_SMLAW_Y (SMULW),
|
|
||||||
|
|
||||||
// load and store instructions
|
|
||||||
ITYPE_SET_LDRH (LDRD),
|
|
||||||
ITYPE_SET_LDRH (STRD),
|
|
||||||
|
|
||||||
// coprocessor instructions
|
|
||||||
ITYPE_SINGLE (MCRR ),
|
|
||||||
ITYPE_SINGLE (MCRR2),
|
|
||||||
ITYPE_SINGLE (MRRC ),
|
|
||||||
ITYPE_SINGLE (MRRC2),
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// MEDIA INSTRUCTIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// basic instructions
|
|
||||||
ITYPE_SINGLE (USAD8 ),
|
|
||||||
ITYPE_SINGLE (USADA8),
|
|
||||||
ITYPE_SINGLE (SBFX ),
|
|
||||||
ITYPE_SINGLE (BFC ),
|
|
||||||
ITYPE_SINGLE (BFI ),
|
|
||||||
ITYPE_SINGLE (UBFX ),
|
|
||||||
|
|
||||||
// parallel add/subtract instructions
|
|
||||||
ITYPE_SET_PAS (ADD16),
|
|
||||||
ITYPE_SET_PAS (ASX ),
|
|
||||||
ITYPE_SET_PAS (SAX ),
|
|
||||||
ITYPE_SET_PAS (SUB16),
|
|
||||||
ITYPE_SET_PAS (ADD8 ),
|
|
||||||
ITYPE_SET_PAS (SUB8 ),
|
|
||||||
|
|
||||||
// packing, unpacking, saturation and reversal instructions
|
|
||||||
ITYPE_SINGLE (PKHBT ),
|
|
||||||
ITYPE_SINGLE (PKHTB ),
|
|
||||||
ITYPE_SINGLE (SSAT ),
|
|
||||||
ITYPE_SINGLE (SSAT16 ),
|
|
||||||
ITYPE_SINGLE (USAT ),
|
|
||||||
ITYPE_SINGLE (USAT16 ),
|
|
||||||
ITYPE_SINGLE (SXTAB ),
|
|
||||||
ITYPE_SINGLE (UXTAB ),
|
|
||||||
ITYPE_SINGLE (SXTAB16),
|
|
||||||
ITYPE_SINGLE (UXTAB16),
|
|
||||||
ITYPE_SINGLE (SXTAH ),
|
|
||||||
ITYPE_SINGLE (UXTAH ),
|
|
||||||
ITYPE_SINGLE (SXTB ),
|
|
||||||
ITYPE_SINGLE (UXTB ),
|
|
||||||
ITYPE_SINGLE (SXTB16 ),
|
|
||||||
ITYPE_SINGLE (UXTB16 ),
|
|
||||||
ITYPE_SINGLE (SXTH ),
|
|
||||||
ITYPE_SINGLE (UXTH ),
|
|
||||||
ITYPE_SINGLE (SEL ),
|
|
||||||
ITYPE_SINGLE (REV ),
|
|
||||||
ITYPE_SINGLE (REV16 ),
|
|
||||||
ITYPE_SINGLE (RBIT ),
|
|
||||||
ITYPE_SINGLE (REVSH ),
|
|
||||||
|
|
||||||
// signed multiply instructions
|
|
||||||
ITYPE_MEDIA_X (SMLAD ),
|
|
||||||
ITYPE_MEDIA_X (SMUAD ),
|
|
||||||
ITYPE_MEDIA_X (SMLSD ),
|
|
||||||
ITYPE_MEDIA_X (SMUSD ),
|
|
||||||
ITYPE_MEDIA_X (SMLALD),
|
|
||||||
ITYPE_MEDIA_X (SMLSLD),
|
|
||||||
ITYPE_MEDIA_R (SMMLA ),
|
|
||||||
ITYPE_MEDIA_R (SMMUL ),
|
|
||||||
ITYPE_MEDIA_R (SMMLS ),
|
|
||||||
|
|
||||||
// VFP data processing instructions
|
|
||||||
ITYPE_SINGLE (VMLA_VFP),
|
|
||||||
ITYPE_SINGLE (VMLS_VFP),
|
|
||||||
ITYPE_SINGLE (VNMLS_VFP),
|
|
||||||
ITYPE_SINGLE (VNMLA_VFP),
|
|
||||||
ITYPE_SINGLE (VMUL_VFP),
|
|
||||||
ITYPE_SINGLE (VNMUL_VFP),
|
|
||||||
ITYPE_SINGLE (VADD_VFP),
|
|
||||||
ITYPE_SINGLE (VSUB_VFP),
|
|
||||||
ITYPE_SINGLE (VDIV_VFP),
|
|
||||||
ITYPE_SINGLE (VFMA_VFP),
|
|
||||||
ITYPE_SINGLE (VFMS_VFP),
|
|
||||||
ITYPE_SINGLE (VFNMS_VFP),
|
|
||||||
ITYPE_SINGLE (VFNMA_VFP),
|
|
||||||
ITYPE_SINGLE (VMOVI_VFP),
|
|
||||||
ITYPE_SINGLE (VMOVR_VFP),
|
|
||||||
ITYPE_SINGLE (VABS_VFP),
|
|
||||||
ITYPE_SINGLE (VNEG_VFP),
|
|
||||||
ITYPE_SINGLE (VSQRT_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTBFH_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTTFH_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTBHF_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTTHF_VFP),
|
|
||||||
ITYPE_SINGLE (VCMP_VFP),
|
|
||||||
ITYPE_SINGLE (VCMPE_VFP),
|
|
||||||
ITYPE_SINGLE (VCMP0_VFP),
|
|
||||||
ITYPE_SINGLE (VCMPE0_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTFU_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTFS_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTFXUH_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTFXUW_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTFXSH_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTFXSW_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTUF_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTRUF_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTSF_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTRSF_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTXFSH_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTXFSW_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTXFUH_VFP),
|
|
||||||
ITYPE_SINGLE (VCVTXFUW_VFP),
|
|
||||||
|
|
||||||
// Extension register load/store instructions
|
|
||||||
ITYPE_VFP_DS (VSTMIA),
|
|
||||||
ITYPE_VFP_DS (VSTMIAW),
|
|
||||||
ITYPE_VFP_DS (VSTR),
|
|
||||||
ITYPE_VFP_DS (VSTMDBW),
|
|
||||||
ITYPE_VFP_DS (VPUSH),
|
|
||||||
ITYPE_VFP_DS (VLDMIA),
|
|
||||||
ITYPE_VFP_DS (VLDMIAW),
|
|
||||||
ITYPE_VFP_DS (VPOP),
|
|
||||||
ITYPE_VFP_DS (VLDR),
|
|
||||||
ITYPE_VFP_DS (VLDMDBW),
|
|
||||||
|
|
||||||
// 8, 16 and 32-bit transfer instructions between ARM core regs and extension regs
|
|
||||||
ITYPE_SINGLE (VMRS),
|
|
||||||
ITYPE_SINGLE (VMSR),
|
|
||||||
ITYPE_SINGLE (VMOVRS),
|
|
||||||
ITYPE_SINGLE (VMOVSR),
|
|
||||||
ITYPE_SINGLE (VMOVZR),
|
|
||||||
ITYPE_SINGLE (VMOVRZ),
|
|
||||||
|
|
||||||
// 64-bit transfer instructions between ARM core regs and extension regs
|
|
||||||
ITYPE_SINGLE (VMOVRRD),
|
|
||||||
ITYPE_SINGLE (VMOVDRR),
|
|
||||||
ITYPE_SINGLE (VMOVRRSS),
|
|
||||||
ITYPE_SINGLE (VMOVSSRR),
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// THUMB INSTRUCTIONS (WHEN DISTINCT FROM ARM INSTRUCTIONS)
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// data processing instructions
|
|
||||||
ITYPE_SINGLE (ADD4),
|
|
||||||
ITYPE_SINGLE (ADD6),
|
|
||||||
ITYPE_SINGLE (ADD7),
|
|
||||||
ITYPE_SINGLE (SUB4),
|
|
||||||
ITYPE_SINGLE (MOV3),
|
|
||||||
|
|
||||||
// address instructions
|
|
||||||
ITYPE_SINGLE (ADD_ADR),
|
|
||||||
ITYPE_SINGLE (SUB_ADR),
|
|
||||||
|
|
||||||
// branch instructions
|
|
||||||
ITYPE_SINGLE (CBNZ),
|
|
||||||
ITYPE_SINGLE (CBZ ),
|
|
||||||
ITYPE_SINGLE (TB ),
|
|
||||||
|
|
||||||
// divide instructions
|
|
||||||
ITYPE_SINGLE (SDIV),
|
|
||||||
ITYPE_SINGLE (UDIV),
|
|
||||||
|
|
||||||
// KEEP LAST
|
|
||||||
ITYPE_SINGLE (LAST)
|
|
||||||
|
|
||||||
} armInstructionType;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Condition code enumeration
|
|
||||||
//
|
|
||||||
typedef enum armConditionE {
|
|
||||||
|
|
||||||
ARM_C_EQ, // ZF==1
|
|
||||||
ARM_C_NE, // ZF==0
|
|
||||||
ARM_C_CS, // CF==1
|
|
||||||
ARM_C_CC, // CF==0
|
|
||||||
ARM_C_MI, // NF==1
|
|
||||||
ARM_C_PL, // NF==0
|
|
||||||
ARM_C_VS, // VF==1
|
|
||||||
ARM_C_VC, // VF==0
|
|
||||||
ARM_C_HI, // (CF==1) && (ZF==0)
|
|
||||||
ARM_C_LS, // (CF==0) || (ZF==1)
|
|
||||||
ARM_C_GE, // NF==VF
|
|
||||||
ARM_C_LT, // NF!=VF
|
|
||||||
ARM_C_GT, // (ZF==0) && (NF==VF)
|
|
||||||
ARM_C_LE, // (ZF==1) || (NF!=VF)
|
|
||||||
ARM_C_AL, // always
|
|
||||||
ARM_C_NV, // never
|
|
||||||
|
|
||||||
// KEEP LAST
|
|
||||||
ARM_C_LAST
|
|
||||||
|
|
||||||
} armCondition;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This defines whether the instruction sets flags
|
|
||||||
//
|
|
||||||
typedef enum armSetFlagsE {
|
|
||||||
ARM_SF_0, // don't set flags
|
|
||||||
ARM_SF_V, // set flags, show in disassembly using "s" suffix
|
|
||||||
ARM_SF_I, // set flags, not shown in instruction disassembly
|
|
||||||
ARM_SF_IT, // only when not in if-then block
|
|
||||||
} armSetFlags;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This defines shift operations
|
|
||||||
//
|
|
||||||
typedef enum armShiftOpE {
|
|
||||||
ARM_SO_NA, // no shift operation
|
|
||||||
ARM_SO_LSL, // logical shift left
|
|
||||||
ARM_SO_LSR, // logical shift right
|
|
||||||
ARM_SO_ASR, // arithmetic shift right
|
|
||||||
ARM_SO_ROR, // rotate right
|
|
||||||
ARM_SO_RRX // rotate right with extend
|
|
||||||
} armShiftOp;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This defines increment/decrement actions
|
|
||||||
//
|
|
||||||
typedef enum armIncDecE {
|
|
||||||
ARM_ID_NA = 0x0, // no increment/decrement spec present
|
|
||||||
ARM_ID_D = 0x0, // decrement
|
|
||||||
ARM_ID_I = 0x1, // increment
|
|
||||||
ARM_ID_A = 0x0, // after
|
|
||||||
ARM_ID_B = 0x2, // before
|
|
||||||
ARM_ID_NS = 0x4, // not shown in disassembly
|
|
||||||
ARM_ID_P = 0x8, // increment/decrement spec present
|
|
||||||
ARM_ID_DA = ARM_ID_P | ARM_ID_D | ARM_ID_A, // decrement after
|
|
||||||
ARM_ID_IA = ARM_ID_P | ARM_ID_I | ARM_ID_A, // increment after
|
|
||||||
ARM_ID_DB = ARM_ID_P | ARM_ID_D | ARM_ID_B, // decrement before
|
|
||||||
ARM_ID_IB = ARM_ID_P | ARM_ID_I | ARM_ID_B, // increment before
|
|
||||||
ARM_ID_IAI = ARM_ID_IA | ARM_ID_NS, // IA, not shown in disassembly
|
|
||||||
ARM_ID_IBI = ARM_ID_IB | ARM_ID_NS, // IB, not shown in disassembly
|
|
||||||
ARM_ID_DAI = ARM_ID_DA | ARM_ID_NS, // DA, not shown in disassembly
|
|
||||||
ARM_ID_DBI = ARM_ID_DB | ARM_ID_NS // DB, not shown in disassembly
|
|
||||||
} armIncDec;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This defines bits in a field mask
|
|
||||||
//
|
|
||||||
typedef enum armSRFieldMaskE {
|
|
||||||
ARM_SR_C = 0x1, // control field mask bit
|
|
||||||
ARM_SR_X = 0x2, // extension field mask bit
|
|
||||||
ARM_SR_S = 0x4, // status field mask bit
|
|
||||||
ARM_SR_F = 0x8 // flags field mask bit
|
|
||||||
} armSRFieldMask;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This defines actions to be taken for unaligned memory accesses
|
|
||||||
//
|
|
||||||
typedef enum armUnalignedActionE {
|
|
||||||
ARM_UA_DABORT, // take data abort exception
|
|
||||||
ARM_UA_ROTATE, // rotate if unaligned (some ARMv4 and ARMv5 reads)
|
|
||||||
ARM_UA_ALIGN, // force alignment
|
|
||||||
ARM_UA_UNALIGNED, // allow unaligned access
|
|
||||||
} armUnalignedAction;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This specifies the effect on any interrupt flags of this instruction
|
|
||||||
//
|
|
||||||
typedef enum armFlagActionE {
|
|
||||||
ARM_FACT_NA = 0, // no flag action
|
|
||||||
ARM_FACT_BAD = 1, // (illegal value)
|
|
||||||
ARM_FACT_IE = 2, // interrupts enabled
|
|
||||||
ARM_FACT_ID = 3 // interrupts disabled
|
|
||||||
} armFlagAction;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This specifies flags affected by this instruction
|
|
||||||
//
|
|
||||||
typedef enum armFlagAffectE {
|
|
||||||
ARM_FAFF_NA = 0x0, // no flags affected
|
|
||||||
ARM_FAFF_F = 0x1, // F flag affected
|
|
||||||
ARM_FAFF_I = 0x2, // I flag affected
|
|
||||||
ARM_FAFF_A = 0x4, // A flag affected
|
|
||||||
} armFlagAffect;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This specifies system registers for MSR/MRS
|
|
||||||
//
|
|
||||||
typedef enum armSysRegIdE {
|
|
||||||
ASRID_APSR = 0,
|
|
||||||
ASRID_IAPSR = 1,
|
|
||||||
ASRID_EAPSR = 2,
|
|
||||||
ASRID_XPSR = 3,
|
|
||||||
ASRID_IPSR = 5,
|
|
||||||
ASRID_EPSR = 6,
|
|
||||||
ASRID_IEPSR = 7,
|
|
||||||
ASRID_MSP = 8,
|
|
||||||
ASRID_PSP = 9,
|
|
||||||
ASRID_PRIMASK = 16,
|
|
||||||
ASRID_BASEPRI = 17,
|
|
||||||
ASRID_BASEPRI_MAX = 18,
|
|
||||||
ASRID_FAULTMASK = 19,
|
|
||||||
ASRID_CONTROL = 20
|
|
||||||
} armSysRegId;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This specifies bits specified by mask field of MSR
|
|
||||||
//
|
|
||||||
typedef enum armPSRBitsE {
|
|
||||||
ARM_PSRBITS_NA = 0, // no bits specified
|
|
||||||
ARM_PSRBITS_GE = 1, // GE only, no flags
|
|
||||||
ARM_PSRBITS_FLAGS = 2, // Flags only, no GE
|
|
||||||
ARM_PSRBITS_ALL = 3, // GE and flags
|
|
||||||
} armPSRBits;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This specifies SIMD/VFP type
|
|
||||||
//
|
|
||||||
typedef enum armSDFPTypeE {
|
|
||||||
ARM_SDFPT_NA, // no SIMD/VFP type
|
|
||||||
ARM_SDFPT_8, // 8 bit value - type not specified
|
|
||||||
ARM_SDFPT_16, // 16 bit value - type not specified
|
|
||||||
ARM_SDFPT_32, // 32 bit value - type not specified
|
|
||||||
ARM_SDFPT_64, // 64 bit value - type not specified
|
|
||||||
ARM_SDFPT_F16, // floating point 16 bit value
|
|
||||||
ARM_SDFPT_F32, // floating point 32 bit value
|
|
||||||
ARM_SDFPT_F64, // floating point 64 bit value
|
|
||||||
ARM_SDFPT_I8, // integer 8 bit value
|
|
||||||
ARM_SDFPT_I16, // integer 16 bit value
|
|
||||||
ARM_SDFPT_I32, // integer 32 bit value
|
|
||||||
ARM_SDFPT_I64, // integer 64 bit value
|
|
||||||
ARM_SDFPT_P8, // polynomial 8 bit value
|
|
||||||
ARM_SDFPT_S8, // signed 8 bit value
|
|
||||||
ARM_SDFPT_S16, // signed 16 bit value
|
|
||||||
ARM_SDFPT_S32, // signed 32 bit value
|
|
||||||
ARM_SDFPT_S64, // signed 64 bit value
|
|
||||||
ARM_SDFPT_U8, // unsigned 8 bit value
|
|
||||||
ARM_SDFPT_U16, // unsigned 16 bit value
|
|
||||||
ARM_SDFPT_U32, // unsigned 32 bit value
|
|
||||||
ARM_SDFPT_U64, // unsigned 64 bit value
|
|
||||||
} armSDFPType;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Type to hold a modified immediate constant value for SIMD and VFP instructions
|
|
||||||
//
|
|
||||||
typedef union armSdfpMItypeU {
|
|
||||||
Uns64 u64;
|
|
||||||
Flt64 f64;
|
|
||||||
Flt32 f32;
|
|
||||||
struct {
|
|
||||||
Uns32 w0;
|
|
||||||
Uns32 w1;
|
|
||||||
} u32;
|
|
||||||
struct {
|
|
||||||
Uns16 h0;
|
|
||||||
Uns16 h1;
|
|
||||||
Uns16 h2;
|
|
||||||
Uns16 h3;
|
|
||||||
} u16;
|
|
||||||
struct {
|
|
||||||
Uns8 b0;
|
|
||||||
Uns8 b1;
|
|
||||||
Uns8 b2;
|
|
||||||
Uns8 b3;
|
|
||||||
Uns8 b4;
|
|
||||||
Uns8 b5;
|
|
||||||
Uns8 b6;
|
|
||||||
Uns8 b7;
|
|
||||||
} u8;
|
|
||||||
} armSdfpMItype;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This specifies instruction support implied by ISAR registers
|
|
||||||
//
|
|
||||||
typedef enum armISARSupportE {
|
|
||||||
ARM_ISAR_NA = 0, // no ISAR restriction
|
|
||||||
ARM_ISAR_DIV, // SDIV/UDIV support
|
|
||||||
ARM_ISAR_BKPT, // BKPT support
|
|
||||||
ARM_ISAR_CBZ, // CBZ/CBNZ support
|
|
||||||
ARM_ISAR_BFC, // BFC/BFI/SBFX/UBFX support
|
|
||||||
ARM_ISAR_CLZ, // CLZ support
|
|
||||||
ARM_ISAR_SWP, // SWP/SWPB support
|
|
||||||
ARM_ISAR_BXJ, // BXJ support
|
|
||||||
ARM_ISAR_BX, // BX support
|
|
||||||
ARM_ISAR_BLX, // BX support
|
|
||||||
ARM_ISAR_MOVT, // MOVT/MOV(16)/ADD(12) etc support
|
|
||||||
ARM_ISAR_IT, // IT support
|
|
||||||
ARM_ISAR_SXTB, // SXTB/SXTH/UXTB/UXTH support
|
|
||||||
ARM_ISAR_SXTAB, // SXTAB/SXTAH/UXTAB/UXTAH support
|
|
||||||
ARM_ISAR_SXTB16, // SXTB16/SXTAB16/UXTB16/UXTAB16 support
|
|
||||||
ARM_ISAR_SRS, // SRS/RFE and A/R profile CPS
|
|
||||||
ARM_ISAR_LDM_UR, // user mode LDM/STM, exception return LDM
|
|
||||||
ARM_ISAR_SETEND, // SETEND support
|
|
||||||
ARM_ISAR_REV, // REV/REV16/REVSH support
|
|
||||||
ARM_ISAR_RBIT, // RBIT support
|
|
||||||
ARM_ISAR_MRS_AR, // A/R profile MRS/MSR and exception return support
|
|
||||||
ARM_ISAR_UMULL, // UMULL/UMLAL support
|
|
||||||
ARM_ISAR_UMAAL, // UMAAL support
|
|
||||||
ARM_ISAR_SMULL, // SMULL/SMLAL support
|
|
||||||
ARM_ISAR_SMLABB, // SMLABB/SMLABT ... SMULWB/SMULWT support
|
|
||||||
ARM_ISAR_SMLAD, // SMLAD/SMLADX ... SMUSD/SMUSDX support
|
|
||||||
ARM_ISAR_MLA, // MLA support
|
|
||||||
ARM_ISAR_MLS, // MLS support
|
|
||||||
ARM_ISAR_PLD, // PLD support
|
|
||||||
ARM_ISAR_PLI, // PLI support
|
|
||||||
ARM_ISAR_LDRD, // LDRD/STRD support
|
|
||||||
ARM_ISAR_NOP, // NOP support
|
|
||||||
ARM_ISAR_MOVLL, // Thumb MOV low->low support
|
|
||||||
ARM_ISAR_TBB, // TBB/TBH support
|
|
||||||
ARM_ISAR_LDREX, // LDREX/STREX support
|
|
||||||
ARM_ISAR_CLREX, // CLREX/LDREXB/LDREXH/STREXB/STREXH support
|
|
||||||
ARM_ISAR_LDREXD, // LDREXD/STREXD support
|
|
||||||
ARM_ISAR_SVC, // SVC support
|
|
||||||
ARM_ISAR_SSAT, // SSAT/USAT support
|
|
||||||
ARM_ISAR_PKHBT, // PKHBT/PKHTB ... USUB8/USAX support
|
|
||||||
ARM_ISAR_QADD, // QADD/QDADD/QDSUB/QSUB support
|
|
||||||
ARM_ISAR_MRS_M, // M profile CPS/MRS/MSR support
|
|
||||||
ARM_ISAR_DMB, // DMB/DSB/ISB support
|
|
||||||
ARM_ISAR_LDRBT, // LDRBT/LDRT/STRBT/STRT support
|
|
||||||
ARM_ISAR_LDRHT, // LDRHT/LDRSBT/LDRSHT/STRHT support
|
|
||||||
ARM_ISAR_VMRS, // load, store, cp moves to SIMD regs supported (VFP2,VFP3,SIMD)
|
|
||||||
ARM_ISAR_VFPSQRT, // VFP VSQRT support
|
|
||||||
ARM_ISAR_VFPDIV, // VFP VDIV support
|
|
||||||
ARM_ISAR_VFPV3, // VFP v3-only support (also check double/single precision support)
|
|
||||||
ARM_ISAR_VFPV2, // VFP v2 and later support (also check double/single precision support)
|
|
||||||
ARM_ISAR_VFPFMAC, // VFP fused multilply accumulate support
|
|
||||||
ARM_ISAR_VFPCVT3, // VFP v3-only conversion support
|
|
||||||
ARM_ISAR_VFPCVT2, // VFP v2 and later conversion support
|
|
||||||
ARM_ISAR_VFPHP, // VFP half precision convert support
|
|
||||||
} armISARSupport;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This structure is filled with information extracted from the decoded
|
|
||||||
// instruction
|
|
||||||
//
|
|
||||||
typedef struct armInstructionInfoS {
|
|
||||||
const char *opcode; // opcode name
|
|
||||||
const char *format; // disassembly format string
|
|
||||||
armArchitecture support; // variants on which instruction supported
|
|
||||||
armISARSupport isar; // ISAR instruction support
|
|
||||||
Uns32 thisPC; // instruction address
|
|
||||||
Uns32 instruction; // instruction word
|
|
||||||
armInstructionType type; // instruction type
|
|
||||||
armCondition cond; // condition under which instruction executes
|
|
||||||
armSetFlags f; // set flags?
|
|
||||||
armShiftOp so; // shifter operation to apply to arg 2
|
|
||||||
armIncDec incDec; // increment/decrement action
|
|
||||||
Uns32 c; // constant value
|
|
||||||
Uns32 t; // target address
|
|
||||||
Uns32 rList; // register list
|
|
||||||
Uns8 crotate; // constant rotation from instruction
|
|
||||||
Uns8 bytes; // instruction size in bytes (1, 2 or 4)
|
|
||||||
Uns8 r1; // register 1
|
|
||||||
Uns8 r2; // register 2
|
|
||||||
Uns8 r3; // register 3
|
|
||||||
Uns8 r4; // register 4
|
|
||||||
Uns8 sz; // load/store size
|
|
||||||
Int8 w; // bit operation width
|
|
||||||
Uns8 cpNum; // coprocessor number
|
|
||||||
Uns8 cpOp1; // coprocessor opcode1
|
|
||||||
Uns8 cpOp2; // coprocessor opcode2
|
|
||||||
Bool xs; // sign extend?
|
|
||||||
Bool tl; // translate?
|
|
||||||
Bool pi; // post-indexed?
|
|
||||||
Bool wb; // instruction specifies writeback?
|
|
||||||
Bool u; // instruction U bit set?
|
|
||||||
Bool ll; // instruction specifies long load?
|
|
||||||
Bool ea; // load/store is exclusive access?
|
|
||||||
armUnalignedAction ua; // unaligned action
|
|
||||||
Bool ma; // mode action (CPS)
|
|
||||||
armFlagAction fact; // flag action (CPS)
|
|
||||||
armFlagAffect faff; // flags affected (CPS)
|
|
||||||
armPSRBits psrbits; // MSR instruction bits value
|
|
||||||
Uns8 it; // IT block specification
|
|
||||||
Uns8 index; // index for VFP scalars
|
|
||||||
Uns8 nregs; // number of registers for vfp register lists
|
|
||||||
armSDFPType dt1; // VFP first data type
|
|
||||||
armSDFPType dt2; // VFP second data type
|
|
||||||
armSdfpMItype sdfpMI; // VFP modified immediate constant value
|
|
||||||
} armInstructionInfo;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_DISASSEMBLE_H
|
|
||||||
#define ARM_DISASSEMBLE_H
|
|
||||||
|
|
||||||
// basic number types
|
|
||||||
#include "hostapi/impTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// ARM disassembler, decoded instruction interface
|
|
||||||
//
|
|
||||||
const char *armDisassembleInfo(armP arm, armInstructionInfoP info);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,213 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_DISASSEMBLE_FORMATS_H
|
|
||||||
#define ARM_DISASSEMBLE_FORMATS_H
|
|
||||||
|
|
||||||
//
|
|
||||||
// These are placeholders in disassembly decoder
|
|
||||||
//
|
|
||||||
#define EMIT_R1 '\001'
|
|
||||||
#define EMIT_R2 '\002'
|
|
||||||
#define EMIT_R3 '\003'
|
|
||||||
#define EMIT_R4 '\004'
|
|
||||||
#define EMIT_CU '\005'
|
|
||||||
#define EMIT_CS '\006'
|
|
||||||
#define EMIT_CX '\007'
|
|
||||||
#define EMIT_T '\010'
|
|
||||||
#define EMIT_SHIFT '\011'
|
|
||||||
#define EMIT_SHIFT_C '\012'
|
|
||||||
#define EMIT_CPNUM '\013'
|
|
||||||
#define EMIT_COP1 '\014'
|
|
||||||
#define EMIT_COP2 '\015'
|
|
||||||
#define EMIT_CR1 '\016'
|
|
||||||
#define EMIT_CR2 '\017'
|
|
||||||
#define EMIT_CR3 '\020'
|
|
||||||
#define EMIT_OPT '\021'
|
|
||||||
#define EMIT_WB '\022'
|
|
||||||
#define EMIT_RLIST '\023'
|
|
||||||
#define EMIT_U '\024'
|
|
||||||
#define EMIT_SR '\025'
|
|
||||||
#define EMIT_FLAGS '\026'
|
|
||||||
#define EMIT_OPT_MODE '\027'
|
|
||||||
#define EMIT_LIM '\031'
|
|
||||||
#define EMIT_WIDTH '\032'
|
|
||||||
#define EMIT_ITC '\033'
|
|
||||||
#define EMIT_SZSHIFT '\034'
|
|
||||||
#define EMIT_R1F '\035'
|
|
||||||
#define EMIT_FPSCR '\036'
|
|
||||||
#define EMIT_S1 '\302'
|
|
||||||
#define EMIT_S2 '\303'
|
|
||||||
#define EMIT_S3 '\304'
|
|
||||||
#define EMIT_D1 '\305'
|
|
||||||
#define EMIT_D2 '\306'
|
|
||||||
#define EMIT_D3 '\307'
|
|
||||||
#define EMIT_Z1 '\313'
|
|
||||||
#define EMIT_Z2 '\314'
|
|
||||||
#define EMIT_SS1 '\316'
|
|
||||||
#define EMIT_SS3 '\317'
|
|
||||||
#define EMIT_C0F '\324'
|
|
||||||
#define EMIT_SDFP_MI '\325'
|
|
||||||
#define EMIT_SIMD_RL '\326'
|
|
||||||
#define EMIT_VFP_RL '\327'
|
|
||||||
|
|
||||||
//
|
|
||||||
// These are placeholders in disassembly format strings
|
|
||||||
//
|
|
||||||
#define EMIT_R1_S "\001"
|
|
||||||
#define EMIT_R2_S "\002"
|
|
||||||
#define EMIT_R3_S "\003"
|
|
||||||
#define EMIT_R4_S "\004"
|
|
||||||
#define EMIT_CU_S "\005"
|
|
||||||
#define EMIT_CS_S "\006"
|
|
||||||
#define EMIT_CX_S "\007"
|
|
||||||
#define EMIT_T_S "\010"
|
|
||||||
#define EMIT_SHIFT_S "\011"
|
|
||||||
#define EMIT_SHIFT_C_S "\012"
|
|
||||||
#define EMIT_CPNUM_S "\013"
|
|
||||||
#define EMIT_COP1_S "\014"
|
|
||||||
#define EMIT_COP2_S "\015"
|
|
||||||
#define EMIT_CR1_S "\016"
|
|
||||||
#define EMIT_CR2_S "\017"
|
|
||||||
#define EMIT_CR3_S "\020"
|
|
||||||
#define EMIT_OPT_S "\021"
|
|
||||||
#define EMIT_WB_S "\022"
|
|
||||||
#define EMIT_RLIST_S "\023"
|
|
||||||
#define EMIT_U_S "\024"
|
|
||||||
#define EMIT_SR_S "\025"
|
|
||||||
#define EMIT_FLAGS_S "\026"
|
|
||||||
#define EMIT_OPT_MODE_S "\027"
|
|
||||||
#define EMIT_LIM_S "\031"
|
|
||||||
#define EMIT_WIDTH_S "\032"
|
|
||||||
#define EMIT_ITC_S "\033"
|
|
||||||
#define EMIT_SZSHIFT_S "\034"
|
|
||||||
#define EMIT_R1F_S "\035"
|
|
||||||
#define EMIT_FPSCR_S "\036"
|
|
||||||
#define EMIT_S1_S "\302"
|
|
||||||
#define EMIT_S2_S "\303"
|
|
||||||
#define EMIT_S3_S "\304"
|
|
||||||
#define EMIT_D1_S "\305"
|
|
||||||
#define EMIT_D2_S "\306"
|
|
||||||
#define EMIT_D3_S "\307"
|
|
||||||
#define EMIT_Z1_S "\313"
|
|
||||||
#define EMIT_Z2_S "\314"
|
|
||||||
#define EMIT_SS1_S "\316"
|
|
||||||
#define EMIT_SS3_S "\317"
|
|
||||||
#define EMIT_C0F_S "\324"
|
|
||||||
#define EMIT_SDFP_MI_S "\325"
|
|
||||||
#define EMIT_SIMD_RL_S "\326"
|
|
||||||
#define EMIT_VFP_RL_S "\327"
|
|
||||||
|
|
||||||
//
|
|
||||||
// These are disassembly format strings
|
|
||||||
//
|
|
||||||
#define FMT_NONE ""
|
|
||||||
#define FMT_R1 EMIT_R1_S
|
|
||||||
#define FMT_R1_R2 EMIT_R1_S "," EMIT_R2_S
|
|
||||||
#define FMT_R1_R2_R3 EMIT_R1_S "," EMIT_R2_S "," EMIT_R3_S
|
|
||||||
#define FMT_R1_R2_R3_R4 EMIT_R1_S "," EMIT_R2_S "," EMIT_R3_S "," EMIT_R4_S
|
|
||||||
#define FMT_XIMM EMIT_CX_S
|
|
||||||
#define FMT_SIMM EMIT_CS_S
|
|
||||||
#define FMT_UIMM EMIT_CU_S
|
|
||||||
#define FMT_R1_SIMM EMIT_R1_S "," EMIT_CS_S
|
|
||||||
#define FMT_R1_UIMM EMIT_R1_S "," EMIT_CU_S
|
|
||||||
#define FMT_R1_R2_SIMM EMIT_R1_S "," EMIT_R2_S "," EMIT_CS_S
|
|
||||||
#define FMT_R1_R2_UIMM EMIT_R1_S "," EMIT_R2_S "," EMIT_CU_S
|
|
||||||
#define FMT_R1_R2_SHIFT_SIMM EMIT_R1_S "," EMIT_R2_S "," EMIT_SHIFT_C_S
|
|
||||||
#define FMT_R1_R2_SHIFT_R3 EMIT_R1_S "," EMIT_R2_S "," EMIT_SHIFT_S " " EMIT_R3_S
|
|
||||||
#define FMT_R1_R2_SHIFT EMIT_R1_S "," EMIT_R2_S "," EMIT_SHIFT_S
|
|
||||||
#define FMT_R1_R2_R3_SHIFT_SIMM EMIT_R1_S "," EMIT_R2_S "," EMIT_R3_S "," EMIT_SHIFT_C_S
|
|
||||||
#define FMT_R1_R2_R3_SHIFT_R4 EMIT_R1_S "," EMIT_R2_S "," EMIT_R3_S "," EMIT_SHIFT_S " " EMIT_R4_S
|
|
||||||
#define FMT_R1_R2_R3_SHIFT EMIT_R1_S "," EMIT_R2_S "," EMIT_R3_S "," EMIT_SHIFT_S
|
|
||||||
#define FMT_R1_WIDTH_R2 EMIT_R1_S "," EMIT_WIDTH_S "," EMIT_R2_S
|
|
||||||
#define FMT_R1_WIDTH_R2_SHIFT_SIMM EMIT_R1_S "," EMIT_WIDTH_S "," EMIT_R2_S "," EMIT_SHIFT_C_S
|
|
||||||
#define FMT_R1_ADDR_R2_SIMM EMIT_R1_S ",[" EMIT_R2_S "1],*" EMIT_CS_S "2]" EMIT_WB_S
|
|
||||||
#define FMT_R1_ADDR_R2_R3 EMIT_R1_S ",[" EMIT_R2_S "1]," EMIT_U_S EMIT_R3_S "2]" EMIT_WB_S
|
|
||||||
#define FMT_R1_ADDR_R2_R3_SHIFT_SIMM EMIT_R1_S ",[" EMIT_R2_S "1]," EMIT_U_S EMIT_R3_S "," EMIT_SHIFT_C_S "2]" EMIT_WB_S
|
|
||||||
#define FMT_R1_ADDR_R2_R3_SHIFT EMIT_R1_S ",[" EMIT_R2_S "1]," EMIT_U_S EMIT_R3_S "," EMIT_SHIFT_S "2]" EMIT_WB_S
|
|
||||||
#define FMT_R1_R4_ADDR_R2_SIMM EMIT_R1_S "," EMIT_R4_S ",[" EMIT_R2_S "1],*" EMIT_CS_S "2]" EMIT_WB_S
|
|
||||||
#define FMT_ADDR_R1_SIMM "[" EMIT_R1_S "1],*" EMIT_CS_S "2]" EMIT_WB_S
|
|
||||||
#define FMT_ADDR_R1_R2 "[" EMIT_R1_S "1]," EMIT_U_S EMIT_R2_S "2]" EMIT_WB_S
|
|
||||||
#define FMT_ADDR_R1_R2_SHIFT_SIMM "[" EMIT_R1_S "1]," EMIT_U_S EMIT_R2_S "," EMIT_SHIFT_C_S "2]" EMIT_WB_S
|
|
||||||
#define FMT_ADDR_R1_R2_SHIFT "[" EMIT_R1_S "1]," EMIT_U_S EMIT_R2_S "," EMIT_SHIFT_S "2]" EMIT_WB_S
|
|
||||||
#define FMT_R1_R2_ADDR_R3_SIMM EMIT_R1_S "," EMIT_R2_S ",[" EMIT_R3_S "1],*" EMIT_CS_S "2]"
|
|
||||||
#define FMT_R1_R2_R4_ADDR_R3_SIMM EMIT_R1_S "," EMIT_R2_S "," EMIT_R4_S ",[" EMIT_R3_S "1],*" EMIT_CS_S "2]"
|
|
||||||
#define FMT_R1_R4_ADDR_R2_SIMM EMIT_R1_S "," EMIT_R4_S ",[" EMIT_R2_S "1],*" EMIT_CS_S "2]" EMIT_WB_S
|
|
||||||
#define ADDR_R1_R2_SZSHIFT ",[" EMIT_R1_S "," EMIT_R2_S ",*" EMIT_SZSHIFT_S "]"
|
|
||||||
#define FMT_CPNUM_CR1_SIMM EMIT_CPNUM_S "," EMIT_CR1_S ",[" EMIT_R2_S "1],*" EMIT_CS_S "2]" EMIT_WB_S
|
|
||||||
#define FMT_CPNUM_CR1_UNINDEXED EMIT_CPNUM_S "," EMIT_CR1_S ",[" EMIT_R2_S "],{" EMIT_OPT_S "}"
|
|
||||||
#define FMT_SR_R1 EMIT_SR_S "," EMIT_R1_S
|
|
||||||
#define FMT_R1_SR EMIT_R1_S "," EMIT_SR_S
|
|
||||||
#define FMT_R1_WB EMIT_R1_S EMIT_WB_S
|
|
||||||
#define FMT_R1_WB_UIMM EMIT_R1_S EMIT_WB_S "," EMIT_CU_S
|
|
||||||
#define FMT_T EMIT_T_S
|
|
||||||
#define FMT_R1_T EMIT_R1_S "," EMIT_T_S
|
|
||||||
#define FMT_CPNUM_COP1_CR1_CR2_CR3_COP2 EMIT_CPNUM_S "," EMIT_COP1_S "," EMIT_CR1_S "," EMIT_CR2_S "," EMIT_CR3_S ",{" EMIT_COP2_S "}"
|
|
||||||
#define FMT_CPNUM_COP1_R1_R2_CR3 EMIT_CPNUM_S "," EMIT_COP1_S "," EMIT_R1_S "," EMIT_R2_S "," EMIT_CR3_S
|
|
||||||
#define FMT_CPNUM_COP1_R1_CR2_CR3_COP2 EMIT_CPNUM_S "," EMIT_COP1_S "," EMIT_R1_S "," EMIT_CR2_S "," EMIT_CR3_S ",{" EMIT_COP2_S "}"
|
|
||||||
#define FMT_CPNUM_COP1_R1F_CR2_CR3_COP2 EMIT_CPNUM_S "," EMIT_COP1_S "," EMIT_R1F_S "," EMIT_CR2_S "," EMIT_CR3_S ",{" EMIT_COP2_S "}"
|
|
||||||
#define FMT_RLIST EMIT_RLIST_S
|
|
||||||
#define FMT_SIMD_RL EMIT_SIMD_RL_S
|
|
||||||
#define FMT_VFP_RL EMIT_VFP_RL_S
|
|
||||||
#define FMT_R1_RLIST EMIT_R1_S EMIT_WB_S "," EMIT_RLIST_S
|
|
||||||
#define FMT_R1_RLIST_T EMIT_R1_S "!," EMIT_RLIST_S
|
|
||||||
#define FMT_R1_RLIST_UM EMIT_R1_S EMIT_WB_S "," EMIT_RLIST_S "^"
|
|
||||||
#define FMT_R1_VFP_RL EMIT_R1_S EMIT_WB_S "," EMIT_VFP_RL_S
|
|
||||||
#define FMT_R1_SIMD_RL EMIT_R1_S EMIT_WB_S "," EMIT_SIMD_RL_S
|
|
||||||
#define FMT_FLAGS_OPT_MODE EMIT_FLAGS_S ",*" EMIT_OPT_MODE_S
|
|
||||||
#define FMT_LIM EMIT_LIM_S
|
|
||||||
#define FMT_R1_R2_LSB_WIDTH EMIT_R1_S "," EMIT_R2_S "," EMIT_CU_S "," EMIT_WIDTH_S
|
|
||||||
#define FMT_R1_LSB_WIDTH EMIT_R1_S "," EMIT_CU_S "," EMIT_WIDTH_S
|
|
||||||
#define FMT_ITC EMIT_ITC_S
|
|
||||||
#define FMT_R1_FPSCR EMIT_R1F_S "," EMIT_FPSCR_S
|
|
||||||
#define FMT_FPSCR_R1 EMIT_FPSCR_S "," EMIT_R1_S
|
|
||||||
#define FMT_R1_S2 EMIT_R1_S "," EMIT_S2_S
|
|
||||||
#define FMT_R1_Z2 EMIT_R1_S "," EMIT_Z2_S
|
|
||||||
#define FMT_S1_F0 EMIT_S1_S "," EMIT_C0F_S
|
|
||||||
#define FMT_S1_S2 EMIT_S1_S "," EMIT_S2_S
|
|
||||||
#define FMT_S1_R2 EMIT_S1_S "," EMIT_R2_S
|
|
||||||
#define FMT_S1_S2_S3 EMIT_S1_S "," EMIT_S2_S "," EMIT_S3_S
|
|
||||||
#define FMT_S1_S2_UIMM EMIT_S1_S "," EMIT_S2_S "," EMIT_CU_S
|
|
||||||
#define FMT_S1_SDFP_MI EMIT_S1_S "," EMIT_SDFP_MI_S
|
|
||||||
#define FMT_S1_ADDR_R2_SIMM EMIT_S1_S ",[" EMIT_R2_S "1],*" EMIT_CS_S "2]"
|
|
||||||
#define FMT_S1_SDFP_MI EMIT_S1_S "," EMIT_SDFP_MI_S
|
|
||||||
#define FMT_Z1_R2 EMIT_Z1_S "," EMIT_R2_S
|
|
||||||
#define FMT_R1_R2_D3 EMIT_R1_S "," EMIT_R2_S "," EMIT_D3_S
|
|
||||||
#define FMT_D1_R2_R3 EMIT_D1_S "," EMIT_R2_S "," EMIT_R3_S
|
|
||||||
#define FMT_D1_ADDR_R2_SIMM EMIT_D1_S ",[" EMIT_R2_S "1],*" EMIT_CS_S "2]"
|
|
||||||
#define FMT_R1_R2_SS3 EMIT_R1_S "," EMIT_R2_S "," EMIT_SS3_S
|
|
||||||
#define FMT_SS1_R2_R3 EMIT_SS1_S "," EMIT_R2_S "," EMIT_R3_S
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,540 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_EMIT_H
|
|
||||||
#define ARM_EMIT_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armMode.h"
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// INTERWORKING
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit code to interwork if required, depending on LSB of target address
|
|
||||||
//
|
|
||||||
void armEmitInterworkLSB(armMorphStateP state, vmiReg ra);
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// INTEGER OPCODES
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd = simPC (true)
|
|
||||||
//
|
|
||||||
void armEmitGetTruePC(armMorphStateP state, vmiReg rd);
|
|
||||||
|
|
||||||
//
|
|
||||||
// r15 = simPC (accoring to ARM pipeline)
|
|
||||||
//
|
|
||||||
void armEmitGetPC(armMorphStateP state);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd = c
|
|
||||||
//
|
|
||||||
void armEmitMoveRC(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiReg rd,
|
|
||||||
Uns64 c
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd = ra
|
|
||||||
//
|
|
||||||
void armEmitMoveRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiReg rd,
|
|
||||||
vmiReg ra
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd<destBits> = ra<srcBits>
|
|
||||||
//
|
|
||||||
void armEmitMoveExtendRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 destBits,
|
|
||||||
vmiReg rd,
|
|
||||||
Uns32 srcBits,
|
|
||||||
vmiReg ra,
|
|
||||||
Bool signExtend
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd = (flag==select1) ? c1 : c2
|
|
||||||
//
|
|
||||||
void armEmitCondMoveRCC(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiReg flag,
|
|
||||||
Bool select1,
|
|
||||||
vmiReg rd,
|
|
||||||
Uns64 c1,
|
|
||||||
Uns64 c2
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd = <unop> ra
|
|
||||||
//
|
|
||||||
void armEmitUnopRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiUnop op,
|
|
||||||
vmiReg rd,
|
|
||||||
vmiReg ra,
|
|
||||||
vmiFlagsCP flags
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd = <unop> c
|
|
||||||
//
|
|
||||||
void armEmitUnopRC(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiUnop op,
|
|
||||||
vmiReg rd,
|
|
||||||
Uns64 c,
|
|
||||||
vmiFlagsCP flags
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd = rd <binop> ra
|
|
||||||
//
|
|
||||||
void armEmitBinopRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiBinop op,
|
|
||||||
vmiReg rd,
|
|
||||||
vmiReg ra,
|
|
||||||
vmiFlagsCP flags
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd = rd <binop> c
|
|
||||||
//
|
|
||||||
void armEmitBinopRC(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiBinop op,
|
|
||||||
vmiReg rd,
|
|
||||||
Uns64 c,
|
|
||||||
vmiFlagsCP flags
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd = ra <binop> rb
|
|
||||||
//
|
|
||||||
void armEmitBinopRRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiBinop op,
|
|
||||||
vmiReg rd,
|
|
||||||
vmiReg ra,
|
|
||||||
vmiReg rb,
|
|
||||||
vmiFlagsCP flags
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd = ra <binop> c
|
|
||||||
//
|
|
||||||
void armEmitBinopRRC(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiBinop op,
|
|
||||||
vmiReg rd,
|
|
||||||
vmiReg ra,
|
|
||||||
Uns64 c,
|
|
||||||
vmiFlagsCP flags
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Generate shift mask prefix (sets mask to 255)
|
|
||||||
//
|
|
||||||
void armEmitSetShiftMask(void);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rdh:rdl = ra*rb
|
|
||||||
//
|
|
||||||
void armEmitMulopRRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiBinop op,
|
|
||||||
vmiReg rdh,
|
|
||||||
vmiReg rdl,
|
|
||||||
vmiReg ra,
|
|
||||||
vmiReg rb,
|
|
||||||
vmiFlagsCP flags
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// FLOATING POINT OPCODES
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// fd = fa <fp ternnop> fb fc
|
|
||||||
//
|
|
||||||
void armEmitFTernopSimdRRRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
vmiFType type,
|
|
||||||
Uns32 num,
|
|
||||||
vmiFTernop op,
|
|
||||||
vmiReg fd,
|
|
||||||
vmiReg fa,
|
|
||||||
vmiReg fb,
|
|
||||||
vmiReg fc,
|
|
||||||
Bool roundInt
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// fd = fa <binop> fb
|
|
||||||
//
|
|
||||||
void armEmitFBinopSimdRRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
vmiFType type,
|
|
||||||
Uns32 num,
|
|
||||||
vmiFBinop op,
|
|
||||||
vmiReg fd,
|
|
||||||
vmiReg fa,
|
|
||||||
vmiReg fb
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// fd = <unop> fa
|
|
||||||
//
|
|
||||||
void armEmitFUnopSimdRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
vmiFType type,
|
|
||||||
Uns32 num,
|
|
||||||
vmiFUnop op,
|
|
||||||
vmiReg fd,
|
|
||||||
vmiReg fa
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// fd = <fp convert> fa
|
|
||||||
//
|
|
||||||
void armEmitFConvertRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
vmiFType destType,
|
|
||||||
vmiReg fd,
|
|
||||||
vmiFType srcType,
|
|
||||||
vmiReg fa,
|
|
||||||
vmiFPRC round
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// compare fa to fb, setting relation and flags
|
|
||||||
//
|
|
||||||
void armEmitFCompareRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
vmiFType type,
|
|
||||||
vmiReg relation,
|
|
||||||
vmiReg fa,
|
|
||||||
vmiReg fb,
|
|
||||||
Bool allowQNaN,
|
|
||||||
Bool setSticky
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// LOAD AND STORE OPCODES
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// mem[ra+offset] = rb (when ra!=VMI_NOREG)
|
|
||||||
// mem[offset] = rb (when ra==VMI_NOREG)
|
|
||||||
//
|
|
||||||
void armEmitStoreRRO(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
Uns32 offset,
|
|
||||||
vmiReg ra,
|
|
||||||
vmiReg rb
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// mem[ra+offset] = rbH:rbL (when ra!=VMI_NOREG)
|
|
||||||
// mem[offset] = rbH:rbL (when ra==VMI_NOREG)
|
|
||||||
//
|
|
||||||
void armEmitStoreRRRO(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
Uns32 offset,
|
|
||||||
vmiReg ra,
|
|
||||||
vmiReg rbL,
|
|
||||||
vmiReg rbH
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rd = mem[ra+offset] (when ra!=VMI_NOREG)
|
|
||||||
// rd = mem[offset] (when ra==VMI_NOREG)
|
|
||||||
//
|
|
||||||
void armEmitLoadRRO(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
Uns32 offset,
|
|
||||||
vmiReg rd,
|
|
||||||
vmiReg ra,
|
|
||||||
Bool signExtend,
|
|
||||||
Bool isReturn
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// rdH:rdL = mem[ra+offset] (when ra!=VMI_NOREG)
|
|
||||||
// rdH:rdL = mem[offset] (when ra==VMI_NOREG)
|
|
||||||
//
|
|
||||||
void armEmitLoadRRRO(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
Uns32 offset,
|
|
||||||
vmiReg rdL,
|
|
||||||
vmiReg rdH,
|
|
||||||
vmiReg ra,
|
|
||||||
vmiReg rt,
|
|
||||||
Bool signExtend,
|
|
||||||
Bool isReturn
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// trystore mem[ra+offset] (when ra!=VMI_NOREG)
|
|
||||||
// trystore mem[offset] (when ra==VMI_NOREG)
|
|
||||||
//
|
|
||||||
void armEmitTryStoreRC(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
Addr offset,
|
|
||||||
vmiReg ra
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// COMPARE OPERATIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// flag = ra <cond> rb
|
|
||||||
//
|
|
||||||
void armEmitCompareRR(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiCondition cond,
|
|
||||||
vmiReg ra,
|
|
||||||
vmiReg rb,
|
|
||||||
vmiReg flag
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// flag = ra <cond> c
|
|
||||||
//
|
|
||||||
void armEmitCompareRC(
|
|
||||||
armMorphStateP state,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiCondition cond,
|
|
||||||
vmiReg ra,
|
|
||||||
Uns64 c,
|
|
||||||
vmiReg flag
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// INTER-INSTRUCTION CONDITIONAL AND UNCONDITIONAL JUMPS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Structure holding information about a jump
|
|
||||||
//
|
|
||||||
typedef struct armJumpInfoS {
|
|
||||||
vmiReg linkReg; // link register
|
|
||||||
vmiJumpHint hint; // call hint
|
|
||||||
Uns32 linkPC; // address to put in link register
|
|
||||||
} armJumpInfo, *armJumpInfoP;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Perform an unconditional direct jump.
|
|
||||||
//
|
|
||||||
void armEmitUncondJump(
|
|
||||||
armMorphStateP state,
|
|
||||||
armJumpInfoP ji
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Perform an unconditional indirect jump.
|
|
||||||
//
|
|
||||||
void armEmitUncondJumpReg(
|
|
||||||
armMorphStateP state,
|
|
||||||
armJumpInfoP ji,
|
|
||||||
vmiReg toReg
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Perform a conditional direct jump if the condition flag is non-zero
|
|
||||||
// (jumpIfTrue) or zero (not jumpIfTrue).
|
|
||||||
//
|
|
||||||
void armEmitCondJump(
|
|
||||||
armMorphStateP state,
|
|
||||||
armJumpInfoP ji,
|
|
||||||
vmiReg flag,
|
|
||||||
Bool jumpIfTrue
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Perform an implicit unconditional direct jump if required
|
|
||||||
//
|
|
||||||
void armEmitImplicitUncondJump(armMorphStateP state);
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// INTRA-INSTRUCTION CONDITIONAL AND UNCONDITIONAL JUMPS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Create and return a new label.
|
|
||||||
//
|
|
||||||
vmiLabelP armEmitNewLabel(void);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Insert a label previously created by vmimtNewLabel at the current location.
|
|
||||||
//
|
|
||||||
void armEmitInsertLabel(vmiLabelP label);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Perform an unconditional jump to the passed local label.
|
|
||||||
//
|
|
||||||
void armEmitUncondJumpLabel(vmiLabelP toLabel);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Perform a conditional jump if the condition flag is non-zero (jumpIfTrue)
|
|
||||||
// or zero (not jumpIfTrue). The target location is the passed local label.
|
|
||||||
//
|
|
||||||
void armEmitCondJumpLabel(vmiReg flag, Bool jumpIfTrue, vmiLabelP toLabel);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Test the register value by performing bitwise AND with the passed constant
|
|
||||||
// value, and jump to 'toLabel' if condition 'cond' is satisfied.
|
|
||||||
//
|
|
||||||
void armEmitTestRCJumpLabel(
|
|
||||||
Uns32 bits,
|
|
||||||
vmiCondition cond,
|
|
||||||
vmiReg r,
|
|
||||||
Uns64 c,
|
|
||||||
vmiLabelP toLabel
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Compare the register value by performing subtraction of the passed constant
|
|
||||||
// value, and jump to 'toLabel' if condition 'cond' is satisfied.
|
|
||||||
//
|
|
||||||
void armEmitCompareRCJumpLabel(
|
|
||||||
Uns32 bits,
|
|
||||||
vmiCondition cond,
|
|
||||||
vmiReg r,
|
|
||||||
Uns64 c,
|
|
||||||
vmiLabelP toLabel
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//// CALLBACK FUNCTION INTERFACE
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add processor argument to the stack frame
|
|
||||||
//
|
|
||||||
void armEmitArgProcessor(armMorphStateP state);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add Uns32 argument to the stack frame
|
|
||||||
//
|
|
||||||
void armEmitArgUns32(armMorphStateP state, Uns32 arg);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add register argument to the stack frame
|
|
||||||
//
|
|
||||||
void armEmitArgReg(armMorphStateP state, Uns32 bits, vmiReg r);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add program counter argument to the stack frame
|
|
||||||
//
|
|
||||||
void armEmitArgSimPC(armMorphStateP state, Uns32 bits);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Make a call with all current stack frame arguments
|
|
||||||
//
|
|
||||||
void armEmitCall(armMorphStateP state, vmiCallFn arg);
|
|
||||||
|
|
||||||
//
|
|
||||||
// As above but generate a function result (placed in rd)
|
|
||||||
//
|
|
||||||
void armEmitCallResult(
|
|
||||||
armMorphStateP state,
|
|
||||||
vmiCallFn arg,
|
|
||||||
Uns32 bits,
|
|
||||||
vmiReg rd
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// SIMULATOR CONTROL
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Stop simulation of the current processor
|
|
||||||
//
|
|
||||||
void armEmitExit(void);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit code to wait for the passed reason
|
|
||||||
//
|
|
||||||
void armEmitWait(armMorphStateP state, armDisable reason);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Terminate the current block
|
|
||||||
//
|
|
||||||
void armEmitEndBlock(void);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit code to validate the current block mode
|
|
||||||
//
|
|
||||||
void armEmitValidateBlockMask(armBlockMask blockMask);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,120 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_EXCEPTION_TYPES_H
|
|
||||||
#define ARM_EXCEPTION_TYPES_H
|
|
||||||
|
|
||||||
//
|
|
||||||
// This enumerates exceptions
|
|
||||||
//
|
|
||||||
typedef enum armExceptNumE {
|
|
||||||
AEN_None = 0,
|
|
||||||
AEN_Reset = 1,
|
|
||||||
AEN_NMI = 2,
|
|
||||||
AEN_HardFault = 3,
|
|
||||||
AEN_MemManage = 4,
|
|
||||||
AEN_BusFault = 5,
|
|
||||||
AEN_UsageFault = 6,
|
|
||||||
AEN_SVCall = 11,
|
|
||||||
AEN_DebugMonitor = 12,
|
|
||||||
AEN_PendSV = 14,
|
|
||||||
AEN_SysTick = 15,
|
|
||||||
AEN_ExternalInt0 = 16,
|
|
||||||
AEN_LAST = 512 // KEEP LAST: for sizing
|
|
||||||
} armExceptNum;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This identifies whether the passed exception is an interrupt (and whether
|
|
||||||
// SCR.SLEEPONEXIT applies to this exception type)
|
|
||||||
//
|
|
||||||
#define EX_IS_INTERRUPT(_E) ((_E)>=AEN_PendSV)
|
|
||||||
|
|
||||||
//
|
|
||||||
// This enumerates the context of a load/store exception
|
|
||||||
//
|
|
||||||
typedef enum armExceptCxtE {
|
|
||||||
AEC_None = 0,
|
|
||||||
AEC_PushStack,
|
|
||||||
AEC_PopStack,
|
|
||||||
AEC_ReadVector,
|
|
||||||
AEC_PreserveFPState
|
|
||||||
} armExceptCxt;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This defines permanently-enabled exceptions
|
|
||||||
//
|
|
||||||
#define ARM_EXCEPT_PERMANENT_ENABLE ( \
|
|
||||||
(1 << AEN_Reset) | \
|
|
||||||
(1 << AEN_NMI) | \
|
|
||||||
(1 << AEN_HardFault) | \
|
|
||||||
(1 << AEN_SVCall) | \
|
|
||||||
(1 << AEN_PendSV) | \
|
|
||||||
(1 << AEN_SysTick) \
|
|
||||||
)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Utility macros for accessing exception bitmasks
|
|
||||||
//
|
|
||||||
#define EX_MASK_INDEX(_N) ((_N)/32)
|
|
||||||
#define EX_MASK_BIT(_N) ((_N)&31)
|
|
||||||
#define EX_MASK_MASK(_N) (1<<EX_MASK_BIT(_N))
|
|
||||||
#define EX_MASK_GET(_M, _N) ((_M[EX_MASK_INDEX(_N)] >> EX_MASK_BIT(_N)) & 1)
|
|
||||||
#define EX_MASK_SET_1(_M, _N) _M[EX_MASK_INDEX(_N)] |= EX_MASK_MASK(_N)
|
|
||||||
#define EX_MASK_SET_0(_M, _N) _M[EX_MASK_INDEX(_N)] &= ~EX_MASK_MASK(_N)
|
|
||||||
|
|
||||||
#define EX_MASK_SET_V(_M, _N, _V) { \
|
|
||||||
EX_MASK_SET_0(_M, _N); \
|
|
||||||
_M[EX_MASK_INDEX(_N)] |= ((_V)<<EX_MASK_BIT(_N)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Masks for the low and high halves of interrupt registers
|
|
||||||
//
|
|
||||||
#define EX_INT_MASK_LO ((1<<AEN_ExternalInt0)-1)
|
|
||||||
#define EX_INT_MASK_HI (~EX_INT_MASK_LO)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Masks for extraction of fields from targetPC possibly specifying exception
|
|
||||||
// return
|
|
||||||
//
|
|
||||||
#define EXC_RETURN_MAGIC 0xf0000000
|
|
||||||
#define EXC_RETURN_TYPE 0x0000000f
|
|
||||||
|
|
||||||
//
|
|
||||||
// Masks for undefined instruction reasons
|
|
||||||
//
|
|
||||||
#define EXC_UNDEF_NOCP 0x00080000
|
|
||||||
#define EXC_UNDEF_UNDEFINSTR 0x00010000
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,156 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_EXCEPTIONS_H
|
|
||||||
#define ARM_EXCEPTIONS_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armExceptionTypes.h"
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the current execution priority
|
|
||||||
//
|
|
||||||
Int32 armGetExecutionPriority(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Refresh execution priority on any state change which affects it
|
|
||||||
//
|
|
||||||
void armRefreshExecutionPriority(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Refresh pending exception state on any state change which affects it
|
|
||||||
//
|
|
||||||
void armRefreshPendingException(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Refresh execution priority and pending exception state on any state change
|
|
||||||
// which affects them
|
|
||||||
//
|
|
||||||
void armRefreshExecutionPriorityPendingException(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Derive value of ICSR.RETTOBASE
|
|
||||||
//
|
|
||||||
Bool armGetRetToBase(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Handle exception return
|
|
||||||
//
|
|
||||||
void armExceptionReturn(armP arm, Uns32 targetPC);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Connect up processor interrupts
|
|
||||||
//
|
|
||||||
void armConnectInterrupts(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Do breakpoint exception
|
|
||||||
//
|
|
||||||
void armBKPT(armP arm, Uns32 thisPC);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Do software exception
|
|
||||||
//
|
|
||||||
void armSWI(armP arm, Uns32 thisPC);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Do UsageFault exception
|
|
||||||
//
|
|
||||||
void armUsageFault(armP arm, Uns32 thisPC);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Do BusFault exception
|
|
||||||
//
|
|
||||||
void armBusFault(armP arm, Uns32 faultAddress, memPriv priv);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Do data/prefetch abort exception
|
|
||||||
//
|
|
||||||
void armMemoryAbort(armP arm, Uns32 faultAddress, memPriv priv);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Raise an exception
|
|
||||||
//
|
|
||||||
void armRaise(armP arm, armExceptNum num);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Perform SEV instruction actions
|
|
||||||
//
|
|
||||||
void armSEV(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read SYST_CVR register
|
|
||||||
//
|
|
||||||
Uns32 armReadSYST_CVR(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write SYST_CVR register
|
|
||||||
//
|
|
||||||
void armWriteSYST_CVR(armP arm, Uns32 newValue);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read SYST_CSR register
|
|
||||||
//
|
|
||||||
Uns32 armReadSYST_CSR(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write SYST_CSR register
|
|
||||||
//
|
|
||||||
void armWriteSYST_CSR(armP arm, Uns32 newValue);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write SYST_RVR register
|
|
||||||
//
|
|
||||||
void armWriteSYST_RVR(armP arm, Uns32 newValue);
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the ARM PreserveFPState primitive
|
|
||||||
//
|
|
||||||
void armPreserveFPState(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Create port specifications
|
|
||||||
//
|
|
||||||
void armNewPortSpecs(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Free port specifications
|
|
||||||
//
|
|
||||||
void armFreePortSpecs(armP arm);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_FPCONSTANTS_H
|
|
||||||
#define ARM_FPCONSTANTS_H
|
|
||||||
|
|
||||||
#define ARM_QNAN_DEFAULT_16 0x7e00
|
|
||||||
#define ARM_QNAN_DEFAULT_32 0x7fc00000
|
|
||||||
#define ARM_QNAN_DEFAULT_64 0x7ff8000000000000ULL
|
|
||||||
#define ARM_QNAN_MASK_16 0x0200
|
|
||||||
#define ARM_QNAN_MASK_32 0x00400000
|
|
||||||
#define ARM_QNAN_MASK_64 0x0008000000000000ULL
|
|
||||||
#define ARM_INDETERMINATE_16 0x8000
|
|
||||||
#define ARM_INDETERMINATE_32 0x80000000
|
|
||||||
#define ARM_INDETERMINATE_64 0x8000000000000000ULL
|
|
||||||
#define ARM_MIN_INT16 0x8000
|
|
||||||
#define ARM_MIN_INT32 0x80000000
|
|
||||||
#define ARM_MIN_INT64 0x8000000000000000ULL
|
|
||||||
#define ARM_MAX_INT16 0x7fff
|
|
||||||
#define ARM_MAX_INT32 0x7fffffff
|
|
||||||
#define ARM_MAX_INT64 0x7fffffffffffffffULL
|
|
||||||
#define ARM_MIN_UNS16 0x0000
|
|
||||||
#define ARM_MIN_UNS32 0x00000000
|
|
||||||
#define ARM_MIN_UNS64 0x0000000000000000ULL
|
|
||||||
#define ARM_MAX_UNS16 0xffff
|
|
||||||
#define ARM_MAX_UNS32 0xffffffff
|
|
||||||
#define ARM_MAX_UNS64 0xffffffffffffffffULL
|
|
||||||
|
|
||||||
//
|
|
||||||
// Single precision access macros
|
|
||||||
//
|
|
||||||
#define ARM_FP32_EXP_BIAS 127
|
|
||||||
#define ARM_FP32_EXP_ONES 0xff
|
|
||||||
#define ARM_FP32_EXP_SHIFT 23
|
|
||||||
#define ARM_FP32_SIGN_SHIFT 31
|
|
||||||
|
|
||||||
#define ARM_FP32_SIGN(_F) (((_F) & 0x80000000) != 0)
|
|
||||||
#define ARM_FP32_EXPONENT(_F) (((_F) & 0x7f800000) >> ARM_FP32_EXP_SHIFT)
|
|
||||||
#define ARM_FP32_FRACTION(_F) ((_F) & ((1<<ARM_FP32_EXP_SHIFT)-1))
|
|
||||||
|
|
||||||
#define ARM_FP32_PLUS_ZERO (0)
|
|
||||||
#define ARM_FP32_MINUS_ZERO (0x80000000)
|
|
||||||
#define ARM_FP32_ZERO(_S) ((_S) ? ARM_FP32_MINUS_ZERO : ARM_FP32_PLUS_ZERO)
|
|
||||||
|
|
||||||
#define ARM_FP32_PLUS_INFINITY (0x7f800000)
|
|
||||||
#define ARM_FP32_MINUS_INFINITY (0xff800000)
|
|
||||||
#define ARM_FP32_INFINITY(_S) ((_S) ? ARM_FP32_MINUS_INFINITY : ARM_FP32_PLUS_INFINITY)
|
|
||||||
|
|
||||||
// Build a fp value from its components
|
|
||||||
#define ARM_FP32_EXP_OFFSET (127)
|
|
||||||
#define ARM_FP32_VALUE(_S, _E, _F) (ARM_FP32_ZERO(_S) | (((_E) + ARM_FP32_EXP_OFFSET) << 23) | (_F))
|
|
||||||
//
|
|
||||||
// Half precision access macros
|
|
||||||
//
|
|
||||||
#define ARM_FP16_EXP_BITS 5
|
|
||||||
#define ARM_FP16_EXP_BIAS 15
|
|
||||||
#define ARM_FP16_EXP_ONES 0x1f
|
|
||||||
#define ARM_FP16_EXP_SHIFT 10
|
|
||||||
#define ARM_FP16_SIGN_SHIFT 15
|
|
||||||
#define ARM_FP16_EXP_MIN -14
|
|
||||||
#define ARM_FP16_EXP_MAX 15
|
|
||||||
|
|
||||||
#define ARM_FP16_SIGN(_F) (((_F) & 0x8000) != 0)
|
|
||||||
#define ARM_FP16_EXPONENT(_F) (((_F) & 0x7c00) >> ARM_FP16_EXP_SHIFT)
|
|
||||||
#define ARM_FP16_FRACTION(_F) ((_F) & ((1<<ARM_FP16_EXP_SHIFT)-1))
|
|
||||||
|
|
||||||
#define ARM_FP16_PLUS_ZERO (0)
|
|
||||||
#define ARM_FP16_MINUS_ZERO (0x8000)
|
|
||||||
#define ARM_FP16_ZERO(_S) ((_S) ? ARM_FP16_MINUS_ZERO : ARM_FP16_PLUS_ZERO)
|
|
||||||
#define ARM_FP16_MAX_NORMAL (0x7bff)
|
|
||||||
#define ARM_FP16_AHP_INFINITY (0x7fff)
|
|
||||||
|
|
||||||
#define ARM_FP16_PLUS_INFINITY (0x7c00)
|
|
||||||
#define ARM_FP16_MINUS_INFINITY (0xfc00)
|
|
||||||
#define ARM_FP16_INFINITY(_S) ((_S) ? ARM_FP16_MINUS_INFINITY : ARM_FP16_PLUS_INFINITY)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_FUNCTIONS_H
|
|
||||||
#define ARM_FUNCTIONS_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiAttrs.h"
|
|
||||||
|
|
||||||
// constructor & destructor
|
|
||||||
VMI_CONSTRUCTOR_FN(armConstructor);
|
|
||||||
VMI_VMINIT_FN(armVMInit);
|
|
||||||
VMI_DESTRUCTOR_FN(armDestructor);
|
|
||||||
|
|
||||||
// morph function
|
|
||||||
VMI_MORPH_FN(armMorphInstruction);
|
|
||||||
VMI_FETCH_SNAP_FN(armFetchSnap);
|
|
||||||
|
|
||||||
// simulation support functions
|
|
||||||
VMI_ENDIAN_FN(armGetEndian);
|
|
||||||
VMI_NEXT_PC_FN(armNextInstruction);
|
|
||||||
VMI_DISASSEMBLE_FN(armDisassemble);
|
|
||||||
VMI_IASSWITCH_FN(armContextSwitchCB);
|
|
||||||
|
|
||||||
// debugger integration support routines
|
|
||||||
VMI_REG_GROUP_FN(armRegGroup);
|
|
||||||
VMI_REG_INFO_FN(armRegInfo);
|
|
||||||
VMI_EXCEPTION_INFO_FN(armExceptionInfo);
|
|
||||||
VMI_MODE_INFO_FN(armModeInfo);
|
|
||||||
VMI_GET_EXCEPTION_FN(armGetException);
|
|
||||||
VMI_GET_MODE_FN(armGetMode);
|
|
||||||
VMI_DEBUG_FN(armDumpRegisters);
|
|
||||||
|
|
||||||
// parameter support functions
|
|
||||||
VMI_PROC_PARAM_SPECS_FN(armGetParamSpec);
|
|
||||||
VMI_PROC_PARAM_TABLE_SIZE_FN(armParamValueSize);
|
|
||||||
|
|
||||||
// port functions
|
|
||||||
VMI_BUS_PORT_SPECS_FN(armGetBusPortSpec);
|
|
||||||
VMI_NET_PORT_SPECS_FN(armGetNetPortSpec);
|
|
||||||
|
|
||||||
// exception functions
|
|
||||||
VMI_RD_PRIV_EXCEPT_FN(armRdPrivExceptionCB);
|
|
||||||
VMI_WR_PRIV_EXCEPT_FN(armWrPrivExceptionCB);
|
|
||||||
VMI_RD_ALIGN_EXCEPT_FN(armRdAlignExceptionCB);
|
|
||||||
VMI_WR_ALIGN_EXCEPT_FN(armWrAlignExceptionCB);
|
|
||||||
VMI_RD_ABORT_EXCEPT_FN(armRdAbortExceptionCB);
|
|
||||||
VMI_WR_ABORT_EXCEPT_FN(armWrAbortExceptionCB);
|
|
||||||
VMI_IFETCH_FN(armIFetchExceptionCB);
|
|
||||||
VMI_ARITH_EXCEPT_FN(armArithExceptionCB);
|
|
||||||
VMI_ICOUNT_FN(armICountPendingCB);
|
|
||||||
|
|
||||||
// Imperas intercepted function support
|
|
||||||
VMI_INT_RETURN_FN(armIntReturnCB);
|
|
||||||
VMI_INT_RESULT_FN(armIntResultCB);
|
|
||||||
VMI_INT_PAR_FN(armIntParCB);
|
|
||||||
|
|
||||||
// Processor information support
|
|
||||||
VMI_PROC_INFO_FN(armProcInfo);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiAttrs.h"
|
|
||||||
#include "vmi/vmiModelInfo.h"
|
|
||||||
|
|
||||||
#include "armFunctions.h"
|
|
||||||
|
|
||||||
#define VENDOR "arm.ovpworld.org"
|
|
||||||
#define LIBRARY "processor"
|
|
||||||
#define NAME "armm"
|
|
||||||
#define VERSION "1.0"
|
|
||||||
#define VARIANT "ARMv7-M"
|
|
||||||
|
|
||||||
VMI_PROC_INFO_FN(armProcInfo) {
|
|
||||||
static const vmiProcessorInfo info = {
|
|
||||||
.vlnv.vendor = VENDOR ,
|
|
||||||
.vlnv.library = LIBRARY ,
|
|
||||||
.vlnv.name = NAME ,
|
|
||||||
.vlnv.version = VERSION ,
|
|
||||||
|
|
||||||
.semihost.vendor = VENDOR,
|
|
||||||
.semihost.library = "semihosting" ,
|
|
||||||
.semihost.name = "armNewlib" ,
|
|
||||||
.semihost.version = "1.0" ,
|
|
||||||
|
|
||||||
.elfCode = 40,
|
|
||||||
.endianFixed = False,
|
|
||||||
.gdbPath = "$IMPERAS_HOME/lib/$IMPERAS_ARCH/CrossCompiler/arm-elf/bin/arm-elf-gdb" VMI_EXE_SUFFIX,
|
|
||||||
.procdoc = DOCPATH(VENDOR,LIBRARY,NAME,VERSION,VARIANT),
|
|
||||||
.family = "ARM",
|
|
||||||
};
|
|
||||||
return &info;
|
|
||||||
}
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_MESSAGE_H
|
|
||||||
#define ARM_MESSAGE_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiRt.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armFunctions.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Macros for emission of source references
|
|
||||||
//
|
|
||||||
#define SRCREF_FMT "CPU '%s' 0x%08x %s: "
|
|
||||||
#define SRCREF_ARGS(_A, _PC) \
|
|
||||||
vmirtProcessorName((vmiProcessorP)(_A)), \
|
|
||||||
_PC, \
|
|
||||||
armDisassemble((vmiProcessorP)(_A), _PC)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_MODE_H
|
|
||||||
#define ARM_MODE_H
|
|
||||||
|
|
||||||
//
|
|
||||||
// Dictionary modes
|
|
||||||
//
|
|
||||||
typedef enum armModeE {
|
|
||||||
|
|
||||||
// BITMASKS
|
|
||||||
ARM_MODE_U = 0x1, // user (unprivileged) mode bitmask
|
|
||||||
ARM_MODE_MPU = 0x2, // MPU enabled mode bitmask
|
|
||||||
|
|
||||||
// VALID MODES
|
|
||||||
ARM_MODE_PRIV = (0 | 0 | 0 ),
|
|
||||||
ARM_MODE_USER = (0 | ARM_MODE_U | 0 ),
|
|
||||||
ARM_MODE_PRIV_MPU = (0 | 0 | ARM_MODE_MPU),
|
|
||||||
ARM_MODE_USER_MPU = (0 | ARM_MODE_U | ARM_MODE_MPU),
|
|
||||||
|
|
||||||
// CATCHER FOR ARM MODE EXECUTION
|
|
||||||
ARM_MODE_ARM,
|
|
||||||
|
|
||||||
// KEEP LAST: for array sizing
|
|
||||||
ARM_MODE_LAST
|
|
||||||
|
|
||||||
} armMode;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Wait reasons (bitmask)
|
|
||||||
//
|
|
||||||
typedef enum armDisableE {
|
|
||||||
AD_WFE = 0x01, // wait for event
|
|
||||||
AD_WFI = 0x02, // wait for interrupt
|
|
||||||
AD_LOCKUP = 0x04 // lockup state
|
|
||||||
} armDisable;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Block mask entries
|
|
||||||
//
|
|
||||||
typedef enum armBlockMaskE {
|
|
||||||
ARM_BM_USE_SP_PROCESS = 0x0001,
|
|
||||||
ARM_BM_BIG_ENDIAN = 0x0002,
|
|
||||||
ARM_BM_UNALIGNED = 0x0004,
|
|
||||||
ARM_BM_CP10 = 0x0008,
|
|
||||||
ARM_BM_FPCA = 0x0010,
|
|
||||||
ARM_BM_ASPEN = 0x0020,
|
|
||||||
ARM_BM_LSPACT = 0x0040,
|
|
||||||
} armBlockMask;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_MORPH_H
|
|
||||||
#define ARM_MORPH_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armDecodeTypes.h"
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
#include "armVariant.h"
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Dispatcher callback type
|
|
||||||
//
|
|
||||||
#define ARM_MORPH_FN(_NAME) void _NAME(armMorphStateP state)
|
|
||||||
typedef ARM_MORPH_FN((*armMorphFn));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Instruction type
|
|
||||||
//
|
|
||||||
typedef enum armInstTypeE {
|
|
||||||
ARM_TY_NORMAL, // normal instructions type
|
|
||||||
ARM_TY_VFP, // VFP instruction
|
|
||||||
} armInstType;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This specifies the conditions under which this is an interworking instruction
|
|
||||||
// if it targets the program counter
|
|
||||||
//
|
|
||||||
typedef enum armInterworkE {
|
|
||||||
ARM_IW_NEVER, // never an interworking instruction
|
|
||||||
ARM_IW_L4, // an interworking instruction if Control.L4 is set
|
|
||||||
ARM_IW_ARM_V7 // an interworking instruction if an ARM v7 instruction
|
|
||||||
} armInterwork;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This structure provides information required to morph code for an instruction
|
|
||||||
//
|
|
||||||
typedef struct armMorphAttrS {
|
|
||||||
|
|
||||||
armMorphFn morphCB; // callback function to morph the instruction
|
|
||||||
armInterwork interwork :2; // whether an interworking instruction
|
|
||||||
armInstType iType :2; // Instruction type
|
|
||||||
|
|
||||||
Bool condJump :1; // is this instruction a conditional jump?
|
|
||||||
Bool jumpIfTrue:1; // take branch or jump if condition is True
|
|
||||||
Bool isLink :1; // whether branch saves link address
|
|
||||||
Bool shiftCOut :1; // whether to set carry with shifter carry
|
|
||||||
Bool exchange :1; // whether to exchange SIMD argument halves
|
|
||||||
Bool sextend :1; // whether to sign-extend SIMD arguments
|
|
||||||
Bool setGE :1; // whether to set SIMD GE fields
|
|
||||||
Bool halve :1; // whether to halve SIMD results
|
|
||||||
Bool round :1; // whether to round intermediate results
|
|
||||||
Bool accumulate:1; // whether to accumulate
|
|
||||||
Bool highhalf :1; // whether to use the highhalf of result
|
|
||||||
Bool negate :1; // negate value
|
|
||||||
Bool subtract :1; // subtract value
|
|
||||||
Bool allowQNaN :1; // whether Quiet NaN's are allowed
|
|
||||||
Bool roundFPSCR:1; // Use FPSCR rounding mode on VFP vcvt instruction
|
|
||||||
|
|
||||||
vmiFlagsCP flagsRW; // flags read and written by the instruction
|
|
||||||
vmiFlagsCP flagsR; // flags read by the instruction
|
|
||||||
|
|
||||||
vmiUnop unop :8; // if a simple unary operation
|
|
||||||
vmiBinop binop :8; // if a simple binary operation
|
|
||||||
vmiBinop binop2 :8; // second binary operation (SIMD)
|
|
||||||
vmiCondition cond :8; // condition to apply
|
|
||||||
|
|
||||||
vmiFUnop funop :8; // if a simple fp unary operation
|
|
||||||
vmiFBinop fbinop :8; // if a simple fp binary operation
|
|
||||||
vmiFBinop fternop :8; // if a simple fp ternary operation
|
|
||||||
Uns8 ebytes; // VFP operand size in bytes
|
|
||||||
|
|
||||||
} armMorphAttr;
|
|
||||||
|
|
||||||
typedef enum armSetPCE {
|
|
||||||
ASPC_NA, // no modification to PC
|
|
||||||
ASPC_R15, // indirect jump to address in R15
|
|
||||||
ASPC_R15_RET, // return to address in R15
|
|
||||||
ASPC_IMM // direct jump to immediate address
|
|
||||||
} armSetPC;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This structure holds state for a single instruction as it is morphed
|
|
||||||
//
|
|
||||||
typedef struct armMorphStateS {
|
|
||||||
armInstructionInfo info; // instruction description (from decoder)
|
|
||||||
armMorphAttrCP attrs; // instruction attributes
|
|
||||||
armP arm; // current processor
|
|
||||||
Uns32 nextPC; // next instruction address in sequence
|
|
||||||
vmiLabelP skipLabel; // label to skip instruction body
|
|
||||||
Uns32 tempIdx; // current temporary index
|
|
||||||
Bool pcFetched; // PC value already fetched?
|
|
||||||
armSetPC pcSet; // PC value updated
|
|
||||||
Uns32 pcImmediate; // immediate value of PC
|
|
||||||
Bool setMode; // test for mode switch?
|
|
||||||
} armMorphState;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This array defines the morpher dispatch table
|
|
||||||
//
|
|
||||||
extern const armMorphAttr armMorphTable[ARM_IT_LAST+1];
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,304 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_MORPH_ENTRIES_H
|
|
||||||
#define ARM_MORPH_ENTRIES_H
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armVariant.h"
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// NORMAL INSTRUCTIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for an instruction with a single variant
|
|
||||||
//
|
|
||||||
#define MORPH_SINGLE(_NAME) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_NAME}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like ADC
|
|
||||||
//
|
|
||||||
#define MORPH_SET_ADC(_NAME, _OP, _FLAGS_RW, _FLAGS_R, _COUT) \
|
|
||||||
[ARM_IT_##_NAME##_IMM] = {morphCB:armEmitBinopI, interwork:ARM_IW_ARM_V7, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RM] = {morphCB:armEmitBinopR, interwork:ARM_IW_ARM_V7, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RM_SHFT_IMM] = {morphCB:armEmitBinopRSI, interwork:ARM_IW_ARM_V7, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RM_RRX] = {morphCB:armEmitBinopRX, interwork:ARM_IW_ARM_V7, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_IT] = {morphCB:armEmitBinopIT, interwork:ARM_IW_ARM_V7, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RT] = {morphCB:armEmitBinopRT, interwork:ARM_IW_ARM_V7, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like MOV
|
|
||||||
//
|
|
||||||
#define MORPH_SET_MOV(_NAME, _OP, _FLAGS_RW, _FLAGS_R, _COUT) \
|
|
||||||
[ARM_IT_##_NAME##_IMM] = {morphCB:armEmitUnopI, interwork:ARM_IW_ARM_V7, unop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RM] = {morphCB:armEmitUnopR, interwork:ARM_IW_ARM_V7, unop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RM_SHFT_IMM] = {morphCB:armEmitUnopRSI, interwork:ARM_IW_ARM_V7, unop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RM_SHFT_RS] = {morphCB:armEmitUnopRSR, interwork:ARM_IW_ARM_V7, unop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RM_RRX] = {morphCB:armEmitUnopRX, interwork:ARM_IW_ARM_V7, unop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RM_SHFT_RST] = {morphCB:armEmitUnopRSRT, interwork:ARM_IW_ARM_V7, unop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like MOVT
|
|
||||||
//
|
|
||||||
#define MORPH_SET_MOVT(_NAME) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitUnopIT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like MLA
|
|
||||||
//
|
|
||||||
#define MORPH_SET_MLA(_NAME, _FLAGS_RW) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_NAME, flagsRW:_FLAGS_RW}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like SMULL
|
|
||||||
//
|
|
||||||
#define MORPH_SET_SMULL(_NAME, _OP1, _OP2, _FLAGS_RW) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_OP1, binop:_OP2, flagsRW:_FLAGS_RW}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like CMN
|
|
||||||
//
|
|
||||||
#define MORPH_SET_CMN(_NAME, _OP, _FLAGS_RW, _FLAGS_R, _COUT) \
|
|
||||||
[ARM_IT_##_NAME##_IMM] = {morphCB:armEmitCmpopI, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RM] = {morphCB:armEmitCmpopR, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RM_SHFT_IMM] = {morphCB:armEmitCmpopRSI, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}, \
|
|
||||||
[ARM_IT_##_NAME##_RM_RRX] = {morphCB:armEmitCmpopRX, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like B
|
|
||||||
//
|
|
||||||
#define MORPH_SET_B(_NAME, _IS_LINK) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitBranchC, condJump:True, isLink:_IS_LINK}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like BLX (2)
|
|
||||||
//
|
|
||||||
#define MORPH_SET_BLX2(_NAME, _IS_LINK) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitBranchR, isLink:_IS_LINK}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like LDR
|
|
||||||
//
|
|
||||||
#define MORPH_SET_LDR(_NAME, _OP) \
|
|
||||||
[ARM_IT_##_NAME##_IMM] = {morphCB:armEmit##_OP##I, interwork:ARM_IW_L4}, \
|
|
||||||
[ARM_IT_##_NAME##_RM] = {morphCB:armEmit##_OP##R, interwork:ARM_IW_L4}, \
|
|
||||||
[ARM_IT_##_NAME##_RM_SHFT_IMM] = {morphCB:armEmit##_OP##RSI, interwork:ARM_IW_L4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like LDM (1)
|
|
||||||
//
|
|
||||||
#define MORPH_SET_LDM1(_NAME) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_NAME, interwork:ARM_IW_L4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like LDRH
|
|
||||||
//
|
|
||||||
#define MORPH_SET_LDRH(_NAME, _OP) \
|
|
||||||
[ARM_IT_##_NAME##_IMM] = {morphCB:armEmit##_OP##I}, \
|
|
||||||
[ARM_IT_##_NAME##_RM] = {morphCB:armEmit##_OP##R}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like SWP
|
|
||||||
//
|
|
||||||
#define MORPH_SET_SWP(_NAME, _OP) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_OP}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like LDC
|
|
||||||
//
|
|
||||||
#define MORPH_SET_LDC(_NAME, _OP) \
|
|
||||||
[ARM_IT_##_NAME##_IMM] = {morphCB:armEmit##_OP}, \
|
|
||||||
[ARM_IT_##_NAME##_UNINDEXED] = {morphCB:armEmit##_OP}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like NOP
|
|
||||||
//
|
|
||||||
#define MORPH_SET_NOP(_NAME) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitNOP}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like SMLA<x><y>
|
|
||||||
//
|
|
||||||
#define MORPH_SET_SMLA_XY(_NAME) \
|
|
||||||
[ARM_IT_##_NAME##BB] = {morphCB:armEmit##_NAME##BB}, \
|
|
||||||
[ARM_IT_##_NAME##BT] = {morphCB:armEmit##_NAME##BT}, \
|
|
||||||
[ARM_IT_##_NAME##TB] = {morphCB:armEmit##_NAME##TB}, \
|
|
||||||
[ARM_IT_##_NAME##TT] = {morphCB:armEmit##_NAME##TT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like SMLAW<y>
|
|
||||||
//
|
|
||||||
#define MORPH_SET_SMLAW_Y(_NAME) \
|
|
||||||
[ARM_IT_##_NAME##B] = {morphCB:armEmit##_NAME##B}, \
|
|
||||||
[ARM_IT_##_NAME##T] = {morphCB:armEmit##_NAME##T}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for parallel add/subtract instructions
|
|
||||||
//
|
|
||||||
#define MORPH_SET_PAS(_NAME, _OP1, _OP2, _SEXTEND, _SETGE, _HALVE) \
|
|
||||||
[ARM_IT_##_NAME##ADD16] = {morphCB:armEmitParallelBinop16, binop:_OP1, binop2:_OP1, exchange:0, sextend:_SEXTEND, setGE:_SETGE, halve:_HALVE}, \
|
|
||||||
[ARM_IT_##_NAME##ASX] = {morphCB:armEmitParallelBinop16, binop:_OP2, binop2:_OP1, exchange:1, sextend:_SEXTEND, setGE:_SETGE, halve:_HALVE}, \
|
|
||||||
[ARM_IT_##_NAME##SAX] = {morphCB:armEmitParallelBinop16, binop:_OP1, binop2:_OP2, exchange:1, sextend:_SEXTEND, setGE:_SETGE, halve:_HALVE}, \
|
|
||||||
[ARM_IT_##_NAME##SUB16] = {morphCB:armEmitParallelBinop16, binop:_OP2, binop2:_OP2, exchange:0, sextend:_SEXTEND, setGE:_SETGE, halve:_HALVE}, \
|
|
||||||
[ARM_IT_##_NAME##ADD8] = {morphCB:armEmitParallelBinop8, binop:_OP1, exchange:0, sextend:_SEXTEND, setGE:_SETGE, halve:_HALVE}, \
|
|
||||||
[ARM_IT_##_NAME##SUB8] = {morphCB:armEmitParallelBinop8, binop:_OP2, exchange:0, sextend:_SEXTEND, setGE:_SETGE, halve:_HALVE}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for signed multiply instructions with optional argument exchange
|
|
||||||
//
|
|
||||||
#define MORPH_SET_MEDIA_X(_NAME, _OP1, _OP2) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_OP1, binop:_OP2, exchange:0}, \
|
|
||||||
[ARM_IT_##_NAME##X] = {morphCB:armEmit##_OP1, binop:_OP2, exchange:1}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for signed multiply instructions with optional rounding
|
|
||||||
//
|
|
||||||
#define MORPH_SET_MEDIA_R(_NAME, _OP1, _OP2, _ACC) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_OP1, binop:_OP2, round:0, accumulate:_ACC}, \
|
|
||||||
[ARM_IT_##_NAME##R] = {morphCB:armEmit##_OP1, binop:_OP2, round:1, accumulate:_ACC}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for ARM instructions like PLD
|
|
||||||
//
|
|
||||||
#define MORPH_SET_PLD(_NAME) \
|
|
||||||
[ARM_IT_##_NAME##_IMM] = {morphCB:armEmitNOP}, \
|
|
||||||
[ARM_IT_##_NAME##_RM] = {morphCB:armEmitNOP}, \
|
|
||||||
[ARM_IT_##_NAME##_RM_SHFT_IMM] = {morphCB:armEmitNOP}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// THUMB INSTRUCTIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for Thumb instructions like ADD (4)
|
|
||||||
//
|
|
||||||
#define MORPH_SET_ADD4(_NAME, _OP, _FLAGS_RW, _FLAGS_R, _COUT) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitBinopRT, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for Thumb instructions like ADD (6)
|
|
||||||
//
|
|
||||||
#define MORPH_SET_ADD6(_NAME, _OP, _FLAGS_RW, _FLAGS_R, _COUT) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitBinopI, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for Thumb instructions like ADD (7)
|
|
||||||
//
|
|
||||||
#define MORPH_SET_ADD7(_NAME, _OP, _FLAGS_RW, _FLAGS_R, _COUT) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitBinopIT, binop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for Thumb instructions like MOV (3)
|
|
||||||
//
|
|
||||||
#define MORPH_SET_MOV3(_NAME, _OP, _FLAGS_RW, _FLAGS_R, _COUT) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitUnopR, unop:_OP, flagsRW:_FLAGS_RW, flagsR:_FLAGS_R, shiftCOut:_COUT}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for Thumb instructions like ADR
|
|
||||||
//
|
|
||||||
#define MORPH_SET_ADR(_NAME, _NEGATE) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitBinopADR, binop:vmi_ADD, negate:_NEGATE}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for Thumb instructions like CBZ
|
|
||||||
//
|
|
||||||
#define MORPH_SET_CBZ(_NAME, _JUMP_IF_TRUE) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitCBZ, jumpIfTrue:_JUMP_IF_TRUE}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for Thumb instructions like SDIV
|
|
||||||
//
|
|
||||||
#define MORPH_SET_SDIV(_NAME, _OP) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitDIV, binop:_OP}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for Single entry VFP instructions
|
|
||||||
//
|
|
||||||
#define MORPH_SET_SINGLE_VFP(_NAME) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_NAME, iType:ARM_TY_VFP}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for VFP instructions with D and S versions
|
|
||||||
//
|
|
||||||
#define MORPH_SET_VFP_DS(_NAME, _FUNC) \
|
|
||||||
[ARM_IT_##_NAME##_S] = {morphCB:armEmit##_FUNC, iType:ARM_TY_VFP, ebytes:4}, \
|
|
||||||
[ARM_IT_##_NAME##_D] = {morphCB:armEmit##_FUNC, iType:ARM_TY_VFP, ebytes:8}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for VFP instructions with S version only
|
|
||||||
//
|
|
||||||
#define MORPH_SET_VFP_S(_NAME, _FUNC) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_FUNC, iType:ARM_TY_VFP, ebytes:4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for VFP instructions doing single precision binary floating point op
|
|
||||||
//
|
|
||||||
#define MORPH_SET_VFP_RRR_F(_NAME, _FUNC, _OP, _NEGATE) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_FUNC, iType:ARM_TY_VFP, fbinop:_OP, ebytes:4, negate:_NEGATE}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for VFP instructions doing single precision unary floating point op
|
|
||||||
//
|
|
||||||
#define MORPH_SET_VFP_RR_F(_NAME, _OP) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitVFPUnop, iType:ARM_TY_VFP, funop:_OP, ebytes:4}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for VFP VCMP instructions
|
|
||||||
//
|
|
||||||
#define MORPH_SET_VFP_VCMP(_NAME, _FUNC, _QNAN) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_FUNC, iType:ARM_TY_VFP, ebytes:4, allowQNaN:_QNAN}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for VFP VCVT instructions
|
|
||||||
//
|
|
||||||
#define MORPH_SET_VFP_VCVT(_NAME, _FUNC, _BYTES, _SIGN, _RND) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_FUNC, iType:ARM_TY_VFP, ebytes:_BYTES, sextend:_SIGN, roundFPSCR:_RND}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for VFP VCVT half precision instructions which may specify top or bottom half
|
|
||||||
//
|
|
||||||
#define MORPH_SET_VFP_VCVT_H(_NAME, _FUNC, _BYTES, _TOP) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmit##_FUNC, iType:ARM_TY_VFP, ebytes:_BYTES, highhalf:_TOP}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morpher attributes for single precision VFP Fused Multiply instructions
|
|
||||||
//
|
|
||||||
#define MORPH_SET_VFP_FMAC_F(_NAME, _SUB, _NEGATE) \
|
|
||||||
[ARM_IT_##_NAME] = {morphCB:armEmitVFusedMAC, iType:ARM_TY_VFP, subtract:_SUB, negate:_NEGATE}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,240 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_MORPH_FUNCTIONS_H
|
|
||||||
#define ARM_MORPH_FUNCTIONS_H
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armMode.h"
|
|
||||||
#include "armMorph.h"
|
|
||||||
|
|
||||||
// unop instructions
|
|
||||||
ARM_MORPH_FN(armEmitUnopI);
|
|
||||||
ARM_MORPH_FN(armEmitUnopR);
|
|
||||||
ARM_MORPH_FN(armEmitUnopRSI);
|
|
||||||
ARM_MORPH_FN(armEmitUnopRSR);
|
|
||||||
ARM_MORPH_FN(armEmitUnopRSRT);
|
|
||||||
ARM_MORPH_FN(armEmitUnopRX);
|
|
||||||
|
|
||||||
// binop instructions
|
|
||||||
ARM_MORPH_FN(armEmitBinopI);
|
|
||||||
ARM_MORPH_FN(armEmitBinopR);
|
|
||||||
ARM_MORPH_FN(armEmitBinopRT);
|
|
||||||
ARM_MORPH_FN(armEmitBinopIT);
|
|
||||||
ARM_MORPH_FN(armEmitBinopADR);
|
|
||||||
ARM_MORPH_FN(armEmitBinopRSI);
|
|
||||||
ARM_MORPH_FN(armEmitBinopRSR);
|
|
||||||
ARM_MORPH_FN(armEmitBinopRX);
|
|
||||||
|
|
||||||
// cmpop instructions
|
|
||||||
ARM_MORPH_FN(armEmitCmpopI);
|
|
||||||
ARM_MORPH_FN(armEmitCmpopR);
|
|
||||||
ARM_MORPH_FN(armEmitCmpopRSI);
|
|
||||||
ARM_MORPH_FN(armEmitCmpopRX);
|
|
||||||
|
|
||||||
// multiply and divide instructions
|
|
||||||
ARM_MORPH_FN(armEmitMUL);
|
|
||||||
ARM_MORPH_FN(armEmitMLA);
|
|
||||||
ARM_MORPH_FN(armEmitMLS);
|
|
||||||
ARM_MORPH_FN(armEmitDIV);
|
|
||||||
ARM_MORPH_FN(armEmitMULL);
|
|
||||||
ARM_MORPH_FN(armEmitMLAL);
|
|
||||||
|
|
||||||
// branch instructions
|
|
||||||
ARM_MORPH_FN(armEmitBranchC);
|
|
||||||
ARM_MORPH_FN(armEmitBranchR);
|
|
||||||
ARM_MORPH_FN(armEmitBLX);
|
|
||||||
|
|
||||||
// miscellaneous instructions
|
|
||||||
ARM_MORPH_FN(armEmitCLZ);
|
|
||||||
ARM_MORPH_FN(armEmitBKPT);
|
|
||||||
ARM_MORPH_FN(armEmitSWI);
|
|
||||||
|
|
||||||
// load and store instructions
|
|
||||||
ARM_MORPH_FN(armEmitLDRI);
|
|
||||||
ARM_MORPH_FN(armEmitLDRR);
|
|
||||||
ARM_MORPH_FN(armEmitLDRRSI);
|
|
||||||
ARM_MORPH_FN(armEmitLDM1);
|
|
||||||
ARM_MORPH_FN(armEmitSTRI);
|
|
||||||
ARM_MORPH_FN(armEmitSTRR);
|
|
||||||
ARM_MORPH_FN(armEmitSTRRSI);
|
|
||||||
ARM_MORPH_FN(armEmitSTM1);
|
|
||||||
|
|
||||||
// coprocessor instructions
|
|
||||||
ARM_MORPH_FN(armEmitUsageFaultCP);
|
|
||||||
|
|
||||||
// status register access instructions
|
|
||||||
ARM_MORPH_FN(armEmitMRS);
|
|
||||||
ARM_MORPH_FN(armEmitMSR);
|
|
||||||
|
|
||||||
// DSP data processing instructions
|
|
||||||
ARM_MORPH_FN(armEmitQADD);
|
|
||||||
ARM_MORPH_FN(armEmitQSUB);
|
|
||||||
ARM_MORPH_FN(armEmitQDADD);
|
|
||||||
ARM_MORPH_FN(armEmitQDSUB);
|
|
||||||
|
|
||||||
// DSP multiply instructions
|
|
||||||
ARM_MORPH_FN(armEmitSMLABB);
|
|
||||||
ARM_MORPH_FN(armEmitSMLABT);
|
|
||||||
ARM_MORPH_FN(armEmitSMLATB);
|
|
||||||
ARM_MORPH_FN(armEmitSMLATT);
|
|
||||||
ARM_MORPH_FN(armEmitSMLALBB);
|
|
||||||
ARM_MORPH_FN(armEmitSMLALBT);
|
|
||||||
ARM_MORPH_FN(armEmitSMLALTB);
|
|
||||||
ARM_MORPH_FN(armEmitSMLALTT);
|
|
||||||
ARM_MORPH_FN(armEmitSMLAWB);
|
|
||||||
ARM_MORPH_FN(armEmitSMLAWT);
|
|
||||||
ARM_MORPH_FN(armEmitSMULBB);
|
|
||||||
ARM_MORPH_FN(armEmitSMULBT);
|
|
||||||
ARM_MORPH_FN(armEmitSMULTB);
|
|
||||||
ARM_MORPH_FN(armEmitSMULTT);
|
|
||||||
ARM_MORPH_FN(armEmitSMULWB);
|
|
||||||
ARM_MORPH_FN(armEmitSMULWT);
|
|
||||||
|
|
||||||
// hint instructions
|
|
||||||
ARM_MORPH_FN(armEmitNOP);
|
|
||||||
ARM_MORPH_FN(armEmitWFE);
|
|
||||||
ARM_MORPH_FN(armEmitWFI);
|
|
||||||
ARM_MORPH_FN(armEmitSEV);
|
|
||||||
|
|
||||||
// move instructions
|
|
||||||
ARM_MORPH_FN(armEmitMOVW);
|
|
||||||
ARM_MORPH_FN(armEmitMOVT);
|
|
||||||
|
|
||||||
// multiply instructions
|
|
||||||
ARM_MORPH_FN(armEmitMAAL);
|
|
||||||
|
|
||||||
// synchronization instructions
|
|
||||||
ARM_MORPH_FN(armEmitLDREX);
|
|
||||||
ARM_MORPH_FN(armEmitSTREX);
|
|
||||||
ARM_MORPH_FN(armEmitCLREX);
|
|
||||||
|
|
||||||
// miscellaneous instructions
|
|
||||||
ARM_MORPH_FN(armEmitCPS);
|
|
||||||
|
|
||||||
// branch instructions
|
|
||||||
ARM_MORPH_FN(armEmitCBZ);
|
|
||||||
ARM_MORPH_FN(armEmitTB);
|
|
||||||
|
|
||||||
// basic media instructions
|
|
||||||
ARM_MORPH_FN(armEmitUSAD8);
|
|
||||||
ARM_MORPH_FN(armEmitUSADA8);
|
|
||||||
ARM_MORPH_FN(armEmitSBFX);
|
|
||||||
ARM_MORPH_FN(armEmitBFC);
|
|
||||||
ARM_MORPH_FN(armEmitBFI);
|
|
||||||
ARM_MORPH_FN(armEmitUBFX);
|
|
||||||
|
|
||||||
// parallel add/subtract instructions
|
|
||||||
ARM_MORPH_FN(armEmitParallelBinop8);
|
|
||||||
ARM_MORPH_FN(armEmitParallelBinop16);
|
|
||||||
|
|
||||||
// packing, unpacking, saturation and reversal instructions
|
|
||||||
ARM_MORPH_FN(armEmitPKHBT);
|
|
||||||
ARM_MORPH_FN(armEmitPKHTB);
|
|
||||||
ARM_MORPH_FN(armEmitSSAT);
|
|
||||||
ARM_MORPH_FN(armEmitSSAT16);
|
|
||||||
ARM_MORPH_FN(armEmitUSAT);
|
|
||||||
ARM_MORPH_FN(armEmitUSAT16);
|
|
||||||
ARM_MORPH_FN(armEmitSXTAB);
|
|
||||||
ARM_MORPH_FN(armEmitUXTAB);
|
|
||||||
ARM_MORPH_FN(armEmitSXTAB16);
|
|
||||||
ARM_MORPH_FN(armEmitUXTAB16);
|
|
||||||
ARM_MORPH_FN(armEmitSXTAH);
|
|
||||||
ARM_MORPH_FN(armEmitUXTAH);
|
|
||||||
ARM_MORPH_FN(armEmitSXTB);
|
|
||||||
ARM_MORPH_FN(armEmitUXTB);
|
|
||||||
ARM_MORPH_FN(armEmitSXTB16);
|
|
||||||
ARM_MORPH_FN(armEmitUXTB16);
|
|
||||||
ARM_MORPH_FN(armEmitSXTH);
|
|
||||||
ARM_MORPH_FN(armEmitUXTH);
|
|
||||||
ARM_MORPH_FN(armEmitSEL);
|
|
||||||
ARM_MORPH_FN(armEmitREV);
|
|
||||||
ARM_MORPH_FN(armEmitREV16);
|
|
||||||
ARM_MORPH_FN(armEmitRBIT);
|
|
||||||
ARM_MORPH_FN(armEmitREVSH);
|
|
||||||
|
|
||||||
// signed multiply instructions
|
|
||||||
ARM_MORPH_FN(armEmitSMLXD);
|
|
||||||
ARM_MORPH_FN(armEmitSMUXD);
|
|
||||||
ARM_MORPH_FN(armEmitSMLXLD);
|
|
||||||
ARM_MORPH_FN(armEmitSMMLX);
|
|
||||||
|
|
||||||
// VFP data processing instructions
|
|
||||||
ARM_MORPH_FN(armEmitVFPUnop);
|
|
||||||
ARM_MORPH_FN(armEmitVFPBinop);
|
|
||||||
ARM_MORPH_FN(armEmitVMulAcc_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVFusedMAC);
|
|
||||||
ARM_MORPH_FN(armEmitVMOVI_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVMOVR_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVABS_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVNEG_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVCMP_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVCMP0_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVCVT_SD_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVCVT_SH_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVCVT_HS_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVCVT_XF_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVCVT_FX_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVCVT_IF_VFP);
|
|
||||||
ARM_MORPH_FN(armEmitVCVT_FI_VFP);
|
|
||||||
|
|
||||||
// VFP Extension register load/store instructions
|
|
||||||
ARM_MORPH_FN(armEmitVLDR);
|
|
||||||
ARM_MORPH_FN(armEmitVSTR);
|
|
||||||
ARM_MORPH_FN(armEmitVLDM);
|
|
||||||
ARM_MORPH_FN(armEmitVSTM);
|
|
||||||
|
|
||||||
// VFP 8, 16 and 32-bit transfer instructions
|
|
||||||
ARM_MORPH_FN(armEmitVMRS);
|
|
||||||
ARM_MORPH_FN(armEmitVMSR);
|
|
||||||
ARM_MORPH_FN(armEmitVMOVRS);
|
|
||||||
ARM_MORPH_FN(armEmitVMOVSR);
|
|
||||||
ARM_MORPH_FN(armEmitVMOVRZ);
|
|
||||||
ARM_MORPH_FN(armEmitVMOVZR);
|
|
||||||
ARM_MORPH_FN(armEmitVDUPR);
|
|
||||||
|
|
||||||
// VFP 64-bit transfer instructions
|
|
||||||
ARM_MORPH_FN(armEmitVMOVRRD);
|
|
||||||
ARM_MORPH_FN(armEmitVMOVDRR);
|
|
||||||
ARM_MORPH_FN(armEmitVMOVRRSS);
|
|
||||||
ARM_MORPH_FN(armEmitVMOVSSRR);
|
|
||||||
|
|
||||||
//
|
|
||||||
// If the register index specifies a banked register, return a vmiReg structure
|
|
||||||
// for the banked register; otherwise, return VMI_NOREG. Also, validate the
|
|
||||||
// current block mode for banked registers.
|
|
||||||
//
|
|
||||||
vmiReg armGetBankedRegMode(Bool useSPProcess, Uns32 r);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_REGISTERS_H
|
|
||||||
#define ARM_REGISTERS_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// REGISTER ACCESS MACROS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// aliases for specific GPRs
|
|
||||||
#define ARM_REG_SP 13
|
|
||||||
#define ARM_REG_LR 14
|
|
||||||
#define ARM_REG_PC 15
|
|
||||||
|
|
||||||
// morph-time macros to calculate offsets to registers in an arm structure
|
|
||||||
#define ARM_CPU_OFFSET(_F) VMI_CPU_OFFSET(armP, _F)
|
|
||||||
#define ARM_CPU_REG(_F) VMI_CPU_REG(armP, _F)
|
|
||||||
#define ARM_CPU_REG_CONST(_F) VMI_CPU_REG_CONST(armP, _F)
|
|
||||||
#define ARM_CPU_TEMP(_F) VMI_CPU_TEMP(armP, _F)
|
|
||||||
|
|
||||||
// morph-time macros to calculate constant offsets to flags in an arm structure
|
|
||||||
#define ARM_ZF_CONST ARM_CPU_REG_CONST(aflags.ZF)
|
|
||||||
#define ARM_NF_CONST ARM_CPU_REG_CONST(aflags.NF)
|
|
||||||
#define ARM_CF_CONST ARM_CPU_REG_CONST(aflags.CF)
|
|
||||||
#define ARM_VF_CONST ARM_CPU_REG_CONST(aflags.VF)
|
|
||||||
#define ARM_HI_CONST ARM_CPU_REG_CONST(oflags.HI)
|
|
||||||
#define ARM_LT_CONST ARM_CPU_REG_CONST(oflags.LT)
|
|
||||||
#define ARM_LE_CONST ARM_CPU_REG_CONST(oflags.LE)
|
|
||||||
|
|
||||||
// morph-time macros to calculate variable offsets to flags in an arm structure
|
|
||||||
#define ARM_AFLAGS ARM_CPU_REG(aflags)
|
|
||||||
#define ARM_ZF ARM_CPU_REG(aflags.ZF)
|
|
||||||
#define ARM_NF ARM_CPU_REG(aflags.NF)
|
|
||||||
#define ARM_CF ARM_CPU_REG(aflags.CF)
|
|
||||||
#define ARM_VF ARM_CPU_REG(aflags.VF)
|
|
||||||
#define ARM_QF ARM_CPU_REG(oflags.QF)
|
|
||||||
|
|
||||||
// morph-time macros to calculate offsets to fields in an arm structure
|
|
||||||
#define ARM_REG(_R) ARM_CPU_REG(regs[_R])
|
|
||||||
#define ARM_TREG(_R) ARM_CPU_TEMP(regs[_R])
|
|
||||||
#define ARM_TEMP(_R) ARM_CPU_TEMP(temps[_R])
|
|
||||||
#define ARM_SP ARM_REG(ARM_REG_SP)
|
|
||||||
#define ARM_LR ARM_REG(ARM_REG_LR)
|
|
||||||
#define ARM_PC ARM_TREG(ARM_REG_PC)
|
|
||||||
|
|
||||||
// morph-time macros to calculate offsets to control registers
|
|
||||||
#define ARM_PSR ARM_CPU_REG(sregs.PSR)
|
|
||||||
#define ARM_CONTROL ARM_CPU_REG(sregs.CONTROL)
|
|
||||||
#define ARM_PRIMASK ARM_CPU_REG(sregs.PRIMASK)
|
|
||||||
#define ARM_FAULTMASK ARM_CPU_REG(sregs.FAULTMASK)
|
|
||||||
#define ARM_BASEPRI ARM_CPU_REG(sregs.BASEPRI)
|
|
||||||
#define ARM_FPSCR ARM_CPU_REG(sregs.FPSCR)
|
|
||||||
|
|
||||||
// morph-time macros to calculate offsets to banked registers in an arm structure
|
|
||||||
#define ARM_BANK_REG(_N, _SET) ARM_CPU_REG(bank.R##_N##_##_SET)
|
|
||||||
#define ARM_BANK_SP ARM_BANK_REG(13, process)
|
|
||||||
|
|
||||||
// morph-time macro to calculate offset to EA tag in an arm structure
|
|
||||||
#define ARM_EA_TAG ARM_CPU_REG(exclusiveTag)
|
|
||||||
|
|
||||||
// morph-time macro to calculate offset to ITSTATE in an arm structure
|
|
||||||
#define ARM_IT_STATE ARM_CPU_REG(itStateRT)
|
|
||||||
|
|
||||||
// morph-time macro to calculate offset to divide target index in an arm structure
|
|
||||||
#define ARM_DIVIDE_TARGET ARM_CPU_REG(divideTarget)
|
|
||||||
|
|
||||||
// morph-time macro to calculate offset to disable reason, event register and
|
|
||||||
// pending interrupt state in an arm structure
|
|
||||||
#define ARM_DISABLE_REASON ARM_CPU_REG(disableReason)
|
|
||||||
#define ARM_EVENT ARM_CPU_REG(eventRegister)
|
|
||||||
#define ARM_PENDING ARM_CPU_REG(pendingInterrupt)
|
|
||||||
|
|
||||||
// morph-time macros to calculate offsets to floating point registers in an arm
|
|
||||||
// structure
|
|
||||||
#define ARM_FP_FLAGS ARM_CPU_REG(sdfpFlags)
|
|
||||||
#define ARM_FP_STICKY ARM_CPU_REG(sdfpSticky)
|
|
||||||
#define ARM_BREG(_R) ARM_CPU_REG(vregs.b[_R])
|
|
||||||
#define ARM_HREG(_R) ARM_CPU_REG(vregs.h[_R])
|
|
||||||
#define ARM_WREG(_R) ARM_CPU_REG(vregs.w[_R])
|
|
||||||
#define ARM_DREG(_R) ARM_CPU_REG(vregs.d[_R])
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,359 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_STRUCTURE_H
|
|
||||||
#define ARM_STRUCTURE_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiPorts.h"
|
|
||||||
#include "vmi/vmiTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armConfig.h"
|
|
||||||
#include "armExceptionTypes.h"
|
|
||||||
#include "armSysRegisters.h"
|
|
||||||
#include "armMode.h"
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
#include "armVariant.h"
|
|
||||||
|
|
||||||
// processor debug flags
|
|
||||||
#define ARM_DISASSEMBLE_MASK 0x00000001
|
|
||||||
#define ARM_THUMB_MASK 0x00000002
|
|
||||||
#define ARM_DEBUG_MMU_MASK 0x00000004
|
|
||||||
#define ARM_DEBUG_EXCEPT_MASK 0x00000008
|
|
||||||
#define ARM_DUMP_SDFP_REG_MASK 0x00000010
|
|
||||||
|
|
||||||
#define ARM_DISASSEMBLE(_P) ((_P)->flags & ARM_DISASSEMBLE_MASK)
|
|
||||||
#define ARM_THUMB(_P) ((_P)->flags & ARM_THUMB_MASK)
|
|
||||||
#define ARM_DEBUG_MMU(_P) ((_P)->flags & ARM_DEBUG_MMU_MASK)
|
|
||||||
#define ARM_DEBUG_EXCEPT(_P) ((_P)->flags & ARM_DEBUG_EXCEPT_MASK)
|
|
||||||
#define ARM_DUMP_SDFP_REG(_P) ((_P)->flags & ARM_DUMP_SDFP_REG_MASK)
|
|
||||||
|
|
||||||
#define ARM_GPR_BITS 32
|
|
||||||
#define ARM_GPR_BYTES (ARM_GPR_BITS/8)
|
|
||||||
#define ARM_GPR_NUM 16
|
|
||||||
#define ARM_TEMP_NUM 12
|
|
||||||
|
|
||||||
#define ARM_VFP_REG_BITS 64
|
|
||||||
#define ARM_VFP_REG_BYTES 8
|
|
||||||
#define ARM_VFP16_REG_NUM 16
|
|
||||||
#define ARM_VFP32_REG_NUM 32
|
|
||||||
|
|
||||||
#define ARM_EXCEPT_NUM 512
|
|
||||||
#define ARM_EXCEPT_MASK_NUM ((ARM_EXCEPT_NUM+31)/32)
|
|
||||||
#define ARM_INTERRUPT_NUM 496
|
|
||||||
|
|
||||||
#define ARM_NO_TAG -1
|
|
||||||
|
|
||||||
// simulator compatibility modes
|
|
||||||
typedef enum armCompatModeE {
|
|
||||||
COMPAT_ISA, // conform to the documented ISA
|
|
||||||
COMPAT_GDB, // conform to gdb simulator
|
|
||||||
COMPAT_CODE_SOURCERY // conform to ARM CodeSourcery toolchain output (ignore BKPT)
|
|
||||||
} armCompatMode;
|
|
||||||
|
|
||||||
// arithmetic flags
|
|
||||||
typedef struct armArithFlagsS {
|
|
||||||
Uns8 ZF; // zero flag
|
|
||||||
Uns8 NF; // sign flag
|
|
||||||
Uns8 CF; // carry flag
|
|
||||||
Uns8 VF; // overflow flag
|
|
||||||
} armArithFlags;
|
|
||||||
|
|
||||||
// other flags
|
|
||||||
typedef struct armOtherFlagsS {
|
|
||||||
Uns8 HI; // hi flag (created on demand)
|
|
||||||
Uns8 LT; // lt flag (created on demand)
|
|
||||||
Uns8 LE; // le flag (created on demand)
|
|
||||||
Uns8 QF; // saturation flag
|
|
||||||
} armOtherFlags;
|
|
||||||
|
|
||||||
// ARM PSR (combines APSR, IPSR and EPSR)
|
|
||||||
typedef union armPSRU {
|
|
||||||
struct {
|
|
||||||
Uns32 exceptNum : 9; // exception number
|
|
||||||
Uns32 align4 : 1; // 4 byte alignment (in stack)
|
|
||||||
Uns32 IT72 : 6; // if-then state, bits 7:2
|
|
||||||
Uns32 GE : 4; // GE bits (unused when no DSP)
|
|
||||||
Uns32 _u1 : 4; // unused bits
|
|
||||||
Uns32 T : 1; // Thumb mode bit
|
|
||||||
Uns32 IT10 : 2; // if-then state, bits 1:0
|
|
||||||
Uns32 Q : 1; // DSP overflow/saturate flag
|
|
||||||
Uns32 V : 1; // overflow flag
|
|
||||||
Uns32 C : 1; // carry flag
|
|
||||||
Uns32 Z : 1; // zero flag
|
|
||||||
Uns32 N : 1; // sign flag
|
|
||||||
} fields;
|
|
||||||
Uns32 reg;
|
|
||||||
} armPSR;
|
|
||||||
|
|
||||||
// PSR Access Macros
|
|
||||||
#define PSR_FIELD(_A, _F) ((_A)->sregs.PSR.fields._F)
|
|
||||||
#define IN_USER_MODE(_A) (!PSR_FIELD(_A, exceptNum) && CONTROL_FIELD(_A, threadUnpriv))
|
|
||||||
#define IN_THUMB_MODE(_A) PSR_FIELD(_A, T)
|
|
||||||
#define IN_HANDLER_MODE(_A) (PSR_FIELD(_A, exceptNum) && True)
|
|
||||||
#define IN_BASE_MODE(_A) IN_USER_MODE(_A)
|
|
||||||
#define IN_PRIV_MPU_MODE(_A) (!IN_USER_MODE(_A) && MPU_ENABLED(_A))
|
|
||||||
|
|
||||||
// Masks for fields in PSR
|
|
||||||
#define PSR_FLAGS 0xf8000000
|
|
||||||
#define PSR_NZCV 0xf0000000
|
|
||||||
#define PSR_EXCEPT_NUM 0x000001ff
|
|
||||||
#define PSR_THUMB 0x01000000
|
|
||||||
#define PSR_IT10 0x06000000
|
|
||||||
#define PSR_IT72 0x0000fc00
|
|
||||||
#define PSR_GE 0x000f0000
|
|
||||||
#define PSR_GE3 0x00080000
|
|
||||||
#define PSR_GE2 0x00040000
|
|
||||||
#define PSR_GE1 0x00020000
|
|
||||||
#define PSR_GE0 0x00010000
|
|
||||||
#define PSR_GE32 (PSR_GE3|PSR_GE2)
|
|
||||||
#define PSR_GE10 (PSR_GE1|PSR_GE0)
|
|
||||||
#define PSR_GE30 (PSR_GE32|PSR_GE10)
|
|
||||||
#define PSR_IT (PSR_IT72 | PSR_IT10)
|
|
||||||
#define PSR_ALL (PSR_FLAGS | PSR_IT | PSR_THUMB | PSR_GE | PSR_EXCEPT_NUM)
|
|
||||||
#define PSR_NOT_FLAGS (PSR_ALL & ~(PSR_FLAGS | PSR_GE))
|
|
||||||
|
|
||||||
// ARM CONTROL
|
|
||||||
typedef union armCONTROLU {
|
|
||||||
struct {
|
|
||||||
Uns32 threadUnpriv : 1; // is thread mode unprivileged?
|
|
||||||
Uns32 useSP_Process : 1; // use SP_process stack
|
|
||||||
Uns32 FPCA : 1; // Is FP active in current context?
|
|
||||||
} fields;
|
|
||||||
Uns32 reg;
|
|
||||||
} armCONTROL;
|
|
||||||
|
|
||||||
// CONTROL Access Macros
|
|
||||||
#define CONTROL_FIELD(_A, _F) ((_A)->sregs.CONTROL.fields._F)
|
|
||||||
#define USE_SP_PROCESS(_A) CONTROL_FIELD(_A, useSP_Process)
|
|
||||||
|
|
||||||
// Masks for fields in CONTROL
|
|
||||||
#define CONTROL_FPCA 0x00000004
|
|
||||||
|
|
||||||
// ARM FPSCR
|
|
||||||
typedef union armFPSCRU {
|
|
||||||
struct {
|
|
||||||
Uns32 IOC : 1;
|
|
||||||
Uns32 DZC : 1;
|
|
||||||
Uns32 OFC : 1;
|
|
||||||
Uns32 UFC : 1;
|
|
||||||
Uns32 IXC : 1;
|
|
||||||
Uns32 _u1 : 2;
|
|
||||||
Uns32 IDC : 1;
|
|
||||||
Uns32 _u2 : 14;
|
|
||||||
Uns32 RMode : 2;
|
|
||||||
Uns32 FZ : 1;
|
|
||||||
Uns32 DN : 1;
|
|
||||||
Uns32 AHP : 1;
|
|
||||||
Uns32 _u3 : 1;
|
|
||||||
Uns32 V : 1;
|
|
||||||
Uns32 C : 1;
|
|
||||||
Uns32 Z : 1;
|
|
||||||
Uns32 N : 1;
|
|
||||||
} fields;
|
|
||||||
Uns32 reg;
|
|
||||||
} armFPSCR;
|
|
||||||
|
|
||||||
// FPSCR Access Macros
|
|
||||||
#define FPSCR_MASK 0xf7c0009f
|
|
||||||
#define FPSCR_REG(_A) ((_A)->sregs.FPSCR.reg)
|
|
||||||
#define FPSCR_FIELD(_A, _F) ((_A)->sregs.FPSCR.fields._F)
|
|
||||||
|
|
||||||
// Write Masks for fields in other control registers (with no structs)
|
|
||||||
#define PRIMASK_MASK 0x00000001
|
|
||||||
#define FAULTMASK_MASK 0x00000001
|
|
||||||
#define BASEPRI_MASK 0x000000ff
|
|
||||||
|
|
||||||
// Special register definitions
|
|
||||||
typedef struct armSpecialRegsS {
|
|
||||||
armPSR PSR;
|
|
||||||
armCONTROL CONTROL;
|
|
||||||
Uns32 PRIMASK;
|
|
||||||
Uns32 FAULTMASK;
|
|
||||||
Uns32 BASEPRI;
|
|
||||||
armFPSCR FPSCR;
|
|
||||||
} armSpecialRegs;
|
|
||||||
|
|
||||||
// Banked registers
|
|
||||||
typedef struct armBankRegsS {
|
|
||||||
|
|
||||||
// process stack pointer
|
|
||||||
Uns32 R13_process;
|
|
||||||
|
|
||||||
} armBankRegs;
|
|
||||||
|
|
||||||
typedef struct armDomainSetS {
|
|
||||||
memDomainP external; // external memory domain
|
|
||||||
memDomainP vmPriv; // virtual code domain, privileged mode
|
|
||||||
memDomainP vmUser; // virtual code domain, user mode
|
|
||||||
memDomainP system; // system domain
|
|
||||||
} armDomainSet, *armDomainSetP;
|
|
||||||
|
|
||||||
typedef enum armPIDSetE {
|
|
||||||
APS_PHYS, // physical domains (privileged or user mode)
|
|
||||||
APS_VM_P, // MMU/MPU-managed privileged mode domains
|
|
||||||
APS_VM_U, // MMU/MPU-managed user mode domains
|
|
||||||
APS_LAST // KEEP LAST: for sizing
|
|
||||||
} armPIDSet;
|
|
||||||
|
|
||||||
// decoder callback function to decode instruction at the passed address
|
|
||||||
#define ARM_DECODER_FN(_NAME) void _NAME( \
|
|
||||||
armP arm, \
|
|
||||||
Uns32 thisPC, \
|
|
||||||
armInstructionInfoP info \
|
|
||||||
)
|
|
||||||
typedef ARM_DECODER_FN((*armDecoderFn));
|
|
||||||
|
|
||||||
// Callback function to return size of instruction at the passed for the specified mode
|
|
||||||
#define ARM_ISIZE_FN(_NAME) Uns32 _NAME( \
|
|
||||||
armP arm, \
|
|
||||||
Uns32 thisPC, \
|
|
||||||
Bool isThumb \
|
|
||||||
)
|
|
||||||
typedef ARM_ISIZE_FN((*armIsizeFn));
|
|
||||||
|
|
||||||
// opaque type for MPU protection region
|
|
||||||
typedef struct protRegionS *protRegionP;
|
|
||||||
|
|
||||||
// VFP register bank
|
|
||||||
typedef union armVFPRS {
|
|
||||||
Uns8 b[ARM_VFP16_REG_NUM*8]; // when viewed as bytes
|
|
||||||
Uns16 h[ARM_VFP16_REG_NUM*4]; // When viewed as 16 bit halfwords
|
|
||||||
Uns32 w[ARM_VFP16_REG_NUM*2]; // when viewed as 32-bit words
|
|
||||||
Uns64 d[ARM_VFP16_REG_NUM]; // when viewed as 64-bit double words
|
|
||||||
} armVFPR;
|
|
||||||
|
|
||||||
#define FP_REG(_A, _I) ((_A)->vregs.w[(_I)])
|
|
||||||
|
|
||||||
// floating point control word type
|
|
||||||
typedef union armFPCWU {
|
|
||||||
Uns32 u32; // when viewed as composed value
|
|
||||||
vmiFPControlWord cw; // when viewed as fields
|
|
||||||
} armFPCW;
|
|
||||||
|
|
||||||
// processor structure
|
|
||||||
typedef struct armS {
|
|
||||||
|
|
||||||
// TRUE PROCESSOR REGISTERS
|
|
||||||
armArithFlags aflags; // arithmetic flags
|
|
||||||
armOtherFlags oflags; // other flags
|
|
||||||
Uns32 regs[ARM_GPR_NUM]; // current mode GPRs
|
|
||||||
armSpecialRegs sregs; // special purpose registers
|
|
||||||
|
|
||||||
// SIMULATOR SUPPORT
|
|
||||||
Uns32 temps[ARM_TEMP_NUM]; // temporary registers
|
|
||||||
Uns8 itStateRT; // if-then state (run time)
|
|
||||||
Uns8 itStateMT; // if-then state (morph time)
|
|
||||||
Uns8 divideTarget; // target of divide instruction
|
|
||||||
Uns8 disableReason; // reason why processor disabled
|
|
||||||
Bool eventRegister; // event register
|
|
||||||
Bool pendingInterrupt; // is interrupt pending?
|
|
||||||
armMode mode :8; // current processor mode
|
|
||||||
Bool validHI :1; // is hi flag valid?
|
|
||||||
Bool validLT :1; // is lt flag valid?
|
|
||||||
Bool validLE :1; // is le flag valid?
|
|
||||||
Bool checkEndian :1; // check endian using blockMask?
|
|
||||||
Bool checkL4 :1; // check interwork using blockMask?
|
|
||||||
Bool checkUnaligned :1; // check alignment mode using blockMask?
|
|
||||||
Bool disableTimerRVR0 :1; // disable timer (SYST_RVR==0)?
|
|
||||||
Bool sleepOnExit :1; // sleeping at exception exit?
|
|
||||||
Bool denormalInput :1; // input denormal sticky flag
|
|
||||||
memEndian instructionEndian:1; // instruction endianness
|
|
||||||
armExceptCxt exceptionContext :3; // exception context
|
|
||||||
Uns32 exclusiveTag; // tag for active exclusive access
|
|
||||||
Uns32 exclusiveTagMask; // mask to select exclusive tag bits
|
|
||||||
Uns32 priorityMask; // priority mask
|
|
||||||
Uns32 exceptNum; // total number of exceptions
|
|
||||||
Uns32 exceptMaskNum; // number of words in exception masks
|
|
||||||
Uns32 timerModulus; // modulus value for counter
|
|
||||||
Uns64 timerBase; // nominal counter base value
|
|
||||||
|
|
||||||
// SYSTEM AND BANKED REGISTERS (INFREQUENTLY USED AT RUN TIME)
|
|
||||||
armBankRegs bank; // banked registers
|
|
||||||
armSCSRegs scs; // SCS registers
|
|
||||||
|
|
||||||
// VFP REGISTERS
|
|
||||||
armFPCW currentCW; // current control word
|
|
||||||
armArithFlags sdfpAFlags; // FPU comparison flags
|
|
||||||
Uns8 sdfpFlags; // FPU operation flags
|
|
||||||
Uns8 sdfpSticky; // FPU sticky flags
|
|
||||||
armVFPR vregs; // VFP data registers
|
|
||||||
|
|
||||||
// VARIANT CONFIGURATION
|
|
||||||
Uns32 flags; // configuration flags
|
|
||||||
armConfig configInfo; // configuration register defaults
|
|
||||||
armCompatMode compatMode :2; // compatibility mode
|
|
||||||
Bool simEx :1; // simulate exceptions?
|
|
||||||
Bool verbose :1; // verbose messages enabled?
|
|
||||||
Bool showHiddenRegs :1; // show hidden registers in reg dump
|
|
||||||
Bool UAL :1; // disassemble using UAL syntax
|
|
||||||
Bool disableBitBand :1; // bit banding disabled
|
|
||||||
|
|
||||||
// MEMORY SUBSYSTEM SUPPORT
|
|
||||||
Bool restoreDomain :1; // whether to resore domain (LDRT, STRT)
|
|
||||||
protRegionP impu; // instruction/unified MPU
|
|
||||||
protRegionP dmpu; // data MPU (if not unified)
|
|
||||||
armDomainSet ids; // instruction domain set
|
|
||||||
armDomainSet dds; // data domain set
|
|
||||||
|
|
||||||
// NET HANDLES (used for NVIC)
|
|
||||||
Uns32 sysResetReq; // system reset requested
|
|
||||||
Uns32 intISS; // interrupt service started
|
|
||||||
Uns32 eventOut; // event output signal
|
|
||||||
Uns32 lockup; // lockup output signal
|
|
||||||
|
|
||||||
// EXCEPTION SUPPORT
|
|
||||||
Int32 unboostedPriority; // unboosted execution priority
|
|
||||||
Int32 executionPriority; // current execution priority
|
|
||||||
armExceptNum enabledException; // current enabled exception
|
|
||||||
armExceptNum pendingException; // current pending exception
|
|
||||||
armExceptNum derivedException; // pushStack/popStack exception
|
|
||||||
Uns32 nestedActivation; // used for handler->thread check
|
|
||||||
Uns32 xPend[ARM_EXCEPT_MASK_NUM]; // pending exceptions
|
|
||||||
Uns32 xActive[ARM_EXCEPT_MASK_NUM];// active exceptions
|
|
||||||
Uns32 xEnable[ARM_EXCEPT_MASK_NUM];// exception enables
|
|
||||||
Uns8 xPriority[ARM_EXCEPT_NUM]; // exception priorities
|
|
||||||
vmiNetPortP netPorts; // net ports on this variant
|
|
||||||
memDomainP FPCARdomain; // memory domain associated with the FPCAR
|
|
||||||
|
|
||||||
// INTERCEPT LIBRARY SUPPORT
|
|
||||||
armDecoderFn decoderCB; // generic instruction decoder
|
|
||||||
armIsizeFn isizeCB; // instruction size callback
|
|
||||||
|
|
||||||
} arm;
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_SYS_H
|
|
||||||
#define ARM_SYS_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armSysRegisters.h"
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// These are the bounds of the Peripheral region
|
|
||||||
//
|
|
||||||
#define PERIPH_LOW 0x40000000
|
|
||||||
#define PERIPH_HIGH 0x4fffffff
|
|
||||||
|
|
||||||
//
|
|
||||||
// These are the bounds of the System Control Space
|
|
||||||
//
|
|
||||||
#define DEVICE_LOW 0xa0000000
|
|
||||||
#define DEVICE_HIGH 0xdfffffff
|
|
||||||
|
|
||||||
//
|
|
||||||
// These are the bounds of the System Control Space
|
|
||||||
//
|
|
||||||
#define SYSTEM_LOW 0xe0000000
|
|
||||||
#define SYSTEM_HIGH 0xffffffff
|
|
||||||
|
|
||||||
//
|
|
||||||
// These are the bounds of the Private Peripheral Bus
|
|
||||||
//
|
|
||||||
#define PPB_LOW 0xe0000000
|
|
||||||
#define PPB_HIGH 0xe00fffff
|
|
||||||
|
|
||||||
//
|
|
||||||
// Call on initialization
|
|
||||||
//
|
|
||||||
void armSysInitialize(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Call on reset
|
|
||||||
//
|
|
||||||
void armSysReset(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Is the indicated system register supported on this processor?
|
|
||||||
//
|
|
||||||
Bool armGetSysRegSupported(armSCSRegId id, armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Perform a privileged-mode read of the system register
|
|
||||||
//
|
|
||||||
Bool armReadSysRegPriv(armSCSRegId id, armP arm, Uns32 *result);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Perform a privileged-mode write of the system register
|
|
||||||
//
|
|
||||||
Bool armWriteSysRegPriv(armSCSRegId id, armP arm, Uns32 value);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add programmer's view of system register
|
|
||||||
//
|
|
||||||
void armAddSysRegisterView(
|
|
||||||
armSCSRegId id,
|
|
||||||
armP arm,
|
|
||||||
vmiViewObjectP baseObject,
|
|
||||||
const char *name
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Structure filled with system register description by
|
|
||||||
// armGetSysRegisterDesc
|
|
||||||
//
|
|
||||||
typedef struct armSysRegDescS {
|
|
||||||
const char *name;
|
|
||||||
armSCSRegId id;
|
|
||||||
Uns32 address;
|
|
||||||
const char *privRW;
|
|
||||||
const char *userRW;
|
|
||||||
} armSysRegDesc, *armSysRegDescP;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Iterator filling 'desc' with the next system register description -
|
|
||||||
// 'desc.name' should be initialized to NULL prior to the first call
|
|
||||||
//
|
|
||||||
Bool armGetSysRegisterDesc(armSysRegDescP desc);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Insert SCS region into the passed domain at the standard location
|
|
||||||
//
|
|
||||||
void armSysCreateSCSRegion(armP arm, memDomainP domain);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_TYPEREFS_H
|
|
||||||
#define ARM_TYPEREFS_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "hostapi/typeMacros.h"
|
|
||||||
|
|
||||||
DEFINE_S(arm);
|
|
||||||
DEFINE_S(armInstructionInfo);
|
|
||||||
DEFINE_S(armMorphState);
|
|
||||||
DEFINE_CS(armMorphAttr);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_UTILS_H
|
|
||||||
#define ARM_UTILS_H
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set the initial endianness for the model
|
|
||||||
//
|
|
||||||
void armSetInitialEndian(armP arm, Bool isBigEndian);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the name of a GPR
|
|
||||||
//
|
|
||||||
const char *armGetGPRName(armP arm, Uns32 index);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the name of a CPR
|
|
||||||
//
|
|
||||||
const char *armGetCPRName(armP arm, Uns32 index);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Update processor block mask
|
|
||||||
//
|
|
||||||
void armSetBlockMask(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Switch banked registers on switch to the passed mode
|
|
||||||
//
|
|
||||||
void armSwitchRegs(armP arm, Bool oldUseSPProcess, Bool newUseSPProcess);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write CONTROL.SP_PROCESS field
|
|
||||||
//
|
|
||||||
void armWriteSPProcess(armP arm, Bool newSPProcess);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read CPSR register
|
|
||||||
//
|
|
||||||
Uns32 armReadCPSR(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write CPSR register
|
|
||||||
//
|
|
||||||
void armWriteCPSR(armP arm, Uns32 value, Uns32 mask);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write PRIMASK register
|
|
||||||
//
|
|
||||||
void armWritePRIMASK(armP arm, Uns32 value);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write BASEPRI register
|
|
||||||
//
|
|
||||||
void armWriteBASEPRI(armP arm, Uns32 value);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write BASEPRI register (using BASEPRI_MAX semantics)
|
|
||||||
//
|
|
||||||
void armWriteBASEPRI_MAX(armP arm, Uns32 value);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write FAULTMASK register
|
|
||||||
//
|
|
||||||
void armWriteFAULTMASK(armP arm, Uns32 value);
|
|
||||||
|
|
||||||
//
|
|
||||||
// read CONTROL register
|
|
||||||
//
|
|
||||||
Uns32 armReadCONTROL(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write CONTROL register
|
|
||||||
//
|
|
||||||
void armWriteCONTROL(armP arm, Uns32 value);
|
|
||||||
|
|
||||||
//
|
|
||||||
// update the CONTROL.FPCA bit to the value. If it changes then set the block mask
|
|
||||||
//
|
|
||||||
void armUpdateFPCA(armP arm, Bool value);
|
|
||||||
|
|
||||||
//
|
|
||||||
// update the FPCCR.LSPACT bit to the value. If it changes then set the block mask
|
|
||||||
//
|
|
||||||
void armUpdateLSPACT(armP arm, Bool value);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write SP register
|
|
||||||
//
|
|
||||||
void armWriteSP(armP arm, Uns32 value);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Switch processor mode if required
|
|
||||||
//
|
|
||||||
void armSwitchMode(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Abort any active exclusive access
|
|
||||||
//
|
|
||||||
void armAbortExclusiveAccess(armP arm);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_SIMD_VFP_H
|
|
||||||
#define ARM_SIMD_VFP_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write VFP FPSCR register
|
|
||||||
//
|
|
||||||
void armWriteFPSCR(armP arm, Uns32 newValue, Uns32 writeMask);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read VFP FPSCR register
|
|
||||||
//
|
|
||||||
Uns32 armReadFPSCR(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Call on initialization
|
|
||||||
//
|
|
||||||
void armFPInitialize(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Call on reset
|
|
||||||
//
|
|
||||||
void armFPReset(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Convert from half-precision to single-precision
|
|
||||||
//
|
|
||||||
Uns32 armFPHalfToSingle(armP arm, Uns16 half);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Convert from single-precision to half-precision
|
|
||||||
//
|
|
||||||
Uns16 armFPSingleToHalf(armP arm, Uns32 single);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return True if the single-precision floating point values op1 and op2 are 0
|
|
||||||
// and infinity (in either order), setting the denormal sticky bit if so
|
|
||||||
//
|
|
||||||
Bool armFPInfinityAndZero(armP arm, Uns32 op1, Uns32 op2);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_VM_H
|
|
||||||
#define ARM_VM_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiTypes.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the minimum page size (1Kb)
|
|
||||||
//
|
|
||||||
#define MIN_PAGE_SIZE 1024
|
|
||||||
|
|
||||||
//
|
|
||||||
// Enumation describing actions performed by armVMMiss
|
|
||||||
//
|
|
||||||
typedef enum armVMActionE {
|
|
||||||
MA_OK, // memory was mapped, access can proceed
|
|
||||||
MA_EXCEPTION // memory was not mapped, exception was triggered
|
|
||||||
} armVMAction;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Try mapping memory at the passed address for the specified access type and
|
|
||||||
// return a status code indicating whether the mapping succeeded
|
|
||||||
//
|
|
||||||
armVMAction armVMMiss(
|
|
||||||
armP arm,
|
|
||||||
memPriv requiredPriv,
|
|
||||||
Uns32 address,
|
|
||||||
Uns32 bytes,
|
|
||||||
memAccessAttrs attrs
|
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set the privileged mode data domain to the user domain (for LDRT, STRT)
|
|
||||||
//
|
|
||||||
void armVMSetUserPrivilegedModeDataDomain(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Restore the normal data domain for the current mode (for LDRT, STRT)
|
|
||||||
//
|
|
||||||
void armVMRestoreNormalDataDomain(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write the indexed MPU RBAR register value
|
|
||||||
//
|
|
||||||
void armVMWriteRBAR(armP arm, Uns32 index, Bool isData, Uns32 newValue);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read the indexed MPU RBAR register value
|
|
||||||
//
|
|
||||||
Uns32 armVMReadRBAR(armP arm, Uns32 index, Bool isData);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write the indexed MPU RASR register value
|
|
||||||
//
|
|
||||||
void armVMWriteRASR(armP arm, Uns32 index, Bool isData, Uns32 newValue);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read the indexed MPU RASR register value
|
|
||||||
//
|
|
||||||
Uns32 armVMReadRASR(armP arm, Uns32 index, Bool isData);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Flush the privileged mode MPU
|
|
||||||
//
|
|
||||||
void armVMFlushMPUPriv(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Reset VM structures
|
|
||||||
//
|
|
||||||
void armVMReset(armP arm);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Free structures used for virtual memory management
|
|
||||||
//
|
|
||||||
void armVMFree(armP arm);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARM_VARIANT_H
|
|
||||||
#define ARM_VARIANT_H
|
|
||||||
|
|
||||||
// this defines the architecture options and variants
|
|
||||||
typedef enum armArchitectureE {
|
|
||||||
|
|
||||||
// ARCHITECTURE OPTIONS
|
|
||||||
ARM_VM = 0x0010, // enable long multiply instructions
|
|
||||||
ARM_VT = 0x0020, // enable thumb instructions
|
|
||||||
ARM_VD = 0x0040, // enable basic DSP instructions
|
|
||||||
ARM_VD2 = 0x0080, // enable LDRD, MCRR, MRRC, PLD and STRD insns
|
|
||||||
ARM_SS = 0x0100, // enable supersections, TEX and S bits
|
|
||||||
ARM_BX = 0x0200, // enable BX instruction
|
|
||||||
ARM_J = 0x0400, // enable trivial Jazelle extension
|
|
||||||
ARM_K = 0x0800, // enable multi-processing instructions
|
|
||||||
ARM_VT2 = 0x1000, // enable Thumb-2 instructions
|
|
||||||
|
|
||||||
// ARCHITECTURE VERSIONS
|
|
||||||
ARM_V4XM = 4,
|
|
||||||
ARM_V4 = 4 | ARM_VM,
|
|
||||||
ARM_V4TXM = 4 | ARM_BX | ARM_VT,
|
|
||||||
ARM_V4T = 4 | ARM_BX | ARM_VM | ARM_VT,
|
|
||||||
ARM_V5XM = 5 | ARM_BX,
|
|
||||||
ARM_V5 = 5 | ARM_BX | ARM_VM,
|
|
||||||
ARM_V5TXM = 5 | ARM_BX | ARM_VT,
|
|
||||||
ARM_V5T = 5 | ARM_BX | ARM_VM | ARM_VT,
|
|
||||||
ARM_V5TEXP = 5 | ARM_BX | ARM_VM | ARM_VT | ARM_VD,
|
|
||||||
ARM_V5TE = 5 | ARM_BX | ARM_VM | ARM_VT | ARM_VD | ARM_VD2 | ARM_SS,
|
|
||||||
ARM_V5TEJ = 5 | ARM_BX | ARM_VM | ARM_VT | ARM_VD | ARM_VD2 | ARM_SS | ARM_J,
|
|
||||||
ARM_V6 = 6 | ARM_BX | ARM_VM | ARM_VT | ARM_VD | ARM_VD2 | ARM_SS | ARM_J,
|
|
||||||
ARM_V6K = 6 | ARM_BX | ARM_VM | ARM_VT | ARM_VD | ARM_VD2 | ARM_SS | ARM_J | ARM_K,
|
|
||||||
ARM_V6T2 = 6 | ARM_BX | ARM_VM | ARM_VT | ARM_VD | ARM_VD2 | ARM_SS | ARM_J | ARM_VT2,
|
|
||||||
ARM_V7 = 7 | ARM_BX | ARM_VM | ARM_VT | ARM_VD | ARM_VD2 | ARM_SS | ARM_J | ARM_K | ARM_VT2
|
|
||||||
|
|
||||||
} armArchitecture;
|
|
||||||
|
|
||||||
// this defines thumb versions
|
|
||||||
typedef enum armThumbVersionE {
|
|
||||||
ARM_THUMB_NONE, // no thumb instructions
|
|
||||||
ARM_THUMB_V1, // version 1 thumb instructions
|
|
||||||
ARM_THUMB_V2 // version 2 thumb instructions
|
|
||||||
} armThumbVersion;
|
|
||||||
|
|
||||||
// this selects armArchitecture bits specifying instruction version
|
|
||||||
#define ARM_MASK_VERSION 0xf
|
|
||||||
|
|
||||||
// this is used to restrict availability of features to certain variants
|
|
||||||
#define ARM_SUPPORT(_V, _M) (((_V) & (_M)) == (_M))
|
|
||||||
|
|
||||||
// get the main instruction set version
|
|
||||||
#define ARM_INSTRUCTION_VERSION(_V) ((_V) & ARM_MASK_VERSION)
|
|
||||||
|
|
||||||
// get the thumb instruction set version
|
|
||||||
#define ARM_THUMB_VERSION(_V) ( \
|
|
||||||
!ARM_SUPPORT(_V, ARM_VT) ? ARM_THUMB_NONE : \
|
|
||||||
(ARM_INSTRUCTION_VERSION(_V)==4) ? ARM_THUMB_V1 : ARM_THUMB_V2 \
|
|
||||||
)
|
|
||||||
|
|
||||||
// get architecture index for the passed variant
|
|
||||||
#define ARM_VARIANT_ARCH(_V) \
|
|
||||||
({ \
|
|
||||||
Uns32 _IV = ARM_INSTRUCTION_VERSION(_V); \
|
|
||||||
(_IV>=7) ? 0xf : \
|
|
||||||
(_IV==6) ? 0x7 : \
|
|
||||||
(_IV==5) && ((_V)&ARM_J) ? 0x6 : \
|
|
||||||
(_IV==5) && ((_V)&ARM_VD2) ? 0x5 : \
|
|
||||||
(_IV==5) && ((_V)&ARM_VT) ? 0x4 : \
|
|
||||||
(_IV==5) ? 0x3 : \
|
|
||||||
(_IV==4) && ((_V)&ARM_VT) ? 0x2 : \
|
|
||||||
(_IV==4) ? 0x1 : 0x0; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiAttrs.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armStructure.h"
|
|
||||||
#include "armFunctions.h"
|
|
||||||
|
|
||||||
static const char *dictNames[] = {"PRIV", "USER", "PRIV_MPU", "USER_MPU", "ARM", 0};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Configuration block for instruction-accurate modelling
|
|
||||||
//
|
|
||||||
const vmiIASAttr modelAttrs = {
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// VERSION & SIZE ATTRIBUTES
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
.versionString = VMI_VERSION,
|
|
||||||
.modelType = VMI_PROCESSOR_MODEL,
|
|
||||||
.dictNames = dictNames,
|
|
||||||
.cpuSize = sizeof(arm),
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// CREATE/DELETE ROUTINES
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
.constructorCB = armConstructor,
|
|
||||||
.vmInitCB = armVMInit,
|
|
||||||
.destructorCB = armDestructor,
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// MORPHER CORE ROUTINES
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
.morphCB = armMorphInstruction,
|
|
||||||
.fetchSnapCB = armFetchSnap,
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// SIMULATION SUPPORT ROUTINES
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
.getEndianCB = armGetEndian,
|
|
||||||
.nextPCCB = armNextInstruction,
|
|
||||||
.disCB = armDisassemble,
|
|
||||||
.switchCB = armContextSwitchCB,
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// EXCEPTION ROUTINES
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
.rdPrivExceptCB = armRdPrivExceptionCB,
|
|
||||||
.wrPrivExceptCB = armWrPrivExceptionCB,
|
|
||||||
.rdAlignExceptCB = armRdAlignExceptionCB,
|
|
||||||
.wrAlignExceptCB = armWrAlignExceptionCB,
|
|
||||||
.rdAbortExceptCB = armRdAbortExceptionCB,
|
|
||||||
.wrAbortExceptCB = armWrAbortExceptionCB,
|
|
||||||
.arithExceptCB = armArithExceptionCB,
|
|
||||||
.ifetchExceptCB = armIFetchExceptionCB,
|
|
||||||
.icountExceptCB = armICountPendingCB,
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// DEBUGGER INTEGRATION SUPPORT ROUTINES
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
.regGroupCB = armRegGroup,
|
|
||||||
.regInfoCB = armRegInfo,
|
|
||||||
.exceptionInfoCB = armExceptionInfo,
|
|
||||||
.modeInfoCB = armModeInfo,
|
|
||||||
.getExceptionCB = armGetException,
|
|
||||||
.getModeCB = armGetMode,
|
|
||||||
.debugCB = armDumpRegisters,
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// PARAMETER SUPPORT ROUTINES
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
.paramSpecsCB = armGetParamSpec,
|
|
||||||
.paramValueSizeCB = armParamValueSize,
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// PORT ROUTINES
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
.busPortSpecsCB = armGetBusPortSpec,
|
|
||||||
.netPortSpecsCB = armGetNetPortSpec,
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// IMPERAS INTERCEPTED FUNCTION SUPPORT ROUTINES
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
.intReturnCB = armIntReturnCB,
|
|
||||||
.intResultCB = armIntResultCB,
|
|
||||||
.intParCB = armIntParCB,
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROCESSOR INFO ROUTINE
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
.procInfoCB = armProcInfo,
|
|
||||||
};
|
|
||||||
@ -1,488 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armConfig.h"
|
|
||||||
#include "armVariant.h"
|
|
||||||
|
|
||||||
const struct armConfigS armConfigTable[] = {
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ISA CONFIGURATIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
{.name = "ARMv7-M", .arch = ARM_V7, .rotateUnaligned = True},
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROCESSOR MODEL CONFIGURATIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
{
|
|
||||||
.name = "Cortex-M3",
|
|
||||||
.arch = ARM_V7,
|
|
||||||
.numInterrupts = 16,
|
|
||||||
.rotateUnaligned = False,
|
|
||||||
.align64as32 = True, // ARMv7-M has no 64-bit load/stores
|
|
||||||
.STRoffsetPC12 = False, // required value for ARMv7 on
|
|
||||||
.priorityBitsM1 = 2, // number of priority bits (minus 1)
|
|
||||||
|
|
||||||
.regDefaults = {
|
|
||||||
.CPUID = {
|
|
||||||
.REVISION = 0,
|
|
||||||
.PARTNO = 0xc23,
|
|
||||||
.ARCHITECTURE = 0xf,
|
|
||||||
.VARIANT = 0x2,
|
|
||||||
.IMPLEMENTER = AI_ARM
|
|
||||||
},
|
|
||||||
.ID_PFR0 = {
|
|
||||||
.State0 = 0, // 32-bit ARM instruction set support
|
|
||||||
.State1 = 3, // Thumb encoding support
|
|
||||||
.State2 = 0, // Jazelle support
|
|
||||||
.State3 = 0 // ThumbEE support
|
|
||||||
},
|
|
||||||
.ID_PFR1 = {
|
|
||||||
.ProgrammersModel = 0, // ARM programmer's model
|
|
||||||
.SecurityExtension = 0, // Security Extensions support
|
|
||||||
.MicroProgrammersModel = 2 // Microcontroller programmer's model
|
|
||||||
},
|
|
||||||
.ID_DFR0 = {
|
|
||||||
.CoreDebug = 0, // Core debug model
|
|
||||||
.SecureDebug = 0, // Secure debug model
|
|
||||||
.EmbeddedDebug = 0, // Embedded debug model
|
|
||||||
.TraceDebugCP = 0, // Trace debug model, coprocessor-based
|
|
||||||
.TraceDebugMM = 0, // Trace debug model, memory mapped
|
|
||||||
.MicroDebug = 0, // Microcontroller debug model
|
|
||||||
},
|
|
||||||
.ID_MMFR0 = {
|
|
||||||
.VMSA = 0, // VMSA support
|
|
||||||
.PMSA = 3, // PMSA support
|
|
||||||
.Cache_Agent = 0, // Cache coherency + CPU agent
|
|
||||||
.Cache_DMA = 0, // Cache coherency + associated DMA
|
|
||||||
.TCM_DMA = 0, // TCM + associated DMA
|
|
||||||
.AuxControl = 0, // ARMv6 Auxillary Control register
|
|
||||||
.FCSE = 0, // FCSE support
|
|
||||||
},
|
|
||||||
.ID_MMFR1 = {
|
|
||||||
.L1VAHarvard = 0, // L1 maintainence by VA, Harvard
|
|
||||||
.L1VAUnified = 0, // L1 maintainence by VA, unified
|
|
||||||
.L1SWHarvard = 0, // L1 maintainence by Set/Way, Harvard
|
|
||||||
.L1SWUnified = 0, // L1 maintainence by Set/Way, unified
|
|
||||||
.L1Harvard = 0, // L1 maintainence, Harvard
|
|
||||||
.L1Unified = 0, // L1 maintainence, unified
|
|
||||||
.L1TestClean = 0, // L1 test and clean
|
|
||||||
.BTB = 0 // Branch target buffer
|
|
||||||
},
|
|
||||||
.ID_MMFR2 = {
|
|
||||||
.L1FgndPrefetchHarvard = 0, // L1 F/ground cache p/fetch range, Harvard
|
|
||||||
.L1BgndPrefetchHarvard = 0, // L1 B/ground cache p/fetch range, Harvard
|
|
||||||
.L1MaintRangeHarvard = 0, // L1 maintanence range, Harvard
|
|
||||||
.TLBMaintHarvard = 0, // TLB maintanence, Harvard
|
|
||||||
.TLBMaintUnified = 0, // TLB maintanence, Unified
|
|
||||||
.MemoryBarrierCP15 = 0, // Memory Barrier, CP15 based
|
|
||||||
.WaitForInterruptStall = 0, // Wait-for-interrupt stalling
|
|
||||||
.HWAccessFlag = 0 // hardware access flag support
|
|
||||||
},
|
|
||||||
.ID_MMFR3 = {
|
|
||||||
.HierMaintSW = 0, // Hierarchical cache maintainence, set/way
|
|
||||||
.HierMaintMVA = 0, // Hierarchical cache maintainence, MVA
|
|
||||||
.BPMaint = 0, // Branch predictor maintainence
|
|
||||||
},
|
|
||||||
.ID_ISAR0 = {
|
|
||||||
.Swap_instrs = 0, // Atomic instructions
|
|
||||||
.BitCount_instrs = 1, // BitCount instructions
|
|
||||||
.BitField_instrs = 1, // BitField instructions
|
|
||||||
.CmpBranch_instrs = 1, // CmpBranch instructions
|
|
||||||
.Coproc_instrs = 4, // Coprocessor instructions
|
|
||||||
.Debug_instrs = 1, // Debug instructions
|
|
||||||
.Divide_instrs = 1, // Divide instructions
|
|
||||||
},
|
|
||||||
.ID_ISAR1 = {
|
|
||||||
.Endian_instrs = 0, // Endian instructions
|
|
||||||
.Except_instrs = 0, // Exception instructions
|
|
||||||
.Except_AR_instrs = 0, // A/R profile exception instructions
|
|
||||||
.Extend_instrs = 1, // Extend instructions
|
|
||||||
.IfThen_instrs = 1, // IfThen instructions
|
|
||||||
.Immediate_instrs = 1, // Immediate instructions
|
|
||||||
.Interwork_instrs = 2, // Interwork instructions
|
|
||||||
.Jazelle_instrs = 0 // Jazelle instructions
|
|
||||||
},
|
|
||||||
.ID_ISAR2 = {
|
|
||||||
.LoadStore_instrs = 1, // LoadStore instructions
|
|
||||||
.MemHint_instrs = 3, // MemoryHint instructions
|
|
||||||
.MultiAccessInt_instrs = 2, // Multi-access interruptible instructions
|
|
||||||
.Mult_instrs = 2, // Multiply instructions
|
|
||||||
.MultS_instrs = 1, // Multiply instructions, advanced signed
|
|
||||||
.MultU_instrs = 1, // Multiply instructions, advanced unsigned
|
|
||||||
.PSR_AR_instrs = 1, // A/R profile PSR instructions
|
|
||||||
.Reversal_instrs = 2 // Reversal instructions
|
|
||||||
},
|
|
||||||
.ID_ISAR3 = {
|
|
||||||
.Saturate_instrs = 0, // Saturate instructions
|
|
||||||
.SIMD_instrs = 1, // SIMD instructions
|
|
||||||
.SVC_instrs = 1, // SVC instructions
|
|
||||||
.SynchPrim_instrs = 1, // SynchPrim instructions
|
|
||||||
.TabBranch_instrs = 1, // TableBranch instructions
|
|
||||||
.ThumbCopy_instrs = 1, // ThumbCopy instructions
|
|
||||||
.TrueNOP_instrs = 1, // TrueNOP instructions
|
|
||||||
.T2ExeEnvExtn_instrs = 0 // Thumb-2 Execution env extensions
|
|
||||||
},
|
|
||||||
.ID_ISAR4 = {
|
|
||||||
.Unpriv_instrs = 2, // Unprivileged instructions
|
|
||||||
.WithShifts_instrs = 0, // Shift instructions
|
|
||||||
.Writeback_instrs = 1, // Writeback instructions
|
|
||||||
.SMI_instrs = 0, // SMI instructions
|
|
||||||
.Barrier_instrs = 1, // Barrier instructions
|
|
||||||
.SynchPrim_instrs_frac = 3, // Fractional support for sync primitive instructions
|
|
||||||
.PSR_M_instrs = 1, // M-profile forms of PSR instructions
|
|
||||||
.SWP_frac = 0 // memory system bus locking
|
|
||||||
},
|
|
||||||
.ICTR = {
|
|
||||||
.INTLINESNUM = 0 // number of interrupt lines supported
|
|
||||||
},
|
|
||||||
.ACTLR = {0}, // auxillary control register
|
|
||||||
.MPU_TYPE = {
|
|
||||||
.SEPARATE = 0, // unified MPU
|
|
||||||
.DREGION = 8, // number of data/unified memory regions
|
|
||||||
.IREGION = 0 // number of instruction memory regions
|
|
||||||
},
|
|
||||||
.SYST_CALIB = {
|
|
||||||
.NOREF = 0, // reference clock provided
|
|
||||||
.SKEW = 0, // whether calibration value inexact
|
|
||||||
.TENMS = 0 // 10ms reload value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
.regMasks = {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
.name = "Cortex-M4",
|
|
||||||
.arch = ARM_V7,
|
|
||||||
.numInterrupts = 16,
|
|
||||||
.rotateUnaligned = False,
|
|
||||||
.align64as32 = True, // ARMv7-M has no 64-bit load/stores
|
|
||||||
.STRoffsetPC12 = False, // required value for ARMv7 on
|
|
||||||
.priorityBitsM1 = 2, // number of priority bits (minus 1)
|
|
||||||
|
|
||||||
.regDefaults = {
|
|
||||||
.CPUID = {
|
|
||||||
.REVISION = 1,
|
|
||||||
.PARTNO = 0xc24,
|
|
||||||
.ARCHITECTURE = 0xf,
|
|
||||||
.VARIANT = 0x0,
|
|
||||||
.IMPLEMENTER = AI_ARM
|
|
||||||
},
|
|
||||||
.ID_PFR0 = {
|
|
||||||
.State0 = 0, // 32-bit ARM instruction set support
|
|
||||||
.State1 = 3, // Thumb encoding support
|
|
||||||
.State2 = 0, // Jazelle support
|
|
||||||
.State3 = 0 // ThumbEE support
|
|
||||||
},
|
|
||||||
.ID_PFR1 = {
|
|
||||||
.ProgrammersModel = 0, // ARM programmer's model
|
|
||||||
.SecurityExtension = 0, // Security Extensions support
|
|
||||||
.MicroProgrammersModel = 2 // Microcontroller programmer's model
|
|
||||||
},
|
|
||||||
.ID_DFR0 = {
|
|
||||||
.CoreDebug = 0, // Core debug model
|
|
||||||
.SecureDebug = 0, // Secure debug model
|
|
||||||
.EmbeddedDebug = 0, // Embedded debug model
|
|
||||||
.TraceDebugCP = 0, // Trace debug model, coprocessor-based
|
|
||||||
.TraceDebugMM = 0, // Trace debug model, memory mapped
|
|
||||||
.MicroDebug = 0, // Microcontroller debug model
|
|
||||||
},
|
|
||||||
.ID_MMFR0 = {
|
|
||||||
.VMSA = 0, // VMSA support
|
|
||||||
.PMSA = 3, // PMSA support
|
|
||||||
.Cache_Agent = 0, // Cache coherency + CPU agent
|
|
||||||
.Cache_DMA = 0, // Cache coherency + associated DMA
|
|
||||||
.TCM_DMA = 0, // TCM + associated DMA
|
|
||||||
.AuxControl = 0, // ARMv6 Auxillary Control register
|
|
||||||
.FCSE = 0, // FCSE support
|
|
||||||
},
|
|
||||||
.ID_MMFR1 = {
|
|
||||||
.L1VAHarvard = 0, // L1 maintainence by VA, Harvard
|
|
||||||
.L1VAUnified = 0, // L1 maintainence by VA, unified
|
|
||||||
.L1SWHarvard = 0, // L1 maintainence by Set/Way, Harvard
|
|
||||||
.L1SWUnified = 0, // L1 maintainence by Set/Way, unified
|
|
||||||
.L1Harvard = 0, // L1 maintainence, Harvard
|
|
||||||
.L1Unified = 0, // L1 maintainence, unified
|
|
||||||
.L1TestClean = 0, // L1 test and clean
|
|
||||||
.BTB = 0 // Branch target buffer
|
|
||||||
},
|
|
||||||
.ID_MMFR2 = {
|
|
||||||
.L1FgndPrefetchHarvard = 0, // L1 F/ground cache p/fetch range, Harvard
|
|
||||||
.L1BgndPrefetchHarvard = 0, // L1 B/ground cache p/fetch range, Harvard
|
|
||||||
.L1MaintRangeHarvard = 0, // L1 maintanence range, Harvard
|
|
||||||
.TLBMaintHarvard = 0, // TLB maintanence, Harvard
|
|
||||||
.TLBMaintUnified = 0, // TLB maintanence, Unified
|
|
||||||
.MemoryBarrierCP15 = 0, // Memory Barrier, CP15 based
|
|
||||||
.WaitForInterruptStall = 0, // Wait-for-interrupt stalling
|
|
||||||
.HWAccessFlag = 0 // hardware access flag support
|
|
||||||
},
|
|
||||||
.ID_MMFR3 = {
|
|
||||||
.HierMaintSW = 0, // Hierarchical cache maintainence, set/way
|
|
||||||
.HierMaintMVA = 0, // Hierarchical cache maintainence, MVA
|
|
||||||
.BPMaint = 0, // Branch predictor maintainence
|
|
||||||
},
|
|
||||||
.ID_ISAR0 = {
|
|
||||||
.Swap_instrs = 0, // Atomic instructions
|
|
||||||
.BitCount_instrs = 1, // BitCount instructions
|
|
||||||
.BitField_instrs = 1, // BitField instructions
|
|
||||||
.CmpBranch_instrs = 1, // CmpBranch instructions
|
|
||||||
.Coproc_instrs = 4, // Coprocessor instructions
|
|
||||||
.Debug_instrs = 1, // Debug instructions
|
|
||||||
.Divide_instrs = 1, // Divide instructions
|
|
||||||
},
|
|
||||||
.ID_ISAR1 = {
|
|
||||||
.Endian_instrs = 0, // Endian instructions
|
|
||||||
.Except_instrs = 0, // Exception instructions
|
|
||||||
.Except_AR_instrs = 0, // A/R profile exception instructions
|
|
||||||
.Extend_instrs = 2, // Extend instructions
|
|
||||||
.IfThen_instrs = 1, // IfThen instructions
|
|
||||||
.Immediate_instrs = 1, // Immediate instructions
|
|
||||||
.Interwork_instrs = 2, // Interwork instructions
|
|
||||||
.Jazelle_instrs = 0 // Jazelle instructions
|
|
||||||
},
|
|
||||||
.ID_ISAR2 = {
|
|
||||||
.LoadStore_instrs = 1, // LoadStore instructions
|
|
||||||
.MemHint_instrs = 3, // MemoryHint instructions
|
|
||||||
.MultiAccessInt_instrs = 2, // Multi-access interruptible instructions
|
|
||||||
.Mult_instrs = 2, // Multiply instructions
|
|
||||||
.MultS_instrs = 3, // Multiply instructions, advanced signed
|
|
||||||
.MultU_instrs = 2, // Multiply instructions, advanced unsigned
|
|
||||||
.PSR_AR_instrs = 1, // A/R profile PSR instructions
|
|
||||||
.Reversal_instrs = 2 // Reversal instructions
|
|
||||||
},
|
|
||||||
.ID_ISAR3 = {
|
|
||||||
.Saturate_instrs = 1, // Saturate instructions
|
|
||||||
.SIMD_instrs = 3, // SIMD instructions
|
|
||||||
.SVC_instrs = 1, // SVC instructions
|
|
||||||
.SynchPrim_instrs = 1, // SynchPrim instructions
|
|
||||||
.TabBranch_instrs = 1, // TableBranch instructions
|
|
||||||
.ThumbCopy_instrs = 1, // ThumbCopy instructions
|
|
||||||
.TrueNOP_instrs = 1, // TrueNOP instructions
|
|
||||||
.T2ExeEnvExtn_instrs = 0 // Thumb-2 Execution env extensions
|
|
||||||
},
|
|
||||||
.ID_ISAR4 = {
|
|
||||||
.Unpriv_instrs = 2, // Unprivileged instructions
|
|
||||||
.WithShifts_instrs = 3, // Shift instructions
|
|
||||||
.Writeback_instrs = 1, // Writeback instructions
|
|
||||||
.SMI_instrs = 0, // SMI instructions
|
|
||||||
.Barrier_instrs = 1, // Barrier instructions
|
|
||||||
.SynchPrim_instrs_frac = 3, // Fractional support for sync primitive instructions
|
|
||||||
.PSR_M_instrs = 1, // M-profile forms of PSR instructions
|
|
||||||
.SWP_frac = 0 // memory system bus locking
|
|
||||||
},
|
|
||||||
.ICTR = {
|
|
||||||
.INTLINESNUM = 0 // number of interrupt lines supported
|
|
||||||
},
|
|
||||||
.ACTLR = {0}, // auxillary control register
|
|
||||||
.MPU_TYPE = {
|
|
||||||
.SEPARATE = 0, // unified MPU
|
|
||||||
.DREGION = 8, // number of data/unified memory regions
|
|
||||||
.IREGION = 0 // number of instruction memory regions
|
|
||||||
},
|
|
||||||
.SYST_CALIB = {
|
|
||||||
.NOREF = 0, // reference clock provided
|
|
||||||
.SKEW = 0, // whether calibration value inexact
|
|
||||||
.TENMS = 0 // 10ms reload value
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
.regMasks = {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
.name = "Cortex-M4F",
|
|
||||||
.arch = ARM_V7,
|
|
||||||
.numInterrupts = 16,
|
|
||||||
.rotateUnaligned = False,
|
|
||||||
.align64as32 = True, // ARMv7-M has no 64-bit load/stores
|
|
||||||
.STRoffsetPC12 = False, // required value for ARMv7 on
|
|
||||||
.priorityBitsM1 = 2, // number of priority bits (minus 1)
|
|
||||||
|
|
||||||
.regDefaults = {
|
|
||||||
.CPUID = {
|
|
||||||
.REVISION = 1,
|
|
||||||
.PARTNO = 0xc24,
|
|
||||||
.ARCHITECTURE = 0xf,
|
|
||||||
.VARIANT = 0x0,
|
|
||||||
.IMPLEMENTER = AI_ARM
|
|
||||||
},
|
|
||||||
.ID_PFR0 = {
|
|
||||||
.State0 = 0, // 32-bit ARM instruction set support
|
|
||||||
.State1 = 3, // Thumb encoding support
|
|
||||||
.State2 = 0, // Jazelle support
|
|
||||||
.State3 = 0 // ThumbEE support
|
|
||||||
},
|
|
||||||
.ID_PFR1 = {
|
|
||||||
.ProgrammersModel = 0, // ARM programmer's model
|
|
||||||
.SecurityExtension = 0, // Security Extensions support
|
|
||||||
.MicroProgrammersModel = 2 // Microcontroller programmer's model
|
|
||||||
},
|
|
||||||
.ID_DFR0 = {
|
|
||||||
.CoreDebug = 0, // Core debug model
|
|
||||||
.SecureDebug = 0, // Secure debug model
|
|
||||||
.EmbeddedDebug = 0, // Embedded debug model
|
|
||||||
.TraceDebugCP = 0, // Trace debug model, coprocessor-based
|
|
||||||
.TraceDebugMM = 0, // Trace debug model, memory mapped
|
|
||||||
.MicroDebug = 0, // Microcontroller debug model
|
|
||||||
},
|
|
||||||
.ID_MMFR0 = {
|
|
||||||
.VMSA = 0, // VMSA support
|
|
||||||
.PMSA = 3, // PMSA support
|
|
||||||
.Cache_Agent = 0, // Cache coherency + CPU agent
|
|
||||||
.Cache_DMA = 0, // Cache coherency + associated DMA
|
|
||||||
.TCM_DMA = 0, // TCM + associated DMA
|
|
||||||
.AuxControl = 0, // ARMv6 Auxillary Control register
|
|
||||||
.FCSE = 0, // FCSE support
|
|
||||||
},
|
|
||||||
.ID_MMFR1 = {
|
|
||||||
.L1VAHarvard = 0, // L1 maintainence by VA, Harvard
|
|
||||||
.L1VAUnified = 0, // L1 maintainence by VA, unified
|
|
||||||
.L1SWHarvard = 0, // L1 maintainence by Set/Way, Harvard
|
|
||||||
.L1SWUnified = 0, // L1 maintainence by Set/Way, unified
|
|
||||||
.L1Harvard = 0, // L1 maintainence, Harvard
|
|
||||||
.L1Unified = 0, // L1 maintainence, unified
|
|
||||||
.L1TestClean = 0, // L1 test and clean
|
|
||||||
.BTB = 0 // Branch target buffer
|
|
||||||
},
|
|
||||||
.ID_MMFR2 = {
|
|
||||||
.L1FgndPrefetchHarvard = 0, // L1 F/ground cache p/fetch range, Harvard
|
|
||||||
.L1BgndPrefetchHarvard = 0, // L1 B/ground cache p/fetch range, Harvard
|
|
||||||
.L1MaintRangeHarvard = 0, // L1 maintanence range, Harvard
|
|
||||||
.TLBMaintHarvard = 0, // TLB maintanence, Harvard
|
|
||||||
.TLBMaintUnified = 0, // TLB maintanence, Unified
|
|
||||||
.MemoryBarrierCP15 = 0, // Memory Barrier, CP15 based
|
|
||||||
.WaitForInterruptStall = 0, // Wait-for-interrupt stalling
|
|
||||||
.HWAccessFlag = 0 // hardware access flag support
|
|
||||||
},
|
|
||||||
.ID_MMFR3 = {
|
|
||||||
.HierMaintSW = 0, // Hierarchical cache maintainence, set/way
|
|
||||||
.HierMaintMVA = 0, // Hierarchical cache maintainence, MVA
|
|
||||||
.BPMaint = 0, // Branch predictor maintainence
|
|
||||||
},
|
|
||||||
.ID_ISAR0 = {
|
|
||||||
.Swap_instrs = 0, // Atomic instructions
|
|
||||||
.BitCount_instrs = 1, // BitCount instructions
|
|
||||||
.BitField_instrs = 1, // BitField instructions
|
|
||||||
.CmpBranch_instrs = 1, // CmpBranch instructions
|
|
||||||
.Coproc_instrs = 4, // Coprocessor instructions
|
|
||||||
.Debug_instrs = 1, // Debug instructions
|
|
||||||
.Divide_instrs = 1, // Divide instructions
|
|
||||||
},
|
|
||||||
.ID_ISAR1 = {
|
|
||||||
.Endian_instrs = 0, // Endian instructions
|
|
||||||
.Except_instrs = 0, // Exception instructions
|
|
||||||
.Except_AR_instrs = 0, // A/R profile exception instructions
|
|
||||||
.Extend_instrs = 2, // Extend instructions
|
|
||||||
.IfThen_instrs = 1, // IfThen instructions
|
|
||||||
.Immediate_instrs = 1, // Immediate instructions
|
|
||||||
.Interwork_instrs = 2, // Interwork instructions
|
|
||||||
.Jazelle_instrs = 0 // Jazelle instructions
|
|
||||||
},
|
|
||||||
.ID_ISAR2 = {
|
|
||||||
.LoadStore_instrs = 1, // LoadStore instructions
|
|
||||||
.MemHint_instrs = 3, // MemoryHint instructions
|
|
||||||
.MultiAccessInt_instrs = 2, // Multi-access interruptible instructions
|
|
||||||
.Mult_instrs = 2, // Multiply instructions
|
|
||||||
.MultS_instrs = 3, // Multiply instructions, advanced signed
|
|
||||||
.MultU_instrs = 2, // Multiply instructions, advanced unsigned
|
|
||||||
.PSR_AR_instrs = 1, // A/R profile PSR instructions
|
|
||||||
.Reversal_instrs = 2 // Reversal instructions
|
|
||||||
},
|
|
||||||
.ID_ISAR3 = {
|
|
||||||
.Saturate_instrs = 1, // Saturate instructions
|
|
||||||
.SIMD_instrs = 3, // SIMD instructions
|
|
||||||
.SVC_instrs = 1, // SVC instructions
|
|
||||||
.SynchPrim_instrs = 1, // SynchPrim instructions
|
|
||||||
.TabBranch_instrs = 1, // TableBranch instructions
|
|
||||||
.ThumbCopy_instrs = 1, // ThumbCopy instructions
|
|
||||||
.TrueNOP_instrs = 1, // TrueNOP instructions
|
|
||||||
.T2ExeEnvExtn_instrs = 0 // Thumb-2 Execution env extensions
|
|
||||||
},
|
|
||||||
.ID_ISAR4 = {
|
|
||||||
.Unpriv_instrs = 2, // Unprivileged instructions
|
|
||||||
.WithShifts_instrs = 3, // Shift instructions
|
|
||||||
.Writeback_instrs = 1, // Writeback instructions
|
|
||||||
.SMI_instrs = 0, // SMI instructions
|
|
||||||
.Barrier_instrs = 1, // Barrier instructions
|
|
||||||
.SynchPrim_instrs_frac = 3, // Fractional support for sync primitive instructions
|
|
||||||
.PSR_M_instrs = 1, // M-profile forms of PSR instructions
|
|
||||||
.SWP_frac = 0 // memory system bus locking
|
|
||||||
},
|
|
||||||
.ICTR = {
|
|
||||||
.INTLINESNUM = 0 // number of interrupt lines supported
|
|
||||||
},
|
|
||||||
.ACTLR = {0}, // auxillary control register
|
|
||||||
.MPU_TYPE = {
|
|
||||||
.SEPARATE = 0, // unified MPU
|
|
||||||
.DREGION = 8, // number of data/unified memory regions
|
|
||||||
.IREGION = 0 // number of instruction memory regions
|
|
||||||
},
|
|
||||||
.SYST_CALIB = {
|
|
||||||
.NOREF = 0, // reference clock provided
|
|
||||||
.SKEW = 0, // whether calibration value inexact
|
|
||||||
.TENMS = 0 // 10ms reload value
|
|
||||||
},
|
|
||||||
.MVFR0 = {
|
|
||||||
.A_SIMD_Registers = 1, // 16x64-bit media register bank
|
|
||||||
.SinglePrecision = 2, // single precision supported
|
|
||||||
.DoublePrecision = 0, // double precision not supported
|
|
||||||
.VFP_ExceptionTrap = 0, // trapped exceptions not supported
|
|
||||||
.Divide = 1, // VFP hardware divide supported
|
|
||||||
.SquareRoot = 1, // VFP hardware square root supported
|
|
||||||
.ShortVectors = 0, // VFP short vector not supported
|
|
||||||
.VFP_RoundingModes = 1 // all VFP rounding modes supported
|
|
||||||
},
|
|
||||||
.MVFR1 = {
|
|
||||||
.FlushToZeroMode = 1, // VFP denormal arithmetic supported
|
|
||||||
.DefaultNaNMode = 1, // VFP NaN propagation supported
|
|
||||||
.VFP_HalfPrecision = 1, // VFP half-precision not supported
|
|
||||||
.VFP_FusedMAC = 1, // Fused multiply accumulate supported
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
.regMasks = {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// null terminator
|
|
||||||
{0}
|
|
||||||
};
|
|
||||||
|
|
||||||
@ -1,683 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Standard header files
|
|
||||||
#include "string.h"
|
|
||||||
#include "stdio.h"
|
|
||||||
|
|
||||||
// Imperas header files
|
|
||||||
#include "hostapi/impAlloc.h"
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiAttrs.h"
|
|
||||||
#include "vmi/vmiDbg.h"
|
|
||||||
#include "vmi/vmiMessage.h"
|
|
||||||
#include "vmi/vmiOSLib.h"
|
|
||||||
#include "vmi/vmiRt.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armRegisters.h"
|
|
||||||
#include "armStructure.h"
|
|
||||||
#include "armUtils.h"
|
|
||||||
#include "armSys.h"
|
|
||||||
#include "armVFP.h"
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Prefix for messages from this module
|
|
||||||
//
|
|
||||||
#define CPU_PREFIX "ARM_DEBUG"
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// REGISTER GROUPS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// This describes the register groups in the processor
|
|
||||||
//
|
|
||||||
typedef enum armRegGroupIdE {
|
|
||||||
ARM_RG_CORE, // Core group
|
|
||||||
ARM_RG_CONTROL, // control register group
|
|
||||||
ARM_RG_SYSTEM, // memory-mapped system register group
|
|
||||||
ARM_RG_FPR, // VFP register group
|
|
||||||
ARM_RG_LAST // KEEP LAST: for sizing
|
|
||||||
} armRegGroupId;
|
|
||||||
|
|
||||||
//
|
|
||||||
// This provides information about each group
|
|
||||||
//
|
|
||||||
static const vmiRegGroup groups[ARM_RG_LAST+1] = {
|
|
||||||
[ARM_RG_CORE] = {name: "Core" },
|
|
||||||
[ARM_RG_CONTROL] = {name: "Control"},
|
|
||||||
[ARM_RG_SYSTEM] = {name: "System" },
|
|
||||||
[ARM_RG_FPR] = {name: "VFP" },
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Macro to specify a the group for a register
|
|
||||||
//
|
|
||||||
#define ARM_GROUP(_G) &groups[ARM_RG_##_G]
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// MACROS FOR REGISTER ACCESS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Macro to specify a register that can be accessed using raw read/write
|
|
||||||
// callbacks
|
|
||||||
//
|
|
||||||
#define ARM_RAW_REG(_R, _G) \
|
|
||||||
VMI_REG_RAW_READ_CB, \
|
|
||||||
VMI_REG_RAW_WRITE_CB, \
|
|
||||||
(void *)ARM_CPU_OFFSET(_R), \
|
|
||||||
_G
|
|
||||||
|
|
||||||
//
|
|
||||||
// Core registers
|
|
||||||
//
|
|
||||||
#define ARM_CORE_REG(_I) ARM_RAW_REG(regs[_I], ARM_GROUP(CORE))
|
|
||||||
|
|
||||||
//
|
|
||||||
// Macro to specify the PC accessible for read/write
|
|
||||||
//
|
|
||||||
#define ARM_PC_RW readPC, writePC, 0, ARM_GROUP(CORE)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Macro to specify access for the stack pointer register
|
|
||||||
//
|
|
||||||
#define ARM_SP_REG(_R) \
|
|
||||||
VMI_REG_RAW_READ_CB, \
|
|
||||||
writeSP, \
|
|
||||||
(void *)ARM_CPU_OFFSET(regs[_R]), \
|
|
||||||
ARM_GROUP(CORE)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Macro to specify the control registers
|
|
||||||
//
|
|
||||||
#define ARM_CONTROL_RW(_ID) read##_ID, write##_ID, 0, ARM_GROUP(CONTROL)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Some registers are hidden in gdb, but we allow access to them
|
|
||||||
//
|
|
||||||
#define ARM_GDB_HIDDEN_INDEX 99
|
|
||||||
#define IS_GDB_HIDDEN_REG(_I) ((_I)>=ARM_GDB_HIDDEN_INDEX)
|
|
||||||
|
|
||||||
//
|
|
||||||
// system registers do not have access
|
|
||||||
//
|
|
||||||
#define ARM_CP_INDEX 0x1000
|
|
||||||
#define IS_SCS_REG(_I) ((_I)>=ARM_CP_INDEX)
|
|
||||||
|
|
||||||
//
|
|
||||||
// VFP registers - must check for existence in the variant
|
|
||||||
//
|
|
||||||
#define ARM_FPSCR_INDEX 24
|
|
||||||
#define ARM_VFP0_INDEX 700
|
|
||||||
#define ARM_VFP15_INDEX 715
|
|
||||||
#define IS_VFP_REG(_I) ((_I)==ARM_FPSCR_INDEX || IS_VFP_DATA_REG(_I))
|
|
||||||
#define IS_VFP_DATA_REG(_I) (((_I)>=ARM_VFP0_INDEX) && ((_I)<=ARM_VFP15_INDEX))
|
|
||||||
#define ARM_VFP_INDEX(_I) ((_I)-ARM_VFP0_INDEX)
|
|
||||||
#define ARM_VFP_DATA_REG(_I) ARM_RAW_REG(vregs.d[_I], ARM_GROUP(FPR))
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DEBUGGER REGISTER INTERFACE
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return current vmiRegInfoCP structure for the passed banked vmiRegInfoCP
|
|
||||||
//
|
|
||||||
vmiRegInfoCP getCurrentInfo(vmiRegInfoCP reg);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return system register id for vmiRegInfoCP
|
|
||||||
//
|
|
||||||
static armSCSRegId getSysId(vmiRegInfoCP reg) {
|
|
||||||
if(!IS_SCS_REG(reg->gdbIndex)) {
|
|
||||||
return SCS_ID(INVALID);
|
|
||||||
} else {
|
|
||||||
return (armSCSRegId)reg->userData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write callback for sp
|
|
||||||
//
|
|
||||||
static VMI_REG_WRITE_FN(writeSP) {
|
|
||||||
armWriteSP((armP)processor, *(Uns32*)buffer);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read callback for pc
|
|
||||||
//
|
|
||||||
static VMI_REG_READ_FN(readPC) {
|
|
||||||
*(Uns32*)buffer = ((Uns32)vmirtGetPC(processor));
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write callback for pc
|
|
||||||
//
|
|
||||||
static VMI_REG_WRITE_FN(writePC) {
|
|
||||||
Uns32 simPC = *(Uns32*)buffer;
|
|
||||||
vmirtSetPC(processor, simPC & ~1);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read callback for PSR
|
|
||||||
//
|
|
||||||
static VMI_REG_READ_FN(readPSR) {
|
|
||||||
*(Uns32*)buffer = armReadCPSR((armP)processor);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write callback for PSR
|
|
||||||
//
|
|
||||||
static VMI_REG_WRITE_FN(writePSR) {
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
armWriteCPSR(arm, *(Uns32*)buffer, PSR_ALL);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read callback for FPSCR
|
|
||||||
//
|
|
||||||
static VMI_REG_READ_FN(readFPSCR) {
|
|
||||||
*(Uns32*)buffer = armReadFPSCR((armP)processor);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write callback for FPSCR
|
|
||||||
//
|
|
||||||
static VMI_REG_WRITE_FN(writeFPSCR) {
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
armWriteFPSCR(arm, *(Uns32*)buffer, FPSCR_MASK);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read callback for CONTROL
|
|
||||||
//
|
|
||||||
static VMI_REG_READ_FN(readControl) {
|
|
||||||
*(Uns32*)buffer = armReadCONTROL((armP)processor);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write callback for CONTROL
|
|
||||||
//
|
|
||||||
static VMI_REG_WRITE_FN(writeControl) {
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
armWriteCONTROL(arm, *(Uns32*)buffer);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read callback for PRIMASK
|
|
||||||
//
|
|
||||||
static VMI_REG_READ_FN(readPRIMASK) {
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
*(Uns32*)buffer = arm->sregs.PRIMASK;
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write callback for PRIMASK
|
|
||||||
//
|
|
||||||
static VMI_REG_WRITE_FN(writePRIMASK) {
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
armWritePRIMASK(arm, *(Uns32*)buffer);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read callback for FAULTMASK
|
|
||||||
//
|
|
||||||
static VMI_REG_READ_FN(readFAULTMASK) {
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
*(Uns32*)buffer = arm->sregs.FAULTMASK;
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// Write callback for FAULTMASK
|
|
||||||
//
|
|
||||||
static VMI_REG_WRITE_FN(writeFAULTMASK) {
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
armWriteFAULTMASK(arm, *(Uns32*)buffer);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read callback for FAULTMASK
|
|
||||||
//
|
|
||||||
static VMI_REG_READ_FN(readBASEPRI) {
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
*(Uns32*)buffer = arm->sregs.BASEPRI;
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write callback for BASEPRI
|
|
||||||
//
|
|
||||||
static VMI_REG_WRITE_FN(writeBASEPRI) {
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
armWriteBASEPRI(arm, *(Uns32*)buffer);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read callback for banked register
|
|
||||||
//
|
|
||||||
static VMI_REG_READ_FN(readBank) {
|
|
||||||
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
Bool trueUseSPProcess = USE_SP_PROCESS(arm);
|
|
||||||
Bool tempUseSPProcess = True;
|
|
||||||
|
|
||||||
armSwitchRegs(arm, trueUseSPProcess, tempUseSPProcess);
|
|
||||||
Bool result = vmiosRegRead(processor, getCurrentInfo(reg), buffer);
|
|
||||||
armSwitchRegs(arm, tempUseSPProcess, trueUseSPProcess);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write callback for banked register
|
|
||||||
//
|
|
||||||
static VMI_REG_WRITE_FN(writeBank) {
|
|
||||||
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
Bool trueUseSPProcess = USE_SP_PROCESS(arm);
|
|
||||||
Bool tempUseSPProcess = True;
|
|
||||||
|
|
||||||
armSwitchRegs(arm, trueUseSPProcess, tempUseSPProcess);
|
|
||||||
Bool result = vmiosRegWrite(processor, getCurrentInfo(reg), buffer);
|
|
||||||
armSwitchRegs(arm, tempUseSPProcess, trueUseSPProcess);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read callback for system register
|
|
||||||
//
|
|
||||||
static VMI_REG_READ_FN(readSCS) {
|
|
||||||
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
armSCSRegId id = getSysId(reg);
|
|
||||||
|
|
||||||
if(!armReadSysRegPriv(id, arm, (Uns32*)buffer)) {
|
|
||||||
|
|
||||||
return False;
|
|
||||||
|
|
||||||
} else if(id!=SCS_ID(CPUID)) {
|
|
||||||
|
|
||||||
return True;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
union {Uns32 u32; SCS_REG_DECL(CPUID);} u = {*(Uns32*)buffer};
|
|
||||||
|
|
||||||
if(!u.u32) {
|
|
||||||
armArchitecture variant = arm->configInfo.arch;
|
|
||||||
u.CPUID.ARCHITECTURE = ARM_VARIANT_ARCH(variant);
|
|
||||||
*(Uns32*)buffer = u.u32;
|
|
||||||
}
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write callback for system register
|
|
||||||
//
|
|
||||||
static VMI_REG_WRITE_FN(writeSCS) {
|
|
||||||
return armWriteSysRegPriv(getSysId(reg), (armP)processor, *(Uns32*)buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Static const array holding information about the registers in the cpu,
|
|
||||||
// used for debugger interaction
|
|
||||||
//
|
|
||||||
static const vmiRegInfo basicRegisters[] = {
|
|
||||||
|
|
||||||
// current mode registers (visible in gdb)
|
|
||||||
{"r0", 0, vmi_REG_NONE, 32, False, ARM_CORE_REG(0) },
|
|
||||||
{"r1", 1, vmi_REG_NONE, 32, False, ARM_CORE_REG(1) },
|
|
||||||
{"r2", 2, vmi_REG_NONE, 32, False, ARM_CORE_REG(2) },
|
|
||||||
{"r3", 3, vmi_REG_NONE, 32, False, ARM_CORE_REG(3) },
|
|
||||||
{"r4", 4, vmi_REG_NONE, 32, False, ARM_CORE_REG(4) },
|
|
||||||
{"r5", 5, vmi_REG_NONE, 32, False, ARM_CORE_REG(5) },
|
|
||||||
{"r6", 6, vmi_REG_NONE, 32, False, ARM_CORE_REG(6) },
|
|
||||||
{"r7", 7, vmi_REG_NONE, 32, False, ARM_CORE_REG(7) },
|
|
||||||
{"r8", 8, vmi_REG_NONE, 32, False, ARM_CORE_REG(8) },
|
|
||||||
{"r9", 9, vmi_REG_NONE, 32, False, ARM_CORE_REG(9) },
|
|
||||||
{"r10", 10, vmi_REG_NONE, 32, False, ARM_CORE_REG(10) },
|
|
||||||
{"r11", 11, vmi_REG_FP, 32, False, ARM_CORE_REG(11) },
|
|
||||||
{"r12", 12, vmi_REG_NONE, 32, False, ARM_CORE_REG(12) },
|
|
||||||
{"sp", 13, vmi_REG_SP, 32, False, ARM_SP_REG (13) },
|
|
||||||
{"lr", 14, vmi_REG_NONE, 32, False, ARM_CORE_REG(14) },
|
|
||||||
{"pc", 15, vmi_REG_PC, 32, False, ARM_PC_RW },
|
|
||||||
{"fps", 24, vmi_REG_NONE, 32, False, ARM_CONTROL_RW(FPSCR) },
|
|
||||||
{"cpsr", 25, vmi_REG_NONE, 32, False, ARM_CONTROL_RW(PSR) },
|
|
||||||
|
|
||||||
// control and SP_process (not visible in gdb)
|
|
||||||
{"control", 100, vmi_REG_NONE, 32, False, ARM_CONTROL_RW(Control)},
|
|
||||||
{"primask", 101, vmi_REG_NONE, 32, False, ARM_CONTROL_RW(PRIMASK)},
|
|
||||||
{"faultmask", 102, vmi_REG_NONE, 32, False, ARM_CONTROL_RW(FAULTMASK)},
|
|
||||||
{"basepri", 103, vmi_REG_NONE, 32, False, ARM_CONTROL_RW(BASEPRI)},
|
|
||||||
{"sp_process", 113, vmi_REG_SP, 32, False, ARM_CONTROL_RW(Bank) },
|
|
||||||
|
|
||||||
// VFP registers - double word view only (not visible in gdb)
|
|
||||||
{"d0", 700, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(0) },
|
|
||||||
{"d1", 701, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(1) },
|
|
||||||
{"d2", 702, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(2) },
|
|
||||||
{"d3", 703, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(3) },
|
|
||||||
{"d4", 704, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(4) },
|
|
||||||
{"d5", 705, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(5) },
|
|
||||||
{"d6", 706, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(6) },
|
|
||||||
{"d7", 707, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(7) },
|
|
||||||
{"d8", 708, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(8) },
|
|
||||||
{"d9", 709, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(9) },
|
|
||||||
{"d10", 710, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(10)},
|
|
||||||
{"d11", 711, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(11)},
|
|
||||||
{"d12", 712, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(12)},
|
|
||||||
{"d13", 713, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(13)},
|
|
||||||
{"d14", 714, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(14)},
|
|
||||||
{"d15", 715, vmi_REG_NONE, 64, False, ARM_VFP_DATA_REG(15)},
|
|
||||||
|
|
||||||
{0},
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return ARM register descriptions
|
|
||||||
//
|
|
||||||
static vmiRegInfoCP getRegisters(void) {
|
|
||||||
|
|
||||||
static vmiRegInfo *allRegisters;
|
|
||||||
|
|
||||||
if(!allRegisters) {
|
|
||||||
|
|
||||||
armSysRegDesc desc;
|
|
||||||
Uns32 basicNum = 0;
|
|
||||||
Uns32 sysNum = 0;
|
|
||||||
Uns32 i;
|
|
||||||
|
|
||||||
// count basic registers
|
|
||||||
while(basicRegisters[basicNum].name) {
|
|
||||||
basicNum++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// count system registers
|
|
||||||
desc.name = 0;
|
|
||||||
while(armGetSysRegisterDesc(&desc)) {
|
|
||||||
sysNum++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate full register information, including terminating NULL entry
|
|
||||||
// TODO: This is never freed! Need to free description too
|
|
||||||
allRegisters = STYPE_CALLOC_N(vmiRegInfo, basicNum+sysNum+1);
|
|
||||||
|
|
||||||
// fill basic entries
|
|
||||||
for(i=0; i<basicNum; i++) {
|
|
||||||
allRegisters[i] = basicRegisters[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// fill system entries
|
|
||||||
for(desc.name=0, i=0; armGetSysRegisterDesc(&desc); i++) {
|
|
||||||
|
|
||||||
vmiRegInfo *reg = &allRegisters[basicNum+i];
|
|
||||||
|
|
||||||
// fill basic fields
|
|
||||||
reg->name = desc.name;
|
|
||||||
reg->usage = vmi_REG_NONE;
|
|
||||||
reg->bits = 32;
|
|
||||||
reg->readonly = False;
|
|
||||||
reg->readCB = readSCS;
|
|
||||||
reg->writeCB = writeSCS;
|
|
||||||
reg->userData = (void *)desc.id;
|
|
||||||
reg->group = ARM_GROUP(SYSTEM);
|
|
||||||
|
|
||||||
// synthesize a description
|
|
||||||
char descStr[64];
|
|
||||||
snprintf(descStr, 64, "Addr: 0x%08x Priv:%s User:%s", desc.address, desc.privRW, desc.userRW);
|
|
||||||
reg->description = strdup(descStr);
|
|
||||||
|
|
||||||
// use address as gdb pseudo-index
|
|
||||||
reg->gdbIndex = desc.address;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return register set
|
|
||||||
return allRegisters;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return current vmiRegInfoCP structure for the passed banked vmiRegInfoCP
|
|
||||||
//
|
|
||||||
vmiRegInfoCP getCurrentInfo(vmiRegInfoCP reg) {
|
|
||||||
|
|
||||||
Uns32 index = reg->gdbIndex % 100;
|
|
||||||
vmiRegInfoCP info;
|
|
||||||
|
|
||||||
for(info=getRegisters(); info->name; info++) {
|
|
||||||
if(info->gdbIndex == index) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Is the passed register supported on this processor?
|
|
||||||
//
|
|
||||||
static Bool isRegSupported(armP arm, vmiRegInfoCP reg, Bool gdbFrame) {
|
|
||||||
|
|
||||||
if(gdbFrame && IS_GDB_HIDDEN_REG(reg->gdbIndex)) {
|
|
||||||
|
|
||||||
// if this is a GDB frame request then registers that should be hidden
|
|
||||||
// from GDB should be ignored
|
|
||||||
return False;
|
|
||||||
|
|
||||||
} else if(IS_VFP_REG(reg->gdbIndex)) {
|
|
||||||
|
|
||||||
// VFP registers are supported if in variant
|
|
||||||
return FPU_PRESENT(arm);
|
|
||||||
|
|
||||||
} else if(IS_SCS_REG(reg->gdbIndex)) {
|
|
||||||
|
|
||||||
// system registers are supported only if the associated unit is present
|
|
||||||
return armGetSysRegSupported(getSysId(reg), arm);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// other registers are always supported
|
|
||||||
return True;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return next supported register on this processor
|
|
||||||
//
|
|
||||||
static vmiRegInfoCP getNextRegister(armP arm, vmiRegInfoCP reg, Bool gdbFrame) {
|
|
||||||
|
|
||||||
do {
|
|
||||||
if(!reg) {
|
|
||||||
reg = getRegisters();
|
|
||||||
} else if((reg+1)->name) {
|
|
||||||
reg = reg+1;
|
|
||||||
} else {
|
|
||||||
reg = 0;
|
|
||||||
}
|
|
||||||
} while(reg && !isRegSupported(arm, reg, gdbFrame));
|
|
||||||
|
|
||||||
return reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Is the passed register group supported on this processor?
|
|
||||||
//
|
|
||||||
static Bool isGroupSupported(armP arm, vmiRegGroupCP group) {
|
|
||||||
|
|
||||||
vmiRegInfoCP info = 0;
|
|
||||||
|
|
||||||
while((info=getNextRegister(arm, info, False))) {
|
|
||||||
if(info->group == group) {
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return next supported group on this processor
|
|
||||||
//
|
|
||||||
static vmiRegGroupCP getNextGroup(armP arm, vmiRegGroupCP group) {
|
|
||||||
|
|
||||||
do {
|
|
||||||
if(!group) {
|
|
||||||
group = groups;
|
|
||||||
} else if((group+1)->name) {
|
|
||||||
group = group+1;
|
|
||||||
} else {
|
|
||||||
group = 0;
|
|
||||||
}
|
|
||||||
} while(group && !isGroupSupported(arm, group));
|
|
||||||
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Register structure iterator
|
|
||||||
//
|
|
||||||
VMI_REG_INFO_FN(armRegInfo) {
|
|
||||||
return getNextRegister((armP)processor, prev, gdbFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Register group iterator
|
|
||||||
//
|
|
||||||
VMI_REG_GROUP_FN(armRegGroup) {
|
|
||||||
return getNextGroup((armP)processor, prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// REGISTER DUMP INTERFACE
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Dump processor registers
|
|
||||||
//
|
|
||||||
VMI_DEBUG_FN(armDumpRegisters) {
|
|
||||||
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
Bool showHiddenRegs = arm->showHiddenRegs;
|
|
||||||
Uns32 nameWidth = showHiddenRegs ? 10 : 7;
|
|
||||||
vmiRegInfoCP info = 0;
|
|
||||||
|
|
||||||
while((info=getNextRegister(arm, info, False))) {
|
|
||||||
|
|
||||||
if(IS_SCS_REG(info->gdbIndex)) {
|
|
||||||
|
|
||||||
// ignore system registers
|
|
||||||
|
|
||||||
} else if(IS_VFP_DATA_REG(info->gdbIndex)) {
|
|
||||||
|
|
||||||
// print VFP regs if enabled
|
|
||||||
if(ARM_DUMP_SDFP_REG(arm)) {
|
|
||||||
|
|
||||||
const char *fmt = " %-*s 0x" FMT_640Nx "\n";
|
|
||||||
Uns64 value;
|
|
||||||
|
|
||||||
// read and print register value
|
|
||||||
vmiosRegRead(processor, info, &value);
|
|
||||||
vmiPrintf(fmt, nameWidth, info->name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(!IS_GDB_HIDDEN_REG(info->gdbIndex) || showHiddenRegs) {
|
|
||||||
|
|
||||||
const char *fmt;
|
|
||||||
Uns32 value;
|
|
||||||
|
|
||||||
// read register value
|
|
||||||
vmiosRegRead(processor, info, &value);
|
|
||||||
|
|
||||||
// select approriate format string
|
|
||||||
if((info->usage==vmi_REG_SP) || (info->usage==vmi_REG_PC)) {
|
|
||||||
fmt = " %-*s 0x%-8x 0x%x\n";
|
|
||||||
} else {
|
|
||||||
fmt = " %-*s 0x%-8x %u\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// print register using selected format
|
|
||||||
vmiPrintf(fmt, nameWidth, info->name, value, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// SCS PROGRAMMER'S VIEW
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add programmer's view of all system registers
|
|
||||||
//
|
|
||||||
void armAddSysRegistersView(armP arm, vmiViewObjectP processorObject) {
|
|
||||||
|
|
||||||
vmiRegInfoCP info = 0;
|
|
||||||
|
|
||||||
// create coprocessor 15 child object
|
|
||||||
vmiViewObjectP baseObject = vmirtAddViewObject(processorObject, "SCS", 0);
|
|
||||||
|
|
||||||
while((info=getNextRegister(arm, info, False))) {
|
|
||||||
|
|
||||||
if(IS_SCS_REG(info->gdbIndex)) {
|
|
||||||
|
|
||||||
const char *name = info->name;
|
|
||||||
armSCSRegId id = getSysId(info);
|
|
||||||
|
|
||||||
armAddSysRegisterView(id, arm, baseObject, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiMessage.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armDecodeThumb.h"
|
|
||||||
#include "armDecodeTypes.h"
|
|
||||||
#include "armStructure.h"
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Prefix for messages from this module
|
|
||||||
//
|
|
||||||
#define CPU_PREFIX "ARM_DECODE"
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Decode the instruction at the passed address. The 'info' structure is filled
|
|
||||||
// with details of the instruction.
|
|
||||||
//
|
|
||||||
ARM_DECODER_FN(armDecode) {
|
|
||||||
|
|
||||||
// record current PC in decoded structure
|
|
||||||
info->thisPC = thisPC;
|
|
||||||
|
|
||||||
// do decode (Thumb mode only)
|
|
||||||
armDecodeThumb(arm, thisPC, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the size of the instruction at the passed address and the mode
|
|
||||||
//
|
|
||||||
ARM_ISIZE_FN(armGetInstructionSizeMode) {
|
|
||||||
return isThumb ? armGetThumbInstructionSize(arm, thisPC) : 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the size of the instruction at the passed address
|
|
||||||
//
|
|
||||||
Uns32 armGetInstructionSize(armP arm, Uns32 thisPC) {
|
|
||||||
return armGetInstructionSizeMode(arm, thisPC, IN_THUMB_MODE(arm));
|
|
||||||
}
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,929 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// standard includes
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiCxt.h"
|
|
||||||
#include "vmi/vmiMessage.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armDecode.h"
|
|
||||||
#include "armDisassemble.h"
|
|
||||||
#include "armDisassembleFormats.h"
|
|
||||||
#include "armFunctions.h"
|
|
||||||
#include "armStructure.h"
|
|
||||||
#include "armUtils.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Prefix for messages from this module
|
|
||||||
//
|
|
||||||
#define CPU_PREFIX "ARM_DISASS"
|
|
||||||
|
|
||||||
//
|
|
||||||
// This defines the minimum string width to use for the opcode
|
|
||||||
//
|
|
||||||
#define OP_WIDTH 7
|
|
||||||
|
|
||||||
//
|
|
||||||
// Condition names
|
|
||||||
//
|
|
||||||
static const char *condNames[] = {
|
|
||||||
"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
|
|
||||||
"hi", "ls", "ge", "lt", "gt", "le", "" , ""
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Condition names in an IT block
|
|
||||||
//
|
|
||||||
static const char *condNamesIT[] = {
|
|
||||||
"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
|
|
||||||
"hi", "ls", "ge", "lt", "gt", "le", "al", "al"
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Limitation names
|
|
||||||
//
|
|
||||||
static const char *limNames[] = {
|
|
||||||
"#0", "#1", "oshst", "osh", "#4", "#5", "nshst", "nsh",
|
|
||||||
"#8", "#9", "ishst", "ish", "#12", "#13", "st", "sy"
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Increment/decrement names
|
|
||||||
//
|
|
||||||
static const char *incDecNames[] = {
|
|
||||||
[ARM_ID_NA] = "",
|
|
||||||
[ARM_ID_IA] = "ia",
|
|
||||||
[ARM_ID_IB] = "ib",
|
|
||||||
[ARM_ID_DA] = "da",
|
|
||||||
[ARM_ID_DB] = "db",
|
|
||||||
[ARM_ID_IAI] = "",
|
|
||||||
[ARM_ID_IBI] = "",
|
|
||||||
[ARM_ID_DBI] = "",
|
|
||||||
[ARM_ID_DAI] = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Flag action names
|
|
||||||
//
|
|
||||||
static const char *flagActionNames[] = {
|
|
||||||
[ARM_FACT_NA] = "",
|
|
||||||
[ARM_FACT_BAD] = "",
|
|
||||||
[ARM_FACT_IE] = "ie",
|
|
||||||
[ARM_FACT_ID] = "id"
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Size names
|
|
||||||
//
|
|
||||||
static const char *sizeNames[] = {"", "b", "h", "", "", "", "", "", "d"};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Shift names
|
|
||||||
//
|
|
||||||
static const char *shiftNames[] = {"???", "lsl", "lsr", "asr", "ror", "rrx"};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Names for armSDFPType values
|
|
||||||
// Note most not used in single precision VFP-Only M profile
|
|
||||||
//
|
|
||||||
static const char *ftypeNames[] = {
|
|
||||||
[ARM_SDFPT_NA] = "", // no floating point type
|
|
||||||
[ARM_SDFPT_8] = ".8",
|
|
||||||
[ARM_SDFPT_16] = ".16",
|
|
||||||
[ARM_SDFPT_32] = ".32",
|
|
||||||
[ARM_SDFPT_64] = ".64",
|
|
||||||
[ARM_SDFPT_F16] = ".f16",
|
|
||||||
[ARM_SDFPT_F32] = ".f32",
|
|
||||||
[ARM_SDFPT_F64] = ".f64",
|
|
||||||
[ARM_SDFPT_I8] = ".i8",
|
|
||||||
[ARM_SDFPT_I16] = ".i16",
|
|
||||||
[ARM_SDFPT_I32] = ".i32",
|
|
||||||
[ARM_SDFPT_I64] = ".i64",
|
|
||||||
[ARM_SDFPT_P8] = ".p8",
|
|
||||||
[ARM_SDFPT_S8] = ".s8",
|
|
||||||
[ARM_SDFPT_S16] = ".s16",
|
|
||||||
[ARM_SDFPT_S32] = ".s32",
|
|
||||||
[ARM_SDFPT_S64] = ".s64",
|
|
||||||
[ARM_SDFPT_U8] = ".u8",
|
|
||||||
[ARM_SDFPT_U16] = ".u16",
|
|
||||||
[ARM_SDFPT_U32] = ".u32",
|
|
||||||
[ARM_SDFPT_U64] = ".u64",
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Append the character to to the result
|
|
||||||
//
|
|
||||||
static void putChar(char **result, char ch) {
|
|
||||||
|
|
||||||
// get the tail pointer
|
|
||||||
char *tail = *result;
|
|
||||||
|
|
||||||
// do the append
|
|
||||||
*tail++ = ch;
|
|
||||||
|
|
||||||
// add null terminator
|
|
||||||
*tail = 0;
|
|
||||||
|
|
||||||
// update the tail pointer
|
|
||||||
*result = tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Append the string to to the result
|
|
||||||
//
|
|
||||||
static void putString(char **result, const char *string) {
|
|
||||||
|
|
||||||
// get the tail pointer
|
|
||||||
char *tail = *result;
|
|
||||||
char ch;
|
|
||||||
|
|
||||||
// do the append
|
|
||||||
while((ch=*string++)) {
|
|
||||||
*tail++ = ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add null terminator
|
|
||||||
*tail = 0;
|
|
||||||
|
|
||||||
// update the tail pointer
|
|
||||||
*result = tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Append comma separator, unless previous character is space or comma (allows
|
|
||||||
// for omitted optional arguments)
|
|
||||||
//
|
|
||||||
static void putComma(char **result) {
|
|
||||||
|
|
||||||
char *tail = *result;
|
|
||||||
|
|
||||||
switch(tail[-1]) {
|
|
||||||
case ',':
|
|
||||||
case ' ':
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
putChar(result, ',');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Append right bracket, overwriting any previous comma (allows for omitted
|
|
||||||
// optional arguments)
|
|
||||||
//
|
|
||||||
static void putRBracket(char **result) {
|
|
||||||
|
|
||||||
char *tail = *result;
|
|
||||||
|
|
||||||
switch(tail[-1]) {
|
|
||||||
case ',':
|
|
||||||
tail[-1] = ']';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
putChar(result, ']');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit hexadecimal argument using format 0x%x
|
|
||||||
//
|
|
||||||
static void put0x(char **result, Uns32 value) {
|
|
||||||
char tmp[32];
|
|
||||||
sprintf(tmp, "0x%x", value);
|
|
||||||
putString(result, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit hexadecimal Uns64 argument using format 0x%x
|
|
||||||
//
|
|
||||||
static void put0xll(char **result, Uns64 value) {
|
|
||||||
char tmp[32];
|
|
||||||
sprintf(tmp, "0x"FMT_640Nx, value);
|
|
||||||
putString(result, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit unsigned argument
|
|
||||||
//
|
|
||||||
static void putU(char **result, Uns32 value) {
|
|
||||||
char tmp[32];
|
|
||||||
sprintf(tmp, "%u", value);
|
|
||||||
putString(result, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit floating point argument
|
|
||||||
//
|
|
||||||
static void putF(char **result, Flt64 value) {
|
|
||||||
char tmp[32];
|
|
||||||
sprintf(tmp, "%g", value);
|
|
||||||
putString(result, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit signed argument
|
|
||||||
//
|
|
||||||
static void putD(char **result, Uns32 value) {
|
|
||||||
char tmp[32];
|
|
||||||
sprintf(tmp, "%d", value);
|
|
||||||
putString(result, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit unsigned argument preceded with hash
|
|
||||||
//
|
|
||||||
static void putHashU(char **result, Uns32 value) {
|
|
||||||
putChar(result, '#');
|
|
||||||
putU(result, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit constant 0 floating point argument preceded with hash
|
|
||||||
//
|
|
||||||
static void putHashF0(char **result) {
|
|
||||||
putString(result, "#0.0");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit signed argument preceded with hash, unless optional and zero
|
|
||||||
//
|
|
||||||
static void putHashD(char **result, Uns32 value, Bool opt) {
|
|
||||||
if(!opt || value) {
|
|
||||||
putChar(result, '#');
|
|
||||||
putD(result, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit minus sign if required
|
|
||||||
//
|
|
||||||
static void putMinus(char **result, Bool uBit) {
|
|
||||||
if(!uBit) {
|
|
||||||
putChar(result, '-');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit instruction format if required
|
|
||||||
//
|
|
||||||
static void putInstruction(armP arm, armInstructionInfoP info, char **result) {
|
|
||||||
|
|
||||||
char tmp[32];
|
|
||||||
|
|
||||||
// emit basic opcode string
|
|
||||||
sprintf(tmp, info->bytes==2 ? "%04x " : "%08x ", info->instruction);
|
|
||||||
putString(result, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit GPR argument
|
|
||||||
//
|
|
||||||
static void putGPR(armP arm, char **result, Uns32 r) {
|
|
||||||
putString(result, armGetGPRName(arm, r));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit GPR argument, or flags if r15 and UAL mode
|
|
||||||
//
|
|
||||||
static void putGPROrFlagsIfR15(armP arm, char **result, Uns32 r) {
|
|
||||||
if(!arm->UAL || (r!=15)) {
|
|
||||||
putString(result, armGetGPRName(arm, r));
|
|
||||||
} else {
|
|
||||||
putString(result, "APSR_nzcv");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit singleword register argument
|
|
||||||
//
|
|
||||||
static void putSR(armP arm, char **result, Uns32 r) {
|
|
||||||
putChar(result, 's');
|
|
||||||
putU(result, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit consecutive pair of singleword registers argument
|
|
||||||
//
|
|
||||||
static void putSSR(armP arm, char **result, Uns32 r) {
|
|
||||||
putChar(result, 's');
|
|
||||||
putU(result, r);
|
|
||||||
putString(result, ",s");
|
|
||||||
putU(result, r+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit doubleword register argument
|
|
||||||
//
|
|
||||||
static void putDR(armP arm, char **result, Uns32 r) {
|
|
||||||
putChar(result, 'd');
|
|
||||||
putU(result, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit scalar argument
|
|
||||||
//
|
|
||||||
static void putScalar(armP arm, char **result, Uns32 d, Uns32 index) {
|
|
||||||
putChar(result, 'd');
|
|
||||||
putU(result, d);
|
|
||||||
putChar(result, '[');
|
|
||||||
putU(result, index);
|
|
||||||
putChar(result, ']');
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit CPR argument
|
|
||||||
//
|
|
||||||
static void putCPR(armP arm, char **result, Uns32 r) {
|
|
||||||
putString(result, armGetCPRName(arm, r));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit fpscr argument (M-profile only supports "fpscr" on vmrs/vmsr)
|
|
||||||
//
|
|
||||||
static void putFPSCR(armP arm, char **result) {
|
|
||||||
putString(result, "fpscr");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit jump target
|
|
||||||
//
|
|
||||||
static void putTarget(char **result, Uns32 value) {
|
|
||||||
char tmp[32];
|
|
||||||
sprintf(tmp, "%x", value);
|
|
||||||
putString(result, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit shiftop argument
|
|
||||||
//
|
|
||||||
static void putShift(char **result, armShiftOp so) {
|
|
||||||
putString(result, shiftNames[so]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit constant shift if non-zero
|
|
||||||
//
|
|
||||||
static void putShiftC(char **result, armShiftOp so, Uns32 value) {
|
|
||||||
if(value) {
|
|
||||||
putShift(result, so);
|
|
||||||
putChar(result, ' ');
|
|
||||||
putHashD(result, value, False);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit constant shift equivalent to size if non-zero
|
|
||||||
//
|
|
||||||
static void putSizeShift(char **result, Uns32 sz) {
|
|
||||||
|
|
||||||
Uns32 shift = 0;
|
|
||||||
|
|
||||||
while(sz>1) {
|
|
||||||
sz >>= 1;
|
|
||||||
shift++;
|
|
||||||
}
|
|
||||||
|
|
||||||
putShiftC(result, ARM_SO_LSL, shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit writeback argument
|
|
||||||
//
|
|
||||||
static void putWB(char **result, Bool pi, Bool wb) {
|
|
||||||
if(wb && !pi) {
|
|
||||||
putChar(result, '!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit register list argument
|
|
||||||
//
|
|
||||||
static void putRList(armP arm, char **result, Uns32 rList) {
|
|
||||||
|
|
||||||
Uns32 r;
|
|
||||||
Uns32 mask;
|
|
||||||
Bool first = True;
|
|
||||||
|
|
||||||
putChar(result, '{');
|
|
||||||
|
|
||||||
for(r=0, mask=0x0001; r<16; r++, mask<<=1) {
|
|
||||||
if(rList&mask) {
|
|
||||||
if(!first) {
|
|
||||||
putChar(result, ',');
|
|
||||||
}
|
|
||||||
putGPR(arm, result, r);
|
|
||||||
first = False;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
putChar(result, '}');
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return string for _<bits> of MSR instruction defined
|
|
||||||
// by the instruction's mask field
|
|
||||||
//
|
|
||||||
static char *msrBits(armPSRBits bits) {
|
|
||||||
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
switch (bits) {
|
|
||||||
case ARM_PSRBITS_GE: s = "_g"; break;
|
|
||||||
// Support for the GE bits was added by Arm in Q3 2010 so now
|
|
||||||
// this should be s = "_nzcvq", but toolchains do not seem to support it yet
|
|
||||||
// so continue using the (deprecated) empty string for now
|
|
||||||
case ARM_PSRBITS_FLAGS: s = NULL; break;
|
|
||||||
case ARM_PSRBITS_ALL: s = "_nzcvqg"; break;
|
|
||||||
default: s = NULL; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit special register argument
|
|
||||||
//
|
|
||||||
static void putSpecialReg(char **result, armSysRegId SYSm, armPSRBits bits) {
|
|
||||||
|
|
||||||
const char *regName;
|
|
||||||
const char *bitsName = NULL;
|
|
||||||
|
|
||||||
switch(SYSm) {
|
|
||||||
case ASRID_APSR: regName = "APSR"; bitsName = msrBits(bits); break;
|
|
||||||
case ASRID_IAPSR: regName = "IAPSR"; bitsName = msrBits(bits); break;
|
|
||||||
case ASRID_EAPSR: regName = "EAPSR"; bitsName = msrBits(bits); break;
|
|
||||||
case ASRID_XPSR: regName = "XPSR"; bitsName = msrBits(bits); break;
|
|
||||||
case ASRID_IPSR: regName = "IPSR"; break;
|
|
||||||
case ASRID_EPSR: regName = "EPSR"; break;
|
|
||||||
case ASRID_IEPSR: regName = "IEPSR"; break;
|
|
||||||
case ASRID_MSP: regName = "MSP"; break;
|
|
||||||
case ASRID_PSP: regName = "PSP"; break;
|
|
||||||
case ASRID_PRIMASK: regName = "PRIMASK"; break;
|
|
||||||
case ASRID_BASEPRI: regName = "BASEPRI"; break;
|
|
||||||
case ASRID_BASEPRI_MAX: regName = "BASEPRI_MAX"; break;
|
|
||||||
case ASRID_FAULTMASK: regName = "FAULTMASK"; break;
|
|
||||||
case ASRID_CONTROL: regName = "CONTROL"; break;
|
|
||||||
default: regName = "RSVD"; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
putString(result, regName);
|
|
||||||
if (bitsName != NULL) putString(result, bitsName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit flags argument (CPS instruction)
|
|
||||||
//
|
|
||||||
static void putFlags(char **result, armFlagAffect faff) {
|
|
||||||
if(faff & ARM_FAFF_A) {putChar(result, 'a');}
|
|
||||||
if(faff & ARM_FAFF_I) {putChar(result, 'i');}
|
|
||||||
if(faff & ARM_FAFF_F) {putChar(result, 'f');}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit optional mode argument (CPS instruction)
|
|
||||||
//
|
|
||||||
static void putOptMode(char **result, Bool ma, Uns32 c) {
|
|
||||||
if(ma) {putHashU(result, c);}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit limitation (DMB, DSB and ISB instructions)
|
|
||||||
//
|
|
||||||
static void putLim(char **result, Uns32 lim) {
|
|
||||||
putString(result, limNames[lim]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit true/else condition list for IT block
|
|
||||||
//
|
|
||||||
static void putIT(char **result, Uns32 it) {
|
|
||||||
|
|
||||||
Bool negate = (it&0x10) ? False : True;
|
|
||||||
|
|
||||||
while(it & 0x7) {
|
|
||||||
Bool select = (it & 0x8) ? True : False;
|
|
||||||
putChar(result, (select ^ negate) ? 't' : 'e');
|
|
||||||
it <<= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit a single register in a register list
|
|
||||||
// May be a scalar which may or may not have a valid index
|
|
||||||
//
|
|
||||||
static void putRListReg(char **result, Uns32 rn, char regType, Bool scalar, Int32 index) {
|
|
||||||
|
|
||||||
putChar(result, regType);
|
|
||||||
putU(result, rn);
|
|
||||||
if (scalar) {
|
|
||||||
putChar(result, '[');
|
|
||||||
if (index >= 0) putU(result, (Uns32) index);
|
|
||||||
putChar(result, ']');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit SIMD/VFP type register list argument
|
|
||||||
//
|
|
||||||
static void putSdfpRList(
|
|
||||||
char **result,
|
|
||||||
Uns32 nRegs,
|
|
||||||
Uns32 incr,
|
|
||||||
Uns32 rn,
|
|
||||||
char regType,
|
|
||||||
Bool scalar,
|
|
||||||
Int32 index,
|
|
||||||
Bool forceList
|
|
||||||
) {
|
|
||||||
|
|
||||||
putChar(result, '{');
|
|
||||||
putRListReg(result, rn, regType, scalar, index);
|
|
||||||
|
|
||||||
if (incr > 1 || forceList) {
|
|
||||||
|
|
||||||
// when there is an incr (or when forced) use a list of regs rx, ry,...rz
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// If forcing a list make sure incr is valid
|
|
||||||
if (incr == 0) incr = 1;
|
|
||||||
|
|
||||||
for (i = 1; i < nRegs; i++) {
|
|
||||||
putChar(result, ',');
|
|
||||||
putRListReg(result, rn+(incr*i), regType, scalar, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// When there is no incr, disassembler uses rx-rz notation for multiple registers
|
|
||||||
if (nRegs > 1) {
|
|
||||||
putChar(result, '-');
|
|
||||||
putRListReg(result, rn+nRegs-1, regType, scalar, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
putChar(result, '}');
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit a SIMD/VFP Modified Immediate constant value
|
|
||||||
//
|
|
||||||
static void putSdfpMI(char **result, armSdfpMItype mi, armSDFPType ftype)
|
|
||||||
{
|
|
||||||
putChar(result, '#');
|
|
||||||
|
|
||||||
switch (ftype) {
|
|
||||||
|
|
||||||
case ARM_SDFPT_I8:
|
|
||||||
putD(result, mi.u8.b0);
|
|
||||||
break;
|
|
||||||
case ARM_SDFPT_I16:
|
|
||||||
putD(result, mi.u16.h0);
|
|
||||||
break;
|
|
||||||
case ARM_SDFPT_I32:
|
|
||||||
putD(result, mi.u32.w0);
|
|
||||||
break;
|
|
||||||
case ARM_SDFPT_I64:
|
|
||||||
put0xll(result, mi.u64);
|
|
||||||
break;
|
|
||||||
case ARM_SDFPT_F32:
|
|
||||||
putF(result, mi.f32);
|
|
||||||
break;
|
|
||||||
case ARM_SDFPT_F64:
|
|
||||||
putF(result, mi.f64);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Only above values for dt1 are supported for instructions with modified immediate constants
|
|
||||||
VMI_ABORT("Unsupported ftype %d withSIMD/VFP modified immediate constant", ftype);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Generate instruction disassembly using the format string
|
|
||||||
//
|
|
||||||
static void disassembleFormat(
|
|
||||||
armP arm,
|
|
||||||
armInstructionInfoP info,
|
|
||||||
char **result,
|
|
||||||
const char *format
|
|
||||||
) {
|
|
||||||
const char *opcode = info->opcode;
|
|
||||||
|
|
||||||
// in UAL mode, some instances of MOV instruction get reclassed as shift
|
|
||||||
// pseudo-ops
|
|
||||||
if(!arm->UAL) {
|
|
||||||
// no action
|
|
||||||
} else if((info->type==ARM_IT_MOV_RM_SHFT_IMM) && info->c) {
|
|
||||||
opcode = shiftNames[info->so];
|
|
||||||
format = FMT_R1_R2_SIMM;
|
|
||||||
} else if(info->type==ARM_IT_MOV_RM_SHFT_RS) {
|
|
||||||
opcode = shiftNames[info->so];
|
|
||||||
format = FMT_R1_R2_R3;
|
|
||||||
} else if(info->type==ARM_IT_MOV_RM_RRX) {
|
|
||||||
opcode = shiftNames[info->so];
|
|
||||||
format = FMT_R1_R2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate instruction pattern
|
|
||||||
putInstruction(arm, info, result);
|
|
||||||
|
|
||||||
// get offset at opcode start
|
|
||||||
const char *opcodeStart = *result;
|
|
||||||
|
|
||||||
// generate opcode text
|
|
||||||
putString(result, opcode);
|
|
||||||
|
|
||||||
if(arm->UAL) {
|
|
||||||
// disassemble using UAL syntax
|
|
||||||
if(info->xs) putChar(result, 's');
|
|
||||||
if(info->ea) putString(result, "ex");
|
|
||||||
putString(result, sizeNames[info->sz]);
|
|
||||||
if(info->f==ARM_SF_V) putChar(result, 's');
|
|
||||||
putString(result, incDecNames[info->incDec]);
|
|
||||||
putString(result, condNames[info->cond]);
|
|
||||||
putString(result, flagActionNames[info->fact]);
|
|
||||||
if(info->tl) putChar(result, 't');
|
|
||||||
if(info->ll) putChar(result, 'l');
|
|
||||||
if(info->it) putIT(result, info->it);
|
|
||||||
putString(result, ftypeNames[info->dt1]);
|
|
||||||
putString(result, ftypeNames[info->dt2]);
|
|
||||||
} else {
|
|
||||||
// disassemble using pre-UAL syntax
|
|
||||||
putString(result, condNames[info->cond]);
|
|
||||||
putString(result, incDecNames[info->incDec]);
|
|
||||||
putString(result, flagActionNames[info->fact]);
|
|
||||||
if(info->xs) putChar(result, 's');
|
|
||||||
if(info->ea) putString(result, "ex");
|
|
||||||
putString(result, sizeNames[info->sz]);
|
|
||||||
if(info->tl) putChar(result, 't');
|
|
||||||
if(info->ll) putChar(result, 'l');
|
|
||||||
if(info->f==ARM_SF_V) putChar(result, 's');
|
|
||||||
if(info->it) putIT(result, info->it);
|
|
||||||
putString(result, ftypeNames[info->dt1]);
|
|
||||||
putString(result, ftypeNames[info->dt2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(*format) {
|
|
||||||
|
|
||||||
// calculate length of opcode text
|
|
||||||
const char *opcodeEnd = *result;
|
|
||||||
Uns32 len = opcodeEnd-opcodeStart;
|
|
||||||
char ch;
|
|
||||||
|
|
||||||
// pad to minimum width
|
|
||||||
for(; len<OP_WIDTH; len++) {
|
|
||||||
putChar(result, ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
// emit space before arguments
|
|
||||||
putChar(result, ' ');
|
|
||||||
|
|
||||||
// this defines whether the next argument is optional
|
|
||||||
Bool nextOpt = False;
|
|
||||||
|
|
||||||
// generate arguments in appropriate format
|
|
||||||
while((ch=*format++)) {
|
|
||||||
|
|
||||||
// is this argument optional?
|
|
||||||
Bool opt = nextOpt;
|
|
||||||
|
|
||||||
// assume subsequent argument is mandatory
|
|
||||||
nextOpt = False;
|
|
||||||
|
|
||||||
switch(ch) {
|
|
||||||
case EMIT_R1:
|
|
||||||
putGPR(arm, result, info->r1);
|
|
||||||
break;
|
|
||||||
case EMIT_R2:
|
|
||||||
putGPR(arm, result, info->r2);
|
|
||||||
break;
|
|
||||||
case EMIT_R3:
|
|
||||||
putGPR(arm, result, info->r3);
|
|
||||||
break;
|
|
||||||
case EMIT_R4:
|
|
||||||
putGPR(arm, result, info->r4);
|
|
||||||
break;
|
|
||||||
case EMIT_S1:
|
|
||||||
putSR(arm, result, info->r1);
|
|
||||||
break;
|
|
||||||
case EMIT_S2:
|
|
||||||
putSR(arm, result, info->r2);
|
|
||||||
break;
|
|
||||||
case EMIT_S3:
|
|
||||||
putSR(arm, result, info->r3);
|
|
||||||
break;
|
|
||||||
case EMIT_D1:
|
|
||||||
putDR(arm, result, info->r1);
|
|
||||||
break;
|
|
||||||
case EMIT_D2:
|
|
||||||
putDR(arm, result, info->r2);
|
|
||||||
break;
|
|
||||||
case EMIT_D3:
|
|
||||||
putDR(arm, result, info->r3);
|
|
||||||
break;
|
|
||||||
case EMIT_Z1:
|
|
||||||
putScalar(arm, result, info->r1, info->index);
|
|
||||||
break;
|
|
||||||
case EMIT_Z2:
|
|
||||||
putScalar(arm, result, info->r2, info->index);
|
|
||||||
break;
|
|
||||||
case EMIT_SS1:
|
|
||||||
putSSR(arm, result, info->r1);
|
|
||||||
break;
|
|
||||||
case EMIT_SS3:
|
|
||||||
putSSR(arm, result, info->r3);
|
|
||||||
break;
|
|
||||||
case EMIT_CU:
|
|
||||||
putHashU(result, info->c);
|
|
||||||
break;
|
|
||||||
case EMIT_CS:
|
|
||||||
putHashD(result, info->c, opt);
|
|
||||||
break;
|
|
||||||
case EMIT_CX:
|
|
||||||
put0x(result, info->c);
|
|
||||||
break;
|
|
||||||
case EMIT_T:
|
|
||||||
putTarget(result, info->t);
|
|
||||||
break;
|
|
||||||
case EMIT_SHIFT:
|
|
||||||
putShift(result, info->so);
|
|
||||||
break;
|
|
||||||
case EMIT_SHIFT_C:
|
|
||||||
putShiftC(result, info->so, info->c);
|
|
||||||
break;
|
|
||||||
case EMIT_CPNUM:
|
|
||||||
putU(result, info->cpNum);
|
|
||||||
break;
|
|
||||||
case EMIT_COP1:
|
|
||||||
putU(result, info->cpOp1);
|
|
||||||
break;
|
|
||||||
case EMIT_COP2:
|
|
||||||
putU(result, info->cpOp2);
|
|
||||||
break;
|
|
||||||
case EMIT_CR1:
|
|
||||||
putCPR(arm, result, info->r1);
|
|
||||||
break;
|
|
||||||
case EMIT_CR2:
|
|
||||||
putCPR(arm, result, info->r2);
|
|
||||||
break;
|
|
||||||
case EMIT_CR3:
|
|
||||||
putCPR(arm, result, info->r3);
|
|
||||||
break;
|
|
||||||
case EMIT_OPT:
|
|
||||||
putU(result, info->c);
|
|
||||||
break;
|
|
||||||
case EMIT_WB:
|
|
||||||
putWB(result, info->pi, info->wb);
|
|
||||||
break;
|
|
||||||
case EMIT_RLIST:
|
|
||||||
putRList(arm, result, info->rList);
|
|
||||||
break;
|
|
||||||
case EMIT_U:
|
|
||||||
putMinus(result, info->u);
|
|
||||||
break;
|
|
||||||
case EMIT_SR:
|
|
||||||
putSpecialReg(result, info->c, info->psrbits);
|
|
||||||
break;
|
|
||||||
case EMIT_FLAGS:
|
|
||||||
putFlags(result, info->faff);
|
|
||||||
break;
|
|
||||||
case EMIT_OPT_MODE:
|
|
||||||
putOptMode(result, info->ma, info->c);
|
|
||||||
break;
|
|
||||||
case EMIT_LIM:
|
|
||||||
putLim(result, info->c);
|
|
||||||
break;
|
|
||||||
case EMIT_WIDTH:
|
|
||||||
putHashD(result, info->w, False);
|
|
||||||
break;
|
|
||||||
case EMIT_ITC:
|
|
||||||
putString(result, condNamesIT[info->it>>4]);
|
|
||||||
break;
|
|
||||||
case EMIT_SZSHIFT:
|
|
||||||
putSizeShift(result, info->sz);
|
|
||||||
break;
|
|
||||||
case EMIT_R1F:
|
|
||||||
putGPROrFlagsIfR15(arm, result, info->r1);
|
|
||||||
break;
|
|
||||||
case EMIT_FPSCR:
|
|
||||||
putFPSCR(arm, result);
|
|
||||||
break;
|
|
||||||
case EMIT_C0F:
|
|
||||||
putHashF0(result);
|
|
||||||
break;
|
|
||||||
case EMIT_SIMD_RL:
|
|
||||||
putSdfpRList(result, info->nregs, 0, info->r2, 'd', False, 0, False);
|
|
||||||
break;
|
|
||||||
case EMIT_SDFP_MI:
|
|
||||||
putSdfpMI(result, info->sdfpMI, info->dt1);
|
|
||||||
break;
|
|
||||||
case EMIT_VFP_RL:
|
|
||||||
putSdfpRList(result, info->nregs, 0, info->r2, 's', False, 0, False);
|
|
||||||
break;
|
|
||||||
case '1':
|
|
||||||
if(!info->pi) format++;
|
|
||||||
break;
|
|
||||||
case '2':
|
|
||||||
if(info->pi) format++;
|
|
||||||
break;
|
|
||||||
case ',':
|
|
||||||
putComma(result);
|
|
||||||
break;
|
|
||||||
case ']':
|
|
||||||
putRBracket(result);
|
|
||||||
break;
|
|
||||||
case '*':
|
|
||||||
nextOpt = True;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
putChar(result, ch);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// strip trailing whitespace and commas
|
|
||||||
char *tail = (*result)-1;
|
|
||||||
while((*tail == ' ') || (*tail == ',')) {
|
|
||||||
*tail-- = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// ARM disassembler, decoded instruction interface
|
|
||||||
//
|
|
||||||
const char *armDisassembleInfo(armP arm, armInstructionInfoP info) {
|
|
||||||
|
|
||||||
// static buffer to hold disassembly result
|
|
||||||
static char result[256];
|
|
||||||
const char *format = info->format;
|
|
||||||
char *tail = result;
|
|
||||||
|
|
||||||
// disassemble using the format for the type
|
|
||||||
if(format) {
|
|
||||||
disassembleFormat(arm, info, &tail, format);
|
|
||||||
} else if(info->bytes==2) {
|
|
||||||
sprintf(result, "0x%04x", info->instruction);
|
|
||||||
} else {
|
|
||||||
sprintf(result, "0x%08x", info->instruction);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the result
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// ARM disassembler, VMI interface
|
|
||||||
//
|
|
||||||
VMI_DISASSEMBLE_FN(armDisassemble) {
|
|
||||||
|
|
||||||
// static buffer to hold disassembly result
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
armInstructionInfo info;
|
|
||||||
|
|
||||||
// get instruction and instruction type
|
|
||||||
arm->itStateMT = arm->itStateRT;
|
|
||||||
armDecode(arm, thisPC, &info);
|
|
||||||
|
|
||||||
// return disassembled instruction
|
|
||||||
return armDisassembleInfo(arm, &info);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiAttrs.h"
|
|
||||||
#include "vmi/vmiModelInfo.h"
|
|
||||||
#include "vmi/vmiDoc.h"
|
|
||||||
|
|
||||||
#include "armmDoc.h"
|
|
||||||
#include "armmParameters.h"
|
|
||||||
#include "armStructure.h"
|
|
||||||
#include "armConfig.h"
|
|
||||||
|
|
||||||
void armmDoc(vmiProcessorP processor, armParamValuesP parameters) {
|
|
||||||
vmiDocNodeP root = vmidocAddSection(0, "Root");
|
|
||||||
vmiDocNodeP desc = vmidocAddSection(root, "Description");
|
|
||||||
vmidocAddText(desc, "ARMM Processor Model");
|
|
||||||
|
|
||||||
vmiDocNodeP lic = vmidocAddSection(root, "Licensing");
|
|
||||||
vmidocAddText(lic, "Imperas Modified Apache 2.0 Open Source License");
|
|
||||||
|
|
||||||
vmiDocNodeP lim = vmidocAddSection(root, "Limitations");
|
|
||||||
vmidocAddText(lim, "Security Extensions are not yet implemented.");
|
|
||||||
vmidocAddText(lim, "Performance Monitors are not implemented.");
|
|
||||||
|
|
||||||
vmiDocNodeP verif = vmidocAddSection(root, "Verification");
|
|
||||||
vmidocAddText(verif, "Models have been validated correct by Imperas "
|
|
||||||
"running through extensive unit and full operating system tests "
|
|
||||||
"and validated in some cases against hardware");
|
|
||||||
|
|
||||||
armP arm = (armP) processor;
|
|
||||||
|
|
||||||
vmiDocNodeP features = vmidocAddSection(root, "Features");
|
|
||||||
|
|
||||||
if (MPU_PRESENT(arm)) {
|
|
||||||
vmidocAddText(features, "MPU is implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARM_SUPPORT(arm->configInfo.arch, ARM_VT)) {
|
|
||||||
vmidocAddText(features, "Thumb instructions are supported.");
|
|
||||||
}
|
|
||||||
if (ARM_SUPPORT(arm->configInfo.arch, ARM_VT2)) {
|
|
||||||
vmidocAddText(features, "Thumb-2 instructions are supported.");
|
|
||||||
}
|
|
||||||
if (ARM_SUPPORT(arm->configInfo.arch, ARM_J)) {
|
|
||||||
vmidocAddText(features, "Jazelle trap is implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
vmidocProcessor(processor, root);
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARMM_DOC_H
|
|
||||||
#define ARMM_DOC_H
|
|
||||||
|
|
||||||
#include "vmi/vmiTyperefs.h"
|
|
||||||
#include "armmParameters.h"
|
|
||||||
|
|
||||||
void armmDoc(vmiProcessorP processor, armParamValuesP parameters);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,284 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// standard header files
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiAttrs.h"
|
|
||||||
#include "vmi/vmiCommand.h"
|
|
||||||
#include "vmi/vmiMessage.h"
|
|
||||||
#include "vmi/vmiRt.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armConfig.h"
|
|
||||||
#include "armDecode.h"
|
|
||||||
#include "armDebug.h"
|
|
||||||
#include "armmDoc.h"
|
|
||||||
#include "armExceptions.h"
|
|
||||||
#include "armFunctions.h"
|
|
||||||
#include "armMode.h"
|
|
||||||
#include "armmParameters.h"
|
|
||||||
#include "armStructure.h"
|
|
||||||
#include "armSys.h"
|
|
||||||
#include "armSysRegisters.h"
|
|
||||||
#include "armUtils.h"
|
|
||||||
#include "armVM.h"
|
|
||||||
#include "armVFP.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
//
|
|
||||||
// Prefix for messages from this module
|
|
||||||
//
|
|
||||||
#define CPU_PREFIX "ARM_MAIN"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PARSING CONFIGURATION OPTIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return processor configuration variant argument
|
|
||||||
//
|
|
||||||
static armConfigCP getConfigVariantArg(armP arm, armParamValuesP params) {
|
|
||||||
|
|
||||||
armConfigCP match;
|
|
||||||
|
|
||||||
if(params->SETBIT(variant)) {
|
|
||||||
|
|
||||||
match = &armConfigTable[params->variant];
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
match = armConfigTable;
|
|
||||||
|
|
||||||
if(arm->verbose) {
|
|
||||||
|
|
||||||
// report the value specified for an option in verbose mode
|
|
||||||
vmiMessage("I", CPU_PREFIX"_ANS1",
|
|
||||||
"Attribute '%s' not specified; defaulting to '%s'",
|
|
||||||
"variant",
|
|
||||||
match->name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return matching configuration
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// CONSTRUCTOR AND DESTRUCTOR
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// specify default value for entire system register
|
|
||||||
#define SET_SCS_REG_DEFAULT(_R, _V) \
|
|
||||||
union {Uns32 u32; SCS_REG_DECL(_R);} _U = {_V}; \
|
|
||||||
SCS_REG_STRUCT_DEFAULT(arm, _R) = _U._R
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize processor exclusiveTagMask
|
|
||||||
//
|
|
||||||
static void setExclusiveTagMask(armP arm) {
|
|
||||||
arm->exclusiveTagMask = (-1 << (arm->configInfo.ERG+2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void failSALset(unsigned int pointer);
|
|
||||||
//
|
|
||||||
// ARM processor constructor
|
|
||||||
//
|
|
||||||
VMI_CONSTRUCTOR_FN(armConstructor) {
|
|
||||||
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
armParamValuesP params = (armParamValuesP)parameterValues;
|
|
||||||
|
|
||||||
|
|
||||||
// initialize exclusive tag
|
|
||||||
arm->exclusiveTag = ARM_NO_TAG;
|
|
||||||
|
|
||||||
// save flags on processor structure
|
|
||||||
arm->flags = vmirtProcessorFlags(processor);
|
|
||||||
|
|
||||||
unsigned int failp = params->fail_salp;
|
|
||||||
failSALset(failp);
|
|
||||||
|
|
||||||
|
|
||||||
// get string configuration options
|
|
||||||
arm->simEx = simulateExceptions;
|
|
||||||
arm->verbose = params->verbose;
|
|
||||||
arm->compatMode = params->compatibility;
|
|
||||||
arm->showHiddenRegs = params->showHiddenRegs;
|
|
||||||
arm->UAL = params->UAL;
|
|
||||||
arm->disableBitBand = params->disableBitBand;
|
|
||||||
|
|
||||||
// get default variant information
|
|
||||||
arm->configInfo = *getConfigVariantArg(arm, params);
|
|
||||||
|
|
||||||
// override data endianness
|
|
||||||
armSetInitialEndian(arm, params->endian);
|
|
||||||
|
|
||||||
// override instruction endianness
|
|
||||||
arm->instructionEndian = params->instructionEndian;
|
|
||||||
|
|
||||||
// override other configuration values
|
|
||||||
if(params->SETBIT(override_debugMask)) {
|
|
||||||
arm->flags = params->override_debugMask;
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_CPUID)) {
|
|
||||||
SET_SCS_REG_DEFAULT(CPUID, params->override_CPUID);
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_MPU_TYPE)) {
|
|
||||||
SET_SCS_REG_DEFAULT(MPU_TYPE, params->override_MPU_TYPE);
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_InstructionAttributes0)) {
|
|
||||||
SET_SCS_REG_DEFAULT(ID_ISAR0, params->override_InstructionAttributes0);
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_InstructionAttributes1)) {
|
|
||||||
SET_SCS_REG_DEFAULT(ID_ISAR1, params->override_InstructionAttributes1);
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_InstructionAttributes2)) {
|
|
||||||
SET_SCS_REG_DEFAULT(ID_ISAR2, params->override_InstructionAttributes2);
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_InstructionAttributes3)) {
|
|
||||||
SET_SCS_REG_DEFAULT(ID_ISAR3, params->override_InstructionAttributes3);
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_InstructionAttributes4)) {
|
|
||||||
SET_SCS_REG_DEFAULT(ID_ISAR4, params->override_InstructionAttributes4);
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_InstructionAttributes5)) {
|
|
||||||
SET_SCS_REG_DEFAULT(ID_ISAR5, params->override_InstructionAttributes5);
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_MVFR0)) {
|
|
||||||
SET_SCS_REG_DEFAULT(MVFR0, params->override_MVFR0);
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_MVFR1)) {
|
|
||||||
SET_SCS_REG_DEFAULT(MVFR1, params->override_MVFR1);
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_rotateUnaligned)) {
|
|
||||||
arm->configInfo.rotateUnaligned = params->override_rotateUnaligned;
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_align64as32)) {
|
|
||||||
arm->configInfo.align64as32 = params->override_align64as32;
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_STRoffsetPC12)) {
|
|
||||||
arm->configInfo.STRoffsetPC12 = params->override_STRoffsetPC12;
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_ERG)) {
|
|
||||||
arm->configInfo.ERG = params->override_ERG;
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_priorityBits)) {
|
|
||||||
arm->configInfo.priorityBitsM1 = params->override_priorityBits-1;
|
|
||||||
}
|
|
||||||
if(params->SETBIT(override_numInterrupts)) {
|
|
||||||
NUM_INTERRUPTS(arm) = params->override_numInterrupts;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set read-only registers to their initial state (AFTER applying overrides)
|
|
||||||
armSysInitialize(arm);
|
|
||||||
|
|
||||||
// register view objects and event handlers (AFTER armSysInitialize)
|
|
||||||
vmiViewObjectP viewObject = vmirtGetProcessorViewObject(processor);
|
|
||||||
armAddSysRegistersView(arm, viewObject);
|
|
||||||
|
|
||||||
// Initialize FPU if present
|
|
||||||
armFPInitialize(arm);
|
|
||||||
|
|
||||||
// Check for user enable of VFP instructions at reset?
|
|
||||||
if (params->SETBIT(enableVFPAtReset) && params->enableVFPAtReset) {
|
|
||||||
SCS_FIELD_DEFAULT(arm, CPACR, cp10) = 3;
|
|
||||||
SCS_FIELD_DEFAULT(arm, CPACR, cp11) = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize exclusiveTagMask
|
|
||||||
setExclusiveTagMask(arm);
|
|
||||||
|
|
||||||
// initialize priority mask
|
|
||||||
Uns32 priorityBits = PRIORITY_BITS(arm);
|
|
||||||
arm->priorityMask = ((1<<priorityBits)-1) << (8-priorityBits);
|
|
||||||
arm->priorityMask |= arm->priorityMask << 8;
|
|
||||||
arm->priorityMask |= arm->priorityMask << 16;
|
|
||||||
|
|
||||||
// ensure number of external interrupts is in bounds
|
|
||||||
if(NUM_INTERRUPTS(arm)>ARM_INTERRUPT_NUM) {
|
|
||||||
NUM_INTERRUPTS(arm) = ARM_INTERRUPT_NUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize exception mask number and top mask
|
|
||||||
arm->exceptNum = NUM_INTERRUPTS(arm) + AEN_ExternalInt0;
|
|
||||||
arm->exceptMaskNum = (arm->exceptNum+31)/32;
|
|
||||||
|
|
||||||
// indicate reset exception is pending; otherwise, force into Thumb mode
|
|
||||||
// (default is ARM mode)
|
|
||||||
if(!ARM_DISASSEMBLE(arm) && params->resetAtTime0) {
|
|
||||||
armRaise(arm, AEN_Reset);
|
|
||||||
} else {
|
|
||||||
IN_THUMB_MODE(arm) = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset stack pointer (and banked variants) in gdb compatibility mode
|
|
||||||
if(arm->compatMode==COMPAT_GDB) {
|
|
||||||
arm->regs[ARM_REG_SP] = 0x800;
|
|
||||||
arm->bank.R13_process = 0x800;
|
|
||||||
}
|
|
||||||
|
|
||||||
// force into thumb mode if required
|
|
||||||
if(ARM_THUMB(arm)) {
|
|
||||||
IN_THUMB_MODE(arm) = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set callbacks (for intercept libraries)
|
|
||||||
arm->decoderCB = armDecode;
|
|
||||||
arm->isizeCB = armGetInstructionSizeMode;
|
|
||||||
|
|
||||||
// create port specifications
|
|
||||||
armNewPortSpecs(arm);
|
|
||||||
|
|
||||||
// install documentation
|
|
||||||
armmDoc(processor, parameterValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// ARM processor destructor
|
|
||||||
//
|
|
||||||
VMI_DESTRUCTOR_FN(armDestructor) {
|
|
||||||
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
|
|
||||||
// free port specifications
|
|
||||||
armFreePortSpecs(arm);
|
|
||||||
|
|
||||||
// free virtual memory structures
|
|
||||||
armVMFree(arm);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,423 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiMessage.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armEmit.h"
|
|
||||||
#include "armMorph.h"
|
|
||||||
#include "armMorphEntries.h"
|
|
||||||
#include "armMorphFunctions.h"
|
|
||||||
#include "armRegisters.h"
|
|
||||||
#include "armStructure.h"
|
|
||||||
#include "armUtils.h"
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// FLAGS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const static vmiFlags flagsZNCV = {
|
|
||||||
ARM_CF_CONST,
|
|
||||||
{
|
|
||||||
[vmi_CF] = ARM_CF_CONST,
|
|
||||||
[vmi_PF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_ZF] = ARM_ZF_CONST,
|
|
||||||
[vmi_SF] = ARM_NF_CONST,
|
|
||||||
[vmi_OF] = ARM_VF_CONST
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const static vmiFlags flagsZNBV = {
|
|
||||||
ARM_CF_CONST,
|
|
||||||
{
|
|
||||||
[vmi_CF] = ARM_CF_CONST,
|
|
||||||
[vmi_PF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_ZF] = ARM_ZF_CONST,
|
|
||||||
[vmi_SF] = ARM_NF_CONST,
|
|
||||||
[vmi_OF] = ARM_VF_CONST
|
|
||||||
},
|
|
||||||
vmi_FN_CF_IN|vmi_FN_CF_OUT
|
|
||||||
};
|
|
||||||
|
|
||||||
const static vmiFlags flagsZN = {
|
|
||||||
ARM_CF_CONST,
|
|
||||||
{
|
|
||||||
[vmi_CF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_PF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_ZF] = ARM_ZF_CONST,
|
|
||||||
[vmi_SF] = ARM_NF_CONST,
|
|
||||||
[vmi_OF] = VMI_NOFLAG_CONST
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const static vmiFlags flagsCIn = {
|
|
||||||
ARM_CF_CONST,
|
|
||||||
{
|
|
||||||
[vmi_CF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_PF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_ZF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_SF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_OF] = VMI_NOFLAG_CONST
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const static vmiFlags flagsBIn = {
|
|
||||||
ARM_CF_CONST,
|
|
||||||
{
|
|
||||||
[vmi_CF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_PF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_ZF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_SF] = VMI_NOFLAG_CONST,
|
|
||||||
[vmi_OF] = VMI_NOFLAG_CONST
|
|
||||||
},
|
|
||||||
vmi_FN_CF_IN
|
|
||||||
};
|
|
||||||
|
|
||||||
// Macro accessors for flags
|
|
||||||
#define FLAGS_ZNCV &flagsZNCV
|
|
||||||
#define FLAGS_ZNBV &flagsZNBV
|
|
||||||
#define FLAGS_ZN &flagsZN
|
|
||||||
#define FLAGS_CIN &flagsCIn
|
|
||||||
#define FLAGS_BIN &flagsBIn
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// MORPHER DISPATCH TABLE
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const armMorphAttr armMorphTable[ARM_IT_LAST+1] = {
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ARM INSTRUCTIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// data processing instructions
|
|
||||||
MORPH_SET_ADC (ADC, vmi_ADC, FLAGS_ZNCV, FLAGS_CIN, False),
|
|
||||||
MORPH_SET_ADC (ADD, vmi_ADD, FLAGS_ZNCV, FLAGS_CIN, False),
|
|
||||||
MORPH_SET_ADC (AND, vmi_AND, FLAGS_ZN, 0, True ),
|
|
||||||
MORPH_SET_ADC (BIC, vmi_ANDN, FLAGS_ZN, 0, True ),
|
|
||||||
MORPH_SET_ADC (EOR, vmi_XOR, FLAGS_ZN, 0, True ),
|
|
||||||
MORPH_SET_MOV (MOV, vmi_MOV, FLAGS_ZN, 0, True ),
|
|
||||||
MORPH_SET_ADC (MUL, vmi_MUL, FLAGS_ZN, 0, True ),
|
|
||||||
MORPH_SET_MOV (MVN, vmi_NOT, FLAGS_ZN, 0, True ),
|
|
||||||
MORPH_SET_MOV (NEG, vmi_NEG, FLAGS_ZNBV, 0, False),
|
|
||||||
MORPH_SET_ADC (ORN, vmi_ORN, FLAGS_ZN, 0, True ),
|
|
||||||
MORPH_SET_ADC (ORR, vmi_OR, FLAGS_ZN, 0, True ),
|
|
||||||
MORPH_SET_ADC (RSB, vmi_RSUB, FLAGS_ZNBV, FLAGS_BIN, False),
|
|
||||||
MORPH_SET_ADC (RSC, vmi_RSBB, FLAGS_ZNBV, FLAGS_BIN, False),
|
|
||||||
MORPH_SET_ADC (SBC, vmi_SBB, FLAGS_ZNBV, FLAGS_BIN, False),
|
|
||||||
MORPH_SET_ADC (SUB, vmi_SUB, FLAGS_ZNBV, FLAGS_BIN, False),
|
|
||||||
|
|
||||||
// ARMv6T2 move instructions
|
|
||||||
MORPH_SINGLE (MOVT),
|
|
||||||
MORPH_SINGLE (MOVW),
|
|
||||||
|
|
||||||
// multiply instructions
|
|
||||||
MORPH_SET_MLA (MLA, FLAGS_ZN),
|
|
||||||
MORPH_SET_MLA (MLS, FLAGS_ZN),
|
|
||||||
MORPH_SET_MLA (MUL, FLAGS_ZN),
|
|
||||||
MORPH_SET_SMULL (SMLAL, MLAL, vmi_IMUL, FLAGS_ZN),
|
|
||||||
MORPH_SET_SMULL (SMULL, MULL, vmi_IMUL, FLAGS_ZN),
|
|
||||||
MORPH_SET_SMULL (UMAAL, MAAL, vmi_MUL, FLAGS_ZN),
|
|
||||||
MORPH_SET_SMULL (UMLAL, MLAL, vmi_MUL, FLAGS_ZN),
|
|
||||||
MORPH_SET_SMULL (UMULL, MULL, vmi_MUL, FLAGS_ZN),
|
|
||||||
|
|
||||||
// compare instructions
|
|
||||||
MORPH_SET_CMN (CMN, vmi_ADD, FLAGS_ZNCV, FLAGS_CIN, False),
|
|
||||||
MORPH_SET_CMN (CMP, vmi_SUB, FLAGS_ZNBV, FLAGS_BIN, False),
|
|
||||||
MORPH_SET_CMN (TEQ, vmi_XOR, FLAGS_ZN, 0, True ),
|
|
||||||
MORPH_SET_CMN (TST, vmi_AND, FLAGS_ZN, 0, True ),
|
|
||||||
|
|
||||||
// branch instructions
|
|
||||||
MORPH_SET_B (B, False),
|
|
||||||
MORPH_SET_B (BL, True ),
|
|
||||||
MORPH_SET_BLX2 (BLX2, True ),
|
|
||||||
MORPH_SET_BLX2 (BX, False),
|
|
||||||
|
|
||||||
// miscellaneous instructions
|
|
||||||
MORPH_SINGLE (BKPT),
|
|
||||||
MORPH_SINGLE (CLZ ),
|
|
||||||
MORPH_SINGLE (SWI ),
|
|
||||||
|
|
||||||
// load and store instructions
|
|
||||||
MORPH_SET_LDR (LDR, LDR ),
|
|
||||||
MORPH_SET_LDR (LDRB, LDR ),
|
|
||||||
MORPH_SET_LDR (LDRBT, LDR ),
|
|
||||||
MORPH_SET_LDRH (LDRH, LDR ),
|
|
||||||
MORPH_SET_LDRH (LDRSB, LDR ),
|
|
||||||
MORPH_SET_LDRH (LDRSH, LDR ),
|
|
||||||
MORPH_SET_LDR (LDRT, LDR ),
|
|
||||||
MORPH_SET_LDR (STR, STR ),
|
|
||||||
MORPH_SET_LDR (STRB, STR ),
|
|
||||||
MORPH_SET_LDR (STRBT, STR ),
|
|
||||||
MORPH_SET_LDRH (STRH, STR ),
|
|
||||||
MORPH_SET_LDR (STRT, STR ),
|
|
||||||
|
|
||||||
// load and store multiple instructions
|
|
||||||
MORPH_SET_LDM1 (LDM1),
|
|
||||||
MORPH_SINGLE (STM1),
|
|
||||||
|
|
||||||
// ARMv6T2 load and store instructions
|
|
||||||
MORPH_SET_LDRH (LDRHT, LDR),
|
|
||||||
MORPH_SET_LDRH (LDRSBT, LDR),
|
|
||||||
MORPH_SET_LDRH (LDRSHT, LDR),
|
|
||||||
MORPH_SET_LDRH (STRHT, STR),
|
|
||||||
|
|
||||||
// synchronization primitives
|
|
||||||
MORPH_SET_SWP (LDREX, LDREX),
|
|
||||||
MORPH_SET_SWP (LDREXB, LDREX),
|
|
||||||
MORPH_SET_SWP (LDREXH, LDREX),
|
|
||||||
MORPH_SET_SWP (STREX, STREX),
|
|
||||||
MORPH_SET_SWP (STREXB, STREX),
|
|
||||||
MORPH_SET_SWP (STREXH, STREX),
|
|
||||||
|
|
||||||
// coprocessor instructions (all UsageFault)
|
|
||||||
MORPH_SET_SWP (CDP, UsageFaultCP),
|
|
||||||
MORPH_SET_SWP (CDP2, UsageFaultCP),
|
|
||||||
MORPH_SET_LDC (LDC, UsageFaultCP),
|
|
||||||
MORPH_SET_LDC (LDC2, UsageFaultCP),
|
|
||||||
MORPH_SET_SWP (MCR, UsageFaultCP),
|
|
||||||
MORPH_SET_SWP (MCR2, UsageFaultCP),
|
|
||||||
MORPH_SET_SWP (MRC, UsageFaultCP),
|
|
||||||
MORPH_SET_SWP (MRC2, UsageFaultCP),
|
|
||||||
MORPH_SET_LDC (STC, UsageFaultCP),
|
|
||||||
MORPH_SET_LDC (STC2, UsageFaultCP),
|
|
||||||
|
|
||||||
// status register access instructions
|
|
||||||
MORPH_SINGLE (MRS),
|
|
||||||
MORPH_SINGLE (MSR),
|
|
||||||
|
|
||||||
// hint instructions
|
|
||||||
MORPH_SET_NOP (NOP ),
|
|
||||||
MORPH_SET_NOP (YIELD),
|
|
||||||
MORPH_SINGLE (WFE ),
|
|
||||||
MORPH_SINGLE (WFI ),
|
|
||||||
MORPH_SINGLE (SEV ),
|
|
||||||
MORPH_SET_NOP (DBG ),
|
|
||||||
|
|
||||||
// ARMv6 miscellaneous instructions
|
|
||||||
MORPH_SINGLE (CPS ),
|
|
||||||
MORPH_SINGLE (CLREX ),
|
|
||||||
MORPH_SET_NOP (DSB ),
|
|
||||||
MORPH_SET_NOP (ISB ),
|
|
||||||
|
|
||||||
// ARMv7 miscellaneous instructions
|
|
||||||
MORPH_SET_PLD (PLD),
|
|
||||||
MORPH_SET_PLD (PLI),
|
|
||||||
MORPH_SET_NOP (DMB),
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DSP INSTRUCTIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// data processing instructions
|
|
||||||
MORPH_SINGLE (QADD ),
|
|
||||||
MORPH_SINGLE (QDADD),
|
|
||||||
MORPH_SINGLE (QDSUB),
|
|
||||||
MORPH_SINGLE (QSUB ),
|
|
||||||
|
|
||||||
// multiply instructions
|
|
||||||
MORPH_SET_SMLA_XY (SMLA ),
|
|
||||||
MORPH_SET_SMLA_XY (SMLAL),
|
|
||||||
MORPH_SET_SMLAW_Y (SMLAW),
|
|
||||||
MORPH_SET_SMLA_XY (SMUL ),
|
|
||||||
MORPH_SET_SMLAW_Y (SMULW),
|
|
||||||
|
|
||||||
// load and store instructions
|
|
||||||
MORPH_SET_LDRH (LDRD, LDR),
|
|
||||||
MORPH_SET_LDRH (STRD, STR),
|
|
||||||
|
|
||||||
// coprocessor instructions (all UsageFault)
|
|
||||||
MORPH_SET_SWP (MCRR, UsageFaultCP),
|
|
||||||
MORPH_SET_SWP (MCRR2, UsageFaultCP),
|
|
||||||
MORPH_SET_SWP (MRRC, UsageFaultCP),
|
|
||||||
MORPH_SET_SWP (MRRC2, UsageFaultCP),
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// MEDIA INSTRUCTIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// basic instructions
|
|
||||||
MORPH_SINGLE (USAD8 ),
|
|
||||||
MORPH_SINGLE (USADA8),
|
|
||||||
MORPH_SINGLE (SBFX ),
|
|
||||||
MORPH_SINGLE (BFC ),
|
|
||||||
MORPH_SINGLE (BFI ),
|
|
||||||
MORPH_SINGLE (UBFX ),
|
|
||||||
|
|
||||||
// parallel add/subtract instructions
|
|
||||||
MORPH_SET_PAS (S, vmi_ADD, vmi_SUB, True, True, False),
|
|
||||||
MORPH_SET_PAS (Q, vmi_ADDSQ, vmi_SUBSQ, False, False, False),
|
|
||||||
MORPH_SET_PAS (SH, vmi_ADD, vmi_SUB, True, False, True ),
|
|
||||||
MORPH_SET_PAS (U, vmi_ADD, vmi_SUB, False, True, False),
|
|
||||||
MORPH_SET_PAS (UQ, vmi_ADDUQ, vmi_SUBUQ, False, False, False),
|
|
||||||
MORPH_SET_PAS (UH, vmi_ADD, vmi_SUB, False, False, True ),
|
|
||||||
|
|
||||||
// packing, unpacking, saturation and reversal instructions
|
|
||||||
MORPH_SINGLE (PKHBT ),
|
|
||||||
MORPH_SINGLE (PKHTB ),
|
|
||||||
MORPH_SINGLE (SSAT ),
|
|
||||||
MORPH_SINGLE (SSAT16 ),
|
|
||||||
MORPH_SINGLE (USAT ),
|
|
||||||
MORPH_SINGLE (USAT16 ),
|
|
||||||
MORPH_SINGLE (SXTAB ),
|
|
||||||
MORPH_SINGLE (UXTAB ),
|
|
||||||
MORPH_SINGLE (SXTAB16),
|
|
||||||
MORPH_SINGLE (UXTAB16),
|
|
||||||
MORPH_SINGLE (SXTAH ),
|
|
||||||
MORPH_SINGLE (UXTAH ),
|
|
||||||
MORPH_SINGLE (SXTB ),
|
|
||||||
MORPH_SINGLE (UXTB ),
|
|
||||||
MORPH_SINGLE (SXTB16 ),
|
|
||||||
MORPH_SINGLE (UXTB16 ),
|
|
||||||
MORPH_SINGLE (SXTH ),
|
|
||||||
MORPH_SINGLE (UXTH ),
|
|
||||||
MORPH_SINGLE (SEL ),
|
|
||||||
MORPH_SINGLE (REV ),
|
|
||||||
MORPH_SINGLE (REV16 ),
|
|
||||||
MORPH_SINGLE (RBIT ),
|
|
||||||
MORPH_SINGLE (REVSH ),
|
|
||||||
|
|
||||||
// signed multiply instructions
|
|
||||||
MORPH_SET_MEDIA_X (SMLAD, SMLXD, vmi_ADD),
|
|
||||||
MORPH_SET_MEDIA_X (SMUAD, SMUXD, vmi_ADD),
|
|
||||||
MORPH_SET_MEDIA_X (SMLSD, SMLXD, vmi_SUB),
|
|
||||||
MORPH_SET_MEDIA_X (SMUSD, SMUXD, vmi_SUB),
|
|
||||||
MORPH_SET_MEDIA_X (SMLALD, SMLXLD, vmi_ADD),
|
|
||||||
MORPH_SET_MEDIA_X (SMLSLD, SMLXLD, vmi_SUB),
|
|
||||||
MORPH_SET_MEDIA_R (SMMLA, SMMLX, vmi_ADD, True ),
|
|
||||||
MORPH_SET_MEDIA_R (SMMUL, SMMLX, vmi_ADD, False),
|
|
||||||
MORPH_SET_MEDIA_R (SMMLS, SMMLX, vmi_RSUB, True ),
|
|
||||||
|
|
||||||
// VFP data processing instructions
|
|
||||||
MORPH_SET_VFP_RRR_F (VMLA_VFP, VMulAcc_VFP, vmi_FADD, 0),
|
|
||||||
MORPH_SET_VFP_RRR_F (VMLS_VFP, VMulAcc_VFP, vmi_FSUB, 0),
|
|
||||||
MORPH_SET_VFP_RRR_F (VNMLA_VFP, VMulAcc_VFP, vmi_FSUB, 1),
|
|
||||||
MORPH_SET_VFP_RRR_F (VNMLS_VFP, VMulAcc_VFP, vmi_FADD, 1),
|
|
||||||
MORPH_SET_VFP_RRR_F (VNMUL_VFP, VFPBinop, vmi_FMUL, 1),
|
|
||||||
MORPH_SET_VFP_RRR_F (VMUL_VFP, VFPBinop, vmi_FMUL, 0),
|
|
||||||
MORPH_SET_VFP_RRR_F (VADD_VFP, VFPBinop, vmi_FADD, 0),
|
|
||||||
MORPH_SET_VFP_RRR_F (VSUB_VFP, VFPBinop, vmi_FSUB, 0),
|
|
||||||
MORPH_SET_VFP_RRR_F (VDIV_VFP, VFPBinop, vmi_FDIV, 0),
|
|
||||||
MORPH_SET_VFP_FMAC_F (VFNMA_VFP, 1, 1),
|
|
||||||
MORPH_SET_VFP_FMAC_F (VFNMS_VFP, 0, 1),
|
|
||||||
MORPH_SET_VFP_FMAC_F (VFMA_VFP, 0, 0),
|
|
||||||
MORPH_SET_VFP_FMAC_F (VFMS_VFP, 1, 0),
|
|
||||||
MORPH_SET_VFP_S (VMOVI_VFP, VMOVI_VFP),
|
|
||||||
MORPH_SET_VFP_S (VMOVR_VFP, VMOVR_VFP),
|
|
||||||
MORPH_SET_VFP_S (VABS_VFP, VABS_VFP),
|
|
||||||
MORPH_SET_VFP_S (VNEG_VFP, VNEG_VFP),
|
|
||||||
MORPH_SET_VFP_RR_F (VSQRT_VFP, vmi_FSQRT),
|
|
||||||
MORPH_SET_VFP_VCMP (VCMP_VFP, VCMP_VFP, 1),
|
|
||||||
MORPH_SET_VFP_VCMP (VCMPE_VFP, VCMP_VFP, 0),
|
|
||||||
MORPH_SET_VFP_VCMP (VCMP0_VFP, VCMP0_VFP, 1),
|
|
||||||
MORPH_SET_VFP_VCMP (VCMPE0_VFP, VCMP0_VFP, 0),
|
|
||||||
// VCVT between half precision and single precision
|
|
||||||
MORPH_SET_VFP_VCVT_H (VCVTTFH_VFP, VCVT_SH_VFP, 2, 1),
|
|
||||||
MORPH_SET_VFP_VCVT_H (VCVTBFH_VFP, VCVT_SH_VFP, 2, 0),
|
|
||||||
MORPH_SET_VFP_VCVT_H (VCVTTHF_VFP, VCVT_HS_VFP, 2, 1),
|
|
||||||
MORPH_SET_VFP_VCVT_H (VCVTBHF_VFP, VCVT_HS_VFP, 2, 0),
|
|
||||||
// VCVT from single precision to Integer (signed or unsigned) with round option
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTRUF_VFP, VCVT_IF_VFP, 4, 0, 1),
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTUF_VFP, VCVT_IF_VFP, 4, 0, 0),
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTRSF_VFP, VCVT_IF_VFP, 4, 1, 1),
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTSF_VFP, VCVT_IF_VFP, 4, 1, 0),
|
|
||||||
// VCVT from single precision to Fixed (signed or unsigned, word or half)
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTXFUW_VFP, VCVT_XF_VFP, 4, 0, 0),
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTXFSW_VFP, VCVT_XF_VFP, 4, 1, 0),
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTXFUH_VFP, VCVT_XF_VFP, 2, 0, 0),
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTXFSH_VFP, VCVT_XF_VFP, 2, 1, 0),
|
|
||||||
// VCVT from Fixed (signed or unsigned, word or half) to single precision
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTFXUW_VFP, VCVT_FX_VFP, 4, 0, 0),
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTFXSW_VFP, VCVT_FX_VFP, 4, 1, 0),
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTFXUH_VFP, VCVT_FX_VFP, 2, 0, 0),
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTFXSH_VFP, VCVT_FX_VFP, 2, 1, 0),
|
|
||||||
// VCVT From Integer (signed or unsigned) to single precision
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTFU_VFP, VCVT_FI_VFP, 4, 0, 1),
|
|
||||||
MORPH_SET_VFP_VCVT (VCVTFS_VFP, VCVT_FI_VFP, 4, 1, 1),
|
|
||||||
|
|
||||||
// 8, 16 and 32-bit transfer instructions
|
|
||||||
MORPH_SET_SINGLE_VFP (VMRS),
|
|
||||||
MORPH_SET_SINGLE_VFP (VMSR),
|
|
||||||
MORPH_SET_SINGLE_VFP (VMOVRS),
|
|
||||||
MORPH_SET_SINGLE_VFP (VMOVSR),
|
|
||||||
MORPH_SET_SINGLE_VFP (VMOVRZ),
|
|
||||||
MORPH_SET_SINGLE_VFP (VMOVZR),
|
|
||||||
|
|
||||||
// Extension register load/store instructions
|
|
||||||
MORPH_SET_VFP_DS (VLDR, VLDR),
|
|
||||||
MORPH_SET_VFP_DS (VSTR, VSTR),
|
|
||||||
MORPH_SET_VFP_DS (VLDR, VLDR),
|
|
||||||
MORPH_SET_VFP_DS (VSTR, VSTR),
|
|
||||||
MORPH_SET_VFP_DS (VLDMIA, VLDM),
|
|
||||||
MORPH_SET_VFP_DS (VLDMIAW, VLDM),
|
|
||||||
MORPH_SET_VFP_DS (VLDMDBW, VLDM),
|
|
||||||
MORPH_SET_VFP_DS (VPOP, VLDM),
|
|
||||||
MORPH_SET_VFP_DS (VSTMIA, VSTM),
|
|
||||||
MORPH_SET_VFP_DS (VSTMIAW, VSTM),
|
|
||||||
MORPH_SET_VFP_DS (VSTMDBW, VSTM),
|
|
||||||
MORPH_SET_VFP_DS (VPUSH, VSTM),
|
|
||||||
|
|
||||||
// 64-bit transfer instructions
|
|
||||||
MORPH_SET_SINGLE_VFP (VMOVRRD),
|
|
||||||
MORPH_SET_SINGLE_VFP (VMOVDRR),
|
|
||||||
MORPH_SET_SINGLE_VFP (VMOVRRSS),
|
|
||||||
MORPH_SET_SINGLE_VFP (VMOVSSRR),
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// THUMB INSTRUCTIONS (WHEN DISTINCT FROM ARM INSTRUCTIONS)
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// data processing instructions
|
|
||||||
MORPH_SET_ADD4 (ADD4, vmi_ADD, 0, 0, False),
|
|
||||||
MORPH_SET_ADD6 (ADD6, vmi_ADD, 0, 0, False),
|
|
||||||
MORPH_SET_ADD7 (ADD7, vmi_ADD, 0, 0, False),
|
|
||||||
MORPH_SET_ADD7 (SUB4, vmi_SUB, 0, 0, False),
|
|
||||||
MORPH_SET_MOV3 (MOV3, vmi_MOV, 0, 0, False),
|
|
||||||
|
|
||||||
// address instructions
|
|
||||||
MORPH_SET_ADR (ADD_ADR, False),
|
|
||||||
MORPH_SET_ADR (SUB_ADR, True ),
|
|
||||||
|
|
||||||
// branch instructions
|
|
||||||
MORPH_SET_CBZ (CBNZ, False),
|
|
||||||
MORPH_SET_CBZ (CBZ, True ),
|
|
||||||
MORPH_SINGLE (TB),
|
|
||||||
|
|
||||||
// divide instructions
|
|
||||||
MORPH_SET_SDIV (SDIV, vmi_IDIV),
|
|
||||||
MORPH_SET_SDIV (UDIV, vmi_DIV ),
|
|
||||||
};
|
|
||||||
@ -1,166 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Imperas header files
|
|
||||||
#include "hostapi/impAlloc.h"
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiAttrs.h"
|
|
||||||
#include "vmi/vmiParameters.h"
|
|
||||||
#include "vmi/vmiMessage.h"
|
|
||||||
|
|
||||||
#include "armFunctions.h"
|
|
||||||
#include "armConfig.h"
|
|
||||||
#include "armmParameters.h"
|
|
||||||
#include "armStructure.h"
|
|
||||||
#include "armVariant.h"
|
|
||||||
|
|
||||||
static vmiEnumParameter compatTable[] = {
|
|
||||||
{"ISA", COMPAT_ISA},
|
|
||||||
{"gdb", COMPAT_GDB},
|
|
||||||
{"nopBKPT", COMPAT_CODE_SOURCERY},
|
|
||||||
{ 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Table of parameter specs
|
|
||||||
//
|
|
||||||
static vmiParameter formals[] = {
|
|
||||||
|
|
||||||
VMI_ENUM_PARAM_SPEC( armParamValues, variant, NULL, "Select variant (either a generic ISA or a specific model)"), // filled in by getVariantList()
|
|
||||||
VMI_ENDIAN_PARAM_SPEC(armParamValues, endian, "Model endian"),
|
|
||||||
VMI_ENUM_PARAM_SPEC( armParamValues, compatibility, compatTable, "Specify compatibility mode (default: ISA)"),
|
|
||||||
|
|
||||||
VMI_BOOL_PARAM_SPEC( armParamValues, verbose, 1, "Specify verbosity of output" ),
|
|
||||||
VMI_BOOL_PARAM_SPEC( armParamValues, showHiddenRegs, 0, "Show hidden registers during register tracing" ),
|
|
||||||
VMI_BOOL_PARAM_SPEC( armParamValues, UAL, 1, "Disassemble using UAL syntax" ),
|
|
||||||
VMI_BOOL_PARAM_SPEC( armParamValues, enableVFPAtReset, 0, "Enable vector floating point (VFP) instructions at reset. (Enables cp10/11 in CPACR)" ),
|
|
||||||
VMI_BOOL_PARAM_SPEC( armParamValues, disableBitBand, 0, "Disable bit banding"),
|
|
||||||
VMI_BOOL_PARAM_SPEC( armParamValues, resetAtTime0, 1, "Reset the model at time=0 (NB: default=1)" ),
|
|
||||||
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_CPUID , 0, 0, VMI_MAXU32, "Override system CPUID register"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_MPU_TYPE , 0, 0, VMI_MAXU32, "Override system MPU_TYPE register"),
|
|
||||||
|
|
||||||
VMI_ENDIAN_PARAM_SPEC(armParamValues, instructionEndian, "The ARMv7-M is defined to always fetch instructions in little endian order; this attribute allows the profile-defined instruction endianness to be overridden if required"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_debugMask , 0, 0, VMI_MAXU32, "Specifies debug mask, enabling debug output for model components"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_MPUType , 0, 0, VMI_MAXU32, "Override MPUType register"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_InstructionAttributes0, 0, 0, VMI_MAXU32, "Override InstructionAttributes0 register"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_InstructionAttributes1, 0, 0, VMI_MAXU32, "Override InstructionAttributes1 register"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_InstructionAttributes2, 0, 0, VMI_MAXU32, "Override InstructionAttributes2 register"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_InstructionAttributes3, 0, 0, VMI_MAXU32, "Override InstructionAttributes3 register"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_InstructionAttributes4, 0, 0, VMI_MAXU32, "Override InstructionAttributes4 register"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_InstructionAttributes5, 0, 0, VMI_MAXU32, "Override InstructionAttributes5 register"),
|
|
||||||
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_MVFR0, 0, 0, VMI_MAXU32, "Override MVFR0 register"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_MVFR1, 0, 0, VMI_MAXU32, "Override MVFR1 register"),
|
|
||||||
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_rotateUnaligned , 0, 0, 1, "Specifies that data from unaligned loads by LDR, LDRT or SWP should be rotated (if 1)"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_align64as32 , 0, 0, 1, "Specifies that 64:bit loads and stores are aligned to 32:bit boundaries (if 1)"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_STRoffsetPC12 , 0, 0, 1, "Specifies that STR/STR of PC should do so with 12:byte offset from the current instruction (if 1), otherwise an 8:byte offset is used"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_ERG , 0, 0, 1024, "Specifies exclusive reservation granule"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_priorityBits , 0, 0, 8 , "Specifies number of priority bits in BASEPRI etc (1-8, default is 3)"),
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, override_numInterrupts , 0, 0, 4096, "Specifies number of external interrupt lines (0-495, default is 16)"),
|
|
||||||
|
|
||||||
VMI_UNS32_PARAM_SPEC( armParamValues, fail_salp , 0, 0, VMI_MAXU32, "Address of Fail* SAL Object"),
|
|
||||||
|
|
||||||
VMI_END_PARAM
|
|
||||||
};
|
|
||||||
|
|
||||||
static Uns32 countVariants(void) {
|
|
||||||
armConfigCP cfg = armConfigTable;
|
|
||||||
Uns32 i = 0;
|
|
||||||
while(cfg->name) {
|
|
||||||
cfg++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// First time through, malloc and fill the variant list from the config table
|
|
||||||
//
|
|
||||||
static vmiEnumParameterP getVariantList() {
|
|
||||||
static vmiEnumParameterP list = NULL;
|
|
||||||
if (!list) {
|
|
||||||
Uns32 v = 1+ countVariants();
|
|
||||||
list = STYPE_CALLOC_N(vmiEnumParameter, v);
|
|
||||||
vmiEnumParameterP prm;
|
|
||||||
armConfigCP cfg;
|
|
||||||
Uns32 i;
|
|
||||||
for (i = 0, cfg = armConfigTable, prm = list;
|
|
||||||
cfg->name;
|
|
||||||
i++, cfg++, prm++) {
|
|
||||||
prm->name = cfg->name;
|
|
||||||
prm->value = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// First time through, fill the formals table
|
|
||||||
//
|
|
||||||
static vmiParameterP getFormals(void) {
|
|
||||||
static Bool first = True;
|
|
||||||
if(first) {
|
|
||||||
first = False;
|
|
||||||
formals[0].u.enumParam.legalValues = getVariantList();
|
|
||||||
}
|
|
||||||
return formals;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Function to iterate the parameter specs
|
|
||||||
//
|
|
||||||
VMI_PROC_PARAM_SPECS_FN(armGetParamSpec) {
|
|
||||||
if(!prev) {
|
|
||||||
return getFormals();
|
|
||||||
} else {
|
|
||||||
prev++;
|
|
||||||
if (prev->name)
|
|
||||||
return prev;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Get the size of the parameter values table
|
|
||||||
//
|
|
||||||
VMI_PROC_PARAM_TABLE_SIZE_FN(armParamValueSize) {
|
|
||||||
return sizeof(armParamValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ARMM_PARAMETERS_H
|
|
||||||
#define ARMM_PARAMETERS_H
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiAttrs.h"
|
|
||||||
#include "vmi/vmiParameters.h"
|
|
||||||
|
|
||||||
#include "armTypeRefs.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Define the attributes value structure
|
|
||||||
//
|
|
||||||
typedef struct armParamValuesS {
|
|
||||||
VMI_ENUM_PARAM(variant);
|
|
||||||
VMI_ENDIAN_PARAM(endian);
|
|
||||||
VMI_ENUM_PARAM(compatibility);
|
|
||||||
|
|
||||||
VMI_BOOL_PARAM(verbose);
|
|
||||||
VMI_BOOL_PARAM(showHiddenRegs);
|
|
||||||
VMI_BOOL_PARAM(UAL);
|
|
||||||
VMI_BOOL_PARAM(enableVFPAtReset);
|
|
||||||
VMI_BOOL_PARAM(disableBitBand);
|
|
||||||
VMI_BOOL_PARAM(resetAtTime0);
|
|
||||||
|
|
||||||
VMI_UNS32_PARAM(override_CPUID);
|
|
||||||
VMI_UNS32_PARAM(override_MPU_TYPE);
|
|
||||||
|
|
||||||
VMI_ENUM_PARAM(instructionEndian);
|
|
||||||
VMI_UNS32_PARAM(override_debugMask);
|
|
||||||
VMI_UNS32_PARAM(override_MPUType);
|
|
||||||
VMI_UNS32_PARAM(override_InstructionAttributes0);
|
|
||||||
VMI_UNS32_PARAM(override_InstructionAttributes1);
|
|
||||||
VMI_UNS32_PARAM(override_InstructionAttributes2);
|
|
||||||
VMI_UNS32_PARAM(override_InstructionAttributes3);
|
|
||||||
VMI_UNS32_PARAM(override_InstructionAttributes4);
|
|
||||||
VMI_UNS32_PARAM(override_InstructionAttributes5);
|
|
||||||
|
|
||||||
VMI_UNS32_PARAM(override_MVFR0);
|
|
||||||
VMI_UNS32_PARAM(override_MVFR1);
|
|
||||||
|
|
||||||
VMI_UNS32_PARAM(override_rotateUnaligned);
|
|
||||||
VMI_UNS32_PARAM(override_align64as32);
|
|
||||||
VMI_UNS32_PARAM(override_STRoffsetPC12);
|
|
||||||
VMI_UNS32_PARAM(override_ERG);
|
|
||||||
VMI_UNS32_PARAM(override_priorityBits);
|
|
||||||
VMI_UNS32_PARAM(override_numInterrupts);
|
|
||||||
|
|
||||||
VMI_UNS32_PARAM(fail_salp);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} armParamValues, *armParamValuesP;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,182 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiTypes.h"
|
|
||||||
#include "vmi/vmiMessage.h"
|
|
||||||
#include "vmi/vmiMt.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armFunctions.h"
|
|
||||||
#include "armRegisters.h"
|
|
||||||
#include "armStructure.h"
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Prefix for messages from this module
|
|
||||||
//
|
|
||||||
#define CPU_PREFIX "ARM_SEMIHOST"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return processor endianness
|
|
||||||
//
|
|
||||||
inline static memEndian getEndian(armP arm) {
|
|
||||||
return armGetEndian((vmiProcessorP)arm, False);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Morph return from an opaque intercepted function
|
|
||||||
//
|
|
||||||
VMI_INT_RETURN_FN(armIntReturnCB) {
|
|
||||||
vmimtUncondJumpReg(0, ARM_REG(ARM_REG_LR), VMI_NOREG, vmi_JH_RETURN);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// This callback should create code to assign function result to the standard
|
|
||||||
// return result register
|
|
||||||
//
|
|
||||||
VMI_INT_RESULT_FN(armIntResultCB) {
|
|
||||||
vmimtMoveRR(32, ARM_REG(0), VMI_FUNCRESULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// This callback should create code to push 32-bit function parameter 'paramNum'
|
|
||||||
//
|
|
||||||
static Uns32 push4ByteArg(vmiProcessorP processor, Uns32 paramNum) {
|
|
||||||
|
|
||||||
if(paramNum<=3) {
|
|
||||||
|
|
||||||
// argument in a register
|
|
||||||
vmimtArgReg(32, ARM_REG(paramNum));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// argument on the stack
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
|
|
||||||
// fetch into a temporary
|
|
||||||
vmimtLoadRRO(
|
|
||||||
32, // destBits
|
|
||||||
32, // memBits
|
|
||||||
(paramNum-4)*4, // offset
|
|
||||||
ARM_TEMP(0), // destination (rd)
|
|
||||||
ARM_REG(ARM_REG_SP), // stack address (ra)
|
|
||||||
getEndian(arm), // endian
|
|
||||||
False, // signExtend
|
|
||||||
False // checkAlign
|
|
||||||
);
|
|
||||||
|
|
||||||
// push temporary argument
|
|
||||||
vmimtArgReg(32, ARM_TEMP(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return paramNum+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// This callback should create code to push 64-bit function parameter 'paramNum'
|
|
||||||
//
|
|
||||||
static Uns32 push8ByteArg(vmiProcessorP processor, Uns32 paramNum) {
|
|
||||||
|
|
||||||
paramNum += push4ByteArg(processor, paramNum);
|
|
||||||
paramNum += push4ByteArg(processor, paramNum);
|
|
||||||
|
|
||||||
return paramNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// This callback should create code to push address function parameter 'paramNum'
|
|
||||||
//
|
|
||||||
static Uns32 pushAddressArg(vmiProcessorP processor, Uns32 paramNum) {
|
|
||||||
|
|
||||||
if(paramNum<=3) {
|
|
||||||
|
|
||||||
// argument in a register
|
|
||||||
vmimtArgRegSimAddress(32, ARM_REG(paramNum));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// argument on the stack
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
|
|
||||||
// fetch into a temporary
|
|
||||||
vmimtLoadRRO(
|
|
||||||
32, // destBits
|
|
||||||
32, // memBits
|
|
||||||
(paramNum-4)*4, // offset
|
|
||||||
ARM_TEMP(0), // destination (rd)
|
|
||||||
ARM_REG(ARM_REG_SP), // stack address (ra)
|
|
||||||
getEndian(arm), // endian
|
|
||||||
False, // signExtend
|
|
||||||
False // checkAlign
|
|
||||||
);
|
|
||||||
|
|
||||||
// push temporary argument
|
|
||||||
vmimtArgRegSimAddress(32, ARM_TEMP(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return paramNum+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// This callback should create code to push function arguments prior to an
|
|
||||||
// Imperas standard intercept
|
|
||||||
//
|
|
||||||
VMI_INT_PAR_FN(armIntParCB) {
|
|
||||||
|
|
||||||
Uns32 paramNum = 0;
|
|
||||||
char ch;
|
|
||||||
|
|
||||||
while((ch=*format++)) {
|
|
||||||
|
|
||||||
switch(ch) {
|
|
||||||
|
|
||||||
case '4':
|
|
||||||
paramNum = push4ByteArg(processor, paramNum);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '8':
|
|
||||||
paramNum = push8ByteArg(processor, paramNum);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'a':
|
|
||||||
paramNum = pushAddressArg(processor, paramNum);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
VMI_ABORT("Unrecognised format character '%c'", ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,509 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiCxt.h"
|
|
||||||
#include "vmi/vmiRt.h"
|
|
||||||
#include "vmi/vmiMessage.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armDecode.h"
|
|
||||||
#include "armExceptions.h"
|
|
||||||
#include "armFunctions.h"
|
|
||||||
#include "armStructure.h"
|
|
||||||
#include "armSysRegisters.h"
|
|
||||||
#include "armUtils.h"
|
|
||||||
#include "armVM.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the version of the instruction set implemented by the processor
|
|
||||||
//
|
|
||||||
inline static Uns32 getInstructionVersion(armP arm) {
|
|
||||||
return ARM_INSTRUCTION_VERSION(arm->configInfo.arch);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return endianness of the processor, public routine
|
|
||||||
//
|
|
||||||
VMI_ENDIAN_FN(armGetEndian) {
|
|
||||||
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
|
|
||||||
if(isFetch) {
|
|
||||||
return arm->instructionEndian;
|
|
||||||
} else if(SCS_FIELD(arm, AIRCR, ENDIANNESS)) {
|
|
||||||
return MEM_ENDIAN_BIG;
|
|
||||||
} else {
|
|
||||||
return MEM_ENDIAN_LITTLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set the initial endianness for the model
|
|
||||||
//
|
|
||||||
void armSetInitialEndian(armP arm, Bool isBigEndian) {
|
|
||||||
SCS_FIELD(arm, AIRCR, ENDIANNESS) = isBigEndian;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the next instruction address after 'thisPC'.
|
|
||||||
//
|
|
||||||
VMI_NEXT_PC_FN(armNextInstruction) {
|
|
||||||
return (Uns32)(thisPC + armGetInstructionSize((armP)processor, thisPC));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the name of a GPR
|
|
||||||
//
|
|
||||||
const char *armGetGPRName(armP arm, Uns32 index) {
|
|
||||||
|
|
||||||
static const char *gprNames[] = {
|
|
||||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
|
||||||
"r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc"
|
|
||||||
};
|
|
||||||
|
|
||||||
return gprNames[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the name of a CPR
|
|
||||||
//
|
|
||||||
const char *armGetCPRName(armP arm, Uns32 index) {
|
|
||||||
|
|
||||||
static const char *cprNames[] = {
|
|
||||||
"cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
|
|
||||||
"cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", "cr15"
|
|
||||||
};
|
|
||||||
|
|
||||||
return cprNames[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SWAP_REG(_R1, _R2) {Uns32 _V = _R1; _R1= _R2; _R2 = _V;}
|
|
||||||
#define SWAP_GPR(_N, _SET) SWAP_REG(arm->regs[_N], arm->bank.R##_N##_##_SET)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Switch banked registers on switch to the passed mode
|
|
||||||
//
|
|
||||||
inline static void switchRegs(armP arm, Bool useSPProcess) {
|
|
||||||
if(useSPProcess) {
|
|
||||||
SWAP_GPR(13, process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Switch banked registers on switch between the passed modes
|
|
||||||
//
|
|
||||||
void armSwitchRegs(armP arm, Bool oldUseSPProcess, Bool newUseSPProcess) {
|
|
||||||
switchRegs(arm, oldUseSPProcess);
|
|
||||||
switchRegs(arm, newUseSPProcess);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return current processor block mask
|
|
||||||
//
|
|
||||||
static armBlockMask getBlockMask(armP arm) {
|
|
||||||
|
|
||||||
armBlockMask blockMask = 0;
|
|
||||||
|
|
||||||
// get blockmask component selecting register bank
|
|
||||||
if(USE_SP_PROCESS(arm)) {
|
|
||||||
blockMask |= ARM_BM_USE_SP_PROCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// include component for endianness
|
|
||||||
if(SCS_FIELD(arm, AIRCR, ENDIANNESS)) {
|
|
||||||
blockMask |= ARM_BM_BIG_ENDIAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// include component for alignment checking
|
|
||||||
if(DO_UNALIGNED(arm)) {
|
|
||||||
blockMask |= ARM_BM_UNALIGNED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// include component for cp10 (and cp11) enable checking
|
|
||||||
// NOTE: arm documentation specifies behavior is undefined if cp10 enable
|
|
||||||
// differs from cp11 enable, so only cp10 enable is checked here
|
|
||||||
Uns32 cp10Enable = SCS_FIELD(arm, CPACR, cp10);
|
|
||||||
if(IN_USER_MODE(arm)) {
|
|
||||||
if(cp10Enable&2) {blockMask |= ARM_BM_CP10;}
|
|
||||||
} else {
|
|
||||||
if(cp10Enable&1) {blockMask |= ARM_BM_CP10;}
|
|
||||||
}
|
|
||||||
|
|
||||||
// include CONTROL.FPCA bit
|
|
||||||
if(CONTROL_FIELD(arm, FPCA)) {
|
|
||||||
blockMask |= ARM_BM_FPCA;
|
|
||||||
}
|
|
||||||
|
|
||||||
// include FPCCR.ASPEN bit
|
|
||||||
if(SCS_FIELD(arm, FPCCR, ASPEN)) {
|
|
||||||
blockMask |= ARM_BM_ASPEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// include FPCCR.LSPACT bit
|
|
||||||
if(SCS_FIELD(arm, FPCCR, LSPACT)) {
|
|
||||||
blockMask |= ARM_BM_LSPACT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return blockMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Update processor block mask
|
|
||||||
//
|
|
||||||
void armSetBlockMask(armP arm) {
|
|
||||||
vmirtSetBlockMask((vmiProcessorP)arm, getBlockMask(arm));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Update processor mode when system state that affects it has been written
|
|
||||||
//
|
|
||||||
static void updateMode(armP arm) {
|
|
||||||
|
|
||||||
// update block mask
|
|
||||||
armSetBlockMask(arm);
|
|
||||||
|
|
||||||
// switch mode if required
|
|
||||||
armSwitchMode(arm);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write CONTROL.SP_PROCESS field
|
|
||||||
//
|
|
||||||
void armWriteSPProcess(armP arm, Bool newUseSPProcess) {
|
|
||||||
|
|
||||||
Bool oldUseSPProcess = USE_SP_PROCESS(arm);
|
|
||||||
|
|
||||||
if(oldUseSPProcess!=newUseSPProcess) {
|
|
||||||
|
|
||||||
// update CONTROL.SP_PROCESS
|
|
||||||
USE_SP_PROCESS(arm) = newUseSPProcess;
|
|
||||||
|
|
||||||
// switch banked registers
|
|
||||||
armSwitchRegs(arm, oldUseSPProcess, newUseSPProcess);
|
|
||||||
|
|
||||||
// update block mask
|
|
||||||
armSetBlockMask(arm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read CPSR register
|
|
||||||
//
|
|
||||||
Uns32 armReadCPSR(armP arm) {
|
|
||||||
|
|
||||||
// seed flag fields from flag structure
|
|
||||||
PSR_FIELD(arm, Z) = arm->aflags.ZF;
|
|
||||||
PSR_FIELD(arm, N) = arm->aflags.NF;
|
|
||||||
PSR_FIELD(arm, C) = arm->aflags.CF;
|
|
||||||
PSR_FIELD(arm, V) = arm->aflags.VF;
|
|
||||||
PSR_FIELD(arm, Q) = arm->oflags.QF;
|
|
||||||
|
|
||||||
// seed if-then state fields
|
|
||||||
PSR_FIELD(arm, IT10) = arm->itStateRT & 0x3;
|
|
||||||
PSR_FIELD(arm, IT72) = arm->itStateRT >> 2;
|
|
||||||
|
|
||||||
// return derived value
|
|
||||||
return arm->sregs.PSR.reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read CONTROL register
|
|
||||||
//
|
|
||||||
Uns32 armReadCONTROL(armP arm) {
|
|
||||||
|
|
||||||
// return value
|
|
||||||
return arm->sregs.CONTROL.reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write CPSR register
|
|
||||||
//
|
|
||||||
void armWriteCPSR(armP arm, Uns32 value, Uns32 mask) {
|
|
||||||
|
|
||||||
// save current processor mode
|
|
||||||
Bool oldHandlerMode = IN_HANDLER_MODE(arm);
|
|
||||||
Bool oldCPSRT = PSR_FIELD(arm, T);
|
|
||||||
|
|
||||||
if (!DSP_PRESENT(arm)) {
|
|
||||||
// GE fields reserved when DSP not implemented
|
|
||||||
mask &= ~PSR_GE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set new register value (writable bits only)
|
|
||||||
arm->sregs.PSR.reg = (value & mask) | (arm->sregs.PSR.reg & ~mask);
|
|
||||||
|
|
||||||
// get new processor mode
|
|
||||||
Bool newHandlerMode = IN_HANDLER_MODE(arm);
|
|
||||||
Bool newCPSRT = PSR_FIELD(arm, T);
|
|
||||||
|
|
||||||
// update arithmetic flag fields if required
|
|
||||||
if(mask & PSR_FLAGS) {
|
|
||||||
arm->aflags.ZF = PSR_FIELD(arm, Z);
|
|
||||||
arm->aflags.NF = PSR_FIELD(arm, N);
|
|
||||||
arm->aflags.CF = PSR_FIELD(arm, C);
|
|
||||||
arm->aflags.VF = PSR_FIELD(arm, V);
|
|
||||||
arm->oflags.QF = PSR_FIELD(arm, Q);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update if-then state if required
|
|
||||||
if(mask & PSR_IT) {
|
|
||||||
arm->itStateRT = (PSR_FIELD(arm, IT10) | (PSR_FIELD(arm, IT72<<2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// update processor mode if required
|
|
||||||
if((oldHandlerMode!=newHandlerMode) || (oldCPSRT!=newCPSRT)) {
|
|
||||||
updateMode(arm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write PRIMASK register
|
|
||||||
//
|
|
||||||
void armWritePRIMASK(armP arm, Uns32 value) {
|
|
||||||
|
|
||||||
value &= PRIMASK_MASK;
|
|
||||||
|
|
||||||
if(arm->sregs.PRIMASK != value) {
|
|
||||||
arm->sregs.PRIMASK = value;
|
|
||||||
armRefreshExecutionPriority(arm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write BASEPRI register
|
|
||||||
//
|
|
||||||
void armWriteBASEPRI(armP arm, Uns32 value) {
|
|
||||||
|
|
||||||
value &= (BASEPRI_MASK & arm->priorityMask);
|
|
||||||
|
|
||||||
if(arm->sregs.BASEPRI != value) {
|
|
||||||
arm->sregs.BASEPRI = value;
|
|
||||||
armRefreshExecutionPriority(arm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write BASEPRI register (using BASEPRI_MAX semantics)
|
|
||||||
//
|
|
||||||
void armWriteBASEPRI_MAX(armP arm, Uns32 value) {
|
|
||||||
|
|
||||||
value &= (BASEPRI_MASK & arm->priorityMask);
|
|
||||||
|
|
||||||
if(value && ((value<arm->sregs.BASEPRI) || !arm->sregs.BASEPRI)) {
|
|
||||||
arm->sregs.BASEPRI = value;
|
|
||||||
armRefreshExecutionPriority(arm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write FAULTMASK register
|
|
||||||
//
|
|
||||||
void armWriteFAULTMASK(armP arm, Uns32 value) {
|
|
||||||
|
|
||||||
value &= FAULTMASK_MASK;
|
|
||||||
|
|
||||||
if((arm->executionPriority>-1) && (value!=arm->sregs.FAULTMASK)) {
|
|
||||||
arm->sregs.FAULTMASK = value;
|
|
||||||
armRefreshExecutionPriority(arm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// update the CONTROL.FPCA bit to the value. If it changes then set the block mask
|
|
||||||
//
|
|
||||||
void armUpdateFPCA(armP arm, Bool value) {
|
|
||||||
|
|
||||||
// if CONTROL.FPCA changes set new value and set the block mask
|
|
||||||
if (CONTROL_FIELD(arm, FPCA) != value) {
|
|
||||||
|
|
||||||
CONTROL_FIELD(arm, FPCA) = value;
|
|
||||||
armSetBlockMask(arm);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// update the FPCCR.LSPACT bit to the value. If it changes then set the block mask
|
|
||||||
//
|
|
||||||
void armUpdateLSPACT(armP arm, Bool value) {
|
|
||||||
|
|
||||||
// if FPCCR.LSPACT changes set new value and set the block mask
|
|
||||||
if (SCS_FIELD(arm, FPCCR, LSPACT) != value) {
|
|
||||||
|
|
||||||
SCS_FIELD(arm, FPCCR, LSPACT) = value;
|
|
||||||
armSetBlockMask(arm);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write CONTROL register
|
|
||||||
//
|
|
||||||
void armWriteCONTROL(armP arm, Uns32 value) {
|
|
||||||
|
|
||||||
armCONTROL u = {reg:value};
|
|
||||||
|
|
||||||
// update CONTROL.FPCA (FPCA is only implemented if FPU is present)
|
|
||||||
if (FPU_PRESENT(arm)) {
|
|
||||||
armUpdateFPCA(arm, u.fields.FPCA);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update CONTROL.threadUnpriv
|
|
||||||
Bool oldUserMode = IN_USER_MODE(arm);
|
|
||||||
CONTROL_FIELD(arm, threadUnpriv) = u.fields.threadUnpriv;
|
|
||||||
Bool newUserMode = IN_USER_MODE(arm);
|
|
||||||
|
|
||||||
// handle any switch to user mode
|
|
||||||
if(oldUserMode!=newUserMode) {
|
|
||||||
updateMode(arm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// CONTROL.useSP_Process may only be modified in Thread mode
|
|
||||||
if(!IN_HANDLER_MODE(arm)) {
|
|
||||||
armWriteSPProcess(arm, u.fields.useSP_Process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write SP register
|
|
||||||
//
|
|
||||||
void armWriteSP(armP arm, Uns32 value) {
|
|
||||||
arm->regs[ARM_REG_SP] = value & ~3;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Switch processor mode if required
|
|
||||||
//
|
|
||||||
void armSwitchMode(armP arm) {
|
|
||||||
|
|
||||||
armMode mode;
|
|
||||||
|
|
||||||
if(!IN_THUMB_MODE(arm)) {
|
|
||||||
|
|
||||||
// invalid mode
|
|
||||||
mode = ARM_MODE_ARM;
|
|
||||||
SCS_FIELD(arm, CFSR, INVSTATE) = 1;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
mode = 0;
|
|
||||||
|
|
||||||
// user/kernel mode mask
|
|
||||||
if(IN_USER_MODE(arm)) {
|
|
||||||
mode |= ARM_MODE_U;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add MPU enable mask
|
|
||||||
if(!MPU_ENABLED(arm)) {
|
|
||||||
// no action
|
|
||||||
} else if(arm->executionPriority>=0) {
|
|
||||||
mode |= ARM_MODE_MPU;
|
|
||||||
} else if(SCS_FIELD(arm, MPU_CONTROL, HFNMIENA)) {
|
|
||||||
mode |= ARM_MODE_MPU;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// switch mode if required
|
|
||||||
if(mode != arm->mode) {
|
|
||||||
vmirtSetMode((vmiProcessorP)arm, mode);
|
|
||||||
arm->mode = mode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// PROCESSOR RUN STATE TRANSITION HANDLING
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// If this memory access callback is triggered, abort any active load linked
|
|
||||||
//
|
|
||||||
static VMI_MEM_WATCH_FN(abortEA) {
|
|
||||||
armAbortExclusiveAccess((armP)userData);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Install or remove the exclusive access monitor callback
|
|
||||||
//
|
|
||||||
static void updateExclusiveAccessCallback(armP arm, Bool install) {
|
|
||||||
|
|
||||||
memDomainP domain = vmirtGetProcessorDataDomain((vmiProcessorP)arm);
|
|
||||||
Uns32 simLow = arm->exclusiveTag;
|
|
||||||
Uns32 simHigh = simLow + ~arm->exclusiveTagMask;
|
|
||||||
|
|
||||||
// install or remove a watchpoint on the current exclusive access address
|
|
||||||
if(install) {
|
|
||||||
vmirtAddWriteCallback(domain, simLow, simHigh, abortEA, arm);
|
|
||||||
} else {
|
|
||||||
vmirtRemoveWriteCallback(domain, simLow, simHigh, abortEA, arm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Abort any active exclusive access
|
|
||||||
//
|
|
||||||
void armAbortExclusiveAccess(armP arm) {
|
|
||||||
|
|
||||||
if(arm->exclusiveTag != ARM_NO_TAG) {
|
|
||||||
|
|
||||||
// remove callback on exclusive access monitor region
|
|
||||||
updateExclusiveAccessCallback(arm, False);
|
|
||||||
|
|
||||||
// clear exclusive tag (AFTER updateExclusiveAccessCallback)
|
|
||||||
arm->exclusiveTag = ARM_NO_TAG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is called on simulator context switch (when this processor is either
|
|
||||||
// about to start or about to stop simulation)
|
|
||||||
//
|
|
||||||
VMI_IASSWITCH_FN(armContextSwitchCB) {
|
|
||||||
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
|
|
||||||
// establish a watchpoint on a pending exclusive address to detect if that
|
|
||||||
// address is written elsewhere.
|
|
||||||
if(arm->exclusiveTag != ARM_NO_TAG) {
|
|
||||||
updateExclusiveAccessCallback(arm, state==RS_SUSPEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if a processor is about to be run, make state consistent with any changes
|
|
||||||
// that may have occurred while the processor was suspended
|
|
||||||
if(state==RS_RUN) {
|
|
||||||
armSetBlockMask(arm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,876 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* YOUR ACCESS TO THE INFORMATION IN THIS MODEL IS CONDITIONAL
|
|
||||||
* UPON YOUR ACCEPTANCE THAT YOU WILL NOT USE OR PERMIT OTHERS
|
|
||||||
* TO USE THE INFORMATION FOR THE PURPOSES OF DETERMINING WHETHER
|
|
||||||
* IMPLEMENTATIONS OF THE ARM ARCHITECTURE INFRINGE ANY THIRD
|
|
||||||
* PARTY PATENTS.
|
|
||||||
*
|
|
||||||
* THE LICENSE BELOW EXTENDS ONLY TO USE OF THE SOFTWARE FOR
|
|
||||||
* MODELING PURPOSES AND SHALL NOT BE CONSTRUED AS GRANTING
|
|
||||||
* A LICENSE TO CREATE A HARDWARE IMPLEMENTATION OF THE
|
|
||||||
* FUNCTIONALITY OF THE SOFTWARE LICENSED HEREUNDER.
|
|
||||||
* YOU MAY USE THE SOFTWARE SUBJECT TO THE LICENSE TERMS BELOW
|
|
||||||
* PROVIDED THAT YOU ENSURE THAT THIS NOTICE IS REPLICATED UNMODIFIED
|
|
||||||
* AND IN ITS ENTIRETY IN ALL DISTRIBUTIONS OF THE SOFTWARE,
|
|
||||||
* MODIFIED OR UNMODIFIED, IN SOURCE CODE OR IN BINARY FORM.
|
|
||||||
*
|
|
||||||
* Licensed under an Imperas Modfied Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.ovpworld.org/licenses/OVP_MODIFIED_1.0_APACHE_OPEN_SOURCE_LICENSE_2.0.pdf
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
// VMI header files
|
|
||||||
#include "vmi/vmiRt.h"
|
|
||||||
#include "vmi/vmiMessage.h"
|
|
||||||
|
|
||||||
// model header files
|
|
||||||
#include "armFPConstants.h"
|
|
||||||
#include "armMessage.h"
|
|
||||||
#include "armVFP.h"
|
|
||||||
#include "armSysRegisters.h"
|
|
||||||
#include "armStructure.h"
|
|
||||||
#include "armUtils.h"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Prefix for messages from this module
|
|
||||||
//
|
|
||||||
#define CPU_PREFIX "ARMM_VFP"
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return current program counter
|
|
||||||
//
|
|
||||||
inline static Uns32 getPC(armP arm) {
|
|
||||||
return vmirtGetPC((vmiProcessorP)arm);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// FLOATING POINT CONTROL PREDICATES
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return the current rounding control
|
|
||||||
//
|
|
||||||
static vmiFPRC getRoundingControl(armP arm) {
|
|
||||||
|
|
||||||
// map ARM rounding mode to VMI rounding mode
|
|
||||||
static const vmiFPRC modeMap[] = {
|
|
||||||
[0] = vmi_FPR_NEAREST,
|
|
||||||
[1] = vmi_FPR_POS_INF,
|
|
||||||
[2] = vmi_FPR_NEG_INF,
|
|
||||||
[3] = vmi_FPR_ZERO
|
|
||||||
};
|
|
||||||
|
|
||||||
if(SCS_USE_CPUID(arm) && !SCS_FIELD(arm, MVFR0, VFP_RoundingModes)) {
|
|
||||||
// if rounding modes are not supported, use vmi_FPR_NEAREST
|
|
||||||
return vmi_FPR_NEAREST;
|
|
||||||
} else {
|
|
||||||
// return the mapped rounding mode
|
|
||||||
return modeMap[FPSCR_FIELD(arm, RMode)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Should the default NaN be returned in any calculation that produces a NaN?
|
|
||||||
//
|
|
||||||
inline static Bool returnDefaultNaN(armP arm) {
|
|
||||||
return (
|
|
||||||
// in VFP mode, return the default NaN if FPSCR.DN is set
|
|
||||||
FPSCR_FIELD(arm, DN) ||
|
|
||||||
// MVFR1.DefaultNaNMode=0 indicates hardware supports only the default
|
|
||||||
// NaN mode
|
|
||||||
(SCS_USE_CPUID(arm) && !SCS_FIELD(arm, MVFR1, DefaultNaNMode))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Is flush-to-zero mode enabled?
|
|
||||||
//
|
|
||||||
inline static Bool inFTZMode(armP arm) {
|
|
||||||
return (
|
|
||||||
// flush-to-zero is enabled if FPSCR.FZ is set
|
|
||||||
FPSCR_FIELD(arm, FZ) ||
|
|
||||||
// MVFR1.FlushToZeroMode=0 indicates hardware supports only
|
|
||||||
// flush-to-zero mode
|
|
||||||
(SCS_USE_CPUID(arm) && !SCS_FIELD(arm, MVFR1, FlushToZeroMode))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Is alternative half precision mode enabled?
|
|
||||||
//
|
|
||||||
inline static Bool inAHPMode(armP arm) {
|
|
||||||
return FPSCR_FIELD(arm, AHP);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// FLOATING REGISTER ACCESS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set control word
|
|
||||||
//
|
|
||||||
inline static void setControlWord(armP arm, armFPCW new) {
|
|
||||||
if(arm->currentCW.u32 != new.u32) {
|
|
||||||
arm->currentCW = new;
|
|
||||||
vmirtSetFPControlWord((vmiProcessorP)arm, new.cw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Update VFP control word to make it consistent with the FPSCR
|
|
||||||
//
|
|
||||||
static void updateVFPControlWord(armP arm) {
|
|
||||||
|
|
||||||
// Mask off all exceptions */
|
|
||||||
armFPCW newFPCW = {.cw.IM=1, .cw.DM=1, .cw.ZM=1, .cw.OM=1, .cw.UM=1, .cw.PM=1};
|
|
||||||
|
|
||||||
// set rounding control, denormals-are-zero and flush-to-zero
|
|
||||||
newFPCW.cw.RC = getRoundingControl(arm);
|
|
||||||
newFPCW.cw.DAZ = newFPCW.cw.FZ = inFTZMode(arm);
|
|
||||||
|
|
||||||
// Set the new control word
|
|
||||||
setControlWord(arm, newFPCW);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Write VFP FPSCR register
|
|
||||||
//
|
|
||||||
void armWriteFPSCR(armP arm, Uns32 newValue, Uns32 writeMask) {
|
|
||||||
|
|
||||||
Uns32 oldValue = FPSCR_REG(arm);
|
|
||||||
|
|
||||||
// update raw register
|
|
||||||
FPSCR_REG(arm) = ((oldValue & ~writeMask) | (newValue & writeMask));
|
|
||||||
|
|
||||||
// set denormal input sticky flag
|
|
||||||
arm->denormalInput = FPSCR_FIELD(arm, IDC);
|
|
||||||
|
|
||||||
// set sticky flags
|
|
||||||
vmiFPFlags sticky = {0};
|
|
||||||
sticky.f.I = FPSCR_FIELD(arm, IOC); // invalid operation flag
|
|
||||||
sticky.f.Z = FPSCR_FIELD(arm, DZC); // divide-by-zero flag
|
|
||||||
sticky.f.O = FPSCR_FIELD(arm, OFC); // overflow flag
|
|
||||||
sticky.f.U = FPSCR_FIELD(arm, UFC); // underflow flag
|
|
||||||
sticky.f.P = FPSCR_FIELD(arm, IXC); // inexact flag
|
|
||||||
arm->sdfpSticky = sticky.bits;
|
|
||||||
|
|
||||||
// set comparison flags
|
|
||||||
arm->sdfpAFlags.NF = (FPSCR_FIELD(arm, N)) ? 1 : 0;
|
|
||||||
arm->sdfpAFlags.ZF = (FPSCR_FIELD(arm, Z)) ? 1 : 0;
|
|
||||||
arm->sdfpAFlags.CF = (FPSCR_FIELD(arm, C)) ? 1 : 0;
|
|
||||||
arm->sdfpAFlags.VF = (FPSCR_FIELD(arm, V)) ? 1 : 0;
|
|
||||||
|
|
||||||
// update simulator floating point control word
|
|
||||||
updateVFPControlWord(arm);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Read VFP FPSCR register
|
|
||||||
//
|
|
||||||
Uns32 armReadFPSCR(armP arm) {
|
|
||||||
|
|
||||||
// compose denormal input flag
|
|
||||||
FPSCR_FIELD(arm, IDC) = arm->denormalInput;
|
|
||||||
|
|
||||||
// compose remaining sticky flags
|
|
||||||
vmiFPFlags sticky = {arm->sdfpSticky};
|
|
||||||
FPSCR_FIELD(arm, IOC) = sticky.f.I; // invalid operation flag
|
|
||||||
FPSCR_FIELD(arm, DZC) = sticky.f.Z; // divide-by-zero flag
|
|
||||||
FPSCR_FIELD(arm, OFC) = sticky.f.O; // overflow flag
|
|
||||||
FPSCR_FIELD(arm, UFC) = sticky.f.U; // underflow flag
|
|
||||||
FPSCR_FIELD(arm, IXC) = sticky.f.P; // inexact flag
|
|
||||||
|
|
||||||
// compose comparison flags
|
|
||||||
FPSCR_FIELD(arm, N) = (arm->sdfpAFlags.NF) ? 1 : 0;
|
|
||||||
FPSCR_FIELD(arm, Z) = (arm->sdfpAFlags.ZF) ? 1 : 0;
|
|
||||||
FPSCR_FIELD(arm, C) = (arm->sdfpAFlags.CF) ? 1 : 0;
|
|
||||||
FPSCR_FIELD(arm, V) = (arm->sdfpAFlags.VF) ? 1 : 0;
|
|
||||||
|
|
||||||
// return composed value
|
|
||||||
return FPSCR_REG(arm);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// EXCEPTION FLAG UTILITIES
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Validate that an exception is disabled
|
|
||||||
//
|
|
||||||
inline static void validateFTZ(armP arm) {
|
|
||||||
VMI_ASSERT(
|
|
||||||
inFTZMode(arm),
|
|
||||||
"expected enabled flush-to-zero mode"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set the denormal sticky bit (when flush-to-zero mode is enabled)
|
|
||||||
//
|
|
||||||
static void setDenormalStickyFTZ(armP arm) {
|
|
||||||
validateFTZ(arm);
|
|
||||||
arm->denormalInput = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set the underflow sticky bit (when flush-to-zero mode is enabled)
|
|
||||||
//
|
|
||||||
static void setUnderflowStickyFTZ(armP arm) {
|
|
||||||
validateFTZ(arm);
|
|
||||||
const static vmiFPFlags underflow = {f:{U:1}};
|
|
||||||
arm->sdfpSticky |= underflow.bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Raise the denormal exception
|
|
||||||
//
|
|
||||||
static void raiseDenormal(armP arm) {
|
|
||||||
arm->denormalInput = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Raise the underflow exception
|
|
||||||
//
|
|
||||||
static void raiseUnderflow(armP arm) {
|
|
||||||
const static vmiFPFlags underflow = {f:{U:1}};
|
|
||||||
arm->sdfpSticky |= underflow.bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Raise the overflow exception
|
|
||||||
//
|
|
||||||
static void raiseOverflow(armP arm) {
|
|
||||||
const static vmiFPFlags overflow = {f:{O:1}};
|
|
||||||
arm->sdfpSticky |= overflow.bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Raise the invalid operation exception
|
|
||||||
//
|
|
||||||
static void raiseInvalidOperation(armP arm) {
|
|
||||||
const static vmiFPFlags invalidOperation = {f:{I:1}};
|
|
||||||
arm->sdfpSticky |= invalidOperation.bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Raise the inexact exception
|
|
||||||
//
|
|
||||||
static void raiseInexact(armP arm) {
|
|
||||||
const static vmiFPFlags inexact = {f:{P:1}};
|
|
||||||
arm->sdfpSticky |= inexact.bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// HALF-PRECISION OPERATIONS
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Convert from half-precision to single-precision
|
|
||||||
//
|
|
||||||
Uns32 armFPHalfToSingle(armP arm, Uns16 half) {
|
|
||||||
|
|
||||||
Int32 exponent = ARM_FP16_EXPONENT(half);
|
|
||||||
Uns32 fraction = ARM_FP16_FRACTION(half);
|
|
||||||
Bool sign = ARM_FP16_SIGN(half);
|
|
||||||
Bool expAll1 = (exponent==ARM_FP16_EXP_ONES);
|
|
||||||
Bool isZero = (!exponent && !fraction);
|
|
||||||
Bool isInfinity = (expAll1 && !fraction);
|
|
||||||
Bool isNaN = (expAll1 && !isInfinity);
|
|
||||||
Bool useAHP = inAHPMode(arm);
|
|
||||||
|
|
||||||
if(isInfinity && !useAHP) {
|
|
||||||
|
|
||||||
// infinities require exponent correction
|
|
||||||
exponent = ARM_FP32_EXPONENT(ARM_FP32_PLUS_INFINITY);
|
|
||||||
fraction = ARM_FP32_FRACTION(ARM_FP32_PLUS_INFINITY);
|
|
||||||
|
|
||||||
} else if(isZero) {
|
|
||||||
|
|
||||||
// zero values require no special processing
|
|
||||||
|
|
||||||
} else if(isNaN && !useAHP) {
|
|
||||||
|
|
||||||
// argument is an SNaN if MSB of fraction is clear
|
|
||||||
Bool isSNaN = !(fraction & (1 << (ARM_FP16_EXP_SHIFT-1)));
|
|
||||||
|
|
||||||
// raise Invalid Operation exception if an SNaN
|
|
||||||
if(isSNaN) {
|
|
||||||
raiseInvalidOperation(arm);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(returnDefaultNaN(arm)) {
|
|
||||||
|
|
||||||
// default QNaN is required
|
|
||||||
exponent = ARM_FP32_EXPONENT(ARM_QNAN_DEFAULT_32);
|
|
||||||
fraction = ARM_FP32_FRACTION(ARM_QNAN_DEFAULT_32);
|
|
||||||
sign = ARM_FP32_SIGN(ARM_QNAN_DEFAULT_32);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// NaNs require exponent correction
|
|
||||||
exponent = ARM_FP32_EXP_ONES;
|
|
||||||
|
|
||||||
// NaNs require fraction correction
|
|
||||||
fraction = fraction << (ARM_FP32_EXP_SHIFT - ARM_FP16_EXP_SHIFT);
|
|
||||||
fraction |= ARM_QNAN_MASK_32;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// normalize a denormal value if required
|
|
||||||
if(!exponent) {
|
|
||||||
|
|
||||||
// shift up until implicit MSB is 1
|
|
||||||
do {
|
|
||||||
fraction <<= 1;
|
|
||||||
exponent--;
|
|
||||||
} while(!(fraction & (1<<ARM_FP16_EXP_SHIFT)));
|
|
||||||
|
|
||||||
// correct exponent and mask off implicit MSB
|
|
||||||
exponent++;
|
|
||||||
fraction &= ~(1<<ARM_FP16_EXP_SHIFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// rebase exponent and fraction
|
|
||||||
exponent += (ARM_FP32_EXP_BIAS - ARM_FP16_EXP_BIAS );
|
|
||||||
fraction <<= (ARM_FP32_EXP_SHIFT - ARM_FP16_EXP_SHIFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// compose single-precision result
|
|
||||||
return (
|
|
||||||
(sign << ARM_FP32_SIGN_SHIFT) |
|
|
||||||
(exponent << ARM_FP32_EXP_SHIFT ) |
|
|
||||||
fraction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Convert from single-precision to half-precision
|
|
||||||
//
|
|
||||||
Uns16 armFPSingleToHalf(armP arm, Uns32 single) {
|
|
||||||
|
|
||||||
Int32 exponent = ARM_FP32_EXPONENT(single);
|
|
||||||
Uns32 fraction = ARM_FP32_FRACTION(single);
|
|
||||||
Bool sign = ARM_FP32_SIGN(single);
|
|
||||||
Bool expAll1 = (exponent==ARM_FP32_EXP_ONES);
|
|
||||||
Bool isZero = (!exponent && !fraction);
|
|
||||||
Bool isDenormal = (!exponent && fraction);
|
|
||||||
Bool isInfinity = (expAll1 && !fraction);
|
|
||||||
Bool isNaN = (expAll1 && !isInfinity);
|
|
||||||
Bool useAHP = inAHPMode(arm);
|
|
||||||
|
|
||||||
if(isInfinity) {
|
|
||||||
|
|
||||||
if(useAHP) {
|
|
||||||
|
|
||||||
// alternative half precision has a different infinity format
|
|
||||||
exponent = ARM_FP16_EXPONENT(ARM_FP16_AHP_INFINITY);
|
|
||||||
fraction = ARM_FP16_FRACTION(ARM_FP16_AHP_INFINITY);
|
|
||||||
|
|
||||||
raiseInvalidOperation(arm);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// IEEE infinities require exponent correction
|
|
||||||
exponent = ARM_FP16_EXPONENT(ARM_FP16_PLUS_INFINITY);
|
|
||||||
fraction = ARM_FP16_FRACTION(ARM_FP16_PLUS_INFINITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(isZero) {
|
|
||||||
|
|
||||||
// zero values require no special processing
|
|
||||||
|
|
||||||
} else if(isNaN) {
|
|
||||||
|
|
||||||
// argument is an SNaN if MSB of fraction is clear
|
|
||||||
Bool isSNaN = !(fraction & (1 << (ARM_FP32_EXP_SHIFT-1)));
|
|
||||||
|
|
||||||
// raise Invalid Operation exception if using Alternative Half Precision
|
|
||||||
// format or argument is an SNaN
|
|
||||||
if(isSNaN || useAHP) {
|
|
||||||
raiseInvalidOperation(arm);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(useAHP) {
|
|
||||||
|
|
||||||
// if using Alternative Half Precision format, NaNs go to zero
|
|
||||||
exponent = 0;
|
|
||||||
fraction = 0;
|
|
||||||
|
|
||||||
} else if(returnDefaultNaN(arm)) {
|
|
||||||
|
|
||||||
// default QNaN is required
|
|
||||||
exponent = ARM_FP16_EXPONENT(ARM_QNAN_DEFAULT_16);
|
|
||||||
fraction = ARM_FP16_FRACTION(ARM_QNAN_DEFAULT_16);
|
|
||||||
sign = ARM_FP16_SIGN(ARM_QNAN_DEFAULT_16);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// NaNs require exponent correction
|
|
||||||
exponent = ARM_FP16_EXP_ONES;
|
|
||||||
|
|
||||||
// NaNs require fraction correction
|
|
||||||
fraction = fraction >> (ARM_FP32_EXP_SHIFT - ARM_FP16_EXP_SHIFT);
|
|
||||||
fraction |= ARM_QNAN_MASK_16;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(isDenormal && inFTZMode(arm)) {
|
|
||||||
|
|
||||||
// flush denormals to zero if required
|
|
||||||
setDenormalStickyFTZ(arm);
|
|
||||||
exponent = 0;
|
|
||||||
fraction = 0;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// split value into sign, unrounded mantissa and exponent
|
|
||||||
union {Uns32 u32; Flt32 f32;} u = {single};
|
|
||||||
Flt32 result = u.f32;
|
|
||||||
Flt32 mantissa = sign ? -result : result;
|
|
||||||
exponent = 0;
|
|
||||||
while(mantissa<1.0) {
|
|
||||||
mantissa *= 2.0; exponent--;
|
|
||||||
}
|
|
||||||
while(mantissa>=2.0) {
|
|
||||||
mantissa /= 2.0; exponent++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// bias the exponent so that the minimum exponent becomes 1, lower
|
|
||||||
// values 0 (indicating possible underflow)
|
|
||||||
exponent -= ARM_FP16_EXP_MIN;
|
|
||||||
while(exponent<0) {
|
|
||||||
exponent++;
|
|
||||||
mantissa /= 2.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the unrounded mantissa as an integer and the "units in last
|
|
||||||
// place" rounding error
|
|
||||||
Flt32 mantissaExp2F = mantissa*(1<<ARM_FP16_EXP_SHIFT);
|
|
||||||
fraction = mantissaExp2F;
|
|
||||||
Flt32 error = mantissaExp2F - fraction;
|
|
||||||
|
|
||||||
// there is an underflow exception if the exponent is too small before
|
|
||||||
// rounding and the result is inexact
|
|
||||||
if(!exponent && error) {
|
|
||||||
raiseUnderflow(arm);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool roundUp;
|
|
||||||
Bool overflowToInf;
|
|
||||||
|
|
||||||
// now round using the required rounding mode
|
|
||||||
switch(getRoundingControl(arm)) {
|
|
||||||
|
|
||||||
case vmi_FPR_NEAREST:
|
|
||||||
roundUp = ((error>0.5) || ((error==0.5) && (fraction&1)));
|
|
||||||
overflowToInf = True;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case vmi_FPR_POS_INF:
|
|
||||||
roundUp = (error && !sign);
|
|
||||||
overflowToInf = !sign;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case vmi_FPR_NEG_INF:
|
|
||||||
roundUp = (error && sign);
|
|
||||||
overflowToInf = sign;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
roundUp = False;
|
|
||||||
overflowToInf = False;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(roundUp) {
|
|
||||||
|
|
||||||
fraction++;
|
|
||||||
|
|
||||||
// check for round up from denormalized to normalized
|
|
||||||
if(fraction==(1<<ARM_FP16_EXP_SHIFT)) {
|
|
||||||
exponent = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for round up to next exponent
|
|
||||||
if(fraction==(1<<(ARM_FP16_EXP_SHIFT+1))) {
|
|
||||||
exponent++;
|
|
||||||
fraction /= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// deal with overflow and generate result
|
|
||||||
if(!useAHP) {
|
|
||||||
|
|
||||||
// IEEE format result required
|
|
||||||
if(exponent>=((1<<ARM_FP16_EXP_BITS)-1)) {
|
|
||||||
|
|
||||||
if(overflowToInf) {
|
|
||||||
exponent = ARM_FP16_EXPONENT(ARM_FP16_PLUS_INFINITY);
|
|
||||||
fraction = ARM_FP16_FRACTION(ARM_FP16_PLUS_INFINITY);
|
|
||||||
} else {
|
|
||||||
exponent = ARM_FP16_EXPONENT(ARM_FP16_MAX_NORMAL);
|
|
||||||
fraction = ARM_FP16_FRACTION(ARM_FP16_MAX_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
raiseOverflow(arm);
|
|
||||||
|
|
||||||
// Note this is not in the psuedo code but is needed to match
|
|
||||||
// behavior of reference simulator
|
|
||||||
raiseInexact(arm);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// alternative half precision result required
|
|
||||||
if(exponent>=(1<<ARM_FP16_EXP_BITS)) {
|
|
||||||
|
|
||||||
exponent = ARM_FP16_EXPONENT(ARM_FP16_AHP_INFINITY);
|
|
||||||
fraction = ARM_FP16_FRACTION(ARM_FP16_AHP_INFINITY);
|
|
||||||
|
|
||||||
raiseInvalidOperation(arm);
|
|
||||||
|
|
||||||
// avoid an inexact exception
|
|
||||||
error = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// deal with inexact exception
|
|
||||||
if(error) {
|
|
||||||
raiseInexact(arm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// compose half-precision result
|
|
||||||
return (
|
|
||||||
(sign << ARM_FP16_SIGN_SHIFT) |
|
|
||||||
(exponent << ARM_FP16_EXP_SHIFT ) |
|
|
||||||
fraction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// INFINITY/ZERO CHECK
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Return True if the single-precision floating point values op1 and op2 are 0
|
|
||||||
// and infinity (in either order), setting the denormal sticky bit if so
|
|
||||||
//
|
|
||||||
Bool armFPInfinityAndZero(armP arm, Uns32 op1, Uns32 op2) {
|
|
||||||
|
|
||||||
Bool op1Zero = ((op1 & 0x7f800000) == 0);
|
|
||||||
Bool op2Zero = ((op2 & 0x7f800000) == 0);
|
|
||||||
Bool op1Inf = ((op1 & 0x7fffffff) == 0x7f800000);
|
|
||||||
Bool op2Inf = ((op2 & 0x7fffffff) == 0x7f800000);
|
|
||||||
|
|
||||||
if((op1Zero && op2Inf) || (op2Zero && op1Inf)) {
|
|
||||||
|
|
||||||
// check if an op is denormal number
|
|
||||||
if ((op1Zero && (op1 & 0x007fffff) != 0) ||
|
|
||||||
(op2Zero && (op2 & 0x007fffff) != 0))
|
|
||||||
{
|
|
||||||
// raise denormal exception
|
|
||||||
raiseDenormal(arm);
|
|
||||||
}
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// QNAN/TINY HANDLING
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Is the argument a 32-bit QNaN?
|
|
||||||
//
|
|
||||||
inline static Bool is32BitQNaN(vmiFPNaNArgP arg) {
|
|
||||||
return arg->isFlt32 && (arg->u32 & ARM_QNAN_MASK_32);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Is the argument a 64-bit QNaN?
|
|
||||||
//
|
|
||||||
inline static Bool is64BitQNaN(vmiFPNaNArgP arg) {
|
|
||||||
return !arg->isFlt32 && (arg->u64 & ARM_QNAN_MASK_64);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Is the argument a 32-bit SNaN?
|
|
||||||
//
|
|
||||||
inline static Bool is32BitSNaN(vmiFPNaNArgP arg) {
|
|
||||||
return arg->isFlt32 && !(arg->u32 & ARM_QNAN_MASK_32);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Is the argument a 64-bit SNaN?
|
|
||||||
//
|
|
||||||
inline static Bool is64BitSNaN(vmiFPNaNArgP arg) {
|
|
||||||
return !arg->isFlt32 && !(arg->u64 & ARM_QNAN_MASK_64);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Handle 32-bit QNaN result
|
|
||||||
//
|
|
||||||
static VMI_FP_QNAN32_RESULT_FN(handleQNaN32) {
|
|
||||||
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
|
|
||||||
if(!NaNArgNum || returnDefaultNaN(arm)) {
|
|
||||||
|
|
||||||
return ARM_QNAN_DEFAULT_32;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
Uns32 i;
|
|
||||||
|
|
||||||
// PASS 1: if any argument is an 32-bit SNaN, return that (as a QNaN)
|
|
||||||
for(i=0; i<NaNArgNum; i++) {
|
|
||||||
if(is32BitSNaN(&NaNArgs[i])) {
|
|
||||||
return NaNArgs[i].u32 | ARM_QNAN_MASK_32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PASS 2: if any argument is a 32-bit QNaN, return that
|
|
||||||
for(i=0; i<NaNArgNum; i++) {
|
|
||||||
if(is32BitQNaN(&NaNArgs[i])) {
|
|
||||||
return NaNArgs[i].u32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, if no argument is a 32-bit NaN (e.g. this is a conversion
|
|
||||||
// from 64-bit) return the calculated result
|
|
||||||
return QNaN32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Handle 64-bit QNaN result
|
|
||||||
//
|
|
||||||
static VMI_FP_QNAN64_RESULT_FN(handleQNaN64) {
|
|
||||||
|
|
||||||
armP arm = (armP)processor;
|
|
||||||
|
|
||||||
if(!NaNArgNum || returnDefaultNaN(arm)) {
|
|
||||||
|
|
||||||
return ARM_QNAN_DEFAULT_64;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
Uns32 i;
|
|
||||||
|
|
||||||
// PASS 1: if any argument is an 64-bit SNaN, return that (as a QNaN)
|
|
||||||
for(i=0; i<NaNArgNum; i++) {
|
|
||||||
if(is64BitSNaN(&NaNArgs[i])) {
|
|
||||||
return NaNArgs[i].u64 | ARM_QNAN_MASK_64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PASS 2: if any argument is a 64-bit QNaN, return that
|
|
||||||
for(i=0; i<NaNArgNum; i++) {
|
|
||||||
if(is64BitQNaN(&NaNArgs[i])) {
|
|
||||||
return NaNArgs[i].u64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, if no argument is a 64-bit NaN (e.g. this is a conversion
|
|
||||||
// from 32-bit) return the calculated result
|
|
||||||
return QNaN64;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Is the passed value a QNaN or SNaN?
|
|
||||||
//
|
|
||||||
static Bool isNaN80(vmiFP80Arg value) {
|
|
||||||
|
|
||||||
// decompose vmiFP80Arg into mantissa and sign
|
|
||||||
union {vmiFP80Arg fp80; struct {Uns64 mantissa; Uns16 expSign;};} u = {
|
|
||||||
value
|
|
||||||
};
|
|
||||||
|
|
||||||
if((u.expSign & 0x7fff)!=0x7fff) {
|
|
||||||
// exponent most be all 1's
|
|
||||||
return False;
|
|
||||||
} else if(u.mantissa==0x8000000000000000ULL) {
|
|
||||||
// +infinity, -infinity
|
|
||||||
return False;
|
|
||||||
} else {
|
|
||||||
// NaNs have some non-zero bit in the mantissa
|
|
||||||
return u.mantissa;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Handle 16-bit indeterminate result
|
|
||||||
//
|
|
||||||
static VMI_FP_IND16_RESULT_FN(handleIndeterminate16) {
|
|
||||||
|
|
||||||
Uns32 result;
|
|
||||||
|
|
||||||
if(isNaN80(value)) {
|
|
||||||
result = 0;
|
|
||||||
} else if(value.bytes[VMI_FP_80_BYTES-1] & 0x80) {
|
|
||||||
result = isSigned ? ARM_MIN_INT16 : ARM_MIN_UNS16;
|
|
||||||
} else {
|
|
||||||
result = isSigned ? ARM_MAX_INT16 : ARM_MAX_UNS16;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Handle 32-bit indeterminate result
|
|
||||||
//
|
|
||||||
static VMI_FP_IND32_RESULT_FN(handleIndeterminate32) {
|
|
||||||
|
|
||||||
Uns32 result;
|
|
||||||
|
|
||||||
if(isNaN80(value)) {
|
|
||||||
result = 0;
|
|
||||||
} else if(value.bytes[VMI_FP_80_BYTES-1] & 0x80) {
|
|
||||||
result = isSigned ? ARM_MIN_INT32 : ARM_MIN_UNS32;
|
|
||||||
} else {
|
|
||||||
result = isSigned ? ARM_MAX_INT32 : ARM_MAX_UNS32;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Enumeration of tiny values that might be returned by flushing
|
|
||||||
//
|
|
||||||
typedef enum tinyValueE {
|
|
||||||
TV_PLUS_0,
|
|
||||||
TV_MINUS_0,
|
|
||||||
TV_LAST
|
|
||||||
} tinyValue;
|
|
||||||
|
|
||||||
//
|
|
||||||
// These contain tiny values
|
|
||||||
//
|
|
||||||
static vmiFP80Arg tinyValues32[TV_LAST];
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize constant tiny 32-bit values
|
|
||||||
//
|
|
||||||
static void initTinyValue32(tinyValue tv, Uns32 pattern) {
|
|
||||||
union {Uns32 u32; Flt32 f32;} u = {pattern};
|
|
||||||
tinyValues32[tv].f80 = u.f32;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize constant tiny values
|
|
||||||
//
|
|
||||||
static void initTinyValues(void) {
|
|
||||||
initTinyValue32(TV_PLUS_0, 0x00000000);
|
|
||||||
initTinyValue32(TV_MINUS_0, 0x80000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Handle 32-bit tiny result
|
|
||||||
//
|
|
||||||
static VMI_FP_TINY_RESULT_FN(handleTinyResult) {
|
|
||||||
|
|
||||||
// set underflow sticky bit
|
|
||||||
setUnderflowStickyFTZ((armP)processor);
|
|
||||||
|
|
||||||
// return appropriately-signed zero
|
|
||||||
Bool isNegative = value.bytes[VMI_FP_80_BYTES-1] & 0x80;
|
|
||||||
return tinyValues32[isNegative ? TV_MINUS_0 : TV_PLUS_0];
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Handle 64-bit tiny argument
|
|
||||||
//
|
|
||||||
static VMI_FP_TINY_ARGUMENT_FN(handleTinyArgument) {
|
|
||||||
|
|
||||||
// set denormal sticky bit
|
|
||||||
setDenormalStickyFTZ((armP)processor);
|
|
||||||
|
|
||||||
// return appropriately-signed zero
|
|
||||||
Bool isNegative = value.bytes[VMI_FP_80_BYTES-1] & 0x80;
|
|
||||||
return tinyValues32[isNegative ? TV_MINUS_0 : TV_PLUS_0];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// RESET AND INITIALIZATION
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// Call on initialization
|
|
||||||
//
|
|
||||||
void armFPInitialize(armP arm) {
|
|
||||||
|
|
||||||
// initialize current control word to an empty value
|
|
||||||
arm->currentCW.u32 = -1;
|
|
||||||
|
|
||||||
// Initialize FP registers if present (AFTER armSysInitialize)
|
|
||||||
if (SCS_USE_CPUID(arm) && FPU_PRESENT(arm)) {
|
|
||||||
|
|
||||||
// initialize constant tiny values
|
|
||||||
initTinyValues();
|
|
||||||
|
|
||||||
// set up QNaN values and handlers
|
|
||||||
vmirtConfigureFPU(
|
|
||||||
(vmiProcessorP)arm,
|
|
||||||
ARM_QNAN_DEFAULT_32,
|
|
||||||
ARM_QNAN_DEFAULT_64,
|
|
||||||
0, // indeterminate value not used
|
|
||||||
0, // indeterminate value not used
|
|
||||||
0, // indeterminate value not used
|
|
||||||
handleQNaN32,
|
|
||||||
handleQNaN64,
|
|
||||||
handleIndeterminate16,
|
|
||||||
handleIndeterminate32,
|
|
||||||
0, // 64-bit indeterminate value handler not required
|
|
||||||
handleTinyResult,
|
|
||||||
handleTinyArgument,
|
|
||||||
True
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set the write mask for CPACR to allow updating field cp10 and cp11
|
|
||||||
SCS_MASK_FIELD(arm, CPACR, cp10) = 3;
|
|
||||||
SCS_MASK_FIELD(arm, CPACR, cp11) = 3;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Call on reset
|
|
||||||
//
|
|
||||||
void armFPReset(armP arm) {
|
|
||||||
|
|
||||||
// no action unless floating point is implemented
|
|
||||||
if(SCS_USE_CPUID(arm) && FPU_PRESENT(arm)) {
|
|
||||||
armWriteFPSCR(arm, 0, FPSCR_MASK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,3 +0,0 @@
|
|||||||
EXPORTS
|
|
||||||
vmiStubs
|
|
||||||
modelAttrs
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
//#include "sal/SimulatorController.hpp"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
|
|
||||||
void hello(unsigned int p){
|
|
||||||
cout << "&fail::simulator: " << hex << p << endl;
|
|
||||||
// fail::SimulatorController * salp = reinterpret_cast<fail::SimulatorController * >(p);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void failSALset(unsigned int pointer){
|
|
||||||
hello(pointer);
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
add_definitions(" -m32 ${IMPERAS_VMIINC} ")
|
|
||||||
|
|
||||||
set(SRCS
|
|
||||||
$ENV{IMPERAS_HOME}/ImpPublic/source/host/icm/icmCpuManager.cpp
|
|
||||||
platform/platform.cc
|
|
||||||
../OVPPlatform.cc
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(ovp_cortexM3 ${SRCS})
|
|
||||||
add_dependencies(ovp_cortexM3 fail-ovpstatusmessages )
|
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries(ovp_cortexM3 ${SIM_LDFLAGS} fail fail-ovpstatusmessages)
|
|
||||||
## OVP links all needed shared libraries via a runtimeloader
|
|
||||||
set_target_properties(ovp_cortexM3 PROPERTIES LINK_FLAGS "-L${CMAKE_BINARY_DIR}/lib -lpcl -lprotobuf -m32 ")
|
|
||||||
@ -1,415 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2005-2011 Imperas Software Ltd., www.imperas.com
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied.
|
|
||||||
*
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "platform.hpp"
|
|
||||||
#include "statreg.hpp"
|
|
||||||
#include "sal/SALInst.hpp"
|
|
||||||
|
|
||||||
#include "icm/icmCpuManager.h"
|
|
||||||
#include "icm/icmQuery.h"
|
|
||||||
|
|
||||||
// enable relaxed scheduling for maximum performance
|
|
||||||
//#define SIM_ATTRS (ICM_ATTR_RELAXED_SCHED|ICM_ATTR_TRACE)
|
|
||||||
#define SIM_ATTRS (ICM_ATTR_RELAXED_SCHED)
|
|
||||||
|
|
||||||
// GDB port
|
|
||||||
#define GDB_PORT 1234
|
|
||||||
|
|
||||||
// Variables set by arguments
|
|
||||||
const char *variant = "Cortex-M3"; // the model variant
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
ARM_Cortex_M3 arm;
|
|
||||||
|
|
||||||
ARM_Cortex_M3::ARM_Cortex_M3() {
|
|
||||||
}
|
|
||||||
|
|
||||||
ARM_Cortex_M3::~ARM_Cortex_M3() {
|
|
||||||
delete platform;
|
|
||||||
delete cpu;
|
|
||||||
delete attrList;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_Cortex_M3::init(bool gdb=false) {
|
|
||||||
|
|
||||||
// initialize OVPsim, enabling verbose mode to get statistics at end of execution
|
|
||||||
platform = new icmPlatform("CortexM3Platform", //name
|
|
||||||
ICM_VERBOSE|ICM_STOP_ON_CTRLC, //attributes
|
|
||||||
gdb ? "rsp" : 0, // optional protocol
|
|
||||||
gdb ? GDB_PORT : 0); // optional port number
|
|
||||||
|
|
||||||
|
|
||||||
// const char *armModel = icmGetVlnvString(NULL, "arm.ovpworld.org", "processor", "armm", "1.0", "model");
|
|
||||||
const char *armModel = "/srv/scratch/hoffmann/test/build/lib/libarmmModel.so";
|
|
||||||
const char *armSemihost = icmGetVlnvString(NULL, "arm.ovpworld.org", "semihosting", "armNewlib", "1.0", "model");
|
|
||||||
|
|
||||||
attrList = new icmAttrListObject();
|
|
||||||
|
|
||||||
attrList->addAttr("endian", "little");
|
|
||||||
attrList->addAttr("compatibility", "nopBKPT");
|
|
||||||
attrList->addAttr("variant", variant);
|
|
||||||
attrList->addAttr("UAL", "1");
|
|
||||||
attrList->addAttr("fail_salp", &fail::simulator);
|
|
||||||
|
|
||||||
char cpuname[64];
|
|
||||||
sprintf(cpuname,"cpu-%s", variant);
|
|
||||||
|
|
||||||
// create a processor instance
|
|
||||||
cpu = new icmProcessorObject(
|
|
||||||
cpuname, // CPU name
|
|
||||||
"armm", // CPU type
|
|
||||||
0, // CPU cpuId
|
|
||||||
0, // CPU model flags
|
|
||||||
32, // address bits
|
|
||||||
armModel, // model file
|
|
||||||
"modelAttrs", // morpher attributes
|
|
||||||
SIM_ATTRS, // attributes
|
|
||||||
attrList, // user-defined attributes
|
|
||||||
armSemihost, // semi-hosting file
|
|
||||||
"modelAttrs" // semi-hosting attributes
|
|
||||||
);
|
|
||||||
|
|
||||||
// Nominate this processor to be attached to a debugger
|
|
||||||
if(gdb) cpu->debugThisProcessor();
|
|
||||||
|
|
||||||
processorP = cpu->getProcessorP();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_Cortex_M3::createFullMMC(const char *vlnRoot=0) {
|
|
||||||
// TODO: ELF Groesse auslesen per OVP (hat funktionen) und dann den Bereich als MMC einrichten...
|
|
||||||
/* const char *mmc_model = icmGetVlnvString("/srv/scratch/sirozipp/build/lib", "ovpworld.org", "mmc", "failMMC", "1.0", "model");
|
|
||||||
if(mmc_model == NULL) {
|
|
||||||
std::cerr << "mmc_model not found!" << std::endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
const char *mmc_model = "/srv/scratch/sirozipp/build/lib/libflaky.so";
|
|
||||||
|
|
||||||
// create full MMCs
|
|
||||||
mmcInstr = new icmMmcObject("mmci", mmc_model, "modelAttrs", 0, False);
|
|
||||||
mmcData = new icmMmcObject("mmcd", mmc_model, "modelAttrs", 0, False);
|
|
||||||
|
|
||||||
// create processor instruction and data bus
|
|
||||||
instrBus = new icmBusObject("instrbus", 32);
|
|
||||||
dataBus = new icmBusObject("databus", 32);
|
|
||||||
|
|
||||||
// create processor main bus
|
|
||||||
mainBus = new icmBusObject("mainbus", 32);
|
|
||||||
|
|
||||||
// connect processor ports to their buses
|
|
||||||
cpu->connect(*instrBus, *dataBus);
|
|
||||||
|
|
||||||
// connect mmcs to buses
|
|
||||||
mmcInstr->connect(*instrBus, "sp1", False);
|
|
||||||
mmcData->connect(*dataBus, "sp1", False);
|
|
||||||
|
|
||||||
// connet master ports of mmc to main bus
|
|
||||||
mmcInstr->connect(*mainBus, "mp1", True);
|
|
||||||
mmcData->connect(*mainBus, "mp1", True);
|
|
||||||
|
|
||||||
// create simulated memory
|
|
||||||
Addr appHighAddr, appLowAddr;
|
|
||||||
|
|
||||||
appHighAddr = 0xFFFFFFFF;
|
|
||||||
appLowAddr = 0x0;
|
|
||||||
icmMem0 = new icmMemoryObject("mem1", ICM_PRIV_RWX, appHighAddr-appLowAddr);
|
|
||||||
|
|
||||||
// connect memory to main bus
|
|
||||||
icmMem0->connect("mp1", *mainBus, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ICM_MEM_READ_FN(extMemRead) {
|
|
||||||
unsigned char res[4];
|
|
||||||
// Int32 tmpres = *(Int32*)value;
|
|
||||||
// icmPrintf("EXTERNAL MEMORY: Reading 0x%08x from 0x%08x\n", *(Int32*)value, (Int32)address);
|
|
||||||
// *(Int32*) value = (Int32)arm.mem[(address-arm.offset)>>2];
|
|
||||||
|
|
||||||
fail::simulator.onMemoryAccessEvent(address, 4, false, ovpplatform.getPC());
|
|
||||||
|
|
||||||
res[0] = arm.mem[(address-arm.offset)+0];
|
|
||||||
res[1] = arm.mem[(address-arm.offset)+1];
|
|
||||||
res[2] = arm.mem[(address-arm.offset)+2];
|
|
||||||
res[3] = arm.mem[(address-arm.offset)+3];
|
|
||||||
|
|
||||||
// icmPrintf("Reading [0] 0x%08x, [1] 0x%08x, [2] 0x%08x, [3] 0x%08x\n", arm.mem[(address-arm.offset)+0], arm.mem[(address-arm.offset)+1], arm.mem[(address-arm.offset)+2], arm.mem[(address-arm.offset)+3]);
|
|
||||||
|
|
||||||
*(Int32*)value = (res[3] << 24) | (res[2] << 16) | (res[1] << 8) | res[0];
|
|
||||||
//
|
|
||||||
// icmPrintf("Reading: 0x%08x\n", (res[3] << 24) | (res[2] << 16) | (res[1] << 8) | res[0]);
|
|
||||||
|
|
||||||
// icmPrintf("Callback: Reading 0x%08x from mem[0x%08x] should be 0x%08x from [0x%08x]\n", *(Int32*)value, (Int32)(address-arm.offset), tmpres, (Int32) address);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static ICM_MEM_WRITE_FN(extMemWrite) {
|
|
||||||
// icmPrintf("EXTERNAL MEMORY: Writing 0x%08x to 0x%08x\n", (Int32)value, (Int32)address);
|
|
||||||
// icmPrintf("Callback: Writing 0x%08x to mem[0x%08x] should be 0x%08x from [0x%08x]\n", *(Int32*)value, (Int32)(address-arm.offset), *(Int32*) value, (Int32) address);
|
|
||||||
fail::simulator.onMemoryAccessEvent(address, 4, true, ovpplatform.getPC());
|
|
||||||
|
|
||||||
Int32 val = *(Int32*)value;
|
|
||||||
|
|
||||||
arm.mem[(address-arm.offset) + 0] = val & 0xFF;
|
|
||||||
arm.mem[(address-arm.offset) + 1] = (val >> 8) & 0xFF;
|
|
||||||
arm.mem[(address-arm.offset) + 2] = (val >> 16) & 0xFF;
|
|
||||||
arm.mem[(address-arm.offset) + 3] = (val >> 24) & 0xFF;
|
|
||||||
|
|
||||||
// icmPrintf("Writing [0] 0x%08x, [1] 0x%08x, [2] 0x%08x, [3] 0x%08x\n", val & 0xFF, (val >> 8) & 0xFF, (val >> 16) & 0xFF, (val >> 24) & 0xFF);
|
|
||||||
// icmPrintf("Writing [0] 0x%08x, [1] 0x%08x, [2] 0x%08x, [3] 0x%08x\n", arm.mem[(address-arm.offset)+0], arm.mem[(address-arm.offset)+1], arm.mem[(address-arm.offset)+2], arm.mem[(address-arm.offset)+3]);
|
|
||||||
|
|
||||||
// Int32 res = arm.mem[(address-arm.offset)+0] | arm.mem[(address-arm.offset)+1] << 8 | arm.mem[(address-arm.offset)+2] << 16 | arm.mem[(address-arm.offset)+3] << 24;
|
|
||||||
|
|
||||||
// icmPrintf("Callback: Writing 0x%08x to mem[0x%08x] should be 0x%08x to [0x%08x]\n", res, (Int32)(address-arm.offset), *(Int32*) value, (Int32) address);
|
|
||||||
// arm.mem[(address-arm.offset) >> 2] = *(Int32*) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ICM_MEM_READ_FN(extTextRead) {
|
|
||||||
// Int16 val = *(Int16*)value;
|
|
||||||
*(Int16*) value = (Int16)arm.textmem[(address-arm.textOffset)>>1];
|
|
||||||
// icmPrintf("Callback: Reading 0x%04x from textmem[0x%08x] should be 0x%04x from [0x%08x]\n", *(Int16*)value, (Int32)(address-arm.textOffset), val, (Int32) address);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ICM_MEM_WRITE_FN(extTextWrite) {
|
|
||||||
arm.textmem[(address-arm.textOffset) >> 1] = *(Int16*) value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_Cortex_M3::mapMemToCallback() {
|
|
||||||
// create processor bus
|
|
||||||
mainBus = new icmBusObject("mainbus", 32);
|
|
||||||
|
|
||||||
// connect the processor bus
|
|
||||||
cpu->connect(*mainBus, *mainBus);
|
|
||||||
|
|
||||||
// create simulated memory
|
|
||||||
Addr appHighAddr, appLowAddr, textLowAddr, textHighAddr, LowAddr, LowAddrH, HighAddr, HighAddrL;
|
|
||||||
|
|
||||||
appLowAddr = offset;
|
|
||||||
appHighAddr = appLowAddr + memSize - 1;
|
|
||||||
|
|
||||||
textLowAddr = textOffset;
|
|
||||||
textHighAddr = textLowAddr + textMemSize - 1;
|
|
||||||
|
|
||||||
// check which section is first
|
|
||||||
if(appLowAddr < textLowAddr) {
|
|
||||||
LowAddr = appLowAddr;
|
|
||||||
LowAddrH = appHighAddr;
|
|
||||||
HighAddr = textHighAddr;
|
|
||||||
HighAddrL = textLowAddr;
|
|
||||||
} else {
|
|
||||||
LowAddr = textLowAddr;
|
|
||||||
LowAddrH = textHighAddr;
|
|
||||||
HighAddr = appHighAddr;
|
|
||||||
HighAddrL = appLowAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Memory from 0x0 to LowAddr
|
|
||||||
icmMem0 = new icmMemoryObject("mem0", ICM_PRIV_RWX, LowAddr - 1);
|
|
||||||
// Memory after callback mem to end
|
|
||||||
icmMem1 = new icmMemoryObject("mem1", ICM_PRIV_RWX, 0xFFFFFFFF - HighAddr - 1);
|
|
||||||
// Memory between text and other sections
|
|
||||||
icmMem2 = new icmMemoryObject("mem2", ICM_PRIV_RWX, HighAddrL - LowAddrH - 1 -1);
|
|
||||||
|
|
||||||
// map the adress range appLowAddr:appHighAddr externally to the processor
|
|
||||||
mainBus->mapExternalMemory("external", ICM_PRIV_RWX, appLowAddr, appHighAddr,
|
|
||||||
extMemRead, // read callback
|
|
||||||
extMemWrite, // write callback
|
|
||||||
0);
|
|
||||||
|
|
||||||
mainBus->mapExternalMemory("exttext", ICM_PRIV_RWX, textLowAddr, textHighAddr,
|
|
||||||
extTextRead,
|
|
||||||
extTextWrite,
|
|
||||||
0);
|
|
||||||
|
|
||||||
// just build memory before external memory if it's not at the beginning
|
|
||||||
if(LowAddr > 0x0) {
|
|
||||||
icmMem0->connect("mp1", *mainBus, 0x0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(HighAddr < 0xffffffff) {
|
|
||||||
icmMem1->connect("mp2", *mainBus, HighAddr+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(LowAddrH != HighAddrL) {
|
|
||||||
icmMem2->connect("mp3", *mainBus, LowAddrH+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
mainBus->printConnections();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ARM_Cortex_M3::makeGPRegister() {
|
|
||||||
const string names[] = {"r0", "r1", "r2", "r3", "r4", "r5",
|
|
||||||
"r6", "r7", "r8", "r9", "r10", "r11", "r12"};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for(int i = 0; i <= 12; ++i) {
|
|
||||||
icmRegInfoP reg = icmGetRegByIndex(processorP, i);
|
|
||||||
fail::simulator.makeGPRegister(32, (void *)reg, names[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set SP pointer
|
|
||||||
// ARM Cortex M3: SP pointer is ID 13
|
|
||||||
icmRegInfoP sp_reg = icmGetRegByIndex(processorP, 13);
|
|
||||||
setSPReg(sp_reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_Cortex_M3::makeSTRegister() {
|
|
||||||
OVPStatusRegister *streg = new CortexM3StatusRegister();
|
|
||||||
|
|
||||||
fail::simulator.makeSTRegister(streg, "sp");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_Cortex_M3::makePCRegister() {
|
|
||||||
// ARM Cortex M3: PC pointer is ID 15
|
|
||||||
icmRegInfoP pc_reg = icmGetRegByIndex(processorP, 15);
|
|
||||||
fail::simulator.makePCRegister(32, (void *)pc_reg, "PC");
|
|
||||||
}
|
|
||||||
|
|
||||||
int ARM_Cortex_M3::startSimulation(const char *app) {
|
|
||||||
bool loadPhysical = true;
|
|
||||||
bool verbose = true;
|
|
||||||
bool useEntry = true;
|
|
||||||
if(!cpu->loadLocalMemory(app, loadPhysical, verbose, useEntry))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// application is loaded, now fill the callback memory with program data
|
|
||||||
fillCallbackMemory();
|
|
||||||
|
|
||||||
// icmSimulatePlatform();
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
// save PC
|
|
||||||
Addr pc_ptr = cpu->getPC();
|
|
||||||
|
|
||||||
fail::simulator.onInstrPtrChanged(pc_ptr);
|
|
||||||
|
|
||||||
// simulate the platform
|
|
||||||
icmStopReason stopreason = cpu->simulate(1);
|
|
||||||
|
|
||||||
if(stopreason!=0x00) {
|
|
||||||
// was simulation interrupted or did it complete
|
|
||||||
if(stopreason==ICM_SR_INTERRUPT) {
|
|
||||||
icmPrintf("*** simulation interrupted\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//icmTerminate();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_Cortex_M3::makeCallbackMemory(size_t sizeText, size_t offText, size_t sizeMem, size_t offMem) {
|
|
||||||
mem = new unsigned char[sizeMem];
|
|
||||||
//mem = new Int32[sizeMem>>2];
|
|
||||||
textmem = new Int16[sizeText>>1];
|
|
||||||
offset = offMem;
|
|
||||||
textOffset = offText;
|
|
||||||
memSize = sizeMem;
|
|
||||||
textMemSize = sizeText;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_Cortex_M3::save(const string& path) {
|
|
||||||
OVPStatusMessage ovpstat;
|
|
||||||
|
|
||||||
// save registers
|
|
||||||
// FIXME: what about reg with id 16? should be status register
|
|
||||||
for(unsigned int i = 0; i < 16; ++i) {
|
|
||||||
uint32_t tmp = 0;
|
|
||||||
icmRegInfoP reg = icmGetRegByIndex(processorP, i);
|
|
||||||
icmReadRegInfoValue(processorP, reg, (void *)&tmp);
|
|
||||||
OVPStatusMessage::Register *msgReg = ovpstat.add_reg();
|
|
||||||
|
|
||||||
switch(i) {
|
|
||||||
case 13: msgReg->set_name("sp");
|
|
||||||
break;
|
|
||||||
case 14: msgReg->set_name("lr");
|
|
||||||
break;
|
|
||||||
case 15: msgReg->set_name("pc");
|
|
||||||
break;
|
|
||||||
case 16: msgReg->set_name("sr");
|
|
||||||
break;
|
|
||||||
default: char num[3];
|
|
||||||
sprintf(num, "r%d", i);
|
|
||||||
msgReg->set_name(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
msgReg->set_value(tmp);
|
|
||||||
// std::cerr << "save " << i << ": " << tmp << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string stmp;
|
|
||||||
ovpstat.SerializeToString(&stmp);
|
|
||||||
ofstream file;
|
|
||||||
file.open(path.c_str(), ios::out);
|
|
||||||
file << stmp;
|
|
||||||
file.close();
|
|
||||||
/* ofstream file(path.c_str(), ios::out | ios::trunc);
|
|
||||||
if(!ovpstat.SerializeToOstream(&file)) {
|
|
||||||
std::cerr << "Error writing to file " << path << "!" << std::endl;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_Cortex_M3::restore(const string& path) {
|
|
||||||
fstream input(path.c_str(), ios::in);
|
|
||||||
OVPStatusMessage ovpstat;
|
|
||||||
ovpstat.ParseFromIstream(&input);
|
|
||||||
|
|
||||||
for(int i = 0; i < ovpstat.reg_size(); ++i) {
|
|
||||||
const OVPStatusMessage::Register& ovpreg = ovpstat.reg(i);
|
|
||||||
uint32_t val = ovpreg.value();
|
|
||||||
// std::cerr << "restore "<<ovpreg.name()<<": " << val << std::endl;
|
|
||||||
icmRegInfoP reg = icmGetRegByIndex(processorP, i);
|
|
||||||
icmWriteRegInfoValue(processorP, reg, (void *)&val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
if(argc != 2) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " application" << std::endl;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
arm.init(false);
|
|
||||||
|
|
||||||
// arm.createFullMMC();
|
|
||||||
|
|
||||||
// arm.makeCallbackMemory(0x100, 0x20000000);
|
|
||||||
// arm.makeCallbackMemory(0x8034, 0x0, 0x11c, 0x82e8);
|
|
||||||
// arm.makeCallbackMemory(0x8034, 0x0, 0x940, 0x8040);
|
|
||||||
arm.makeCallbackMemory(0x802c, 0x0, 0x930, 0x8038);
|
|
||||||
arm.mapMemToCallback();
|
|
||||||
|
|
||||||
|
|
||||||
ovpplatform.setCpu((void *) &arm);
|
|
||||||
|
|
||||||
arm.makeGPRegister();
|
|
||||||
arm.makeSTRegister();
|
|
||||||
arm.makePCRegister();
|
|
||||||
|
|
||||||
arm.startSimulation(argv[1]);
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
#ifndef _armCortexM3_HPP_
|
|
||||||
#define _armCortexM3_HPP_
|
|
||||||
|
|
||||||
|
|
||||||
#include "../../OVPCpu.hpp"
|
|
||||||
#include "ovp/statusmsg/OVPStatusMessage.pb.h"
|
|
||||||
|
|
||||||
using namespace icmCpuManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \class ARM_Cortex_M3
|
|
||||||
* Implements the OVP platform for ARM Cortex M3 with callback memory
|
|
||||||
*/
|
|
||||||
class ARM_Cortex_M3 : public OVPCpu {
|
|
||||||
private:
|
|
||||||
|
|
||||||
public:
|
|
||||||
ARM_Cortex_M3();
|
|
||||||
~ARM_Cortex_M3();
|
|
||||||
void init(bool);
|
|
||||||
int startSimulation(const char*);
|
|
||||||
void createFullMMC(const char *);
|
|
||||||
void mapMemToCallback();
|
|
||||||
|
|
||||||
void makeGPRegister();
|
|
||||||
void makeSTRegister();
|
|
||||||
void makePCRegister();
|
|
||||||
|
|
||||||
void makeCallbackMemory(size_t, size_t, size_t, size_t);
|
|
||||||
|
|
||||||
void save(const string&);
|
|
||||||
void restore(const string&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
#include "platform.hpp"
|
|
||||||
#include "../../OVPStatusRegister.hpp"
|
|
||||||
|
|
||||||
extern ARM_Cortex_M3 arm;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \class CortexM3StatusRegister
|
|
||||||
* Status register for ARM Cortex M3
|
|
||||||
*/
|
|
||||||
class CortexM3StatusRegister : public OVPStatusRegister {
|
|
||||||
|
|
||||||
private:
|
|
||||||
icmRegInfoP cpsr; //!< pointer to status register
|
|
||||||
icmProcessorP cpuP;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CortexM3StatusRegister() : OVPStatusRegister(32, icmGetRegByIndex(arm.getProcessorP(), 16)) {
|
|
||||||
cpuP = arm.getProcessorP();
|
|
||||||
|
|
||||||
// status register is index 16
|
|
||||||
cpsr = icmGetRegByIndex(cpuP, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
~CortexM3StatusRegister() {}
|
|
||||||
|
|
||||||
bool getFlag(int pos) const {
|
|
||||||
uint32_t val;
|
|
||||||
uint32_t bit;
|
|
||||||
icmReadRegInfoValue(cpuP, cpsr, (void *)&val);
|
|
||||||
|
|
||||||
// put bit to correct place
|
|
||||||
bit = 1 << pos;
|
|
||||||
|
|
||||||
// Flag at position pos
|
|
||||||
val = val & bit;
|
|
||||||
val = val >> pos;
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFlag(int pos, bool newval) {
|
|
||||||
uint32_t val;
|
|
||||||
uint32_t bit = 1 << pos;
|
|
||||||
|
|
||||||
icmReadRegInfoValue(cpuP, cpsr, (void *)&val);
|
|
||||||
|
|
||||||
if(newval == 0) {
|
|
||||||
// AND with 0xFFFEFFFF (e.g.)
|
|
||||||
bit = ~bit; // invert bits
|
|
||||||
|
|
||||||
val = val & bit;
|
|
||||||
} else {
|
|
||||||
// OR with 0x00010000 (e.g.)
|
|
||||||
val = val | bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
icmWriteRegInfoValue(cpuP, cpsr, (void *)&val);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getSignFlag() const {
|
|
||||||
return getFlag(31);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getZeroFlag() const {
|
|
||||||
return getFlag(30);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getCarryFlag() const {
|
|
||||||
return getFlag(29);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getOverflowFlag() const {
|
|
||||||
return getFlag(28);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSignFlag(bool b) {
|
|
||||||
setFlag(31, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setZeroFlag(bool b) {
|
|
||||||
setFlag(30, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setCarryFlag(bool b) {
|
|
||||||
setFlag(29, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setOverflowFlag(bool b) {
|
|
||||||
setFlag(28, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
set(SRCS
|
|
||||||
flipBits.cpp
|
|
||||||
model.cpp
|
|
||||||
)
|
|
||||||
add_definitions("-m32")
|
|
||||||
message(STATUS "flaky ld flags: ${HOST_LDFLAGS}")
|
|
||||||
add_library(fail-flaky SHARED ${SRCS})
|
|
||||||
|
|
||||||
add_dependencies(fail-flaky fail-comm fail-sal)
|
|
||||||
set_target_properties(fail-flaky PROPERTIES LINK_FLAGS "${HOST_LDFLAGS} -m32")
|
|
||||||
|
|
||||||
target_link_libraries(fail-flaky ${IMPERAS_VMISTUBS} ${LIBRARY_OUTPUT_PATH}/libsal.a)
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "flipBits.h"
|
|
||||||
|
|
||||||
void flipBits(const void *value, Uns32 bytes, vmiProcessorP processor, Addr address) {
|
|
||||||
if (address == 0x019e) {
|
|
||||||
*((Uns32 *)value) ^= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
#ifndef FLIP_BITS_H
|
|
||||||
#define FLIP_BITS_H
|
|
||||||
extern "C" {
|
|
||||||
#include "vmi/vmiTypes.h"
|
|
||||||
|
|
||||||
|
|
||||||
void flipBits(const void *value, Uns32 bytes, vmiProcessorP processor, Addr address);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,189 +0,0 @@
|
|||||||
// Modifies values read from or written to memory
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
//#include <time.h>
|
|
||||||
extern "C" {
|
|
||||||
// VMI module includes
|
|
||||||
#include "vmi/vmiMessage.h"
|
|
||||||
#include "vmi/vmiMmcAttrs.h"
|
|
||||||
#include "vmi/vmiMmc.h"
|
|
||||||
#include "vmi/vmiRt.h"
|
|
||||||
#include "vmi/vmiTypes.h"
|
|
||||||
#include "flipBits.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
//#include "sal/ovp/OVPController.hpp"
|
|
||||||
#include "sal/SALInst.hpp"
|
|
||||||
|
|
||||||
// Model prefix (used by vmiMessage interface)
|
|
||||||
#define CPU_PREFIX "flakyMemory"
|
|
||||||
|
|
||||||
// ...
|
|
||||||
// Cache object
|
|
||||||
typedef struct flakyObjectS {
|
|
||||||
// MODELLING ARTIFACTS
|
|
||||||
memDomainP nextDomain; // next domain (FULL model)
|
|
||||||
memRegionP lastRegion; // last accessed (FULL model)
|
|
||||||
|
|
||||||
Uns64 count; // intercepted reads and writes
|
|
||||||
|
|
||||||
} flakyObject, *flakyObjectP;
|
|
||||||
|
|
||||||
// ...
|
|
||||||
#define BUF_SIZE 30
|
|
||||||
static char tmpCharBuffer[BUF_SIZE];
|
|
||||||
|
|
||||||
|
|
||||||
// Return a static temporary string that has the digits in the passed string
|
|
||||||
// separated into groups by a comma, e.g. "1234567" -> "1,234,567". The result
|
|
||||||
// is in a static buffer so it will be overwritten by the next call.
|
|
||||||
static const char *getCommaString(const char *string) {
|
|
||||||
|
|
||||||
static char buffer2[BUF_SIZE];
|
|
||||||
|
|
||||||
Uns32 length = strlen(string);
|
|
||||||
Uns32 count = 0;
|
|
||||||
char *dst = buffer2+BUF_SIZE;
|
|
||||||
const char *src = string+length;
|
|
||||||
|
|
||||||
// copy null terminator for comma string
|
|
||||||
*--dst = *src--;
|
|
||||||
|
|
||||||
// copy remaining characters in groups
|
|
||||||
do {
|
|
||||||
|
|
||||||
*--dst = *src--;
|
|
||||||
|
|
||||||
// insert comma every three characters
|
|
||||||
if((++count==3) && (src>=string)) {
|
|
||||||
count = 0;
|
|
||||||
*--dst = ',';
|
|
||||||
}
|
|
||||||
|
|
||||||
} while((src>=string) && (dst>=buffer2));
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Return a static temporary string that has the passed Uns64 value shown
|
|
||||||
// with digits separated by commas
|
|
||||||
static const char *uns64String(Uns64 value) {
|
|
||||||
sprintf(tmpCharBuffer, FMT_64u, value);
|
|
||||||
return getCommaString(tmpCharBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Utility routine for statistics reporting
|
|
||||||
static void printStats(flakyObjectP info) {
|
|
||||||
vmiMessage("I", CPU_PREFIX, "TOTAL ALTERED READS/WRITES: %15s\n", uns64String(info->count));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Cache object constructor
|
|
||||||
static VMIMMC_CONSTRUCTOR_FN(flakyConstructor) {
|
|
||||||
//srand(time(NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache object link
|
|
||||||
static VMIMMC_LINK_FN(flakyLink)
|
|
||||||
{
|
|
||||||
flakyObjectP flaky = (flakyObjectP)component;
|
|
||||||
VMI_ASSERT(
|
|
||||||
vmimmcGetNextPort(component, "mp1") == NULL,
|
|
||||||
"%sCannot accept a transparent connection",
|
|
||||||
vmimmcGetHierarchicalName(component)
|
|
||||||
);
|
|
||||||
|
|
||||||
memDomainP nextDomain = vmimmcGetNextDomain(component, "mp1");
|
|
||||||
|
|
||||||
// sanity check that we are in full mode
|
|
||||||
VMI_ASSERT(
|
|
||||||
nextDomain,
|
|
||||||
"%s: expected an opaque connection",
|
|
||||||
vmimmcGetHierarchicalName(component)
|
|
||||||
);
|
|
||||||
flaky->nextDomain = nextDomain;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache object destructor
|
|
||||||
static VMIMMC_DESTRUCTOR_FN(flakyDestructor) {
|
|
||||||
flakyObjectP flaky = (flakyObjectP)component;
|
|
||||||
printStats(flaky);
|
|
||||||
}
|
|
||||||
|
|
||||||
// N-byte read function
|
|
||||||
static VMI_MEM_READ_FN(readNFull)
|
|
||||||
{
|
|
||||||
vmimmcPortP port = reinterpret_cast<vmimmcPortP>(userData);
|
|
||||||
flakyObjectP flaky = (flakyObjectP)port->component;
|
|
||||||
Uns32 shortAddress = (Uns32)address;
|
|
||||||
|
|
||||||
// read from real memory connected to mmc:
|
|
||||||
vmirtReadNByteDomain(
|
|
||||||
flaky->nextDomain,
|
|
||||||
shortAddress,
|
|
||||||
value,
|
|
||||||
bytes,
|
|
||||||
&flaky->lastRegion,
|
|
||||||
MEM_AA_TRUE
|
|
||||||
);
|
|
||||||
|
|
||||||
// flipBits(value, bytes, processor, address);
|
|
||||||
//fail::simulator.onMemoryAccessEvent(address, bytes, false, processor.getPC());
|
|
||||||
|
|
||||||
// increment counter of reads and writes:
|
|
||||||
flaky->count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// N-byte write function
|
|
||||||
static VMI_MEM_WRITE_FN(writeNFull)
|
|
||||||
{
|
|
||||||
vmimmcPortP port = reinterpret_cast<vmimmcPortP>(userData);
|
|
||||||
flakyObjectP flaky = (flakyObjectP)port->component;
|
|
||||||
Uns32 shortAddress = (Uns32)address;
|
|
||||||
|
|
||||||
//flipBits(value, bytes, processor, address);
|
|
||||||
|
|
||||||
// write to real memory connected to this mmc:
|
|
||||||
vmirtWriteNByteDomain(
|
|
||||||
flaky->nextDomain,
|
|
||||||
shortAddress,
|
|
||||||
value,
|
|
||||||
bytes,
|
|
||||||
&flaky->lastRegion,
|
|
||||||
MEM_AA_TRUE
|
|
||||||
);
|
|
||||||
|
|
||||||
// increment counter of reads and writes:
|
|
||||||
flaky->count += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vmimmcAttr modelAttrs =
|
|
||||||
{
|
|
||||||
// VERSION
|
|
||||||
VMI_VERSION, // version string (THIS MUST BE FIRST)
|
|
||||||
VMI_MMC_MODEL, // type
|
|
||||||
sizeof(flakyObject), // size in bytes of MMC object
|
|
||||||
|
|
||||||
// CONSTRUCTOR/DESTRUCTOR ROUTINES
|
|
||||||
flakyConstructor, // constructor
|
|
||||||
flakyLink, // link component
|
|
||||||
flakyDestructor, // destructor
|
|
||||||
|
|
||||||
// MODEL REFRESH (AT START OF TIME SLICE)
|
|
||||||
0, // refresh
|
|
||||||
|
|
||||||
// FULL MODEL CALLBACKS
|
|
||||||
readNFull, // N-byte read callback
|
|
||||||
writeNFull, // N-byte write callback
|
|
||||||
|
|
||||||
// TRANSPARENT MODEL CALLBACKS
|
|
||||||
0, // N-byte read callback
|
|
||||||
0 // N-byte write callback
|
|
||||||
};
|
|
||||||
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
INSTDIR=/proj/i4danceos/ovp/current
|
|
||||||
|
|
||||||
source $INSTDIR/bin/setup.sh
|
|
||||||
|
|
||||||
setupImperas -m32 $INSTDIR
|
|
||||||
|
|
||||||
export PATH=${PATH}:$IMPERAS_HOME/bin/$IMPERAS_ARCH
|
|
||||||
export IMPERASD_LICENSE_FILE=@faui49
|
|
||||||
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$IMPERAS_HOME/bin/$IMPERAS_ARCH:$IMPERAS_HOME/bin/$IMPERAS_HOME/External/lib
|
|
||||||
export IMPERASD_LICENSE_FILE=@faui49.informatik.uni-erlangen.de
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
## Setup desired protobuf descriptions HERE ##
|
|
||||||
set(MY_PROTOS
|
|
||||||
OVPStatusMessage.proto
|
|
||||||
)
|
|
||||||
|
|
||||||
#### PROTOBUFS ####
|
|
||||||
find_package(Protobuf REQUIRED)
|
|
||||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
|
|
||||||
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS} )
|
|
||||||
|
|
||||||
## Build library
|
|
||||||
add_library(fail-ovpstatusmessages ${PROTO_SRCS} ${PROTO_HDRS} )
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
message OVPStatusMessage {
|
|
||||||
// Registers
|
|
||||||
message Register {
|
|
||||||
required string name = 1;
|
|
||||||
required uint32 value = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
repeated Register reg = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
protoc --cpp_out=. FailControlMessage.proto
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
add_definitions(" -m32 ${IMPERAS_VMIINC} ")
|
|
||||||
|
|
||||||
set(SRCS
|
|
||||||
$ENV{IMPERAS_HOME}/ImpPublic/source/host/icm/icmCpuManager.cpp
|
|
||||||
platform/flakyMemory.cpp
|
|
||||||
platform/beforeInstruction.cpp
|
|
||||||
platform/platform.cpp
|
|
||||||
)
|
|
||||||
add_executable(ovp ${SRCS})
|
|
||||||
add_dependencies(ovp fail-comm)
|
|
||||||
target_link_libraries(ovp ${SIM_LDFLAGS} )
|
|
||||||
## OVP links all needed shared libraries via a runtimeloader
|
|
||||||
set_target_properties(ovp PROPERTIES LINK_FLAGS " -m32 ")
|
|
||||||
Binary file not shown.
@ -1,20 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int foo = 0x37;
|
|
||||||
int bar = 34;
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
long i;
|
|
||||||
printf("\nHello\n\n");
|
|
||||||
|
|
||||||
for (i=0; i<50000; i++) {
|
|
||||||
printf("%d\n", i);
|
|
||||||
foo = 0x37;
|
|
||||||
printf("foo: (0x%x) = 0x%x\n", &foo, foo);
|
|
||||||
bar = 34;
|
|
||||||
printf("bar: (0x%x) = %d\n\n", &bar, bar);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
#include "beforeInstruction.hpp"
|
|
||||||
|
|
||||||
Uns8 bpCount;
|
|
||||||
Addr breakpoints[255];
|
|
||||||
|
|
||||||
//Ignore warning: deprecated conversion from string constant to ‘char*’
|
|
||||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
|
||||||
|
|
||||||
void printArmCortexM3Registers(icmProcessorObject processor) {
|
|
||||||
Uns32 registers[17];
|
|
||||||
icmPrintf("---------------\t\t---------------\n");
|
|
||||||
readRegister(processor, "R0", registers[0]);
|
|
||||||
readRegister(processor, "R1", registers[1]);
|
|
||||||
readRegister(processor, "R2", registers[2]);
|
|
||||||
readRegister(processor, "R3", registers[3]);
|
|
||||||
readRegister(processor, "R4", registers[4]);
|
|
||||||
readRegister(processor, "R5", registers[5]);
|
|
||||||
readRegister(processor, "R6", registers[6]);
|
|
||||||
readRegister(processor, "R7", registers[7]);
|
|
||||||
readRegister(processor, "R8", registers[8]);
|
|
||||||
readRegister(processor, "R9", registers[9]);
|
|
||||||
readRegister(processor, "R10", registers[10]);
|
|
||||||
readRegister(processor, "R11", registers[11]);
|
|
||||||
readRegister(processor, "R12", registers[12]);
|
|
||||||
readRegister(processor, "SP", registers[13]);
|
|
||||||
readRegister(processor, "LR", registers[14]);
|
|
||||||
readRegister(processor, "PC", registers[15]);
|
|
||||||
readRegister(processor, "CPSR", registers[16]);
|
|
||||||
icmPrintf("R0: 0x%08x\t\t", registers[0]);
|
|
||||||
icmPrintf("R1: 0x%08x\n", registers[1]);
|
|
||||||
icmPrintf("R2: 0x%08x\t\t", registers[2]);
|
|
||||||
icmPrintf("R3: 0x%08x\n", registers[3]);
|
|
||||||
icmPrintf("R4: 0x%08x\t\t", registers[4]);
|
|
||||||
icmPrintf("R5: 0x%08x\n", registers[5]);
|
|
||||||
icmPrintf("R6: 0x%08x\t\t", registers[6]);
|
|
||||||
icmPrintf("R7: 0x%08x\n", registers[7]);
|
|
||||||
icmPrintf("R8: 0x%08x\t\t", registers[8]);
|
|
||||||
icmPrintf("R9: 0x%08x\n", registers[9]);
|
|
||||||
icmPrintf("R10: 0x%08x\t\t", registers[10]);
|
|
||||||
icmPrintf("R11: 0x%08x\n", registers[11]);
|
|
||||||
icmPrintf("R12: 0x%08x\n\n", registers[12]);
|
|
||||||
icmPrintf("SP: 0x%08x\t\t", registers[13]);
|
|
||||||
icmPrintf("LR: 0x%08x\n", registers[14]);
|
|
||||||
icmPrintf("PC: 0x%08x\n", registers[15]);
|
|
||||||
icmPrintf("PSR: 0x%08x\n\n", registers[16]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool readRegister(icmProcessorObject processor, char *regName, Uns32 &value) {
|
|
||||||
if (regName[0] == 'P' && regName[1] == 'C') {
|
|
||||||
value = (Uns32)processor.getPC();
|
|
||||||
return True;
|
|
||||||
} else {
|
|
||||||
return processor.readReg(regName, &value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool writeRegister(icmProcessorObject processor, char *regName, Uns32 &newValue) {
|
|
||||||
if (regName[0] == 'P' && regName[1] == 'C') {
|
|
||||||
processor.setPC((Addr)newValue);
|
|
||||||
return True;
|
|
||||||
} else {
|
|
||||||
return processor.writeReg(regName, &newValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void addBreakpoint(Addr breakAddr) {
|
|
||||||
if (breakAddr != 0x00 && bpCount != 255) {
|
|
||||||
breakpoints[bpCount] = breakAddr;
|
|
||||||
bpCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Addr simulateUntilBP(icmProcessorObject processor) {
|
|
||||||
if (bpCount == 0) {
|
|
||||||
icmPlatform::Instance()->simulate();
|
|
||||||
return 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
Addr currentPC = 0x00;
|
|
||||||
while (processor.simulate(1) == ICM_SR_SCHED) {
|
|
||||||
currentPC = processor.getPC();
|
|
||||||
for (Uns8 u = 0; u < bpCount; u++) {
|
|
||||||
if (currentPC == breakpoints[u]) {
|
|
||||||
return currentPC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0x00;
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
#ifndef BEFORE_INSTRUCTION_HPP
|
|
||||||
#define BEFORE_INSTRUCTION_HPP
|
|
||||||
|
|
||||||
#include "icm/icmCpuManager.hpp"
|
|
||||||
|
|
||||||
using namespace icmCpuManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints all the registers for an ARM Cortex M3 processor.
|
|
||||||
* @param processor The processor (must be an ARM Cortex M3)
|
|
||||||
*/
|
|
||||||
void printArmCortexM3Registers(icmProcessorObject processor);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads a register and stores its content in an Uns32 variable.
|
|
||||||
* @param processor The processor for which to read the register
|
|
||||||
* @param regName The name of the register as a string
|
|
||||||
* @param value The address of where to store the register's content
|
|
||||||
*/
|
|
||||||
Bool readRegister(icmProcessorObject processor, char *regName, Uns32 &value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes the value given as an Uns32 variable to a register.
|
|
||||||
* @param processor The processor for which to write the variable
|
|
||||||
* @param regName The name of the register as a string
|
|
||||||
* @param newValue The address of the new value to be written to the register
|
|
||||||
*/
|
|
||||||
Bool writeRegister(icmProcessorObject processor, char *regName, Uns32 &newValue);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a breakpoint for simulateUntilBreakpoint
|
|
||||||
* @param breakAddr The address to be added as a breakpoint
|
|
||||||
*/
|
|
||||||
void addBreakpoint(Addr breakAddr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simulates until breakpoint,
|
|
||||||
* or the entire application file at once if no breakpoint was added.
|
|
||||||
* Returns the address of the next instruction,
|
|
||||||
* or zero if simulation did not stop at a breakpoint.
|
|
||||||
* @param processor The processor to run the simulation on
|
|
||||||
*/
|
|
||||||
Addr simulateUntilBP(icmProcessorObject processor);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
#include "flakyMemory.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
void createFlakyMem(
|
|
||||||
icmProcessorObject processor,
|
|
||||||
Addr lowAddr,
|
|
||||||
Addr highAddr,
|
|
||||||
const char *vlnvRoot
|
|
||||||
) {
|
|
||||||
|
|
||||||
icmBusObject *mainBus;
|
|
||||||
icmBusObject *interBus;
|
|
||||||
icmBusObject *mmcBus;
|
|
||||||
icmMmcObject *mmc1;
|
|
||||||
icmMemoryObject *memory1;
|
|
||||||
icmMemoryObject *memory2;
|
|
||||||
icmMemoryObject *memory3;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// get location of mmc object file:
|
|
||||||
const char *flakyMem = icmGetVlnvString(
|
|
||||||
vlnvRoot,
|
|
||||||
"ovpworld.org",
|
|
||||||
"mmc",
|
|
||||||
"flakyMemory",
|
|
||||||
"1.0",
|
|
||||||
"model"
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
// create full MMC
|
|
||||||
mmc1 = new icmMmcObject("mmc1", "/srv/scratch/sirozipp/build/lib/libflaky.so", "modelAttrs", 0, False);
|
|
||||||
|
|
||||||
// create the processor bus
|
|
||||||
mainBus = new icmBusObject("bus1", 32);
|
|
||||||
|
|
||||||
// create the intermediate bus
|
|
||||||
interBus = new icmBusObject("bus2", 32);
|
|
||||||
|
|
||||||
// create the bus connecting the mmc to the memory
|
|
||||||
mmcBus = new icmBusObject("bus3", 32);
|
|
||||||
|
|
||||||
// connect mmc direct to processor ports
|
|
||||||
processor.connect(*mainBus, *mainBus);
|
|
||||||
|
|
||||||
// connect master port of MMC to bus
|
|
||||||
mmc1->connect(*interBus, "sp1", False);
|
|
||||||
mmc1->connect(*mmcBus, "mp1", True);
|
|
||||||
|
|
||||||
if (lowAddr != 0x00) {
|
|
||||||
memory1 = new icmMemoryObject("mem1", ICM_PRIV_RWX, lowAddr-1);
|
|
||||||
memory1->connect("memp1", *mainBus, 0x00);
|
|
||||||
}
|
|
||||||
memory2 = new icmMemoryObject("mem2", ICM_PRIV_RWX, highAddr-lowAddr);
|
|
||||||
memory2->connect("memp2", *mmcBus, lowAddr);
|
|
||||||
if (highAddr != 0xffffffff) {
|
|
||||||
memory3 = new icmMemoryObject("mem3", ICM_PRIV_RWX, 0xffffffff-(highAddr+1));
|
|
||||||
memory3->connect("memp3", *mainBus, highAddr+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
mainBus->newBridge(*interBus, "br1", "sp2", "mp2", lowAddr, highAddr, lowAddr);
|
|
||||||
|
|
||||||
// show the bus connections
|
|
||||||
mainBus->printConnections();
|
|
||||||
interBus->printConnections();
|
|
||||||
mmcBus->printConnections();
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
#ifndef FLAKY_MEMORY_HPP
|
|
||||||
#define FLAKY_MEMORY_HPP
|
|
||||||
|
|
||||||
#include "icm/icmCpuManager.hpp"
|
|
||||||
|
|
||||||
using namespace icmCpuManager;
|
|
||||||
|
|
||||||
/** Creates flaky memory by attaching an MMC for the specified address range.
|
|
||||||
* @param processor The processor on which to set up the MMC
|
|
||||||
* @param loAddr The lowest address for which to do on-the-fly manipulation.
|
|
||||||
* @param hiAddr The highest address for which to do manipulation.
|
|
||||||
*/
|
|
||||||
void createFlakyMem(
|
|
||||||
icmProcessorObject processor,
|
|
||||||
Addr loAddr,
|
|
||||||
Addr hiAddr,
|
|
||||||
const char *vlnvRoot = 0
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
#include "icm/icmCpuManager.hpp"
|
|
||||||
#include "flakyMemory.hpp"
|
|
||||||
#include "beforeInstruction.hpp"
|
|
||||||
|
|
||||||
// enable relaxed scheduling for maximum performance
|
|
||||||
#define SIM_ATTRS (ICM_ATTR_RELAXED_SCHED)
|
|
||||||
|
|
||||||
|
|
||||||
icmProcessorObject createPlatform(
|
|
||||||
const char *application,
|
|
||||||
bool gdb,
|
|
||||||
bool flaky=false,
|
|
||||||
Addr lowAddr=0x00,
|
|
||||||
Addr highAddr=0xffffffff
|
|
||||||
) {
|
|
||||||
// select library components
|
|
||||||
const char *vlnvRoot = 0; // when null use default library
|
|
||||||
const char *vlnvRoot2 ="/srv/scratch/sirozipp/build/lib/" ;
|
|
||||||
const char *model = icmGetVlnvString(vlnvRoot,
|
|
||||||
"arm.ovpworld.org",
|
|
||||||
"processor",
|
|
||||||
"armm",
|
|
||||||
"1.0",
|
|
||||||
"model");
|
|
||||||
const char *semihosting = icmGetVlnvString(vlnvRoot, "arm.ovpworld.org", "semihosting", "armNewlib", "1.0", "model");
|
|
||||||
|
|
||||||
// set attributes for CPU model
|
|
||||||
icmAttrListObject icmAttr;
|
|
||||||
icmAttr.addAttr("endian", "little");
|
|
||||||
icmAttr.addAttr("compatibility", "nopBKPT");
|
|
||||||
icmAttr.addAttr("variant", "Cortex-M3");
|
|
||||||
icmAttr.addAttr("UAL", "1");
|
|
||||||
|
|
||||||
icmProcessorObject processor(
|
|
||||||
"cpu-Cortex-M3", // CPU name
|
|
||||||
"armm", // CPU type
|
|
||||||
0, // CPU cpuId
|
|
||||||
0, // CPU model flags
|
|
||||||
32, // address bits
|
|
||||||
model, // model file
|
|
||||||
"modelAttrs", // morpher attributes
|
|
||||||
gdb?ICM_ATTR_DEFAULT:SIM_ATTRS, // simulation attributes
|
|
||||||
&icmAttr, // user-defined attributes
|
|
||||||
semihosting, // semi-hosting file
|
|
||||||
"modelAttrs" // semi-hosting attributes
|
|
||||||
);
|
|
||||||
|
|
||||||
// if (flaky) {
|
|
||||||
createFlakyMem(processor, lowAddr, highAddr, vlnvRoot2);
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (gdb) {
|
|
||||||
processor.debugThisProcessor();
|
|
||||||
}
|
|
||||||
|
|
||||||
// load the processor object file
|
|
||||||
processor.loadLocalMemory(application, true, true, true);
|
|
||||||
|
|
||||||
return processor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Main simulation routine
|
|
||||||
int main(int argc, char ** argv) {
|
|
||||||
const char *application = "application.elf";
|
|
||||||
bool gdb = false;
|
|
||||||
Uns32 portNum = (Uns32)-1;
|
|
||||||
|
|
||||||
if(argc >= 2) {
|
|
||||||
application = argv[1];
|
|
||||||
if(argc >= 3) {
|
|
||||||
gdb = true;
|
|
||||||
portNum = (Uns32)atoi(argv[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
icmPlatform platform(
|
|
||||||
"fiPlatformCpp",
|
|
||||||
ICM_VERBOSE | ICM_STOP_ON_CTRLC,
|
|
||||||
gdb ? "rsp" : 0,
|
|
||||||
gdb ? portNum : 0
|
|
||||||
);
|
|
||||||
icmProcessorObject processor = createPlatform(application, gdb);
|
|
||||||
|
|
||||||
simulateUntilBP(processor);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#### Configuration file emitting BUILD_OVP/BOCHS defines ####
|
#### Configuration file emitting BUILD_BOCHS/GEM5/... defines ####
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/VariantConfig.hpp.in
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/VariantConfig.hpp.in
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/VariantConfig.hpp)
|
${CMAKE_CURRENT_BINARY_DIR}/VariantConfig.hpp)
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#cmakedefine BUILD_BOCHS
|
#cmakedefine BUILD_BOCHS
|
||||||
#cmakedefine BUILD_GEM5
|
#cmakedefine BUILD_GEM5
|
||||||
#cmakedefine BUILD_OVP
|
|
||||||
#cmakedefine BUILD_QEMU
|
#cmakedefine BUILD_QEMU
|
||||||
#cmakedefine BUILD_T32
|
#cmakedefine BUILD_T32
|
||||||
#cmakedefine T32_MOCK_API
|
#cmakedefine T32_MOCK_API
|
||||||
|
|||||||
@ -27,17 +27,6 @@ elseif(BUILD_GEM5)
|
|||||||
gem5/Gem5ArmCPU.cc
|
gem5/Gem5ArmCPU.cc
|
||||||
)
|
)
|
||||||
endif(BUILD_ARM)
|
endif(BUILD_ARM)
|
||||||
elseif(BUILD_OVP)
|
|
||||||
set(SRCS
|
|
||||||
CPU.cc
|
|
||||||
CPUState.cc
|
|
||||||
Listener.cc
|
|
||||||
ListenerManager.cc
|
|
||||||
SALConfig.cc
|
|
||||||
Register.cc
|
|
||||||
SimulatorController.cc
|
|
||||||
${VARIANT}/OVPController.cc
|
|
||||||
)
|
|
||||||
elseif(BUILD_QEMU)
|
elseif(BUILD_QEMU)
|
||||||
set(SRCS
|
set(SRCS
|
||||||
CPU.cc
|
CPU.cc
|
||||||
|
|||||||
@ -9,8 +9,6 @@
|
|||||||
#else
|
#else
|
||||||
#error Active config currently not supported!
|
#error Active config currently not supported!
|
||||||
#endif
|
#endif
|
||||||
#elif defined BUILD_OVP
|
|
||||||
#include "ovp/OVPConfig.hpp"
|
|
||||||
#elif defined BUILD_QEMU
|
#elif defined BUILD_QEMU
|
||||||
#include "qemu/QEMUConfig.hpp"
|
#include "qemu/QEMUConfig.hpp"
|
||||||
#elif defined BUILD_T32
|
#elif defined BUILD_T32
|
||||||
|
|||||||
@ -5,8 +5,7 @@ namespace fail {
|
|||||||
// Flag initialization depends on the current selected simulator
|
// Flag initialization depends on the current selected simulator
|
||||||
// (For now, the initialization values are all the same):
|
// (For now, the initialization values are all the same):
|
||||||
#if defined BUILD_BOCHS || defined BUILD_GEM5 || \
|
#if defined BUILD_BOCHS || defined BUILD_GEM5 || \
|
||||||
defined BUILD_OVP || defined BUILD_QEMU || \
|
defined BUILD_T32 || defined BUILD_QEMU
|
||||||
defined BUILD_T32
|
|
||||||
const address_t ADDR_INV = static_cast<address_t> (0);
|
const address_t ADDR_INV = static_cast<address_t> (0);
|
||||||
const address_t ANY_ADDR = static_cast<address_t> (-1);
|
const address_t ANY_ADDR = static_cast<address_t> (-1);
|
||||||
const unsigned ANY_INSTR = static_cast<unsigned> (-1);
|
const unsigned ANY_INSTR = static_cast<unsigned> (-1);
|
||||||
|
|||||||
@ -10,8 +10,6 @@
|
|||||||
#include "bochs/BochsConfig.hpp"
|
#include "bochs/BochsConfig.hpp"
|
||||||
#elif defined BUILD_GEM5
|
#elif defined BUILD_GEM5
|
||||||
#include "gem5/Gem5Config.hpp"
|
#include "gem5/Gem5Config.hpp"
|
||||||
#elif defined BUILD_OVP
|
|
||||||
#include "ovp/OVPConfig.hpp"
|
|
||||||
#elif defined BUILD_QEMU
|
#elif defined BUILD_QEMU
|
||||||
#include "qemu/QEMUConfig.hpp"
|
#include "qemu/QEMUConfig.hpp"
|
||||||
#elif defined BUILD_T32
|
#elif defined BUILD_T32
|
||||||
|
|||||||
@ -20,14 +20,6 @@ namespace fail {
|
|||||||
typedef Gem5Controller ConcreteSimulatorController; //!< concrete simulator (type)
|
typedef Gem5Controller ConcreteSimulatorController; //!< concrete simulator (type)
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined BUILD_OVP
|
|
||||||
|
|
||||||
#include "ovp/OVPController.hpp"
|
|
||||||
|
|
||||||
namespace fail {
|
|
||||||
typedef OVPController ConcreteSimulatorController; //!< concrete simulator (type)
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined BUILD_QEMU
|
#elif defined BUILD_QEMU
|
||||||
|
|
||||||
#include "qemu/QEMUController.hpp"
|
#include "qemu/QEMUController.hpp"
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
#ifndef __OVPINIT_AH__
|
|
||||||
#define __OVPINIT_AH__
|
|
||||||
|
|
||||||
#include "config/VariantConfig.hpp"
|
|
||||||
|
|
||||||
#ifdef BUILD_OVP
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "../SALInst.hpp"
|
|
||||||
|
|
||||||
aspect FailOVPInit {
|
|
||||||
advice call("% ...::startSimulation(...)") : before ()
|
|
||||||
{
|
|
||||||
std::cout << "OVP init aspect!" << std::endl;
|
|
||||||
// TODO: Log-Level?
|
|
||||||
// TODO pass on command-line parameters
|
|
||||||
fail::simulator.startup();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BUILD_OVP
|
|
||||||
#endif // __OVPINIT_AH__
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
/**
|
|
||||||
* \brief Type definitions and configuration settings for
|
|
||||||
* the OVP simulator.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __OVP_CONFIG_HPP__
|
|
||||||
#define __OVP_CONFIG_HPP__
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
namespace fail {
|
|
||||||
|
|
||||||
typedef uint32_t guest_address_t; //!< the guest memory address type
|
|
||||||
typedef uint8_t* host_address_t; //!< the host memory address type
|
|
||||||
typedef uint32_t register_data_t; //!< register data type (32 bit)
|
|
||||||
typedef int timer_t; //!< type of timer IDs
|
|
||||||
|
|
||||||
} // end-of-namespace: fail
|
|
||||||
|
|
||||||
#endif // __OVP_CONFIG_HPP__
|
|
||||||
@ -1,132 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "OVPController.hpp"
|
|
||||||
#include "OVPMemory.hpp"
|
|
||||||
#include "OVPRegister.hpp"
|
|
||||||
#include "ovp/OVPStatusRegister.hpp"
|
|
||||||
|
|
||||||
namespace fail {
|
|
||||||
|
|
||||||
OVPController::OVPController()
|
|
||||||
: SimulatorController(new OVPRegisterManager(), new OVPMemoryManager())
|
|
||||||
{
|
|
||||||
// FIXME: This should be obsolete now...
|
|
||||||
// set = new UniformRegisterSet(RT_GP);
|
|
||||||
// setStatus = new UniformRegisterSet(RT_ST);
|
|
||||||
// setPC = new UniformRegisterSet(RT_PC);
|
|
||||||
}
|
|
||||||
|
|
||||||
OVPController::~OVPController()
|
|
||||||
{
|
|
||||||
// FIXME: This should be obsolete now...
|
|
||||||
// delete set;
|
|
||||||
// delete setStatus;
|
|
||||||
// delete setPC;
|
|
||||||
|
|
||||||
// Free memory of OVPRegister objects (actually allocated in make*Register):
|
|
||||||
for (RegisterManager::iterator it = m_Regs->begin(); it != m_Regs->end(); it++)
|
|
||||||
delete (*it); // free the memory, allocated in the constructor
|
|
||||||
}
|
|
||||||
|
|
||||||
void OVPController::makeGPRegister(int width, void *link, const string& name)
|
|
||||||
{
|
|
||||||
// Add general purpose register
|
|
||||||
OVPRegister *reg = new OVPRegister(m_currentRegId++, width, link, RT_GP);
|
|
||||||
reg->setName(name);
|
|
||||||
m_Regs->add(reg);
|
|
||||||
// Note: The RegisterManager (aka m_Regs) automatically assigns the
|
|
||||||
// added registers (herein typed OVPRegister) to their matching
|
|
||||||
// UniformRegisterSet (@see RegisterManager::add).
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OVPController::makeSTRegister(Register *reg, const string& name)
|
|
||||||
{
|
|
||||||
// Add status register
|
|
||||||
reg->setName(name);
|
|
||||||
cerr << "Add Status Register: " << reg << endl;
|
|
||||||
m_Regs->add(reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OVPController::makePCRegister(int width, void *link, const string& name)
|
|
||||||
{
|
|
||||||
// Add general purpose register
|
|
||||||
OVPRegister *reg = new OVPRegister(m_currentRegId++, width, link, RT_PC);
|
|
||||||
reg->setName(name);
|
|
||||||
m_Regs->add(reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: This should be obsolete now...
|
|
||||||
/*
|
|
||||||
void OVPController::finishedRegisterCreation()
|
|
||||||
{
|
|
||||||
m_Regs->add(*set);
|
|
||||||
m_Regs->add(*setStatus);
|
|
||||||
m_Regs->add(*setPC);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void OVPController::onInstrPtrChanged(address_t instrPtr)
|
|
||||||
{
|
|
||||||
// make some funny outputs
|
|
||||||
unsigned int r0 = m_Regs->getSetOfType(RT_GP)->getRegister(0)->getData();
|
|
||||||
OVPRegisterManager *ovp_Regs = (OVPRegisterManager*) m_Regs;
|
|
||||||
// FIXME: This cast seems to be invalid: RT_GP vs. OVPStatusRegister (= RT_ST)?
|
|
||||||
OVPStatusRegister *rid_st = (OVPStatusRegister*) m_Regs->getSetOfType(RT_GP)->first();
|
|
||||||
// cerr << "Addr: " << rid_st << endl;
|
|
||||||
unsigned int st = rid_st->getData();
|
|
||||||
|
|
||||||
// save("/srv/scratch/sirozipp/test.txt");
|
|
||||||
|
|
||||||
// ovpplatform.setPC(0x123);
|
|
||||||
|
|
||||||
// restore("/srv/scratch/sirozipp/test.txt");
|
|
||||||
// cerr << "instrPtr: 0x" << hex << instrPtr << " SP: 0x" << hex << m_Regs->getStackPointer() \
|
|
||||||
// << " R0: 0x" << hex << r0 << " ST: 0x" << hex << st << endl;
|
|
||||||
|
|
||||||
// Check for active breakpoint-Listeners:
|
|
||||||
ListenerManager::iterator it = m_EvList.begin();
|
|
||||||
while (it != m_EvList.end()) {
|
|
||||||
// FIXME: Performance verbessern (dazu muss entsprechend auch die Speicherung
|
|
||||||
// in ListenerManager(.cc|.hpp) angepasst bzw. verbessert werden).
|
|
||||||
BPSingleListener* pEvBreakpt = dynamic_cast<BPSingleListener*>(*it);
|
|
||||||
if (pEvBreakpt && (instrPtr == pEvBreakpt->getWatchInstructionPointer() ||
|
|
||||||
pEvBreakpt->getWatchInstructionPointer() == ANY_ADDR)) {
|
|
||||||
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
|
|
||||||
it = m_EvList.makeActive(it);
|
|
||||||
// "it" has already been set to the next element (by calling
|
|
||||||
// makeActive()):
|
|
||||||
continue; // -> skip iterator increment
|
|
||||||
}
|
|
||||||
BPRangeListener* pEvRange = dynamic_cast<BPRangeListener*>(*it);
|
|
||||||
if (pEvRange && pEvRange->isMatching(instrPtr)) {
|
|
||||||
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
|
|
||||||
it = m_EvList.makeActive(it);
|
|
||||||
continue; // dito.
|
|
||||||
}
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
m_EvList.fireActiveListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OVPController::save(const string& path)
|
|
||||||
{
|
|
||||||
// TODO!
|
|
||||||
ovpplatform.save(path);
|
|
||||||
return false; // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void OVPController::restore(const string& path)
|
|
||||||
{
|
|
||||||
//TODO!
|
|
||||||
assert(path.length() > 0 &&
|
|
||||||
"FATAL ERROR: Tried to restore state without valid path!");
|
|
||||||
ovpplatform.restore(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OVPController::reboot()
|
|
||||||
{
|
|
||||||
// TODO!
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end-of-namespace: fail
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
#ifndef __OVP_CONTROLLER_HPP__
|
|
||||||
#define __OVP_CONTROLLER_HPP__
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <cassert>
|
|
||||||
#include <string.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "../SimulatorController.hpp"
|
|
||||||
#include "../Listener.hpp"
|
|
||||||
#include "../Register.hpp"
|
|
||||||
#include "ovp/OVPPlatform.hpp"
|
|
||||||
|
|
||||||
namespace fail {
|
|
||||||
|
|
||||||
extern OVPPlatform ovpplatform;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \class OVPController
|
|
||||||
* OVP-specific implementation of a SimulatorController.
|
|
||||||
*/
|
|
||||||
class OVPController : public SimulatorController {
|
|
||||||
private:
|
|
||||||
// FIXME: This should be obsolete now...
|
|
||||||
// UniformRegisterSet *set; //(RT_GP);
|
|
||||||
// UniformRegisterSet *setStatus;//(RT_ST);
|
|
||||||
// UniformRegisterSet *setPC;//(RT_PC);
|
|
||||||
|
|
||||||
// FIXME: Perhaps this should be declared as a static member:
|
|
||||||
unsigned int m_currentRegId;
|
|
||||||
// NOTE: Constants (such as GPRegisterId in sal/x86/Architecture.hpp)
|
|
||||||
// are much easier to read...
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Initialize the controller.
|
|
||||||
*/
|
|
||||||
OVPController();
|
|
||||||
~OVPController();
|
|
||||||
void onInstrPtrChanged(address_t instrPtr);
|
|
||||||
/**
|
|
||||||
* Save simulator state.
|
|
||||||
* @param path Location to store state information
|
|
||||||
* @return \c true if the state has been successfully saved, \c false otherwise
|
|
||||||
*/
|
|
||||||
bool save(const std::string& path);
|
|
||||||
/**
|
|
||||||
* Restore simulator state.
|
|
||||||
* @param path Location to previously saved state information
|
|
||||||
*/
|
|
||||||
void restore(const std::string& path);
|
|
||||||
/**
|
|
||||||
* Reboot simulator.
|
|
||||||
*/
|
|
||||||
void reboot();
|
|
||||||
/**
|
|
||||||
* Returns the current instruction pointer.
|
|
||||||
* @return the current eip
|
|
||||||
*/
|
|
||||||
void makeGPRegister(int, void*, const std::string&);
|
|
||||||
void makeSTRegister(Register *, const std::string&);
|
|
||||||
void makePCRegister(int, void*, const std::string&);
|
|
||||||
/**
|
|
||||||
* Due to empty RegisterSets are not allowed, OVP platform
|
|
||||||
* must tell OVPController when it is finished
|
|
||||||
*
|
|
||||||
* FIXME: This should be obsolete now...
|
|
||||||
*/
|
|
||||||
// void finishedRegisterCreation();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end-of-namespace: fail
|
|
||||||
|
|
||||||
#endif // __OVP_CONTROLLER_HPP__
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
#ifndef __OVP_MEMORY_HPP__
|
|
||||||
#define __OVP_MEMORY_HPP__
|
|
||||||
|
|
||||||
#include "../Memory.hpp"
|
|
||||||
|
|
||||||
namespace fail {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \class OVPMemoryManager
|
|
||||||
* Represents a concrete implemenation of the abstract
|
|
||||||
* MemoryManager to provide access to OVP's memory pool.
|
|
||||||
*/
|
|
||||||
class OVPMemoryManager : public MemoryManager {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Constructs a new MemoryManager object and initializes
|
|
||||||
* it's attributes appropriately.
|
|
||||||
*/
|
|
||||||
OVPMemoryManager() : MemoryManager() { }
|
|
||||||
/**
|
|
||||||
* Retrieves the size of the available simulated memory.
|
|
||||||
* @return the size of the memory pool in bytes
|
|
||||||
*/
|
|
||||||
size_t getPoolSize() const { return 0; }
|
|
||||||
/**
|
|
||||||
* Retrieves the starting address of the host memory. This is the
|
|
||||||
* first valid address in memory.
|
|
||||||
* @return the starting address
|
|
||||||
*/
|
|
||||||
host_address_t getStartAddr() const { return 0; }
|
|
||||||
/**
|
|
||||||
* Retrieves the byte at address \a addr in the memory.
|
|
||||||
* @param addr The guest address where the byte is located.
|
|
||||||
* The address is expected to be valid.
|
|
||||||
* @return the byte at \a addr
|
|
||||||
*/
|
|
||||||
byte_t getByte(guest_address_t addr) { return 0; }
|
|
||||||
/**
|
|
||||||
* Retrieves \a cnt bytes at address \a addr in the memory.
|
|
||||||
* @param addr The guest address where the bytes are located.
|
|
||||||
* The address is expected to be valid.
|
|
||||||
* @param cnt the number of bytes to be retrieved. \a addr + \a cnt
|
|
||||||
* is expected to not exceed the memory limit.
|
|
||||||
* @param dest Pointer to destination buffer to copy the data to.
|
|
||||||
*/
|
|
||||||
void getBytes(guest_address_t addr, size_t cnt, void *dest) { }
|
|
||||||
/**
|
|
||||||
* Writes the byte \a data to memory.
|
|
||||||
* @param addr The guest address to write.
|
|
||||||
* The address is expected to be valid.
|
|
||||||
* @param data The new byte to write
|
|
||||||
*/
|
|
||||||
void setByte(guest_address_t addr, byte_t data) { }
|
|
||||||
/**
|
|
||||||
* Copies data to memory.
|
|
||||||
* @param addr The guest address to write.
|
|
||||||
* The address is expected to be valid.
|
|
||||||
* @param cnt The number of bytes to be retrieved. \a addr + \a cnt
|
|
||||||
* is expected to not exceed the memory limit.
|
|
||||||
* @param src Pointer to data to be copied.
|
|
||||||
*/
|
|
||||||
void setBytes(guest_address_t addr, size_t cnt, void const *src) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end-of-namespace: fail
|
|
||||||
|
|
||||||
#endif // __OVP_MEMORY_HPP__
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user