1 # 2 # x86 register and target modifier recognition 3 # 4 # Copyright (C) 2002-2007 Peter Johnson 5 # 6 # Redistribution and use in source and binary forms, with or without 7 # modification, are permitted provided that the following conditions 8 # are met: 9 # 1. Redistributions of source code must retain the above copyright 10 # notice, this list of conditions and the following disclaimer. 11 # 2. Redistributions in binary form must reproduce the above copyright 12 # notice, this list of conditions and the following disclaimer in the 13 # documentation and/or other materials provided with the distribution. 14 # 15 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 16 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 19 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 # POSSIBILITY OF SUCH DAMAGE. 26 %{ 27 #include <util.h> 28 29 #include <ctype.h> 30 #include <libyasm.h> 31 #include <libyasm/phash.h> 32 33 #include "modules/arch/x86/x86arch.h" 34 35 enum regtmod_type { 36 REG = 1, 37 REGGROUP, 38 SEGREG, 39 TARGETMOD 40 }; 41 %} 42 %ignore-case 43 %language=ANSI-C 44 %compare-strncmp 45 %readonly-tables 46 %enum 47 %struct-type 48 %define hash-function-name regtmod_hash 49 %define lookup-function-name regtmod_find 50 struct regtmod_parse_data { 51 const char *name; 52 unsigned int type:8; /* regtmod_type */ 53 54 /* REG: register size 55 * SEGREG: prefix encoding 56 * Others: 0 57 */ 58 unsigned int size_prefix:8; 59 60 /* REG: register index 61 * REGGROUP: register group type 62 * SEGREG: register encoding 63 * TARGETMOD: target modifier 64 */ 65 unsigned int data:8; 66 67 /* REG: required bits setting 68 * SEGREG: BITS in which the segment is ignored 69 * Others: 0 70 */ 71 unsigned int bits:8; 72 }; 73 %% 74 # 75 # control, debug, and test registers 76 # 77 cr0, REG, X86_CRREG, 0, 0 78 cr2, REG, X86_CRREG, 2, 0 79 cr3, REG, X86_CRREG, 3, 0 80 cr4, REG, X86_CRREG, 4, 0 81 cr8, REG, X86_CRREG, 8, 64 82 # 83 dr0, REG, X86_DRREG, 0, 0 84 dr1, REG, X86_DRREG, 1, 0 85 dr2, REG, X86_DRREG, 2, 0 86 dr3, REG, X86_DRREG, 3, 0 87 dr4, REG, X86_DRREG, 4, 0 88 dr5, REG, X86_DRREG, 5, 0 89 dr6, REG, X86_DRREG, 6, 0 90 dr7, REG, X86_DRREG, 7, 0 91 # 92 tr0, REG, X86_TRREG, 0, 0 93 tr1, REG, X86_TRREG, 1, 0 94 tr2, REG, X86_TRREG, 2, 0 95 tr3, REG, X86_TRREG, 3, 0 96 tr4, REG, X86_TRREG, 4, 0 97 tr5, REG, X86_TRREG, 5, 0 98 tr6, REG, X86_TRREG, 6, 0 99 tr7, REG, X86_TRREG, 7, 0 100 # 101 # floating point, MMX, and SSE/SSE2 registers 102 # 103 st0, REG, X86_FPUREG, 0, 0 104 st1, REG, X86_FPUREG, 1, 0 105 st2, REG, X86_FPUREG, 2, 0 106 st3, REG, X86_FPUREG, 3, 0 107 st4, REG, X86_FPUREG, 4, 0 108 st5, REG, X86_FPUREG, 5, 0 109 st6, REG, X86_FPUREG, 6, 0 110 st7, REG, X86_FPUREG, 7, 0 111 # 112 mm0, REG, X86_MMXREG, 0, 0 113 mm1, REG, X86_MMXREG, 1, 0 114 mm2, REG, X86_MMXREG, 2, 0 115 mm3, REG, X86_MMXREG, 3, 0 116 mm4, REG, X86_MMXREG, 4, 0 117 mm5, REG, X86_MMXREG, 5, 0 118 mm6, REG, X86_MMXREG, 6, 0 119 mm7, REG, X86_MMXREG, 7, 0 120 # 121 xmm0, REG, X86_XMMREG, 0, 0 122 xmm1, REG, X86_XMMREG, 1, 0 123 xmm2, REG, X86_XMMREG, 2, 0 124 xmm3, REG, X86_XMMREG, 3, 0 125 xmm4, REG, X86_XMMREG, 4, 0 126 xmm5, REG, X86_XMMREG, 5, 0 127 xmm6, REG, X86_XMMREG, 6, 0 128 xmm7, REG, X86_XMMREG, 7, 0 129 xmm8, REG, X86_XMMREG, 8, 64 130 xmm9, REG, X86_XMMREG, 9, 64 131 xmm10, REG, X86_XMMREG, 10, 64 132 xmm11, REG, X86_XMMREG, 11, 64 133 xmm12, REG, X86_XMMREG, 12, 64 134 xmm13, REG, X86_XMMREG, 13, 64 135 xmm14, REG, X86_XMMREG, 14, 64 136 xmm15, REG, X86_XMMREG, 15, 64 137 # AVX registers 138 ymm0, REG, X86_YMMREG, 0, 0 139 ymm1, REG, X86_YMMREG, 1, 0 140 ymm2, REG, X86_YMMREG, 2, 0 141 ymm3, REG, X86_YMMREG, 3, 0 142 ymm4, REG, X86_YMMREG, 4, 0 143 ymm5, REG, X86_YMMREG, 5, 0 144 ymm6, REG, X86_YMMREG, 6, 0 145 ymm7, REG, X86_YMMREG, 7, 0 146 ymm8, REG, X86_YMMREG, 8, 64 147 ymm9, REG, X86_YMMREG, 9, 64 148 ymm10, REG, X86_YMMREG, 10, 64 149 ymm11, REG, X86_YMMREG, 11, 64 150 ymm12, REG, X86_YMMREG, 12, 64 151 ymm13, REG, X86_YMMREG, 13, 64 152 ymm14, REG, X86_YMMREG, 14, 64 153 ymm15, REG, X86_YMMREG, 15, 64 154 # 155 # integer registers 156 # 157 rax, REG, X86_REG64, 0, 64 158 rcx, REG, X86_REG64, 1, 64 159 rdx, REG, X86_REG64, 2, 64 160 rbx, REG, X86_REG64, 3, 64 161 rsp, REG, X86_REG64, 4, 64 162 rbp, REG, X86_REG64, 5, 64 163 rsi, REG, X86_REG64, 6, 64 164 rdi, REG, X86_REG64, 7, 64 165 r8, REG, X86_REG64, 8, 64 166 r9, REG, X86_REG64, 9, 64 167 r10, REG, X86_REG64, 10, 64 168 r11, REG, X86_REG64, 11, 64 169 r12, REG, X86_REG64, 12, 64 170 r13, REG, X86_REG64, 13, 64 171 r14, REG, X86_REG64, 14, 64 172 r15, REG, X86_REG64, 15, 64 173 # 174 eax, REG, X86_REG32, 0, 0 175 ecx, REG, X86_REG32, 1, 0 176 edx, REG, X86_REG32, 2, 0 177 ebx, REG, X86_REG32, 3, 0 178 esp, REG, X86_REG32, 4, 0 179 ebp, REG, X86_REG32, 5, 0 180 esi, REG, X86_REG32, 6, 0 181 edi, REG, X86_REG32, 7, 0 182 r8d, REG, X86_REG32, 8, 64 183 r9d, REG, X86_REG32, 9, 64 184 r10d, REG, X86_REG32, 10, 64 185 r11d, REG, X86_REG32, 11, 64 186 r12d, REG, X86_REG32, 12, 64 187 r13d, REG, X86_REG32, 13, 64 188 r14d, REG, X86_REG32, 14, 64 189 r15d, REG, X86_REG32, 15, 64 190 # 191 ax, REG, X86_REG16, 0, 0 192 cx, REG, X86_REG16, 1, 0 193 dx, REG, X86_REG16, 2, 0 194 bx, REG, X86_REG16, 3, 0 195 sp, REG, X86_REG16, 4, 0 196 bp, REG, X86_REG16, 5, 0 197 si, REG, X86_REG16, 6, 0 198 di, REG, X86_REG16, 7, 0 199 r8w, REG, X86_REG16, 8, 64 200 r9w, REG, X86_REG16, 9, 64 201 r10w, REG, X86_REG16, 10, 64 202 r11w, REG, X86_REG16, 11, 64 203 r12w, REG, X86_REG16, 12, 64 204 r13w, REG, X86_REG16, 13, 64 205 r14w, REG, X86_REG16, 14, 64 206 r15w, REG, X86_REG16, 15, 64 207 # 208 al, REG, X86_REG8, 0, 0 209 cl, REG, X86_REG8, 1, 0 210 dl, REG, X86_REG8, 2, 0 211 bl, REG, X86_REG8, 3, 0 212 ah, REG, X86_REG8, 4, 0 213 ch, REG, X86_REG8, 5, 0 214 dh, REG, X86_REG8, 6, 0 215 bh, REG, X86_REG8, 7, 0 216 r8b, REG, X86_REG8, 8, 64 217 r9b, REG, X86_REG8, 9, 64 218 r10b, REG, X86_REG8, 10, 64 219 r11b, REG, X86_REG8, 11, 64 220 r12b, REG, X86_REG8, 12, 64 221 r13b, REG, X86_REG8, 13, 64 222 r14b, REG, X86_REG8, 14, 64 223 r15b, REG, X86_REG8, 15, 64 224 # 225 spl, REG, X86_REG8X, 4, 64 226 bpl, REG, X86_REG8X, 5, 64 227 sil, REG, X86_REG8X, 6, 64 228 dil, REG, X86_REG8X, 7, 64 229 # 230 rip, REG, X86_RIP, 0, 64 231 # 232 # floating point, MMX, and SSE/SSE2 registers 233 # 234 st, REGGROUP, 0, X86_FPUREG, 0 235 mm, REGGROUP, 0, X86_MMXREG, 0 236 xmm, REGGROUP, 0, X86_XMMREG, 0 237 ymm, REGGROUP, 0, X86_YMMREG, 0 238 # 239 # segment registers 240 # 241 es, SEGREG, 0x26, 0x00, 64 242 cs, SEGREG, 0x2e, 0x01, 0 243 ss, SEGREG, 0x36, 0x02, 64 244 ds, SEGREG, 0x3e, 0x03, 64 245 fs, SEGREG, 0x64, 0x04, 0 246 gs, SEGREG, 0x65, 0x05, 0 247 # 248 # target modifiers 249 # 250 near, TARGETMOD, 0, X86_NEAR, 0 251 short, TARGETMOD, 0, X86_SHORT, 0 252 far, TARGETMOD, 0, X86_FAR, 0 253 to, TARGETMOD, 0, X86_TO, 0 254 %% 255 256 yasm_arch_regtmod 257 yasm_x86__parse_check_regtmod(yasm_arch *arch, const char *id, size_t id_len, 258 uintptr_t *data) 259 { 260 yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch; 261 /*@null@*/ const struct regtmod_parse_data *pdata; 262 size_t i; 263 static char lcaseid[8]; 264 unsigned int bits; 265 yasm_arch_regtmod type; 266 267 if (id_len > 7) 268 return YASM_ARCH_NOTREGTMOD; 269 for (i=0; i<id_len; i++) 270 lcaseid[i] = tolower(id[i]); 271 lcaseid[id_len] = '\0'; 272 273 pdata = regtmod_find(lcaseid, id_len); 274 if (!pdata) 275 return YASM_ARCH_NOTREGTMOD; 276 277 type = (yasm_arch_regtmod)pdata->type; 278 bits = pdata->bits; 279 280 if (type == YASM_ARCH_REG && bits != 0 && arch_x86->mode_bits != bits) { 281 yasm_warn_set(YASM_WARN_GENERAL, 282 N_("`%s' is a register in %u-bit mode"), id, bits); 283 return YASM_ARCH_NOTREGTMOD; 284 } 285 286 if (type == YASM_ARCH_SEGREG && bits != 0 && arch_x86->mode_bits == bits) { 287 yasm_warn_set(YASM_WARN_GENERAL, 288 N_("`%s' segment register ignored in %u-bit mode"), id, 289 bits); 290 } 291 292 if (type == YASM_ARCH_SEGREG) 293 *data = (pdata->size_prefix<<8) | pdata->data; 294 else 295 *data = pdata->size_prefix | pdata->data; 296 return type; 297 } 298