xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ARMDefines.h (revision e25152834cdf3b353892835a4f3b157e066a8ed4)
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