[PATCH 1/4] [RFC] Add generic ARM instruction set condition code checks.
Leif Lindholm
leif.lindholm at arm.com
Mon Nov 21 13:30:46 EST 2011
This patch breaks the ARM condition checking code out of nwfpe/fpopcode.{ch}
into a standalone file for opcode operations. It also modifies the code
somwhat for coding style adherence, and adds some temporary variables for
increased readability.
Signed-off-by: Leif Lindholm <leif.lindholm at arm.com>
---
arch/arm/include/asm/opcodes.h | 14 +++++++++
arch/arm/kernel/Makefile | 2 +
arch/arm/kernel/opcodes.c | 61 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 76 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/include/asm/opcodes.h
create mode 100644 arch/arm/kernel/opcodes.c
diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h
new file mode 100644
index 0000000..4c18fcb
--- /dev/null
+++ b/arch/arm/include/asm/opcodes.h
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/include/asm/opcodes.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_OPCODES_H
+#define __ASM_ARM_OPCODES_H
+
+extern unsigned int arm_check_condition(unsigned int opcode, unsigned int psr);
+
+#endif /* __ASM_ARM_OPCODES_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 16eed6a..43b740d 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -13,7 +13,7 @@ CFLAGS_REMOVE_return_address.o = -pg
# Object file lists.
-obj-y := elf.o entry-armv.o entry-common.o irq.o \
+obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \
process.o ptrace.o return_address.o setup.o signal.o \
sys_arm.o stacktrace.o time.o traps.o
diff --git a/arch/arm/kernel/opcodes.c b/arch/arm/kernel/opcodes.c
new file mode 100644
index 0000000..8adc20c
--- /dev/null
+++ b/arch/arm/kernel/opcodes.c
@@ -0,0 +1,61 @@
+/*
+ * linux/arch/arm/kernel/opcodes.c
+ *
+ * A32 condition code lookup feature moved from nwfpe/fpopcode.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <asm/opcodes.h>
+
+#define ARM_OPCODE_UNCONDITIONAL 0xf
+
+/*
+ * condition code lookup table
+ * index into the table is test code: EQ, NE, ... LT, GT, AL, NV
+ *
+ * bit position in short is condition code: NZCV
+ */
+static const unsigned short cc_map[16] = {
+ 0xF0F0, /* EQ == Z set */
+ 0x0F0F, /* NE */
+ 0xCCCC, /* CS == C set */
+ 0x3333, /* CC */
+ 0xFF00, /* MI == N set */
+ 0x00FF, /* PL */
+ 0xAAAA, /* VS == V set */
+ 0x5555, /* VC */
+ 0x0C0C, /* HI == C set && Z clear */
+ 0xF3F3, /* LS == C clear || Z set */
+ 0xAA55, /* GE == (N==V) */
+ 0x55AA, /* LT == (N!=V) */
+ 0x0A05, /* GT == (!Z && (N==V)) */
+ 0xF5FA, /* LE == (Z || (N!=V)) */
+ 0xFFFF, /* AL always */
+ 0 /* NV */
+};
+
+/*
+ * Returns:
+ * 0 - if condition fails
+ * 1 - if condition passes (including AL)
+ * 2 - if unconditional encoding (or before ARMv3, NV condition)
+ *
+ * Code that needs to check whether a condition has explicitly passed,
+ * should compare the return value to 1.
+ * Code that wants to check if a condition means that the instruction
+ * should be executed, should compare the return value to !0.
+ */
+unsigned int arm_check_condition(unsigned int opcode, unsigned int psr)
+{
+ unsigned int cc_bits = opcode >> 28;
+ unsigned int psr_cond = psr >> 28;
+
+ /* NV condition or unconditional */
+ if (cc_bits == ARM_OPCODE_UNCONDITIONAL)
+ return 2;
+
+ return (cc_map[cc_bits] >> (psr_cond)) & 1;
+}
More information about the linux-arm-kernel
mailing list