Home | History | Annotate | Download | only in x86
      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