Files
lifting-bits-remill/lib/Arch/SPARC32/Semantics/COND.cpp
T
Sonya 6322f794d1 New arch support (#461)
* This branch contains support for new architectures.

* Initial start to support for AArch 32

* Progress

* Forgot the new files

* Added all data Integer processing instructions without S + ADDS and started ANDS

* Updated

* Finished Integer Data Processing with three registers, added integer data processing with 2 regs + immediate, started MUL instructions

* UMULL, UMULLS, UMLAL, UMLALS

* Corrected condition for addend or 0 immediate for UMULL/UMLAL + SMULL/SMLAL instructions

* Correct ops in Binary.cpp

* UMAAL

* SMULL, SMULLS, SMLAL, SMLALS + corrected acc was missing shift left in concatination

* Updated decoding instructions based on top level encodings

* Update returns around kDataProcessingRI and kDataProcessingI with comments to explain the correlation to the instruction rep

* Added appropriate inst.category flags to Multiply and accumulate

* Load/Store Word, Unsigned Byte (immediate, literal) && start of Logical Arithmetic (three register, immediate shift)

* Was missing UMAAL DEF_ISEL in Binary.cpp

* AddAddrRegOp

* Logical Arithmetic (three register, immediate shift) without accounting for the possible PC jump

* Made DecodeA32ExpandImm much much smaller

* Replaced some imm ops with AddImmOp calls

* Created AddShiftOp

* Added interpreter for evaluating new PC value at decoding time to handle direct jumps and conditional jumps

* Created EvalPCDest added PC evaluation to Logical Arithmetic Instructions

* AddShiftOp -> AddShiftOp, AddShiftThenExtractOp, AddExtractThenShiftOp

* Cleaned up some formatting, Renamed DecodeA32ExpandImm to ExpandTo32AddImmAddCarry and added a clarifying comment

* Added comment to EvalPCDest for clarity

* Cleaned up some things, updated the decoding semantics and semantics for the logical instructions

* Shortened kLogArithEvaluators and fixed a bug

* Updates from testing instructions

* Fixed DEF_ISEL for pre/post index instructions in MEM.cpp

* Integer Test and Compare (two register, immediate shift)

* Logical Arithmetic (two register and immediate)

* Integer Test and Compare (one register and immediate)

* Added to the top level encoding infrastructure to handle the Data-processing register (register shift) set of instructions and 3 corresponding subsets

* Add structs for the 3 subsets of Data-processing register (register shift)

* Code status before refactoring operand types

* This branch contains support for new architectures.

* Initial start to support for AArch 32

* Progress

* Forgot the new files

* Added all data Integer processing instructions without S + ADDS and started ANDS

* Updated

* Finished Integer Data Processing with three registers, added integer data processing with 2 regs + immediate, started MUL instructions

* UMULL, UMULLS, UMLAL, UMLALS

* Corrected condition for addend or 0 immediate for UMULL/UMLAL + SMULL/SMLAL instructions

* Correct ops in Binary.cpp

* UMAAL

* SMULL, SMULLS, SMLAL, SMLALS + corrected acc was missing shift left in concatination

* Updated decoding instructions based on top level encodings

* Update returns around kDataProcessingRI and kDataProcessingI with comments to explain the correlation to the instruction rep

* Added appropriate inst.category flags to Multiply and accumulate

* Load/Store Word, Unsigned Byte (immediate, literal) && start of Logical Arithmetic (three register, immediate shift)

* Was missing UMAAL DEF_ISEL in Binary.cpp

* AddAddrRegOp

* Logical Arithmetic (three register, immediate shift) without accounting for the possible PC jump

* Made DecodeA32ExpandImm much much smaller

* Replaced some imm ops with AddImmOp calls

* Created AddShiftOp

* Added interpreter for evaluating new PC value at decoding time to handle direct jumps and conditional jumps

* Created EvalPCDest added PC evaluation to Logical Arithmetic Instructions

* AddShiftOp -> AddShiftOp, AddShiftThenExtractOp, AddExtractThenShiftOp

* Cleaned up some formatting, Renamed DecodeA32ExpandImm to ExpandTo32AddImmAddCarry and added a clarifying comment

* Added comment to EvalPCDest for clarity

* Cleaned up some things, updated the decoding semantics and semantics for the logical instructions

* Shortened kLogArithEvaluators and fixed a bug

* Updates from testing instructions

* Fixed DEF_ISEL for pre/post index instructions in MEM.cpp

* Integer Test and Compare (two register, immediate shift)

* Logical Arithmetic (two register and immediate)

* Integer Test and Compare (one register and immediate)

* Added to the top level encoding infrastructure to handle the Data-processing register (register shift) set of instructions and 3 corresponding subsets

* Add structs for the 3 subsets of Data-processing register (register shift)

* Code status before refactoring operand types

* Finished updates off master

* Start of operand refactor

* Finished Expression Operand Support

* Fix the .gitignore to add AArch32 to lib/Arch && removed all extra rrx ops from semantics

* Updated .gitignore again, Added AddShiftRegRegOperand, Updated AddShiftRegImmOperand, Finished Register shift instructions for Integer Test and Compare, Logical Arithmetic, Integer Data Processing

* Updated ROR in AddShiftRegRegOperand

* Created ExtractAndZExtExpr

* Fixed comment formatting in if else statements

* Created RORExpr

* Small fixes

* Small fix in Logical Arithmetic (two register and immediate)

* Corrected AddShiftRegRegOperand and cleaned it up. Split the carry op into a separate function.

* conditional support + Start of Branch instructions

* Created AddExprOp, cleaned up some expressions in reg shifted reg, and updated some occurances of ShiftThenExtractOp with ExtractAndZExtExpr

* Updates from testing register shifted by register value inst

* Fix to ROR in AddShiftRegCarryOperand

* Corrected negation in DecodeCondition

* DecodeCondition edit

* DecodeCondition and AddShiftRegCarryOperand edits

* Updated arch_for_decode to arch

* Halfword Multiply and Accumulate

* Edits from testing Halfword Multiply and Accumulate

* Changed order of operands in Halfword Multiply and Accumulate to better reflect inst format + updated inst errors

* Branch (Imm) & BX/BXL

* Update aarch32 cmake

* cmake update

* CLZ

* Forgot BITBYTE.cpp

* MOVT

* Integer Saturating Arithmetic

* updated semantics in SMLAWh & SMLAh to use Select for setting PSTATE.Q

* Started Load/Store Word, Unsigned Byte (register) & fixed MOV halfword

* Load/Store Word, Unsigned Byte (register)

* Finished testing load/Store Word, Unsigned Byte (register)

* Load/Store Dual, Half, Signed Byte (register)

* Rest of Extra load store: Load/Store Dual, Half, Signed Byte (immediate, literal)

* Finished testing all the Load/store additions

* Signed multiply, Divide

* Cleaned up SExt some

* Saturate Insts and Start of Load Store Multiple - STMDB and LDM (aliases which support PUSH and POP of multiple regs)

* Condensed args in STMDB and LDM semantics

* Rest of Multiple Load/Store that do not execute in a different mode

* Bitfield Extract

* Extend and Add

* fix

* NOP

* Small fix

* Simplified the bit reps in TryMoveSpecialRegisterAndHintsI

* Moved Bitfield extract semantics out of BINARY and into BITBYTE

* Finished correcting S/ZExt and Trunc use

* Ran scripts/format-files to format

* Smoke Test

* Add false delay slot to kCategoryConditionalDirectFunctionCall

* CI: Use single packaging job, add changelog support (#491)

* CI: Add tag handler (#492)

* Delay slot fixes to TraceLifter

Co-authored-by: Peter Goodman <peter.goodman@gmail.com>
Co-authored-by: Alessandro Gario <5714290+alessandrogario@users.noreply.github.com>
2021-02-24 14:01:09 -05:00

251 lines
7.1 KiB
C++

/*
* Copyright (c) 2020 Trail of Bits, Inc.
*/
#define MAKE_CONDITIONS(cc) \
static inline bool CondA_##cc(const State &state) { \
return true; \
} \
static inline bool CondN_##cc(const State &state) { \
return false; \
} \
static inline bool CondE_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_zf = ccr.z; \
return flag_zf; \
} \
static inline bool CondNE_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_zf = ccr.z; \
return !flag_zf; \
} \
static inline bool CondG_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_nf = ccr.n; \
const bool flag_zf = ccr.z; \
const bool flag_vf = ccr.v; \
return (flag_nf == flag_vf) && !flag_zf; \
} \
static inline bool CondLE_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_nf = ccr.n; \
const bool flag_zf = ccr.z; \
const bool flag_vf = ccr.v; \
return (flag_nf != flag_vf) || flag_zf; \
} \
static inline bool CondGE_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_nf = ccr.n; \
const bool flag_vf = ccr.v; \
return flag_nf == flag_vf; \
} \
static inline bool CondL_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_nf = ccr.n; \
const bool flag_vf = ccr.v; \
return flag_nf != flag_vf; \
} \
static inline bool CondGU_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_cf = ccr.c; \
const bool flag_zf = ccr.z; \
return !(flag_cf || flag_zf); \
} \
static inline bool CondLEU_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_cf = ccr.c; \
const bool flag_zf = ccr.z; \
return flag_cf || flag_zf; \
} \
static inline bool CondCS_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_cf = ccr.c; \
return flag_cf; \
} \
static inline bool CondCC_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_cf = ccr.c; \
return !flag_cf; \
} \
static inline bool CondPOS_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_nf = ccr.n; \
return !flag_nf; \
} \
static inline bool CondNEG_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_nf = ccr.n; \
return flag_nf; \
} \
static inline bool CondVS_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_vf = ccr.v; \
return flag_vf; \
} \
static inline bool CondVC_##cc(const State &state) { \
const auto ccr = state.asr.ccr.cc; \
const bool flag_vf = ccr.v; \
return !flag_vf; \
}
MAKE_CONDITIONS(xcc)
MAKE_CONDITIONS(icc)
#undef MAKE_CONDITIONS
#define MAKE_CONDITIONS(fcc) \
static inline bool CondU_##fcc(const State &state) { \
return (state.fsr.fcc == 0x3); \
} \
static inline bool CondG_##fcc(const State &state) { \
return (state.fsr.fcc == 0x2); \
} \
static inline bool CondUG_##fcc(const State &state) { \
return (state.fsr.fcc == 0x3) || (state.fsr.fcc == 0x2); \
} \
static inline bool CondL_##fcc(const State &state) { \
return (state.fsr.fcc == 0x1); \
} \
static inline bool CondUL_##fcc(const State &state) { \
return (state.fsr.fcc == 0x3) || (state.fsr.fcc == 0x1); \
} \
static inline bool CondLG_##fcc(const State &state) { \
return (state.fsr.fcc == 0x2) || (state.fsr.fcc == 0x1); \
} \
static inline bool CondLGU_##fcc(const State &state) { \
return (state.fsr.fcc == 0x3) || (state.fsr.fcc == 0x2) || \
(state.fsr.fcc == 0x1); \
} \
static inline bool CondNE_##fcc(const State &state) { \
return (state.fsr.fcc == 0x3) || (state.fsr.fcc == 0x2) || \
(state.fsr.fcc == 0x1); \
} \
static inline bool CondE_##fcc(const State &state) { \
return (state.fsr.fcc == 0x0); \
} \
static inline bool CondUE_##fcc(const State &state) { \
return (state.fsr.fcc == 0x3) || (state.fsr.fcc == 0x0); \
} \
static inline bool CondGE_##fcc(const State &state) { \
return (state.fsr.fcc == 0x2) || (state.fsr.fcc == 0x0); \
} \
static inline bool CondUGE_##fcc(const State &state) { \
return (state.fsr.fcc == 0x3) || (state.fsr.fcc == 0x2) || \
(state.fsr.fcc == 0x0); \
} \
static inline bool CondLE_##fcc(const State &state) { \
return (state.fsr.fcc == 0x1) || (state.fsr.fcc == 0x0); \
} \
static inline bool CondULE_##fcc(const State &state) { \
return (state.fsr.fcc == 0x3) || (state.fsr.fcc == 0x1) || \
(state.fsr.fcc == 0x0); \
} \
static inline bool CondGLE_##fcc(const State &state) { \
return (state.fsr.fcc == 0x2) || (state.fsr.fcc == 0x1) || \
(state.fsr.fcc == 0x0); \
} \
static inline bool CondO_##fcc(const State &state) { \
return (state.fsr.fcc == 0x2) || (state.fsr.fcc == 0x1) || \
(state.fsr.fcc == 0x0); \
}
MAKE_CONDITIONS(fcc0)
MAKE_CONDITIONS(fcc1)
MAKE_CONDITIONS(fcc2)
MAKE_CONDITIONS(fcc3)
template <typename T>
static inline bool CondRZ(const State &state, T cc) {
return cc == 0;
}
template <typename T>
static inline bool CondRLEZ(const State &state, T cc) {
return Signed(cc) <= 0;
}
template <typename T>
static inline bool CondRLZ(const State &state, T cc) {
return Signed(cc) < 0;
}
template <typename T>
static inline bool CondRNZ(const State &state, T cc) {
return cc != 0;
}
template <typename T>
static inline bool CondRGZ(const State &state, T cc) {
return Signed(cc) > 0;
}
template <typename T>
static inline bool CondRGEZ(const State &state, T cc) {
return Signed(cc) >= 0;
}
static inline bool CondA_ccc(const State &state) {
return state.csr.ccc == 0b1000;
}
static inline bool CondN_ccc(const State &state) {
return state.csr.ccc == 0b0000;
}
static inline bool Cond3_ccc(const State &state) {
return state.csr.ccc == 0b0111;
}
static inline bool Cond2_ccc(const State &state) {
return state.csr.ccc == 0b0110;
}
static inline bool Cond23_ccc(const State &state) {
return state.csr.ccc == 0b0101;
}
static inline bool Cond1_ccc(const State &state) {
return state.csr.ccc == 0b0100;
}
static inline bool Cond13_ccc(const State &state) {
return state.csr.ccc == 0b0011;
}
static inline bool Cond12_ccc(const State &state) {
return state.csr.ccc == 0b0010;
}
static inline bool Cond123_ccc(const State &state) {
return state.csr.ccc == 0b0001;
}
static inline bool Cond0_ccc(const State &state) {
return state.csr.ccc == 0b1001;
}
static inline bool Cond03_ccc(const State &state) {
return state.csr.ccc == 0b1010;
}
static inline bool Cond02_ccc(const State &state) {
return state.csr.ccc == 0b1011;
}
static inline bool Cond023_ccc(const State &state) {
return state.csr.ccc == 0b1100;
}
static inline bool Cond01_ccc(const State &state) {
return state.csr.ccc == 0b1101;
}
static inline bool Cond013_ccc(const State &state) {
return state.csr.ccc == 0b1110;
}
static inline bool Cond012_ccc(const State &state) {
return state.csr.ccc == 0b1111;
}