git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1321 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
305 lines
13 KiB
C
305 lines
13 KiB
C
/*
|
|
* 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
|