x86reg.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,979 行 · 第 1/5 页

C
1,979
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  X86 registers structures and procedures
*               for input/output/expressions.
*
****************************************************************************/


#include <stddef.h>
#include <string.h>
#include <ctype.h>
#include "x86.h"
#include "x86types.h"
#include "madregs.h"

#define NUM_ELTS( name ) (sizeof( name ) / sizeof( name[0] ) )

typedef enum {
    RF_NONE,
    RF_GPREG  = 0x1,
    RF_FPREG  = 0x2,
    RF_MMREG  = 0x4,
    RF_XMMREG = 0x8,
} register_flags;

#define REG( p, name, type, start, size, flags, sublist, cpulevel, fpulevel ) \
    const x86_reg_info p##_##name = { { #name, X86T_##type, start, size,    \
                                    RF_##flags##REG }, sublist, cpulevel, fpulevel };

#define CPU( name, type, basereg, startbit, size, sublist, cpulevel )   \
    REG( CPU, name, type, offsetof( mad_registers, x86.cpu.basereg )*8+startbit,        \
        size, GP, sublist, cpulevel, LX )

#define CPU_FLAG( name, cpulevel )      \
    CPU( name, BYTE, efl, SHIFT_##name, LEN_##name, NULL, cpulevel )

#define FPU( name, type, basereg, startbit, size, sublist, fpulevel )   \
    REG( FPU, name, type, offsetof( mad_registers, x86.fpu.basereg )*8+startbit,        \
        size, FP, sublist, LX, fpulevel )

#define FPU_STK( num )  \
    FPU( st##num, EXTENDED, reg[num], 0, 80, NULL, L1 )

#define FPU_SW( name, fpulevel )        \
    FPU( name, BYTE, sw, SHIFT_##name, LEN_##name, NULL, fpulevel )

#define FPU_CW( name, fpulevel )        \
    FPU( name, BYTE, cw, SHIFT_##name, LEN_##name, NULL, fpulevel )

#define MMX( num )      \
    REG( MMX, mm##num, U64, offsetof( mad_registers, x86.mmx.mm[num] )*8,\
    64, MM, MMXSubList##num, L5, LX )

#define XMM( num )      \
    REG( XMM, xmm##num, U128, offsetof( mad_registers, x86.xmm.xmm[num] )*8,\
    128, XMM, XMMSubList##num, L6, LX )

#define MXCSR( name )        \
    REG( XMM_mxcsr, name, BYTE, offsetof( mad_registers, x86.xmm.mxcsr )*8 + SHIFT_mxcsr_##name, \
        LEN_mxcsr_##name, XMM, NULL, L6, LX )


/* forward definitions */
static const x86_reg_info       * const EFLRegList[];
static const x86_reg_info       * const SWRegList[];
static const x86_reg_info       * const CWRegList[];
static const x86_reg_info       * const MXCSRRegList[];

/* register definitions */
CPU( eax, DWORD, eax, 0, 32, NULL, L3 );
CPU( ebx, DWORD, ebx, 0, 32, NULL, L3 );
CPU( ecx, DWORD, ecx, 0, 32, NULL, L3 );
CPU( edx, DWORD, edx, 0, 32, NULL, L3 );
CPU( esi, DWORD, esi, 0, 32, NULL, L3 );
CPU( edi, DWORD, edi, 0, 32, NULL, L3 );
CPU( ebp, DWORD, ebp, 0, 32, NULL, L3 );
CPU( esp, DWORD, esp, 0, 32, NULL, L3 );
CPU( eip, DWORD, eip, 0, 32, NULL, L3 );
CPU( efl, DWORD, efl, 0, 32, &EFLRegList[0], L3 );

CPU(  ax,  WORD, eax, 0, 16, NULL, L1 );
CPU(  bx,  WORD, ebx, 0, 16, NULL, L1 );
CPU(  cx,  WORD, ecx, 0, 16, NULL, L1 );
CPU(  dx,  WORD, edx, 0, 16, NULL, L1 );
CPU(  si,  WORD, esi, 0, 16, NULL, L1 );
CPU(  di,  WORD, edi, 0, 16, NULL, L1 );
CPU(  bp,  WORD, ebp, 0, 16, NULL, L1 );
CPU(  sp,  WORD, esp, 0, 16, NULL, L1 );
CPU(  ip,  WORD, eip, 0, 16, NULL, L1 );
CPU(  fl,  WORD, efl, 0, 16, &EFLRegList[2], L1 );

CPU(  al,  BYTE, eax, 0,  8, NULL, L1 );
CPU(  bl,  BYTE, ebx, 0,  8, NULL, L1 );
CPU(  cl,  BYTE, ecx, 0,  8, NULL, L1 );
CPU(  dl,  BYTE, edx, 0,  8, NULL, L1 );
CPU(  ah,  BYTE, eax, 8,  8, NULL, L1 );
CPU(  bh,  BYTE, ebx, 8,  8, NULL, L1 );
CPU(  ch,  BYTE, ecx, 8,  8, NULL, L1 );
CPU(  dh,  BYTE, edx, 8,  8, NULL, L1 );

CPU(  cs,  WORD,  cs, 0, 16, NULL, L1 );
CPU(  ds,  WORD,  ds, 0, 16, NULL, L1 );
CPU(  es,  WORD,  es, 0, 16, NULL, L1 );
CPU(  ss,  WORD,  ss, 0, 16, NULL, L1 );
CPU(  fs,  WORD,  fs, 0, 16, NULL, L3 );
CPU(  gs,  WORD,  gs, 0, 16, NULL, L3 );

CPU_FLAG( vm,   L3 );
CPU_FLAG( rf,   L3 );
CPU_FLAG( nt,   L2 );
CPU_FLAG( iopl, L2 );
CPU_FLAG( o,    L1 );
CPU_FLAG( d,    L1 );
CPU_FLAG( i,    L1 );
CPU_FLAG( s,    L1 );
CPU_FLAG( z,    L1 );
CPU_FLAG( a,    L1 );
CPU_FLAG( p,    L1 );
CPU_FLAG( c,    L1 );

FPU_STK( 0 );
FPU_STK( 1 );
FPU_STK( 2 );
FPU_STK( 3 );
FPU_STK( 4 );
FPU_STK( 5 );
FPU_STK( 6 );
FPU_STK( 7 );

FPU( sw,  WORD, sw,  0, 16, SWRegList, L1 );
FPU( cw,  WORD, cw,  0, 16, CWRegList, L1 );
FPU( tag, WORD, tag, 0, 16, NULL, L1 );
FPU( tag0, BIT, tag, 0,  2, NULL, L1 );
FPU( tag1, BIT, tag, 2,  2, NULL, L1 );
FPU( tag2, BIT, tag, 4,  2, NULL, L1 );
FPU( tag3, BIT, tag, 6,  2, NULL, L1 );
FPU( tag4, BIT, tag, 8,  2, NULL, L1 );
FPU( tag5, BIT, tag,10,  2, NULL, L1 );
FPU( tag6, BIT, tag,12,  2, NULL, L1 );
FPU( tag7, BIT, tag,14,  2, NULL, L1 );
FPU( iptr, F32_PTR, ip_err, 0, 64, NULL, L1 );
FPU( optr, F32_PTR, op_err, 0, 64, NULL, L1 );

FPU_SW( ie, L1 );
FPU_SW( de, L1 );
FPU_SW( ze, L1 );
FPU_SW( oe, L1 );
FPU_SW( ue, L1 );
FPU_SW( pe, L1 );
FPU_SW( sf, L3 );
FPU_SW( c0, L1 );
FPU_SW( es, L1 );
FPU_SW( c1, L1 );
FPU_SW( c2, L1 );
FPU_SW( st, L1 );
FPU_SW( c3, L1 );
FPU_SW( b,  L1 );

FPU_CW( im,  L1 );
FPU_CW( dm,  L1 );
FPU_CW( zm,  L1 );
FPU_CW( om,  L1 );
FPU_CW( um,  L1 );
FPU_CW( pm,  L1 );
FPU_CW( iem, L1 );
FPU_CW( pc,  L1 );
FPU_CW( rc,  L1 );
FPU_CW( ic,  L1 );

/* register list definitions */
static const x86_reg_info * const CPURegList[] = {
    &CPU_eax, &CPU_ebx, &CPU_ecx, &CPU_edx, &CPU_eip,
    &CPU_esi, &CPU_edi, &CPU_esp, &CPU_ebp, &CPU_efl,

    &CPU_ax,  &CPU_bx,  &CPU_cx,  &CPU_dx,  &CPU_ip,
    &CPU_si,  &CPU_di,  &CPU_sp,  &CPU_bp,  &CPU_fl,

    &CPU_al,  &CPU_bl,  &CPU_cl,  &CPU_dl,
    &CPU_ah,  &CPU_bh,  &CPU_ch,  &CPU_dh,

    &CPU_cs,  &CPU_ds,  &CPU_es,  &CPU_ss,  &CPU_fs,  &CPU_gs,
NULL };

static const x86_reg_info * const EFLRegList[] = {
    &CPU_vm, &CPU_rf, &CPU_nt, &CPU_iopl,
    &CPU_o, &CPU_d, &CPU_i, &CPU_s, &CPU_z, &CPU_a, &CPU_p, &CPU_c,
NULL };

static const x86_reg_info * const FPURegList[] = {
    &FPU_st0, &FPU_st1, &FPU_st2, &FPU_st3,
    &FPU_st4, &FPU_st5, &FPU_st6, &FPU_st7,
    &FPU_sw,  &FPU_cw,  &FPU_tag,
NULL };

static const x86_reg_info * const SWRegList[] = {
    &FPU_ie, &FPU_de, &FPU_ze, &FPU_oe, &FPU_ue, &FPU_pe,
    &FPU_sf, &FPU_c0, &FPU_es, &FPU_c1, &FPU_c2, &FPU_st, &FPU_c3, &FPU_b,
NULL };

static const x86_reg_info * const CWRegList[] = {
    &FPU_im, &FPU_dm, &FPU_zm, &FPU_om, &FPU_um, &FPU_pm,
    &FPU_iem, &FPU_pc, &FPU_rc, &FPU_ic,
NULL };

#define X86T_b  X86T_BYTE
#define X86T_w  X86T_WORD
#define X86T_d  X86T_DWORD
#define X86T_q  X86T_QWORD
#define MMXS_b  8
#define MMXS_w  16
#define MMXS_d  32
#define MMXS_q  64
#define XMMS_b  8
#define XMMS_w  16
#define XMMS_d  32
#define XMMS_q  64

#define MMX_SUBREG( s, i, reg ) \
    REG( MMX##reg, s##i, s,     \
    offsetof( mad_registers, x86.mmx.mm[reg] )*8 + MMXS_##s * i,\
    MMXS_##s, MM, NULL, L5, LX )

#define XMM_SUBREG( s, i, reg ) \
    REG( XMM##reg, s##i, s,     \
    offsetof( mad_registers, x86.xmm.xmm[reg] )*8 + XMMS_##s * i,\
    XMMS_##s, XMM, NULL, L6, LX )

#define MMX_SUBLIST( n )        \
        MMX_SUBREG( b, 0, n )   \
        MMX_SUBREG( b, 1, n )   \
        MMX_SUBREG( b, 2, n )   \
        MMX_SUBREG( b, 3, n )   \
        MMX_SUBREG( b, 4, n )   \
        MMX_SUBREG( b, 5, n )   \
        MMX_SUBREG( b, 6, n )   \
        MMX_SUBREG( b, 7, n )   \
        MMX_SUBREG( w, 0, n )   \
        MMX_SUBREG( w, 1, n )   \
        MMX_SUBREG( w, 2, n )   \
        MMX_SUBREG( w, 3, n )   \
        MMX_SUBREG( d, 0, n )   \
        MMX_SUBREG( d, 1, n )   \
        MMX_SUBREG( q, 0, n )   \
                                \
        static const x86_reg_info * const MMXSubList##n[] = {           \
            &MMX##n##_b0, &MMX##n##_b1, &MMX##n##_b2, &MMX##n##_b3,     \
            &MMX##n##_b4, &MMX##n##_b5, &MMX##n##_b6, &MMX##n##_b7,     \
            &MMX##n##_w0, &MMX##n##_w1, &MMX##n##_w2, &MMX##n##_w3,     \
            &MMX##n##_d0, &MMX##n##_d1, &MMX##n##_q0, NULL };

MMX_SUBLIST( 0 )
MMX_SUBLIST( 1 )
MMX_SUBLIST( 2 )
MMX_SUBLIST( 3 )
MMX_SUBLIST( 4 )
MMX_SUBLIST( 5 )
MMX_SUBLIST( 6 )
MMX_SUBLIST( 7 )

MMX( 0 );
MMX( 1 );
MMX( 2 );
MMX( 3 );
MMX( 4 );
MMX( 5 );
MMX( 6 );
MMX( 7 );

static const x86_reg_info * const MMXRegList[] = {
    &MMX_mm0, &MMX_mm1, &MMX_mm2, &MMX_mm3,
    &MMX_mm4, &MMX_mm5, &MMX_mm6, &MMX_mm7,
NULL };


#define XMM_SUBLIST( n )        \
        XMM_SUBREG( b, 0, n )   \
        XMM_SUBREG( b, 1, n )   \
        XMM_SUBREG( b, 2, n )   \
        XMM_SUBREG( b, 3, n )   \
        XMM_SUBREG( b, 4, n )   \
        XMM_SUBREG( b, 5, n )   \
        XMM_SUBREG( b, 6, n )   \
        XMM_SUBREG( b, 7, n )   \
        XMM_SUBREG( b, 8, n )   \
        XMM_SUBREG( b, 9, n )   \
        XMM_SUBREG( b, 10, n )  \
        XMM_SUBREG( b, 11, n )  \
        XMM_SUBREG( b, 12, n )  \
        XMM_SUBREG( b, 13, n )  \
        XMM_SUBREG( b, 14, n )  \
        XMM_SUBREG( b, 15, n )  \
        XMM_SUBREG( w, 0, n )   \
        XMM_SUBREG( w, 1, n )   \
        XMM_SUBREG( w, 2, n )   \
        XMM_SUBREG( w, 3, n )   \
        XMM_SUBREG( w, 4, n )   \
        XMM_SUBREG( w, 5, n )   \
        XMM_SUBREG( w, 6, n )   \
        XMM_SUBREG( w, 7, n )   \
        XMM_SUBREG( d, 0, n )   \
        XMM_SUBREG( d, 1, n )   \
        XMM_SUBREG( d, 2, n )   \
        XMM_SUBREG( d, 3, n )   \
        XMM_SUBREG( q, 0, n )   \
        XMM_SUBREG( q, 1, n )   \
                                \
        static const x86_reg_info * const XMMSubList##n[] = {           \
            &XMM##n##_b0, &XMM##n##_b1, &XMM##n##_b2, &XMM##n##_b3,     \
            &XMM##n##_b4, &XMM##n##_b5, &XMM##n##_b6, &XMM##n##_b7,     \
            &XMM##n##_b8, &XMM##n##_b9, &XMM##n##_b10,&XMM##n##_b11,    \
            &XMM##n##_b12,&XMM##n##_b13,&XMM##n##_b14,&XMM##n##_b15,    \
            &XMM##n##_w0, &XMM##n##_w1, &XMM##n##_w2, &XMM##n##_w3,     \
            &XMM##n##_w4, &XMM##n##_w5, &XMM##n##_w6, &XMM##n##_w7,     \
            &XMM##n##_d0, &XMM##n##_d1, &XMM##n##_d2, &XMM##n##_d3,     \
            &XMM##n##_q0, &XMM##n##_q1, NULL };

XMM_SUBLIST( 0 )
XMM_SUBLIST( 1 )
XMM_SUBLIST( 2 )
XMM_SUBLIST( 3 )
XMM_SUBLIST( 4 )
XMM_SUBLIST( 5 )
XMM_SUBLIST( 6 )
XMM_SUBLIST( 7 )

XMM( 0 );
XMM( 1 );
XMM( 2 );
XMM( 3 );
XMM( 4 );
XMM( 5 );
XMM( 6 );
XMM( 7 );

/* MXCSR register */
REG( XMM, mxcsr, DWORD, offsetof( mad_registers, x86.xmm.mxcsr )*8, \
    32, XMM, MXCSRRegList, L6, LX )

MXCSR( ie );
MXCSR( de );
MXCSR( ze );
MXCSR( oe );
MXCSR( ue );
MXCSR( pe );
MXCSR( daz );
MXCSR( im );
MXCSR( dm );
MXCSR( zm );
MXCSR( om );
MXCSR( um );
MXCSR( pm );
MXCSR( rc );
MXCSR( fz );

static const x86_reg_info * const XMMRegList[] = {
    &XMM_xmm0, &XMM_xmm1, &XMM_xmm2, &XMM_xmm3,
    &XMM_xmm4, &XMM_xmm5, &XMM_xmm6, &XMM_xmm7,
    &XMM_mxcsr,
NULL };

static const x86_reg_info * const MXCSRRegList[] = {
    &XMM_mxcsr_ie, &XMM_mxcsr_de, &XMM_mxcsr_ze, &XMM_mxcsr_oe, &XMM_mxcsr_ue, &XMM_mxcsr_pe,
    &XMM_mxcsr_daz,
    &XMM_mxcsr_im, &XMM_mxcsr_dm, &XMM_mxcsr_zm, &XMM_mxcsr_om, &XMM_mxcsr_um, &XMM_mxcsr_pm,
    &XMM_mxcsr_rc, &XMM_mxcsr_fz,
NULL };



struct mad_reg_set_data {
    mad_status (*get_piece)( const mad_registers *mr, unsigned piece, char **descript, unsigned *max_descript, const mad_reg_info **reg, mad_type_handle *disp_type, unsigned *max_value );
    const mad_toggle_strings    *togglelist;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?