root/arch/arm/kernel/opcodes.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. arm_check_condition

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  linux/arch/arm/kernel/opcodes.c
   4  *
   5  *  A32 condition code lookup feature moved from nwfpe/fpopcode.c
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <asm/opcodes.h>
  10 
  11 #define ARM_OPCODE_CONDITION_UNCOND 0xf
  12 
  13 /*
  14  * condition code lookup table
  15  * index into the table is test code: EQ, NE, ... LT, GT, AL, NV
  16  *
  17  * bit position in short is condition code: NZCV
  18  */
  19 static const unsigned short cc_map[16] = {
  20         0xF0F0,                 /* EQ == Z set            */
  21         0x0F0F,                 /* NE                     */
  22         0xCCCC,                 /* CS == C set            */
  23         0x3333,                 /* CC                     */
  24         0xFF00,                 /* MI == N set            */
  25         0x00FF,                 /* PL                     */
  26         0xAAAA,                 /* VS == V set            */
  27         0x5555,                 /* VC                     */
  28         0x0C0C,                 /* HI == C set && Z clear */
  29         0xF3F3,                 /* LS == C clear || Z set */
  30         0xAA55,                 /* GE == (N==V)           */
  31         0x55AA,                 /* LT == (N!=V)           */
  32         0x0A05,                 /* GT == (!Z && (N==V))   */
  33         0xF5FA,                 /* LE == (Z || (N!=V))    */
  34         0xFFFF,                 /* AL always              */
  35         0                       /* NV                     */
  36 };
  37 
  38 /*
  39  * Returns:
  40  * ARM_OPCODE_CONDTEST_FAIL   - if condition fails
  41  * ARM_OPCODE_CONDTEST_PASS   - if condition passes (including AL)
  42  * ARM_OPCODE_CONDTEST_UNCOND - if NV condition, or separate unconditional
  43  *                              opcode space from v5 onwards
  44  *
  45  * Code that tests whether a conditional instruction would pass its condition
  46  * check should check that return value == ARM_OPCODE_CONDTEST_PASS.
  47  *
  48  * Code that tests if a condition means that the instruction would be executed
  49  * (regardless of conditional or unconditional) should instead check that the
  50  * return value != ARM_OPCODE_CONDTEST_FAIL.
  51  */
  52 asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr)
  53 {
  54         u32 cc_bits  = opcode >> 28;
  55         u32 psr_cond = psr >> 28;
  56         unsigned int ret;
  57 
  58         if (cc_bits != ARM_OPCODE_CONDITION_UNCOND) {
  59                 if ((cc_map[cc_bits] >> (psr_cond)) & 1)
  60                         ret = ARM_OPCODE_CONDTEST_PASS;
  61                 else
  62                         ret = ARM_OPCODE_CONDTEST_FAIL;
  63         } else {
  64                 ret = ARM_OPCODE_CONDTEST_UNCOND;
  65         }
  66 
  67         return ret;
  68 }
  69 EXPORT_SYMBOL_GPL(arm_check_condition);

/* [<][>][^][v][top][bottom][index][help] */