diff options
Diffstat (limited to 'src/vppinfra/asm_x86.h')
-rw-r--r-- | src/vppinfra/asm_x86.h | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/vppinfra/asm_x86.h b/src/vppinfra/asm_x86.h new file mode 100644 index 00000000000..dacef61755c --- /dev/null +++ b/src/vppinfra/asm_x86.h @@ -0,0 +1,125 @@ +/* + * 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 */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |