Merge "Removed OVP-related (source) files/code (backend discarded)."

This commit is contained in:
Adrian Böckenkamp
2013-04-23 14:27:02 +02:00
committed by Gerrit Code Review
101 changed files with 22 additions and 28293 deletions

View File

@ -30,9 +30,8 @@ include(doxygen)
#### Backend selection ####
OPTION( BUILD_BOCHS "Build Bochs Variant?" ON)
OPTION( BUILD_GEM5 "Build gem5 Variant?" OFF)
OPTION( BUILD_OVP "Build OVP 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_ARM "Build for ARM guests?" OFF)
@ -47,8 +46,6 @@ if(BUILD_BOCHS)
elseif(BUILD_GEM5)
include_directories(simulators/gem5/src simulators/gem5/build/ARM)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -DTRACING_ON")
elseif(BUILD_OVP)
add_subdirectory(simulators/ovp)
elseif(BUILD_QEMU)
include_directories(simulators)
elseif(BUILD_T32)
@ -73,7 +70,6 @@ add_subdirectory(src)
#### Backend-related build system stuff
include(bochs)
include(gem5)
include(ovp)
include(qemu)
include(t32)

View File

@ -1,5 +0,0 @@
#### OVP-specific stuff
if(BUILD_OVP)
message(STATUS "[${PROJECT_NAME}] Building OVP variant ...")
SET(VARIANT ovp)
endif(BUILD_OVP)

View File

@ -11,21 +11,31 @@ fail: Fail* parent directory, containing all source & configuration files (${FA
|-scripts: python/shell scripts for Fail*-compilation and experiment distribution
|-simulators: parent directory of simulators supported by Fail* (may still be WIP)
|-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
|-core: core source files forming the Fail* framework
|-util: utility classes and miscellaneous helper functions
|-config: CMake configuration files, defining the Fail* components and variant
|-sal: source file forming the Simulator Abstraction Layer (backend-interface)
|-bochs: backend source files to the Bochs simulator
|-ovp: backend source files to the Open Virtual Platform simulator
|-bochs: backend source files of the Bochs 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
|-efw: experiment-framework- (and therefore client-)related source files
|-comm: communication related source files (these files are used by cpn and efw)
|-msg: Google protobuf message definitions used for communication purposes
|-comm: communication related source files (these files are used by cpn and efw), incl.
protobuf message definitions used for communication purposes
|-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
|-[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:
@ -40,8 +50,8 @@ Some additional useful notes:
- CMake invokes the compiler with the following include directories:
* ${FAIL_DIR}/src/core
* ${BUILD_DIR}/src/core
When compiling the Bochs variant the following directory is added, too:
* ${FAIL_DIR}/simulators/bochs
When compiling the $SIMULATOR variant the following directory is added, too:
* ${FAIL_DIR}/simulators/$SIMULATOR
These definitions simplify and shorten the include paths.
=========================================================================================

View File

@ -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):
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:
**********************************************************************

View File

@ -117,7 +117,7 @@ Buildsystem:
(verwendeter Compiler, Installationsverzeichnis, ...), den Rest in einem
brauchbaren Konfigurationswerkzeug mit Ausdrucksmöglichkeiten für
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)
http://www.kitware.com/blog/home/post/82
- Hinzufügen eines neuen Experiments konkreter dokumentieren (how-to-build.txt?)
@ -218,21 +218,3 @@ Theorie TODO
==========================================================================================
- Problem Fork von FI Tools -> Merging eklig.
-> 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:
-

View File

@ -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}
)

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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__

View File

@ -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

View File

@ -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})

View File

@ -1,5 +0,0 @@
IMPERAS_HOME := $(shell getpath.exe "$(IMPERAS_HOME)")
LDFLAGS+=-lm
include $(IMPERAS_HOME)/ImperasLib/source/buildutils/Makefile.host

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,
};

View File

@ -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}
};

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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 ),
};

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -1,3 +0,0 @@
EXPORTS
vmiStubs
modelAttrs

View File

@ -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);
}

View File

@ -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 ")

View File

@ -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]);
}

View File

@ -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

View File

@ -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);
}
};

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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} )

View File

@ -1,10 +0,0 @@
message OVPStatusMessage {
// Registers
message Register {
required string name = 1;
required uint32 value = 2;
}
repeated Register reg = 1;
}

View File

@ -1,2 +0,0 @@
#!/bin/bash
protoc --cpp_out=. FailControlMessage.proto

View File

@ -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.

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}

View File

@ -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
${CMAKE_CURRENT_BINARY_DIR}/VariantConfig.hpp)

View File

@ -3,7 +3,6 @@
#cmakedefine BUILD_BOCHS
#cmakedefine BUILD_GEM5
#cmakedefine BUILD_OVP
#cmakedefine BUILD_QEMU
#cmakedefine BUILD_T32
#cmakedefine T32_MOCK_API

View File

@ -27,17 +27,6 @@ elseif(BUILD_GEM5)
gem5/Gem5ArmCPU.cc
)
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)
set(SRCS
CPU.cc

View File

@ -9,8 +9,6 @@
#else
#error Active config currently not supported!
#endif
#elif defined BUILD_OVP
#include "ovp/OVPConfig.hpp"
#elif defined BUILD_QEMU
#include "qemu/QEMUConfig.hpp"
#elif defined BUILD_T32

View File

@ -5,8 +5,7 @@ namespace fail {
// Flag initialization depends on the current selected simulator
// (For now, the initialization values are all the same):
#if defined BUILD_BOCHS || defined BUILD_GEM5 || \
defined BUILD_OVP || defined BUILD_QEMU || \
defined BUILD_T32
defined BUILD_T32 || defined BUILD_QEMU
const address_t ADDR_INV = static_cast<address_t> (0);
const address_t ANY_ADDR = static_cast<address_t> (-1);
const unsigned ANY_INSTR = static_cast<unsigned> (-1);

View File

@ -10,8 +10,6 @@
#include "bochs/BochsConfig.hpp"
#elif defined BUILD_GEM5
#include "gem5/Gem5Config.hpp"
#elif defined BUILD_OVP
#include "ovp/OVPConfig.hpp"
#elif defined BUILD_QEMU
#include "qemu/QEMUConfig.hpp"
#elif defined BUILD_T32

View File

@ -20,14 +20,6 @@ namespace fail {
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
#include "qemu/QEMUController.hpp"

View File

@ -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__

View File

@ -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__

View File

@ -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

View File

@ -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__

View File

@ -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