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 + -
显示快捷键?