#BEGIN_LEGAL
#
#Copyright (c) 2017 Intel Corporation
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#  
#END_LEGAL
########################################################################
## file: xed-reg-tables.txt
########################################################################

# Need to handle flags, rIP, seg-selectors, pseudo regs
# Also does not specify register width

# What about something like this:
#     op1=GPRv_R():rw
# we need to know what to bind the result to ultimately.
# Just specifying a register is confusing to me. Don't know where to store it.
# Have a "store-here" location for this kind of thing?

#######################################################################
# Expand the generic registers using the effective address size EASZ
#######################################################################
xed_reg_enum_t ArAX()::
EASZ=1 | OUTREG=XED_REG_AX
EASZ=2 | OUTREG=XED_REG_EAX
EASZ=3 | OUTREG=XED_REG_RAX
xed_reg_enum_t ArBX()::
EASZ=1 | OUTREG=XED_REG_BX
EASZ=2 | OUTREG=XED_REG_EBX
EASZ=3 | OUTREG=XED_REG_RBX
xed_reg_enum_t ArCX()::
EASZ=1 | OUTREG=XED_REG_CX
EASZ=2 | OUTREG=XED_REG_ECX
EASZ=3 | OUTREG=XED_REG_RCX
xed_reg_enum_t ArDX()::
EASZ=1 | OUTREG=XED_REG_DX
EASZ=2 | OUTREG=XED_REG_EDX
EASZ=3 | OUTREG=XED_REG_RDX

xed_reg_enum_t ArSI()::
EASZ=1 | OUTREG=XED_REG_SI
EASZ=2 | OUTREG=XED_REG_ESI
EASZ=3 | OUTREG=XED_REG_RSI
xed_reg_enum_t ArDI()::
EASZ=1 | OUTREG=XED_REG_DI
EASZ=2 | OUTREG=XED_REG_EDI
EASZ=3 | OUTREG=XED_REG_RDI
xed_reg_enum_t ArSP()::
EASZ=1 | OUTREG=XED_REG_SP
EASZ=2 | OUTREG=XED_REG_ESP
EASZ=3 | OUTREG=XED_REG_RSP
xed_reg_enum_t ArBP()::
EASZ=1 | OUTREG=XED_REG_BP
EASZ=2 | OUTREG=XED_REG_EBP
EASZ=3 | OUTREG=XED_REG_RBP

xed_reg_enum_t SrSP()::
smode16 | OUTREG=XED_REG_SP
smode32 | OUTREG=XED_REG_ESP
smode64 | OUTREG=XED_REG_RSP
xed_reg_enum_t SrBP()::
smode16 | OUTREG=XED_REG_BP
smode32 | OUTREG=XED_REG_EBP
smode64 | OUTREG=XED_REG_RBP

xed_reg_enum_t Ar8()::
EASZ=1 | OUTREG=XED_REG_R8W
EASZ=2 | OUTREG=XED_REG_R8D
EASZ=3 | OUTREG=XED_REG_R8
xed_reg_enum_t Ar9()::
EASZ=1 | OUTREG=XED_REG_R9W
EASZ=2 | OUTREG=XED_REG_R9D
EASZ=3 | OUTREG=XED_REG_R9
xed_reg_enum_t Ar10()::
EASZ=1 | OUTREG=XED_REG_R10W
EASZ=2 | OUTREG=XED_REG_R10D
EASZ=3 | OUTREG=XED_REG_R10
xed_reg_enum_t Ar11()::
EASZ=1 | OUTREG=XED_REG_R11W
EASZ=2 | OUTREG=XED_REG_R11D
EASZ=3 | OUTREG=XED_REG_R11
xed_reg_enum_t Ar12()::
EASZ=1 | OUTREG=XED_REG_R12W
EASZ=2 | OUTREG=XED_REG_R12D
EASZ=3 | OUTREG=XED_REG_R12
xed_reg_enum_t Ar13()::
EASZ=1 | OUTREG=XED_REG_R13W
EASZ=2 | OUTREG=XED_REG_R13D
EASZ=3 | OUTREG=XED_REG_R13
xed_reg_enum_t Ar14()::
EASZ=1 | OUTREG=XED_REG_R14W
EASZ=2 | OUTREG=XED_REG_R14D
EASZ=3 | OUTREG=XED_REG_R14
xed_reg_enum_t Ar15()::
EASZ=1 | OUTREG=XED_REG_R15W
EASZ=2 | OUTREG=XED_REG_R15D
EASZ=3 | OUTREG=XED_REG_R15

xed_reg_enum_t rIP()::
mode16 | OUTREG=XED_REG_EIP
mode32 | OUTREG=XED_REG_EIP
mode64 | OUTREG=XED_REG_RIP

xed_reg_enum_t rIPa()::
EASZ=2 | OUTREG=XED_REG_EIP
EASZ=3 | OUTREG=XED_REG_RIP

#######################################################################
# Expand the generic registers using the effective address size EOSZ - limit 32b
#######################################################################


xed_reg_enum_t OeAX()::
EOSZ=1 | OUTREG=XED_REG_AX
EOSZ=2 | OUTREG=XED_REG_EAX
EOSZ=3 | OUTREG=XED_REG_EAX


#######################################################################
# Expand the generic registers using the effective address size EOSZ - limit 64b
#######################################################################

xed_reg_enum_t OrAX()::
EOSZ=1 | OUTREG=XED_REG_AX
EOSZ=2 | OUTREG=XED_REG_EAX
EOSZ=3 | OUTREG=XED_REG_RAX
xed_reg_enum_t OrDX()::
EOSZ=1 | OUTREG=XED_REG_DX
EOSZ=2 | OUTREG=XED_REG_EDX
EOSZ=3 | OUTREG=XED_REG_RDX

xed_reg_enum_t OrSP()::
EOSZ=1 | OUTREG=XED_REG_SP
EOSZ=2 | OUTREG=XED_REG_ESP
EOSZ=3 | OUTREG=XED_REG_RSP
xed_reg_enum_t OrBP()::
EOSZ=1 | OUTREG=XED_REG_BP
EOSZ=2 | OUTREG=XED_REG_EBP
EOSZ=3 | OUTREG=XED_REG_RBP


#####################################################

xed_reg_enum_t rFLAGS()::
mode16 | OUTREG=XED_REG_FLAGS
mode32 | OUTREG=XED_REG_EFLAGS
mode64 | OUTREG=XED_REG_RFLAGS

#####################################################


xed_reg_enum_t MMX_R()::
REG=0x0  | OUTREG=XED_REG_MMX0
REG=0x1  | OUTREG=XED_REG_MMX1
REG=0x2  | OUTREG=XED_REG_MMX2
REG=0x3  | OUTREG=XED_REG_MMX3
REG=0x4  | OUTREG=XED_REG_MMX4
REG=0x5  | OUTREG=XED_REG_MMX5
REG=0x6  | OUTREG=XED_REG_MMX6
REG=0x7  | OUTREG=XED_REG_MMX7

xed_reg_enum_t MMX_B()::
RM=0x0  | OUTREG=XED_REG_MMX0
RM=0x1  | OUTREG=XED_REG_MMX1
RM=0x2  | OUTREG=XED_REG_MMX2
RM=0x3  | OUTREG=XED_REG_MMX3
RM=0x4  | OUTREG=XED_REG_MMX4
RM=0x5  | OUTREG=XED_REG_MMX5
RM=0x6  | OUTREG=XED_REG_MMX6
RM=0x7  | OUTREG=XED_REG_MMX7

#################################

# Things that scale with effective operand size 



# When used as the MODRM.REG register
xed_reg_enum_t GPRv_R()::
EOSZ=3 | OUTREG=GPR64_R() 
EOSZ=2 | OUTREG=GPR32_R() 
EOSZ=1 | OUTREG=GPR16_R() 

xed_reg_enum_t GPRv_SB()::
EOSZ=3 | OUTREG=GPR64_SB() 
EOSZ=2 | OUTREG=GPR32_SB() 
EOSZ=1 | OUTREG=GPR16_SB() 

xed_reg_enum_t GPRz_R()::
EOSZ=3 | OUTREG=GPR32_R() 
EOSZ=2 | OUTREG=GPR32_R() 
EOSZ=1 | OUTREG=GPR16_R() 

# When used as the MOD=11/RM register
xed_reg_enum_t GPRv_B()::
EOSZ=3 | OUTREG=GPR64_B() 
EOSZ=2 | OUTREG=GPR32_B() 
EOSZ=1 | OUTREG=GPR16_B() 

xed_reg_enum_t GPRz_B()::
EOSZ=3 | OUTREG=GPR32_B() 
EOSZ=2 | OUTREG=GPR32_B() 
EOSZ=1 | OUTREG=GPR16_B() 

xed_reg_enum_t GPRy_B()::
EOSZ=3 | OUTREG=GPR64_B() 
EOSZ=2 | OUTREG=GPR32_B() 
EOSZ=1 | OUTREG=GPR32_B() 

xed_reg_enum_t GPRy_R()::
EOSZ=3 | OUTREG=GPR64_R() 
EOSZ=2 | OUTREG=GPR32_R() 
EOSZ=1 | OUTREG=GPR32_R() 

#####################################

xed_reg_enum_t GPR64_R()::
REXR=0 REG=0x0  | OUTREG=XED_REG_RAX
REXR=0 REG=0x1  | OUTREG=XED_REG_RCX
REXR=0 REG=0x2  | OUTREG=XED_REG_RDX
REXR=0 REG=0x3  | OUTREG=XED_REG_RBX
REXR=0 REG=0x4  | OUTREG=XED_REG_RSP
REXR=0 REG=0x5  | OUTREG=XED_REG_RBP
REXR=0 REG=0x6  | OUTREG=XED_REG_RSI
REXR=0 REG=0x7  | OUTREG=XED_REG_RDI
REXR=1 REG=0x0  | OUTREG=XED_REG_R8
REXR=1 REG=0x1  | OUTREG=XED_REG_R9
REXR=1 REG=0x2  | OUTREG=XED_REG_R10
REXR=1 REG=0x3  | OUTREG=XED_REG_R11
REXR=1 REG=0x4  | OUTREG=XED_REG_R12
REXR=1 REG=0x5  | OUTREG=XED_REG_R13
REXR=1 REG=0x6  | OUTREG=XED_REG_R14
REXR=1 REG=0x7  | OUTREG=XED_REG_R15


xed_reg_enum_t GPR64_B()::
REXB=0 RM=0x0  | OUTREG=XED_REG_RAX
REXB=0 RM=0x1  | OUTREG=XED_REG_RCX
REXB=0 RM=0x2  | OUTREG=XED_REG_RDX
REXB=0 RM=0x3  | OUTREG=XED_REG_RBX
REXB=0 RM=0x4  | OUTREG=XED_REG_RSP
REXB=0 RM=0x5  | OUTREG=XED_REG_RBP
REXB=0 RM=0x6  | OUTREG=XED_REG_RSI
REXB=0 RM=0x7  | OUTREG=XED_REG_RDI
REXB=1 RM=0x0  | OUTREG=XED_REG_R8
REXB=1 RM=0x1  | OUTREG=XED_REG_R9
REXB=1 RM=0x2  | OUTREG=XED_REG_R10
REXB=1 RM=0x3  | OUTREG=XED_REG_R11
REXB=1 RM=0x4  | OUTREG=XED_REG_R12
REXB=1 RM=0x5  | OUTREG=XED_REG_R13
REXB=1 RM=0x6  | OUTREG=XED_REG_R14
REXB=1 RM=0x7  | OUTREG=XED_REG_R15

xed_reg_enum_t GPR64_SB()::
REXB=0 SRM=0x0  | OUTREG=XED_REG_RAX
REXB=0 SRM=0x1  | OUTREG=XED_REG_RCX
REXB=0 SRM=0x2  | OUTREG=XED_REG_RDX
REXB=0 SRM=0x3  | OUTREG=XED_REG_RBX
REXB=0 SRM=0x4  | OUTREG=XED_REG_RSP
REXB=0 SRM=0x5  | OUTREG=XED_REG_RBP
REXB=0 SRM=0x6  | OUTREG=XED_REG_RSI
REXB=0 SRM=0x7  | OUTREG=XED_REG_RDI
REXB=1 SRM=0x0  | OUTREG=XED_REG_R8
REXB=1 SRM=0x1  | OUTREG=XED_REG_R9
REXB=1 SRM=0x2  | OUTREG=XED_REG_R10
REXB=1 SRM=0x3  | OUTREG=XED_REG_R11
REXB=1 SRM=0x4  | OUTREG=XED_REG_R12
REXB=1 SRM=0x5  | OUTREG=XED_REG_R13
REXB=1 SRM=0x6  | OUTREG=XED_REG_R14
REXB=1 SRM=0x7  | OUTREG=XED_REG_R15



xed_reg_enum_t GPR64_X()::
REXX=0 SIBINDEX=0x0  | OUTREG=XED_REG_RAX
REXX=0 SIBINDEX=0x1  | OUTREG=XED_REG_RCX
REXX=0 SIBINDEX=0x2  | OUTREG=XED_REG_RDX
REXX=0 SIBINDEX=0x3  | OUTREG=XED_REG_RBX
REXX=0 SIBINDEX=0x4  | OUTREG=XED_REG_INVALID
REXX=0 SIBINDEX=0x5  | OUTREG=XED_REG_RBP
REXX=0 SIBINDEX=0x6  | OUTREG=XED_REG_RSI
REXX=0 SIBINDEX=0x7  | OUTREG=XED_REG_RDI
REXX=1 SIBINDEX=0x0  | OUTREG=XED_REG_R8
REXX=1 SIBINDEX=0x1  | OUTREG=XED_REG_R9
REXX=1 SIBINDEX=0x2  | OUTREG=XED_REG_R10
REXX=1 SIBINDEX=0x3  | OUTREG=XED_REG_R11
REXX=1 SIBINDEX=0x4  | OUTREG=XED_REG_R12
REXX=1 SIBINDEX=0x5  | OUTREG=XED_REG_R13
REXX=1 SIBINDEX=0x6  | OUTREG=XED_REG_R14
REXX=1 SIBINDEX=0x7  | OUTREG=XED_REG_R15


#################################


xed_reg_enum_t GPR32_R()::
REXR=0 REG=0x0  | OUTREG=XED_REG_EAX
REXR=0 REG=0x1  | OUTREG=XED_REG_ECX
REXR=0 REG=0x2  | OUTREG=XED_REG_EDX
REXR=0 REG=0x3  | OUTREG=XED_REG_EBX
REXR=0 REG=0x4  | OUTREG=XED_REG_ESP
REXR=0 REG=0x5  | OUTREG=XED_REG_EBP
REXR=0 REG=0x6  | OUTREG=XED_REG_ESI
REXR=0 REG=0x7  | OUTREG=XED_REG_EDI
REXR=1 REG=0x0  | OUTREG=XED_REG_R8D
REXR=1 REG=0x1  | OUTREG=XED_REG_R9D
REXR=1 REG=0x2  | OUTREG=XED_REG_R10D
REXR=1 REG=0x3  | OUTREG=XED_REG_R11D
REXR=1 REG=0x4  | OUTREG=XED_REG_R12D
REXR=1 REG=0x5  | OUTREG=XED_REG_R13D
REXR=1 REG=0x6  | OUTREG=XED_REG_R14D
REXR=1 REG=0x7  | OUTREG=XED_REG_R15D

xed_reg_enum_t GPR32_B()::
REXB=0 RM=0x0  | OUTREG=XED_REG_EAX
REXB=0 RM=0x1  | OUTREG=XED_REG_ECX
REXB=0 RM=0x2  | OUTREG=XED_REG_EDX
REXB=0 RM=0x3  | OUTREG=XED_REG_EBX
REXB=0 RM=0x4  | OUTREG=XED_REG_ESP
REXB=0 RM=0x5  | OUTREG=XED_REG_EBP
REXB=0 RM=0x6  | OUTREG=XED_REG_ESI
REXB=0 RM=0x7  | OUTREG=XED_REG_EDI
REXB=1 RM=0x0  | OUTREG=XED_REG_R8D
REXB=1 RM=0x1  | OUTREG=XED_REG_R9D
REXB=1 RM=0x2  | OUTREG=XED_REG_R10D
REXB=1 RM=0x3  | OUTREG=XED_REG_R11D
REXB=1 RM=0x4  | OUTREG=XED_REG_R12D
REXB=1 RM=0x5  | OUTREG=XED_REG_R13D
REXB=1 RM=0x6  | OUTREG=XED_REG_R14D
REXB=1 RM=0x7  | OUTREG=XED_REG_R15D

xed_reg_enum_t GPR32_SB()::
REXB=0 SRM=0x0  | OUTREG=XED_REG_EAX
REXB=0 SRM=0x1  | OUTREG=XED_REG_ECX
REXB=0 SRM=0x2  | OUTREG=XED_REG_EDX
REXB=0 SRM=0x3  | OUTREG=XED_REG_EBX
REXB=0 SRM=0x4  | OUTREG=XED_REG_ESP
REXB=0 SRM=0x5  | OUTREG=XED_REG_EBP
REXB=0 SRM=0x6  | OUTREG=XED_REG_ESI
REXB=0 SRM=0x7  | OUTREG=XED_REG_EDI
REXB=1 SRM=0x0  | OUTREG=XED_REG_R8D
REXB=1 SRM=0x1  | OUTREG=XED_REG_R9D
REXB=1 SRM=0x2  | OUTREG=XED_REG_R10D
REXB=1 SRM=0x3  | OUTREG=XED_REG_R11D
REXB=1 SRM=0x4  | OUTREG=XED_REG_R12D
REXB=1 SRM=0x5  | OUTREG=XED_REG_R13D
REXB=1 SRM=0x6  | OUTREG=XED_REG_R14D
REXB=1 SRM=0x7  | OUTREG=XED_REG_R15D





xed_reg_enum_t GPR32_X()::
REXX=0 SIBINDEX=0x0  | OUTREG=XED_REG_EAX
REXX=0 SIBINDEX=0x1  | OUTREG=XED_REG_ECX
REXX=0 SIBINDEX=0x2  | OUTREG=XED_REG_EDX
REXX=0 SIBINDEX=0x3  | OUTREG=XED_REG_EBX
REXX=0 SIBINDEX=0x4  | OUTREG=XED_REG_INVALID
REXX=0 SIBINDEX=0x5  | OUTREG=XED_REG_EBP
REXX=0 SIBINDEX=0x6  | OUTREG=XED_REG_ESI
REXX=0 SIBINDEX=0x7  | OUTREG=XED_REG_EDI
REXX=1 SIBINDEX=0x0  | OUTREG=XED_REG_R8D
REXX=1 SIBINDEX=0x1  | OUTREG=XED_REG_R9D
REXX=1 SIBINDEX=0x2  | OUTREG=XED_REG_R10D
REXX=1 SIBINDEX=0x3  | OUTREG=XED_REG_R11D
REXX=1 SIBINDEX=0x4  | OUTREG=XED_REG_R12D
REXX=1 SIBINDEX=0x5  | OUTREG=XED_REG_R13D
REXX=1 SIBINDEX=0x6  | OUTREG=XED_REG_R14D
REXX=1 SIBINDEX=0x7  | OUTREG=XED_REG_R15D


#############################


xed_reg_enum_t GPR16_R()::
REXR=0 REG=0x0  | OUTREG=XED_REG_AX
REXR=0 REG=0x1  | OUTREG=XED_REG_CX
REXR=0 REG=0x2  | OUTREG=XED_REG_DX
REXR=0 REG=0x3  | OUTREG=XED_REG_BX
REXR=0 REG=0x4  | OUTREG=XED_REG_SP
REXR=0 REG=0x5  | OUTREG=XED_REG_BP
REXR=0 REG=0x6  | OUTREG=XED_REG_SI
REXR=0 REG=0x7  | OUTREG=XED_REG_DI
REXR=1 REG=0x0  | OUTREG=XED_REG_R8W
REXR=1 REG=0x1  | OUTREG=XED_REG_R9W
REXR=1 REG=0x2  | OUTREG=XED_REG_R10W
REXR=1 REG=0x3  | OUTREG=XED_REG_R11W
REXR=1 REG=0x4  | OUTREG=XED_REG_R12W
REXR=1 REG=0x5  | OUTREG=XED_REG_R13W
REXR=1 REG=0x6  | OUTREG=XED_REG_R14W
REXR=1 REG=0x7  | OUTREG=XED_REG_R15W



xed_reg_enum_t GPR16_B()::
REXB=0 RM=0x0  | OUTREG=XED_REG_AX
REXB=0 RM=0x1  | OUTREG=XED_REG_CX
REXB=0 RM=0x2  | OUTREG=XED_REG_DX
REXB=0 RM=0x3  | OUTREG=XED_REG_BX
REXB=0 RM=0x4  | OUTREG=XED_REG_SP
REXB=0 RM=0x5  | OUTREG=XED_REG_BP
REXB=0 RM=0x6  | OUTREG=XED_REG_SI
REXB=0 RM=0x7  | OUTREG=XED_REG_DI
REXB=1 RM=0x0  | OUTREG=XED_REG_R8W
REXB=1 RM=0x1  | OUTREG=XED_REG_R9W
REXB=1 RM=0x2  | OUTREG=XED_REG_R10W
REXB=1 RM=0x3  | OUTREG=XED_REG_R11W
REXB=1 RM=0x4  | OUTREG=XED_REG_R12W
REXB=1 RM=0x5  | OUTREG=XED_REG_R13W
REXB=1 RM=0x6  | OUTREG=XED_REG_R14W
REXB=1 RM=0x7  | OUTREG=XED_REG_R15W

xed_reg_enum_t GPR16_SB()::
REXB=0 SRM=0x0  | OUTREG=XED_REG_AX
REXB=0 SRM=0x1  | OUTREG=XED_REG_CX
REXB=0 SRM=0x2  | OUTREG=XED_REG_DX
REXB=0 SRM=0x3  | OUTREG=XED_REG_BX
REXB=0 SRM=0x4  | OUTREG=XED_REG_SP
REXB=0 SRM=0x5  | OUTREG=XED_REG_BP
REXB=0 SRM=0x6  | OUTREG=XED_REG_SI
REXB=0 SRM=0x7  | OUTREG=XED_REG_DI
REXB=1 SRM=0x0  | OUTREG=XED_REG_R8W
REXB=1 SRM=0x1  | OUTREG=XED_REG_R9W
REXB=1 SRM=0x2  | OUTREG=XED_REG_R10W
REXB=1 SRM=0x3  | OUTREG=XED_REG_R11W
REXB=1 SRM=0x4  | OUTREG=XED_REG_R12W
REXB=1 SRM=0x5  | OUTREG=XED_REG_R13W
REXB=1 SRM=0x6  | OUTREG=XED_REG_R14W
REXB=1 SRM=0x7  | OUTREG=XED_REG_R15W



#############################

# GPR8_R and GPR8_B are handled in separate files -- grep for them.

###########################a

xed_reg_enum_t CR_R()::
REXR=0 REG=0x0  | OUTREG=XED_REG_CR0
REXR=0 REG=0x1  | OUTREG=XED_REG_ERROR  enc
REXR=0 REG=0x2  | OUTREG=XED_REG_CR2
REXR=0 REG=0x3  | OUTREG=XED_REG_CR3
REXR=0 REG=0x4  | OUTREG=XED_REG_CR4
REXR=0 REG=0x5  | OUTREG=XED_REG_ERROR
REXR=0 REG=0x6  | OUTREG=XED_REG_ERROR
REXR=0 REG=0x7  | OUTREG=XED_REG_ERROR
REXR=1 REG=0x0  | OUTREG=XED_REG_CR8
REXR=1 REG=0x1  | OUTREG=XED_REG_ERROR
REXR=1 REG=0x2  | OUTREG=XED_REG_ERROR
REXR=1 REG=0x3  | OUTREG=XED_REG_ERROR
REXR=1 REG=0x4  | OUTREG=XED_REG_ERROR
REXR=1 REG=0x5  | OUTREG=XED_REG_ERROR
REXR=1 REG=0x6  | OUTREG=XED_REG_ERROR
REXR=1 REG=0x7  | OUTREG=XED_REG_ERROR

# FIXME: not used
xed_reg_enum_t CR_B()::
REXB=0 RM=0x0  | OUTREG=XED_REG_CR0
REXB=0 RM=0x1  | OUTREG=XED_REG_ERROR   enc
REXB=0 RM=0x2  | OUTREG=XED_REG_CR2
REXB=0 RM=0x3  | OUTREG=XED_REG_CR3
REXB=0 RM=0x4  | OUTREG=XED_REG_CR4
REXB=0 RM=0x5  | OUTREG=XED_REG_ERROR
REXB=0 RM=0x6  | OUTREG=XED_REG_ERROR
REXB=0 RM=0x7  | OUTREG=XED_REG_ERROR
REXB=1 RM=0x0  | OUTREG=XED_REG_CR8
REXB=1 RM=0x1  | OUTREG=XED_REG_ERROR
REXB=1 RM=0x2  | OUTREG=XED_REG_ERROR
REXB=1 RM=0x3  | OUTREG=XED_REG_ERROR
REXB=1 RM=0x4  | OUTREG=XED_REG_ERROR
REXB=1 RM=0x5  | OUTREG=XED_REG_ERROR
REXB=1 RM=0x6  | OUTREG=XED_REG_ERROR
REXB=1 RM=0x7  | OUTREG=XED_REG_ERROR

########################

xed_reg_enum_t DR_R()::
REXR=0 REG=0x0  | OUTREG=XED_REG_DR0
REXR=0 REG=0x1  | OUTREG=XED_REG_DR1
REXR=0 REG=0x2  | OUTREG=XED_REG_DR2
REXR=0 REG=0x3  | OUTREG=XED_REG_DR3
REXR=0 REG=0x4  | OUTREG=XED_REG_DR4
REXR=0 REG=0x5  | OUTREG=XED_REG_DR5
REXR=0 REG=0x6  | OUTREG=XED_REG_DR6
REXR=0 REG=0x7  | OUTREG=XED_REG_DR7
REXR=1 REG=0x0  | OUTREG=XED_REG_DR8
REXR=1 REG=0x1  | OUTREG=XED_REG_DR9
REXR=1 REG=0x2  | OUTREG=XED_REG_DR10
REXR=1 REG=0x3  | OUTREG=XED_REG_DR11
REXR=1 REG=0x4  | OUTREG=XED_REG_DR12
REXR=1 REG=0x5  | OUTREG=XED_REG_DR13
REXR=1 REG=0x6  | OUTREG=XED_REG_DR14
REXR=1 REG=0x7  | OUTREG=XED_REG_DR15

xed_reg_enum_t DR_B()::
REXB=0 RM=0x0  | OUTREG=XED_REG_DR0
REXB=0 RM=0x1  | OUTREG=XED_REG_DR1
REXB=0 RM=0x2  | OUTREG=XED_REG_DR2
REXB=0 RM=0x3  | OUTREG=XED_REG_DR3
REXB=0 RM=0x4  | OUTREG=XED_REG_DR4
REXB=0 RM=0x5  | OUTREG=XED_REG_DR5
REXB=0 RM=0x6  | OUTREG=XED_REG_DR6
REXB=0 RM=0x7  | OUTREG=XED_REG_DR7
REXB=1 RM=0x0  | OUTREG=XED_REG_DR8
REXB=1 RM=0x1  | OUTREG=XED_REG_DR9
REXB=1 RM=0x2  | OUTREG=XED_REG_DR10
REXB=1 RM=0x3  | OUTREG=XED_REG_DR11
REXB=1 RM=0x4  | OUTREG=XED_REG_DR12
REXB=1 RM=0x5  | OUTREG=XED_REG_DR13
REXB=1 RM=0x6  | OUTREG=XED_REG_DR14
REXB=1 RM=0x7  | OUTREG=XED_REG_DR15

#######################


xed_reg_enum_t X87()::
RM=0x0  | OUTREG=XED_REG_ST0
RM=0x1  | OUTREG=XED_REG_ST1
RM=0x2  | OUTREG=XED_REG_ST2
RM=0x3  | OUTREG=XED_REG_ST3
RM=0x4  | OUTREG=XED_REG_ST4
RM=0x5  | OUTREG=XED_REG_ST5
RM=0x6  | OUTREG=XED_REG_ST6
RM=0x7  | OUTREG=XED_REG_ST7

###################

xed_reg_enum_t SEG()::
REG=0x0  | OUTREG=XED_REG_ES
REG=0x1  | OUTREG=XED_REG_CS
REG=0x2  | OUTREG=XED_REG_SS
REG=0x3  | OUTREG=XED_REG_DS
REG=0x4  | OUTREG=XED_REG_FS
REG=0x5  | OUTREG=XED_REG_GS
REG=0x6  | OUTREG=XED_REG_ERROR     enc
REG=0x7  | OUTREG=XED_REG_ERROR

# MOV to CR cannot load CS 
xed_reg_enum_t SEG_MOV()::
REG=0x0  | OUTREG=XED_REG_ES
REG=0x1  | OUTREG=XED_REG_ERROR
REG=0x2  | OUTREG=XED_REG_SS
REG=0x3  | OUTREG=XED_REG_DS
REG=0x4  | OUTREG=XED_REG_FS
REG=0x5  | OUTREG=XED_REG_GS
REG=0x6  | OUTREG=XED_REG_ERROR     enc
REG=0x7  | OUTREG=XED_REG_ERROR


###################################################

# We have two versions of FINAL_DSEG called FINAL_DSEG and
# FINAL_DSEG1. This is required because in the nonterminal function, I
# don't know if which memop (MEM0 or MEM1) the segment selector is
# being applied to. I set USING_DEFAULT_SEGMENT0 for MEM0 and
# USING_DEFAULT_SEGMENT1 for MEM1.


# These set USING_DEFAULT_SEGMENT0

xed_reg_enum_t FINAL_DSEG()::
mode16 | OUTREG=FINAL_DSEG_NOT64()  
mode32 | OUTREG=FINAL_DSEG_NOT64() 
mode64 | OUTREG=FINAL_DSEG_MODE64() 

xed_reg_enum_t FINAL_DSEG_NOT64()::
SEG_OVD=0 | OUTREG=XED_REG_DS  USING_DEFAULT_SEGMENT0=1 enc # default data seg
SEG_OVD=1 | OUTREG=XED_REG_CS  USING_DEFAULT_SEGMENT0=0
SEG_OVD=2 | OUTREG=XED_REG_DS  USING_DEFAULT_SEGMENT0=1 # explicit ds seg
SEG_OVD=3 | OUTREG=XED_REG_ES  USING_DEFAULT_SEGMENT0=0
SEG_OVD=4 | OUTREG=XED_REG_FS  USING_DEFAULT_SEGMENT0=0
SEG_OVD=5 | OUTREG=XED_REG_GS  USING_DEFAULT_SEGMENT0=0
SEG_OVD=6 | OUTREG=XED_REG_SS  USING_DEFAULT_SEGMENT0=0

xed_reg_enum_t FINAL_DSEG_MODE64()::
SEG_OVD=0 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT0=1  enc
SEG_OVD=1 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT0=1 
SEG_OVD=2 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT0=1  
SEG_OVD=3 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT0=1 
SEG_OVD=4 | OUTREG=XED_REG_FS      USING_DEFAULT_SEGMENT0=0 
SEG_OVD=5 | OUTREG=XED_REG_GS      USING_DEFAULT_SEGMENT0=0 
SEG_OVD=6 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT0=1 


# These set USING_DEFAULT_SEGMENT1 

xed_reg_enum_t FINAL_DSEG1()::
mode16 | OUTREG=FINAL_DSEG1_NOT64()  
mode32 | OUTREG=FINAL_DSEG1_NOT64() 
mode64 | OUTREG=FINAL_DSEG1_MODE64() 

xed_reg_enum_t FINAL_DSEG1_NOT64()::
SEG_OVD=0 | OUTREG=XED_REG_DS  USING_DEFAULT_SEGMENT1=1 enc # default data seg
SEG_OVD=1 | OUTREG=XED_REG_CS  USING_DEFAULT_SEGMENT1=0
SEG_OVD=2 | OUTREG=XED_REG_DS  USING_DEFAULT_SEGMENT1=1 # explicit ds seg
SEG_OVD=3 | OUTREG=XED_REG_ES  USING_DEFAULT_SEGMENT1=0
SEG_OVD=4 | OUTREG=XED_REG_FS  USING_DEFAULT_SEGMENT1=0
SEG_OVD=5 | OUTREG=XED_REG_GS  USING_DEFAULT_SEGMENT1=0
SEG_OVD=6 | OUTREG=XED_REG_SS  USING_DEFAULT_SEGMENT1=0

xed_reg_enum_t FINAL_DSEG1_MODE64()::
SEG_OVD=0 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT1=1  enc
SEG_OVD=1 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT1=1 
SEG_OVD=2 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT1=1  
SEG_OVD=3 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT1=1 
SEG_OVD=4 | OUTREG=XED_REG_FS      USING_DEFAULT_SEGMENT1=0 
SEG_OVD=5 | OUTREG=XED_REG_GS      USING_DEFAULT_SEGMENT1=0 
SEG_OVD=6 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT1=1 





###################################################

# FINAL_ESEG is only called for STRING OPS and only specifies MEM0's SEG0.

xed_reg_enum_t FINAL_ESEG()::
mode16 | OUTREG=XED_REG_ES        USING_DEFAULT_SEGMENT0=1
mode32 | OUTREG=XED_REG_ES        USING_DEFAULT_SEGMENT0=1
mode64 | OUTREG=XED_REG_INVALID   USING_DEFAULT_SEGMENT0=1

xed_reg_enum_t FINAL_ESEG1()::
mode16 | OUTREG=XED_REG_ES        USING_DEFAULT_SEGMENT1=1
mode32 | OUTREG=XED_REG_ES        USING_DEFAULT_SEGMENT1=1
mode64 | OUTREG=XED_REG_INVALID   USING_DEFAULT_SEGMENT1=1

# For synthesized stack operands (see generator.py)
xed_reg_enum_t FINAL_SSEG1()::
mode16 | OUTREG=XED_REG_SS       USING_DEFAULT_SEGMENT1=1
mode32 | OUTREG=XED_REG_SS       USING_DEFAULT_SEGMENT1=1
mode64 | OUTREG=XED_REG_INVALID  USING_DEFAULT_SEGMENT1=1

# For stack operands that cannot be overridden
xed_reg_enum_t FINAL_SSEG0()::
mode16 | OUTREG=XED_REG_SS       USING_DEFAULT_SEGMENT0=1
mode32 | OUTREG=XED_REG_SS       USING_DEFAULT_SEGMENT0=1
mode64 | OUTREG=XED_REG_INVALID  USING_DEFAULT_SEGMENT0=1

# This is only called for MODRM BYTEs and they only set MEM0's SEG0.

xed_reg_enum_t FINAL_SSEG()::
mode16 | OUTREG=FINAL_SSEG_NOT64()  
mode32 | OUTREG=FINAL_SSEG_NOT64() 
mode64 | OUTREG=FINAL_SSEG_MODE64() 

xed_reg_enum_t FINAL_SSEG_NOT64()::
SEG_OVD=0 | OUTREG=XED_REG_SS  USING_DEFAULT_SEGMENT0=1     enc # default stack seg
SEG_OVD=1 | OUTREG=XED_REG_CS  USING_DEFAULT_SEGMENT0=0
SEG_OVD=2 | OUTREG=XED_REG_DS  USING_DEFAULT_SEGMENT0=0
SEG_OVD=3 | OUTREG=XED_REG_ES  USING_DEFAULT_SEGMENT0=0
SEG_OVD=4 | OUTREG=XED_REG_FS  USING_DEFAULT_SEGMENT0=0
SEG_OVD=5 | OUTREG=XED_REG_GS  USING_DEFAULT_SEGMENT0=0
SEG_OVD=6 | OUTREG=XED_REG_SS  USING_DEFAULT_SEGMENT0=1 # explicit ss seg

xed_reg_enum_t FINAL_SSEG_MODE64()::
SEG_OVD=0 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT0=1  enc
SEG_OVD=1 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT0=1 
SEG_OVD=2 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT0=1  
SEG_OVD=3 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT0=1 
SEG_OVD=4 | OUTREG=XED_REG_FS      USING_DEFAULT_SEGMENT0=0 
SEG_OVD=5 | OUTREG=XED_REG_GS      USING_DEFAULT_SEGMENT0=0 
SEG_OVD=6 | OUTREG=XED_REG_INVALID USING_DEFAULT_SEGMENT0=1 

