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 35enum 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 50struct 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# 77cr0, REG, X86_CRREG, 0, 0 78cr2, REG, X86_CRREG, 2, 0 79cr3, REG, X86_CRREG, 3, 0 80cr4, REG, X86_CRREG, 4, 0 81cr8, REG, X86_CRREG, 8, 64 82# 83dr0, REG, X86_DRREG, 0, 0 84dr1, REG, X86_DRREG, 1, 0 85dr2, REG, X86_DRREG, 2, 0 86dr3, REG, X86_DRREG, 3, 0 87dr4, REG, X86_DRREG, 4, 0 88dr5, REG, X86_DRREG, 5, 0 89dr6, REG, X86_DRREG, 6, 0 90dr7, REG, X86_DRREG, 7, 0 91# 92tr0, REG, X86_TRREG, 0, 0 93tr1, REG, X86_TRREG, 1, 0 94tr2, REG, X86_TRREG, 2, 0 95tr3, REG, X86_TRREG, 3, 0 96tr4, REG, X86_TRREG, 4, 0 97tr5, REG, X86_TRREG, 5, 0 98tr6, REG, X86_TRREG, 6, 0 99tr7, REG, X86_TRREG, 7, 0 100# 101# floating point, MMX, and SSE/SSE2 registers 102# 103st0, REG, X86_FPUREG, 0, 0 104st1, REG, X86_FPUREG, 1, 0 105st2, REG, X86_FPUREG, 2, 0 106st3, REG, X86_FPUREG, 3, 0 107st4, REG, X86_FPUREG, 4, 0 108st5, REG, X86_FPUREG, 5, 0 109st6, REG, X86_FPUREG, 6, 0 110st7, REG, X86_FPUREG, 7, 0 111# 112mm0, REG, X86_MMXREG, 0, 0 113mm1, REG, X86_MMXREG, 1, 0 114mm2, REG, X86_MMXREG, 2, 0 115mm3, REG, X86_MMXREG, 3, 0 116mm4, REG, X86_MMXREG, 4, 0 117mm5, REG, X86_MMXREG, 5, 0 118mm6, REG, X86_MMXREG, 6, 0 119mm7, REG, X86_MMXREG, 7, 0 120# 121xmm0, REG, X86_XMMREG, 0, 0 122xmm1, REG, X86_XMMREG, 1, 0 123xmm2, REG, X86_XMMREG, 2, 0 124xmm3, REG, X86_XMMREG, 3, 0 125xmm4, REG, X86_XMMREG, 4, 0 126xmm5, REG, X86_XMMREG, 5, 0 127xmm6, REG, X86_XMMREG, 6, 0 128xmm7, REG, X86_XMMREG, 7, 0 129xmm8, REG, X86_XMMREG, 8, 64 130xmm9, REG, X86_XMMREG, 9, 64 131xmm10, REG, X86_XMMREG, 10, 64 132xmm11, REG, X86_XMMREG, 11, 64 133xmm12, REG, X86_XMMREG, 12, 64 134xmm13, REG, X86_XMMREG, 13, 64 135xmm14, REG, X86_XMMREG, 14, 64 136xmm15, REG, X86_XMMREG, 15, 64 137# AVX registers 138ymm0, REG, X86_YMMREG, 0, 0 139ymm1, REG, X86_YMMREG, 1, 0 140ymm2, REG, X86_YMMREG, 2, 0 141ymm3, REG, X86_YMMREG, 3, 0 142ymm4, REG, X86_YMMREG, 4, 0 143ymm5, REG, X86_YMMREG, 5, 0 144ymm6, REG, X86_YMMREG, 6, 0 145ymm7, REG, X86_YMMREG, 7, 0 146ymm8, REG, X86_YMMREG, 8, 64 147ymm9, REG, X86_YMMREG, 9, 64 148ymm10, REG, X86_YMMREG, 10, 64 149ymm11, REG, X86_YMMREG, 11, 64 150ymm12, REG, X86_YMMREG, 12, 64 151ymm13, REG, X86_YMMREG, 13, 64 152ymm14, REG, X86_YMMREG, 14, 64 153ymm15, REG, X86_YMMREG, 15, 64 154# 155# integer registers 156# 157rax, REG, X86_REG64, 0, 64 158rcx, REG, X86_REG64, 1, 64 159rdx, REG, X86_REG64, 2, 64 160rbx, REG, X86_REG64, 3, 64 161rsp, REG, X86_REG64, 4, 64 162rbp, REG, X86_REG64, 5, 64 163rsi, REG, X86_REG64, 6, 64 164rdi, REG, X86_REG64, 7, 64 165r8, REG, X86_REG64, 8, 64 166r9, REG, X86_REG64, 9, 64 167r10, REG, X86_REG64, 10, 64 168r11, REG, X86_REG64, 11, 64 169r12, REG, X86_REG64, 12, 64 170r13, REG, X86_REG64, 13, 64 171r14, REG, X86_REG64, 14, 64 172r15, REG, X86_REG64, 15, 64 173# 174eax, REG, X86_REG32, 0, 0 175ecx, REG, X86_REG32, 1, 0 176edx, REG, X86_REG32, 2, 0 177ebx, REG, X86_REG32, 3, 0 178esp, REG, X86_REG32, 4, 0 179ebp, REG, X86_REG32, 5, 0 180esi, REG, X86_REG32, 6, 0 181edi, REG, X86_REG32, 7, 0 182r8d, REG, X86_REG32, 8, 64 183r9d, REG, X86_REG32, 9, 64 184r10d, REG, X86_REG32, 10, 64 185r11d, REG, X86_REG32, 11, 64 186r12d, REG, X86_REG32, 12, 64 187r13d, REG, X86_REG32, 13, 64 188r14d, REG, X86_REG32, 14, 64 189r15d, REG, X86_REG32, 15, 64 190# 191ax, REG, X86_REG16, 0, 0 192cx, REG, X86_REG16, 1, 0 193dx, REG, X86_REG16, 2, 0 194bx, REG, X86_REG16, 3, 0 195sp, REG, X86_REG16, 4, 0 196bp, REG, X86_REG16, 5, 0 197si, REG, X86_REG16, 6, 0 198di, REG, X86_REG16, 7, 0 199r8w, REG, X86_REG16, 8, 64 200r9w, REG, X86_REG16, 9, 64 201r10w, REG, X86_REG16, 10, 64 202r11w, REG, X86_REG16, 11, 64 203r12w, REG, X86_REG16, 12, 64 204r13w, REG, X86_REG16, 13, 64 205r14w, REG, X86_REG16, 14, 64 206r15w, REG, X86_REG16, 15, 64 207# 208al, REG, X86_REG8, 0, 0 209cl, REG, X86_REG8, 1, 0 210dl, REG, X86_REG8, 2, 0 211bl, REG, X86_REG8, 3, 0 212ah, REG, X86_REG8, 4, 0 213ch, REG, X86_REG8, 5, 0 214dh, REG, X86_REG8, 6, 0 215bh, REG, X86_REG8, 7, 0 216r8b, REG, X86_REG8, 8, 64 217r9b, REG, X86_REG8, 9, 64 218r10b, REG, X86_REG8, 10, 64 219r11b, REG, X86_REG8, 11, 64 220r12b, REG, X86_REG8, 12, 64 221r13b, REG, X86_REG8, 13, 64 222r14b, REG, X86_REG8, 14, 64 223r15b, REG, X86_REG8, 15, 64 224# 225spl, REG, X86_REG8X, 4, 64 226bpl, REG, X86_REG8X, 5, 64 227sil, REG, X86_REG8X, 6, 64 228dil, REG, X86_REG8X, 7, 64 229# 230rip, REG, X86_RIP, 0, 64 231# 232# floating point, MMX, and SSE/SSE2 registers 233# 234st, REGGROUP, 0, X86_FPUREG, 0 235mm, REGGROUP, 0, X86_MMXREG, 0 236xmm, REGGROUP, 0, X86_XMMREG, 0 237ymm, REGGROUP, 0, X86_YMMREG, 0 238# 239# segment registers 240# 241es, SEGREG, 0x26, 0x00, 64 242cs, SEGREG, 0x2e, 0x01, 0 243ss, SEGREG, 0x36, 0x02, 64 244ds, SEGREG, 0x3e, 0x03, 64 245fs, SEGREG, 0x64, 0x04, 0 246gs, SEGREG, 0x65, 0x05, 0 247# 248# target modifiers 249# 250near, TARGETMOD, 0, X86_NEAR, 0 251short, TARGETMOD, 0, X86_SHORT, 0 252far, TARGETMOD, 0, X86_FAR, 0 253to, TARGETMOD, 0, X86_TO, 0 254%% 255 256yasm_arch_regtmod 257yasm_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