Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2015 Cisco and/or its affiliates. |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at: |
| 6 | * |
| 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | * |
| 9 | * Unless required by applicable law or agreed to in writing, software |
| 10 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | * See the License for the specific language governing permissions and |
| 13 | * limitations under the License. |
| 14 | */ |
| 15 | #ifndef included_asm_x86_h |
| 16 | #define included_asm_x86_h |
| 17 | |
| 18 | #include <vppinfra/format.h> |
| 19 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 20 | typedef union |
| 21 | { |
| 22 | struct |
| 23 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 24 | u8 code; |
| 25 | u8 type; |
| 26 | }; |
| 27 | u8 data[2]; |
| 28 | } x86_insn_operand_t; |
| 29 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 30 | typedef struct |
| 31 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 32 | /* Instruction name. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 33 | char *name; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 34 | |
| 35 | /* X86 instructions may have up to 3 operands. */ |
| 36 | x86_insn_operand_t operands[3]; |
| 37 | |
| 38 | u16 flags; |
| 39 | #define X86_INSN_FLAG_DEFAULT_64_BIT (1 << 0) |
| 40 | #define X86_INSN_FLAG_SET_SSE_GROUP(n) ((n) << 5) |
| 41 | #define X86_INSN_FLAG_GET_SSE_GROUP(f) (((f) >> 5) & 0x1f) |
| 42 | #define X86_INSN_FLAG_SET_MODRM_REG_GROUP(n) (((n) & 0x3f) << 10) |
| 43 | #define X86_INSN_FLAG_GET_MODRM_REG_GROUP(f) (((f) >> 10) & 0x3f) |
| 44 | } x86_insn_t; |
| 45 | |
| 46 | always_inline uword |
| 47 | x86_insn_operand_is_valid (x86_insn_t * i, uword o) |
| 48 | { |
| 49 | ASSERT (o < ARRAY_LEN (i->operands)); |
| 50 | return i->operands[o].code != '_'; |
| 51 | } |
| 52 | |
| 53 | #define foreach_x86_legacy_prefix \ |
| 54 | _ (OPERAND_SIZE, 0x66) \ |
| 55 | _ (ADDRESS_SIZE, 0x67) \ |
| 56 | _ (SEGMENT_CS, 0x2e) \ |
| 57 | _ (SEGMENT_DS, 0x3e) \ |
| 58 | _ (SEGMENT_ES, 0x26) \ |
| 59 | _ (SEGMENT_FS, 0x64) \ |
| 60 | _ (SEGMENT_GS, 0x65) \ |
| 61 | _ (SEGMENT_SS, 0x36) \ |
| 62 | _ (LOCK, 0xf0) \ |
| 63 | _ (REPZ, 0xf3) \ |
| 64 | _ (REPNZ, 0xf2) |
| 65 | |
| 66 | #define foreach_x86_insn_parse_flag \ |
| 67 | /* Parse in 32/64-bit mode. */ \ |
| 68 | _ (PARSE_32_BIT, 0) \ |
| 69 | _ (PARSE_64_BIT, 0) \ |
| 70 | _ (IS_ADDRESS, 0) \ |
| 71 | /* regs[1/2] is a valid base/index register */ \ |
| 72 | _ (HAS_BASE, 0) \ |
| 73 | _ (HAS_INDEX, 0) \ |
| 74 | /* rex w bit */ \ |
| 75 | _ (OPERAND_SIZE_64, 0) |
| 76 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 77 | typedef enum |
| 78 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 79 | #define _(f,o) X86_INSN_FLAG_BIT_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 80 | foreach_x86_insn_parse_flag foreach_x86_legacy_prefix |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 81 | #undef _ |
| 82 | } x86_insn_parse_flag_bit_t; |
| 83 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 84 | typedef enum |
| 85 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 86 | #define _(f,o) X86_INSN_##f = 1 << X86_INSN_FLAG_BIT_##f, |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 87 | foreach_x86_insn_parse_flag foreach_x86_legacy_prefix |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 88 | #undef _ |
| 89 | } x86_insn_parse_flag_t; |
| 90 | |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 91 | typedef struct |
| 92 | { |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 93 | /* Registers in instruction. |
| 94 | [0] is modrm reg field |
| 95 | [1] is base reg |
| 96 | [2] is index reg. */ |
| 97 | u8 regs[3]; |
| 98 | |
| 99 | /* Scale for index register. */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 100 | u8 log2_index_scale:2; |
| 101 | u8 log2_effective_operand_bytes:3; |
| 102 | u8 log2_effective_address_bytes:3; |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 103 | |
| 104 | i32 displacement; |
| 105 | |
| 106 | /* Parser flags: set of x86_insn_parse_flag_t enums. */ |
| 107 | u32 flags; |
| 108 | |
| 109 | i64 immediate; |
| 110 | |
| 111 | x86_insn_t insn; |
| 112 | } x86_insn_parse_t; |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 113 | |
| 114 | u8 *x86_insn_parse (x86_insn_parse_t * p, u8 * code_start); |
Ed Warnicke | cb9cada | 2015-12-08 15:45:58 -0700 | [diff] [blame] | 115 | format_function_t format_x86_insn_parse; |
| 116 | |
| 117 | #endif /* included_asm_x86_h */ |
Dave Barach | c379999 | 2016-08-15 11:12:27 -0400 | [diff] [blame] | 118 | |
| 119 | /* |
| 120 | * fd.io coding-style-patch-verification: ON |
| 121 | * |
| 122 | * Local Variables: |
| 123 | * eval: (c-set-style "gnu") |
| 124 | * End: |
| 125 | */ |