aboutsummaryrefslogtreecommitdiffstats
path: root/vppinfra/vppinfra/asm_x86.h
diff options
context:
space:
mode:
Diffstat (limited to 'vppinfra/vppinfra/asm_x86.h')
-rw-r--r--vppinfra/vppinfra/asm_x86.h113
1 files changed, 113 insertions, 0 deletions
diff --git a/vppinfra/vppinfra/asm_x86.h b/vppinfra/vppinfra/asm_x86.h
new file mode 100644
index 00000000000..378da0f8167
--- /dev/null
+++ b/vppinfra/vppinfra/asm_x86.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef included_asm_x86_h
+#define included_asm_x86_h
+
+#include <vppinfra/format.h>
+
+typedef union {
+ struct {
+ u8 code;
+ u8 type;
+ };
+ u8 data[2];
+} x86_insn_operand_t;
+
+typedef struct {
+ /* Instruction name. */
+ char * name;
+
+ /* X86 instructions may have up to 3 operands. */
+ x86_insn_operand_t operands[3];
+
+ u16 flags;
+#define X86_INSN_FLAG_DEFAULT_64_BIT (1 << 0)
+#define X86_INSN_FLAG_SET_SSE_GROUP(n) ((n) << 5)
+#define X86_INSN_FLAG_GET_SSE_GROUP(f) (((f) >> 5) & 0x1f)
+#define X86_INSN_FLAG_SET_MODRM_REG_GROUP(n) (((n) & 0x3f) << 10)
+#define X86_INSN_FLAG_GET_MODRM_REG_GROUP(f) (((f) >> 10) & 0x3f)
+} x86_insn_t;
+
+always_inline uword
+x86_insn_operand_is_valid (x86_insn_t * i, uword o)
+{
+ ASSERT (o < ARRAY_LEN (i->operands));
+ return i->operands[o].code != '_';
+}
+
+#define foreach_x86_legacy_prefix \
+ _ (OPERAND_SIZE, 0x66) \
+ _ (ADDRESS_SIZE, 0x67) \
+ _ (SEGMENT_CS, 0x2e) \
+ _ (SEGMENT_DS, 0x3e) \
+ _ (SEGMENT_ES, 0x26) \
+ _ (SEGMENT_FS, 0x64) \
+ _ (SEGMENT_GS, 0x65) \
+ _ (SEGMENT_SS, 0x36) \
+ _ (LOCK, 0xf0) \
+ _ (REPZ, 0xf3) \
+ _ (REPNZ, 0xf2)
+
+#define foreach_x86_insn_parse_flag \
+ /* Parse in 32/64-bit mode. */ \
+ _ (PARSE_32_BIT, 0) \
+ _ (PARSE_64_BIT, 0) \
+ _ (IS_ADDRESS, 0) \
+ /* regs[1/2] is a valid base/index register */ \
+ _ (HAS_BASE, 0) \
+ _ (HAS_INDEX, 0) \
+ /* rex w bit */ \
+ _ (OPERAND_SIZE_64, 0)
+
+typedef enum {
+#define _(f,o) X86_INSN_FLAG_BIT_##f,
+ foreach_x86_insn_parse_flag
+ foreach_x86_legacy_prefix
+#undef _
+} x86_insn_parse_flag_bit_t;
+
+typedef enum {
+#define _(f,o) X86_INSN_##f = 1 << X86_INSN_FLAG_BIT_##f,
+ foreach_x86_insn_parse_flag
+ foreach_x86_legacy_prefix
+#undef _
+} x86_insn_parse_flag_t;
+
+typedef struct {
+ /* Registers in instruction.
+ [0] is modrm reg field
+ [1] is base reg
+ [2] is index reg. */
+ u8 regs[3];
+
+ /* Scale for index register. */
+ u8 log2_index_scale : 2;
+ u8 log2_effective_operand_bytes : 3;
+ u8 log2_effective_address_bytes : 3;
+
+ i32 displacement;
+
+ /* Parser flags: set of x86_insn_parse_flag_t enums. */
+ u32 flags;
+
+ i64 immediate;
+
+ x86_insn_t insn;
+} x86_insn_parse_t;
+
+u8 * x86_insn_parse (x86_insn_parse_t * p, u8 * code_start);
+format_function_t format_x86_insn_parse;
+
+#endif /* included_asm_x86_h */