10b57cec5SDimitry Andric //===-- ARMDefines.h --------------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
9*5ffd83dbSDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H
10*5ffd83dbSDimitry Andric #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H
110b57cec5SDimitry Andric
120b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include <cassert>
150b57cec5SDimitry Andric #include <cstdint>
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric // Common definitions for the ARM/Thumb Instruction Set Architecture.
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric namespace lldb_private {
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric // ARM shifter types
220b57cec5SDimitry Andric enum ARM_ShifterType {
230b57cec5SDimitry Andric SRType_LSL,
240b57cec5SDimitry Andric SRType_LSR,
250b57cec5SDimitry Andric SRType_ASR,
260b57cec5SDimitry Andric SRType_ROR,
270b57cec5SDimitry Andric SRType_RRX,
280b57cec5SDimitry Andric SRType_Invalid
290b57cec5SDimitry Andric };
300b57cec5SDimitry Andric
310b57cec5SDimitry Andric // ARM conditions // Meaning (integer) Meaning (floating-point)
320b57cec5SDimitry Andric // Condition flags
330b57cec5SDimitry Andric #define COND_EQ \
340b57cec5SDimitry Andric 0x0 // Equal Equal Z == 1
350b57cec5SDimitry Andric #define COND_NE \
360b57cec5SDimitry Andric 0x1 // Not equal Not equal, or unordered Z == 0
370b57cec5SDimitry Andric #define COND_CS \
380b57cec5SDimitry Andric 0x2 // Carry set >, ==, or unordered C == 1
390b57cec5SDimitry Andric #define COND_HS 0x2
400b57cec5SDimitry Andric #define COND_CC \
410b57cec5SDimitry Andric 0x3 // Carry clear Less than C == 0
420b57cec5SDimitry Andric #define COND_LO 0x3
430b57cec5SDimitry Andric #define COND_MI \
440b57cec5SDimitry Andric 0x4 // Minus, negative Less than N == 1
450b57cec5SDimitry Andric #define COND_PL \
460b57cec5SDimitry Andric 0x5 // Plus, positive or zero >, ==, or unordered N == 0
470b57cec5SDimitry Andric #define COND_VS \
480b57cec5SDimitry Andric 0x6 // Overflow Unordered V == 1
490b57cec5SDimitry Andric #define COND_VC \
500b57cec5SDimitry Andric 0x7 // No overflow Not unordered V == 0
510b57cec5SDimitry Andric #define COND_HI \
520b57cec5SDimitry Andric 0x8 // Unsigned higher Greater than, or unordered C == 1 and Z ==
530b57cec5SDimitry Andric // 0
540b57cec5SDimitry Andric #define COND_LS \
550b57cec5SDimitry Andric 0x9 // Unsigned lower or same Less than or equal C == 0 or Z ==
560b57cec5SDimitry Andric // 1
570b57cec5SDimitry Andric #define COND_GE \
580b57cec5SDimitry Andric 0xA // Greater than or equal Greater than or equal N == V
590b57cec5SDimitry Andric #define COND_LT \
600b57cec5SDimitry Andric 0xB // Less than Less than, or unordered N != V
610b57cec5SDimitry Andric #define COND_GT \
620b57cec5SDimitry Andric 0xC // Greater than Greater than Z == 0 and N ==
630b57cec5SDimitry Andric // V
640b57cec5SDimitry Andric #define COND_LE \
650b57cec5SDimitry Andric 0xD // Less than or equal <, ==, or unordered Z == 1 or N !=
660b57cec5SDimitry Andric // V
670b57cec5SDimitry Andric #define COND_AL \
680b57cec5SDimitry Andric 0xE // Always (unconditional) Always (unconditional) Any
690b57cec5SDimitry Andric #define COND_UNCOND 0xF
700b57cec5SDimitry Andric
ARMCondCodeToString(uint32_t CC)710b57cec5SDimitry Andric static inline const char *ARMCondCodeToString(uint32_t CC) {
720b57cec5SDimitry Andric switch (CC) {
730b57cec5SDimitry Andric case COND_EQ:
740b57cec5SDimitry Andric return "eq";
750b57cec5SDimitry Andric case COND_NE:
760b57cec5SDimitry Andric return "ne";
770b57cec5SDimitry Andric case COND_HS:
780b57cec5SDimitry Andric return "hs";
790b57cec5SDimitry Andric case COND_LO:
800b57cec5SDimitry Andric return "lo";
810b57cec5SDimitry Andric case COND_MI:
820b57cec5SDimitry Andric return "mi";
830b57cec5SDimitry Andric case COND_PL:
840b57cec5SDimitry Andric return "pl";
850b57cec5SDimitry Andric case COND_VS:
860b57cec5SDimitry Andric return "vs";
870b57cec5SDimitry Andric case COND_VC:
880b57cec5SDimitry Andric return "vc";
890b57cec5SDimitry Andric case COND_HI:
900b57cec5SDimitry Andric return "hi";
910b57cec5SDimitry Andric case COND_LS:
920b57cec5SDimitry Andric return "ls";
930b57cec5SDimitry Andric case COND_GE:
940b57cec5SDimitry Andric return "ge";
950b57cec5SDimitry Andric case COND_LT:
960b57cec5SDimitry Andric return "lt";
970b57cec5SDimitry Andric case COND_GT:
980b57cec5SDimitry Andric return "gt";
990b57cec5SDimitry Andric case COND_LE:
1000b57cec5SDimitry Andric return "le";
1010b57cec5SDimitry Andric case COND_AL:
1020b57cec5SDimitry Andric return "al";
1030b57cec5SDimitry Andric }
1040b57cec5SDimitry Andric llvm_unreachable("Unknown condition code");
1050b57cec5SDimitry Andric }
1060b57cec5SDimitry Andric
ARMConditionPassed(const uint32_t condition,const uint32_t cpsr)1070b57cec5SDimitry Andric static inline bool ARMConditionPassed(const uint32_t condition,
1080b57cec5SDimitry Andric const uint32_t cpsr) {
1090b57cec5SDimitry Andric const uint32_t cpsr_n = (cpsr >> 31) & 1u; // Negative condition code flag
1100b57cec5SDimitry Andric const uint32_t cpsr_z = (cpsr >> 30) & 1u; // Zero condition code flag
1110b57cec5SDimitry Andric const uint32_t cpsr_c = (cpsr >> 29) & 1u; // Carry condition code flag
1120b57cec5SDimitry Andric const uint32_t cpsr_v = (cpsr >> 28) & 1u; // Overflow condition code flag
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andric switch (condition) {
1150b57cec5SDimitry Andric case COND_EQ:
1160b57cec5SDimitry Andric return (cpsr_z == 1);
1170b57cec5SDimitry Andric case COND_NE:
1180b57cec5SDimitry Andric return (cpsr_z == 0);
1190b57cec5SDimitry Andric case COND_CS:
1200b57cec5SDimitry Andric return (cpsr_c == 1);
1210b57cec5SDimitry Andric case COND_CC:
1220b57cec5SDimitry Andric return (cpsr_c == 0);
1230b57cec5SDimitry Andric case COND_MI:
1240b57cec5SDimitry Andric return (cpsr_n == 1);
1250b57cec5SDimitry Andric case COND_PL:
1260b57cec5SDimitry Andric return (cpsr_n == 0);
1270b57cec5SDimitry Andric case COND_VS:
1280b57cec5SDimitry Andric return (cpsr_v == 1);
1290b57cec5SDimitry Andric case COND_VC:
1300b57cec5SDimitry Andric return (cpsr_v == 0);
1310b57cec5SDimitry Andric case COND_HI:
1320b57cec5SDimitry Andric return ((cpsr_c == 1) && (cpsr_z == 0));
1330b57cec5SDimitry Andric case COND_LS:
1340b57cec5SDimitry Andric return ((cpsr_c == 0) || (cpsr_z == 1));
1350b57cec5SDimitry Andric case COND_GE:
1360b57cec5SDimitry Andric return (cpsr_n == cpsr_v);
1370b57cec5SDimitry Andric case COND_LT:
1380b57cec5SDimitry Andric return (cpsr_n != cpsr_v);
1390b57cec5SDimitry Andric case COND_GT:
1400b57cec5SDimitry Andric return ((cpsr_z == 0) && (cpsr_n == cpsr_v));
1410b57cec5SDimitry Andric case COND_LE:
1420b57cec5SDimitry Andric return ((cpsr_z == 1) || (cpsr_n != cpsr_v));
1430b57cec5SDimitry Andric case COND_AL:
1440b57cec5SDimitry Andric case COND_UNCOND:
1450b57cec5SDimitry Andric default:
1460b57cec5SDimitry Andric return true;
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric return false;
1490b57cec5SDimitry Andric }
1500b57cec5SDimitry Andric
1510b57cec5SDimitry Andric // Bit positions for CPSR
1520b57cec5SDimitry Andric #define CPSR_T_POS 5
1530b57cec5SDimitry Andric #define CPSR_F_POS 6
1540b57cec5SDimitry Andric #define CPSR_I_POS 7
1550b57cec5SDimitry Andric #define CPSR_A_POS 8
1560b57cec5SDimitry Andric #define CPSR_E_POS 9
1570b57cec5SDimitry Andric #define CPSR_J_POS 24
1580b57cec5SDimitry Andric #define CPSR_Q_POS 27
1590b57cec5SDimitry Andric #define CPSR_V_POS 28
1600b57cec5SDimitry Andric #define CPSR_C_POS 29
1610b57cec5SDimitry Andric #define CPSR_Z_POS 30
1620b57cec5SDimitry Andric #define CPSR_N_POS 31
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric // CPSR mode definitions
1650b57cec5SDimitry Andric #define CPSR_MODE_USR 0x10u
1660b57cec5SDimitry Andric #define CPSR_MODE_FIQ 0x11u
1670b57cec5SDimitry Andric #define CPSR_MODE_IRQ 0x12u
1680b57cec5SDimitry Andric #define CPSR_MODE_SVC 0x13u
1690b57cec5SDimitry Andric #define CPSR_MODE_ABT 0x17u
1700b57cec5SDimitry Andric #define CPSR_MODE_UND 0x1bu
1710b57cec5SDimitry Andric #define CPSR_MODE_SYS 0x1fu
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andric // Masks for CPSR
1740b57cec5SDimitry Andric #define MASK_CPSR_MODE_MASK (0x0000001fu)
1750b57cec5SDimitry Andric #define MASK_CPSR_IT_MASK (0x0600fc00u)
1760b57cec5SDimitry Andric #define MASK_CPSR_T (1u << CPSR_T_POS)
1770b57cec5SDimitry Andric #define MASK_CPSR_F (1u << CPSR_F_POS)
1780b57cec5SDimitry Andric #define MASK_CPSR_I (1u << CPSR_I_POS)
1790b57cec5SDimitry Andric #define MASK_CPSR_A (1u << CPSR_A_POS)
1800b57cec5SDimitry Andric #define MASK_CPSR_E (1u << CPSR_E_POS)
1810b57cec5SDimitry Andric #define MASK_CPSR_GE_MASK (0x000f0000u)
1820b57cec5SDimitry Andric #define MASK_CPSR_J (1u << CPSR_J_POS)
1830b57cec5SDimitry Andric #define MASK_CPSR_Q (1u << CPSR_Q_POS)
1840b57cec5SDimitry Andric #define MASK_CPSR_V (1u << CPSR_V_POS)
1850b57cec5SDimitry Andric #define MASK_CPSR_C (1u << CPSR_C_POS)
1860b57cec5SDimitry Andric #define MASK_CPSR_Z (1u << CPSR_Z_POS)
1870b57cec5SDimitry Andric #define MASK_CPSR_N (1u << CPSR_N_POS)
1880b57cec5SDimitry Andric
1890b57cec5SDimitry Andric } // namespace lldb_private
1900b57cec5SDimitry Andric
191*5ffd83dbSDimitry Andric #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMDEFINES_H
192