mirror of
https://github.com/lifting-bits/remill
synced 2026-06-21 13:56:07 +00:00
6322f794d1
* 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>
251 lines
7.1 KiB
C++
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;
|
|
}
|