mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-10-10 00:25:06 -04:00
insns: more macro goodness
Even better macro support, add match for the BX register. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
@@ -246,9 +246,9 @@ static inline bool is_reg_class(opflags_t class, int reg)
|
||||
#define RN_NZERO GEN_SUBCLASS(7) /* Register number 1+ */
|
||||
#define RN_1_15 (RN_NZERO | RN_L16) /* Register number 1-15 */
|
||||
|
||||
#define RN_FLAGS(n) ((n) == 0 ? RN_ZERO : \
|
||||
(n) < 16 ? RN_1_15 : \
|
||||
0)
|
||||
#define RN_FLAGS(n) \
|
||||
(((n) == 0 ? RN_ZERO : RN_NZERO) | \
|
||||
((n) < 16 ? RN_L16 : 0))
|
||||
|
||||
#define RM_L16 (RN_L16 | REGMEM)
|
||||
#define RM_ZERO (RN_ZERO | REGMEM)
|
||||
@@ -342,8 +342,15 @@ static inline bool is_reg_class(opflags_t class, int reg)
|
||||
#define REG_EDX (REG_DATA | BITS32)
|
||||
#define REG_RDX (REG_DATA | BITS64)
|
||||
|
||||
/* base: BL, BX, EBX, RBX */
|
||||
#define REG_BASE (REG_GPR | REG_1_15 | GEN_SUBCLASS(2))
|
||||
#define REG_BL (REG_BASE | BITS8 )
|
||||
#define REG_BX (REG_BASE | BITS16)
|
||||
#define REG_EBX (REG_BASE | BITS32)
|
||||
#define REG_RBX (REG_BASE | BITS64)
|
||||
|
||||
/* high 8-bit regs: AH, CH, DH, BH */
|
||||
#define REG_HIGH (REG8 | REG_1_15 | GEN_SUBCLASS(2))
|
||||
#define REG_HIGH (REG8 | REG_1_15 | GEN_SUBCLASS(3))
|
||||
|
||||
/* Non-accumulator registers */
|
||||
#define REG_NA (REG_GPR | REG_NZERO)
|
||||
|
||||
@@ -172,9 +172,21 @@ sub set_implied_flags($;$) {
|
||||
|
||||
$flags->{'LONG'}++ if ($flags->{'APX'});
|
||||
$flags->{'NOAPX'}++ if ($flags->{'NOLONG'});
|
||||
$flags->{'X86_64'}++ if ($flags->{'LONG'});
|
||||
$flags->{'OBSOLETE'}++ if ($flags->{'NEVER'} || $flags->{'NOP'});
|
||||
$flags->{'NF'}++ if ($flags->{'NF_R'} || $flags->{'NF_E'});
|
||||
$flags->{'ZU'}++ if ($flags->{'ZU_R'} || $flags->{'ZU_E'});
|
||||
|
||||
# Retain only the highest CPU level flag
|
||||
my $found = 0;
|
||||
for (my $i = $flag_byname{'ANY'}->[0]; $i >= $flag_byname{'8086'}->[0]; $i--) {
|
||||
my $f = $flag_bynum[$i]->[1];
|
||||
if ($found) {
|
||||
delete $flags->{$f};
|
||||
} else {
|
||||
$found = $flags->{$f};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Return the value of any assume-size flag if one exists;
|
||||
@@ -216,6 +228,8 @@ sub split_flags($) {
|
||||
$flagstr = uc($flagstr);
|
||||
|
||||
foreach my $flag (split(',', $flagstr)) {
|
||||
next if ($flag =~ /^\s*$/); # Null flag
|
||||
|
||||
# Somewhat nicer syntax for required flags (NF! -> NF_R)
|
||||
$flag =~ s/\!$/_R/;
|
||||
# Ditto for weak flags (SX- -> SX_W)
|
||||
@@ -250,7 +264,8 @@ sub merge_flags($;$) {
|
||||
|
||||
clean_flags(\%flags);
|
||||
|
||||
my @flagslist = sort grep { !/^(\s*|\!.*)$/ } keys(%$flags);
|
||||
my @flagslist = sort { $flag_byname{$a} <=> $flag_byname{$b} }
|
||||
grep { !/^(\s*|\!.*)$/ } keys(%$flags);
|
||||
|
||||
if ($merge) {
|
||||
# For possibe human consumption. Merge subsequent SM and AR
|
||||
@@ -282,11 +297,12 @@ sub merge_flags($;$) {
|
||||
$nstr .= $n;
|
||||
}
|
||||
}
|
||||
$nstr =~ s/^\+/$pfx/;
|
||||
push(@flagslist, $nstr);
|
||||
$n++;
|
||||
$mask >>= 1;
|
||||
}
|
||||
|
||||
$nstr =~ s/^\+/$pfx/;
|
||||
push(@flagslist, $nstr);
|
||||
} else {
|
||||
push(@flagslist, $fl);
|
||||
}
|
||||
|
||||
180
x86/insns.dat
180
x86/insns.dat
@@ -87,40 +87,21 @@ AAS void [ 3f] 8086,NOLONG
|
||||
ARPL rm16,reg16 [mr: 63 /r] 286,PROT,SM,NOLONG
|
||||
BB0_RESET void [ 0f 3a] PENT,CYRIX,NOLONG,OBSOLETE,ND
|
||||
BB1_RESET void [ 0f 3b] PENT,CYRIX,NOLONG,OBSOLETE,ND
|
||||
BOUND reg16,mem [rm: o16 62 /r] 186,NOLONG
|
||||
BOUND reg32,mem [rm: o32 62 /r] 386,NOLONG
|
||||
BSF reg16,rm16 [rm: o16 nof3 0f bc /r] 386,SM
|
||||
BSF reg32,rm32 [rm: o32 nof3 0f bc /r] 386,SM
|
||||
BSF reg64,rm64 [rm: o64 nof3 0f bc /r] X86_64,LONG,SM
|
||||
BSR reg16,rm16 [rm: o16 nof3 0f bd /r] 386,SM
|
||||
BSR reg32,rm32 [rm: o32 nof3 0f bd /r] 386,SM
|
||||
BSR reg64,rm64 [rm: o64 nof3 0f bd /r] X86_64,LONG,SM
|
||||
$trio BOUND reg#,mem [rm: o# 62 /r] 186,NOLONG
|
||||
$trio BSF reg#,rm# [rm: o# nof3 0f bc /r] 386,SM
|
||||
$trio BSR reg#,rm# [rm: o# nof3 0f bd /r] 386,SM
|
||||
BSWAP reg32 [r: o32 0f c8+r] 486
|
||||
BSWAP reg64 [r: o64 0f c8+r] X86_64,LONG
|
||||
BT rm16,reg16 [mr: o16 0f a3 /r] 386,SM
|
||||
BT rm32,reg32 [mr: o32 0f a3 /r] 386,SM
|
||||
BT rm64,reg64 [mr: o64 0f a3 /r] X86_64,LONG,SM
|
||||
BT rm16,imm8 [mi: o16 0f ba /4 ib,u] 386
|
||||
BT rm32,imm8 [mi: o32 0f ba /4 ib,u] 386
|
||||
BT rm64,imm8 [mi: o64 0f ba /4 ib,u] X86_64,LONG
|
||||
BTC rm16,reg16 [mr: hle o16 0f bb /r] 386,SM,LOCK
|
||||
BTC rm32,reg32 [mr: hle o32 0f bb /r] 386,SM,LOCK
|
||||
BTC rm64,reg64 [mr: hle o64 0f bb /r] X86_64,LONG,SM,LOCK
|
||||
BTC rm16,imm8 [mi: hle o16 0f ba /7 ib,u] 386,LOCK
|
||||
BTC rm32,imm8 [mi: hle o32 0f ba /7 ib,u] 386,LOCK
|
||||
BTC rm64,imm8 [mi: hle o64 0f ba /7 ib,u] X86_64,LONG,LOCK
|
||||
BTR rm16,reg16 [mr: hle o16 0f b3 /r] 386,SM,LOCK
|
||||
BTR rm32,reg32 [mr: hle o32 0f b3 /r] 386,SM,LOCK
|
||||
BTR rm64,reg64 [mr: hle o64 0f b3 /r] X86_64,LONG,SM,LOCK
|
||||
BTR rm16,imm8 [mi: hle o16 0f ba /6 ib,u] 386,LOCK
|
||||
BTR rm32,imm8 [mi: hle o32 0f ba /6 ib,u] 386,LOCK
|
||||
BTR rm64,imm8 [mi: hle o64 0f ba /6 ib,u] X86_64,LONG,LOCK
|
||||
BTS rm16,reg16 [mr: hle o16 0f ab /r] 386,SM,LOCK
|
||||
BTS rm32,reg32 [mr: o32 0f ab /r] 386
|
||||
BTS rm64,reg64 [mr: o64 0f ab /r] X86_64,LONG
|
||||
BTS rm16,imm8 [mi: hle o16 0f ba /5 ib,u] 386,LOCK
|
||||
BTS rm32,imm8 [mi: hle o32 0f ba /5 ib,u] 386,LOCK
|
||||
BTS rm64,imm8 [mi: hle o64 0f ba /5 ib,u] X86_64,LONG,LOCK
|
||||
; Basically a useless instruction; sets the 16-bit register to 0, but it executes
|
||||
BSWAP reg16 [r: o16 0f c8+r] 486,UNDOC
|
||||
$trio BT rm#,reg# [mr: o# 0f a3 /r] 386,SM
|
||||
$trio BT rm#,imm8 [mi: o# 0f ba /4 ib,u] 386
|
||||
$trio BTC rm#,reg# [mr: o# 0f bb /r] 386,SM,LOCK
|
||||
$trio BTC rm#,imm8 [mi: o# 0f ba /7 ib,u] 386,LOCK
|
||||
$trio BTR rm#,reg# [mr: o# 0f b3 /r] 386,SM,LOCK
|
||||
$trio BTR rm#,imm8 [mi: o# 0f ab /6 ib,u] 386,LOCK
|
||||
$trio BTC rm#,reg# [mr: o# 0f ab /r] 386,SM,LOCK
|
||||
$trio BTC rm#,imm8 [mi: o# 0f ba /5 ib,u] 386,LOCK
|
||||
|
||||
CALL imm [i: odf e8 rel] 8086,BND,NOAPX,SIZE
|
||||
CALL imm|near [i: odf e8 rel] 8086,ND,BND,NOAPX,SIZE
|
||||
@@ -729,45 +710,6 @@ NOT rm8 [m: hle f6 /2] 8086,LOCK
|
||||
NOT rm16 [m: hle o16 f7 /2] 8086,LOCK
|
||||
NOT rm32 [m: hle o32 f7 /2] 386,LOCK
|
||||
NOT rm64 [m: hle o64 f7 /2] X86_64,LONG,LOCK
|
||||
OR mem,reg8 [mr: hle 08 /r] 8086,SM,LOCK
|
||||
OR reg8,reg8 [mr: 08 /r] 8086
|
||||
OR mem,reg16 [mr: hle o16 09 /r] 8086,SM,LOCK
|
||||
OR reg16,reg16 [mr: o16 09 /r] 8086
|
||||
OR mem,reg32 [mr: hle o32 09 /r] 386,SM,LOCK
|
||||
OR reg32,reg32 [mr: o32 09 /r] 386
|
||||
OR mem,reg64 [mr: hle o64 09 /r] X86_64,LONG,SM,LOCK
|
||||
OR reg64,reg64 [mr: o64 09 /r] X86_64,LONG
|
||||
OR reg8,mem [rm: 0a /r] 8086,SM
|
||||
OR reg8,reg8 [rm: 0a /r] 8086
|
||||
OR reg16,mem [rm: o16 0b /r] 8086,SM
|
||||
OR reg16,reg16 [rm: o16 0b /r] 8086
|
||||
OR reg32,mem [rm: o32 0b /r] 386,SM
|
||||
OR reg32,reg32 [rm: o32 0b /r] 386
|
||||
OR reg64,mem [rm: o64 0b /r] X86_64,LONG,SM
|
||||
OR reg64,reg64 [rm: o64 0b /r] X86_64,LONG
|
||||
OR rm16,imm8 [mi: hle o16 83 /1 ib,s] 8086,LOCK
|
||||
OR rm32,imm8 [mi: hle o32 83 /1 ib,s] 386,LOCK
|
||||
OR rm64,imm8 [mi: hle o64 83 /1 ib,s] X86_64,LONG,LOCK
|
||||
OR reg_al,imm [-i: 0c ib] 8086,SM
|
||||
OR reg_ax,sbyteword [mi: o16 83 /1 ib,s] 8086,SM,ND
|
||||
OR reg_ax,imm [-i: o16 0d iw] 8086,SM
|
||||
OR reg_eax,sbytedword [mi: o32 83 /1 ib,s] 386,SM,ND
|
||||
OR reg_eax,imm [-i: o32 0d id] 386,SM
|
||||
OR reg_rax,sbytedword [mi: o64 83 /1 ib,s] X86_64,LONG,SM,ND
|
||||
OR reg_rax,imm [-i: o64 0d id,s] X86_64,LONG,SM
|
||||
OR rm8,imm [mi: hle 80 /1 ib] 8086,SM,LOCK
|
||||
OR rm16,sbyteword [mi: hle o16 83 /1 ib,s] 8086,SM,LOCK,ND
|
||||
OR rm16,imm [mi: hle o16 81 /1 iw] 8086,SM,LOCK
|
||||
OR rm32,sbytedword [mi: hle o32 83 /1 ib,s] 386,SM,LOCK,ND
|
||||
OR rm32,imm [mi: hle o32 81 /1 id] 386,SM,LOCK
|
||||
OR rm64,sbytedword [mi: hle o64 83 /1 ib,s] X86_64,LONG,SM,LOCK,ND
|
||||
OR rm64,imm [mi: hle o64 81 /1 id,s] X86_64,LONG,SM,LOCK
|
||||
OR mem,imm8 [mi: hle 80 /1 ib] 8086,SM,LOCK
|
||||
OR mem,sbyteword16 [mi: hle o16 83 /1 ib,s] 8086,SM,LOCK,ND
|
||||
OR mem,imm16 [mi: hle o16 81 /1 iw] 8086,SM,LOCK
|
||||
OR mem,sbytedword32 [mi: hle o32 83 /1 ib,s] 386,SM,LOCK,ND
|
||||
OR mem,imm32 [mi: hle o32 81 /1 id] 386,SM,LOCK
|
||||
OR rm8,imm [mi: hle 82 /1 ib] 8086,SM,LOCK,ND,NOLONG
|
||||
OUT imm,reg_al [i-: e6 ib,u] 8086,SB,NOAPX
|
||||
OUT imm,reg_ax [i-: o16 e7 ib,u] 8086,SB,NOAPX
|
||||
OUT imm,reg_eax [i-: o32 e7 ib,u] 386,SB,NOAPX
|
||||
@@ -909,30 +851,6 @@ PUSHFD void [ o32 9c] 386,NOLONG
|
||||
PUSHFQ void [ o32 9c] X86_64,LONG
|
||||
PUSHFW void [ o16 9c] 8086
|
||||
PXOR mmxreg,mmxrm [rm: np 0f ef /r] PENT,MMX,SQ
|
||||
RCL rm8,unity [m-: d0 /2] 8086
|
||||
RCL rm8,reg_cl [m-: d2 /2] 8086
|
||||
RCL rm8,imm8 [mi: c0 /2 ib,u] 186
|
||||
RCL rm16,unity [m-: o16 d1 /2] 8086
|
||||
RCL rm16,reg_cl [m-: o16 d3 /2] 8086
|
||||
RCL rm16,imm8 [mi: o16 c1 /2 ib,u] 186
|
||||
RCL rm32,unity [m-: o32 d1 /2] 386
|
||||
RCL rm32,reg_cl [m-: o32 d3 /2] 386
|
||||
RCL rm32,imm8 [mi: o32 c1 /2 ib,u] 386
|
||||
RCL rm64,unity [m-: o64 d1 /2] X86_64,LONG
|
||||
RCL rm64,reg_cl [m-: o64 d3 /2] X86_64,LONG
|
||||
RCL rm64,imm8 [mi: o64 c1 /2 ib,u] X86_64,LONG
|
||||
RCR rm8,unity [m-: d0 /3] 8086
|
||||
RCR rm8,reg_cl [m-: d2 /3] 8086
|
||||
RCR rm8,imm8 [mi: c0 /3 ib,u] 186
|
||||
RCR rm16,unity [m-: o16 d1 /3] 8086
|
||||
RCR rm16,reg_cl [m-: o16 d3 /3] 8086
|
||||
RCR rm16,imm8 [mi: o16 c1 /3 ib,u] 186
|
||||
RCR rm32,unity [m-: o32 d1 /3] 386
|
||||
RCR rm32,reg_cl [m-: o32 d3 /3] 386
|
||||
RCR rm32,imm8 [mi: o32 c1 /3 ib,u] 386
|
||||
RCR rm64,unity [m-: o64 d1 /3] X86_64,LONG
|
||||
RCR rm64,reg_cl [m-: o64 d3 /3] X86_64,LONG
|
||||
RCR rm64,imm8 [mi: o64 c1 /3 ib,u] X86_64,LONG
|
||||
RDSHR rm32 [m: o32 0f 36 /0] P6,CYRIX,SMM,NOAPX
|
||||
RDMSR void [ 0f 32] PENT,PRIV,NOAPX
|
||||
RDPMC void [ 0f 33] P6,NOAPX
|
||||
@@ -963,79 +881,19 @@ RETFQ imm [i: o64 ca iw] X86_64,LONG,SW
|
||||
RETNQ void [ o64nw c3] X86_64,LONG,BND
|
||||
RETNQ imm [i: o64nw c2 iw] X86_64,LONG,SW,BND
|
||||
|
||||
ROL rm8,unity [m-: d0 /0] 8086
|
||||
ROL rm8,reg_cl [m-: d2 /0] 8086
|
||||
ROL rm8,imm8 [mi: c0 /0 ib,u] 186
|
||||
ROL rm16,unity [m-: o16 d1 /0] 8086
|
||||
ROL rm16,reg_cl [m-: o16 d3 /0] 8086
|
||||
ROL rm16,imm8 [mi: o16 c1 /0 ib,u] 186
|
||||
ROL rm32,unity [m-: o32 d1 /0] 386
|
||||
ROL rm32,reg_cl [m-: o32 d3 /0] 386
|
||||
ROL rm32,imm8 [mi: o32 c1 /0 ib,u] 386
|
||||
ROL rm64,unity [m-: o64 d1 /0] X86_64,LONG
|
||||
ROL rm64,reg_cl [m-: o64 d3 /0] X86_64,LONG
|
||||
ROL rm64,imm8 [mi: o64 c1 /0 ib,u] X86_64,LONG
|
||||
ROR rm8,unity [m-: d0 /1] 8086
|
||||
ROR rm8,reg_cl [m-: d2 /1] 8086
|
||||
ROR rm8,imm8 [mi: c0 /1 ib,u] 186
|
||||
ROR rm16,unity [m-: o16 d1 /1] 8086
|
||||
ROR rm16,reg_cl [m-: o16 d3 /1] 8086
|
||||
ROR rm16,imm8 [mi: o16 c1 /1 ib,u] 186
|
||||
ROR rm32,unity [m-: o32 d1 /1] 386
|
||||
ROR rm32,reg_cl [m-: o32 d3 /1] 386
|
||||
ROR rm32,imm8 [mi: o32 c1 /1 ib,u] 386
|
||||
ROR rm64,unity [m-: o64 d1 /1] X86_64,LONG
|
||||
ROR rm64,reg_cl [m-: o64 d3 /1] X86_64,LONG
|
||||
ROR rm64,imm8 [mi: o64 c1 /1 ib,u] X86_64,LONG
|
||||
RDM void [ 0f 3a] P6,CYRIX,ND,NOLONG,OBSOLETE
|
||||
RSDC reg_sreg,mem80 [rm: 0f 79 /r] 486,CYRIX,SMM
|
||||
RSLDT mem80 [m: 0f 7b /0] 486,CYRIX,SMM
|
||||
RSM void [ 0f aa] PENT,SMM
|
||||
RSTS mem80 [m: 0f 7d /0] 486,CYRIX,SMM
|
||||
SAHF void [ 9e] 8086
|
||||
SAL rm8,unity [m-: d0 /4] 8086,ND
|
||||
SAL rm8,reg_cl [m-: d2 /4] 8086,ND
|
||||
SAL rm8,imm8 [mi: c0 /4 ib,u] 186,ND
|
||||
SAL rm16,unity [m-: o16 d1 /4] 8086,ND
|
||||
SAL rm16,reg_cl [m-: o16 d3 /4] 8086,ND
|
||||
SAL rm16,imm8 [mi: o16 c1 /4 ib,u] 186,ND
|
||||
SAL rm32,unity [m-: o32 d1 /4] 386,ND
|
||||
SAL rm32,reg_cl [m-: o32 d3 /4] 386,ND
|
||||
SAL rm32,imm8 [mi: o32 c1 /4 ib,u] 386,ND
|
||||
SAL rm64,unity [m-: o64 d1 /4] X86_64,LONG,ND
|
||||
SAL rm64,reg_cl [m-: o64 d3 /4] X86_64,LONG,ND
|
||||
SAL rm64,imm8 [mi: o64 c1 /4 ib,u] X86_64,LONG,ND
|
||||
SALC void [ d6] 8086,UNDOC
|
||||
SAR rm8,unity [m-: d0 /7] 8086
|
||||
SAR rm8,reg_cl [m-: d2 /7] 8086
|
||||
SAR rm8,imm8 [mi: c0 /7 ib,u] 186
|
||||
SAR rm16,unity [m-: o16 d1 /7] 8086
|
||||
SAR rm16,reg_cl [m-: o16 d3 /7] 8086
|
||||
SAR rm16,imm8 [mi: o16 c1 /7 ib,u] 186
|
||||
SAR rm32,unity [m-: o32 d1 /7] 386
|
||||
SAR rm32,reg_cl [m-: o32 d3 /7] 386
|
||||
SAR rm32,imm8 [mi: o32 c1 /7 ib,u] 386
|
||||
SAR rm64,unity [m-: o64 d1 /7] X86_64,LONG
|
||||
SAR rm64,reg_cl [m-: o64 d3 /7] X86_64,LONG
|
||||
SAR rm64,imm8 [mi: o64 c1 /7 ib,u] X86_64,LONG
|
||||
SCASB void [ repe ae] 8086,NOAPX
|
||||
SCASD void [ repe o32 af] 386,NOAPX
|
||||
SCASQ void [ repe o64 af] X86_64,LONG,NOAPX
|
||||
SCASW void [ repe o16 af] 8086,NOAPX
|
||||
SFENCE void [ np 0f ae f8] X86_64,LONG,AMD
|
||||
SGDT mem [m: 0f 01 /0] 286
|
||||
SHL rm8,unity [m-: d0 /4] 8086
|
||||
SHL rm8,reg_cl [m-: d2 /4] 8086
|
||||
SHL rm8,imm8 [mi: c0 /4 ib,u] 186
|
||||
SHL rm16,unity [m-: o16 d1 /4] 8086
|
||||
SHL rm16,reg_cl [m-: o16 d3 /4] 8086
|
||||
SHL rm16,imm8 [mi: o16 c1 /4 ib,u] 186
|
||||
SHL rm32,unity [m-: o32 d1 /4] 386
|
||||
SHL rm32,reg_cl [m-: o32 d3 /4] 386
|
||||
SHL rm32,imm8 [mi: o32 c1 /4 ib,u] 386
|
||||
SHL rm64,unity [m-: o64 d1 /4] X86_64,LONG
|
||||
SHL rm64,reg_cl [m-: o64 d3 /4] X86_64,LONG
|
||||
SHL rm64,imm8 [mi: o64 c1 /4 ib,u] X86_64,LONG
|
||||
SHLD mem,reg16,imm [mri: o16 0f a4 /r ib,u] 386,SM0-1,SB,AR2
|
||||
SHLD reg16,reg16,imm [mri: o16 0f a4 /r ib,u] 386,SM0-1,SB,AR2
|
||||
SHLD mem,reg32,imm [mri: o32 0f a4 /r ib,u] 386,SM0-1,SB,AR2
|
||||
@@ -1048,18 +906,6 @@ SHLD mem,reg32,reg_cl [mr-: o32 0f a5 /r] 386,SM
|
||||
SHLD reg32,reg32,reg_cl [mr-: o32 0f a5 /r] 386
|
||||
SHLD mem,reg64,reg_cl [mr-: o64 0f a5 /r] X86_64,LONG,SM
|
||||
SHLD reg64,reg64,reg_cl [mr-: o64 0f a5 /r] X86_64,LONG
|
||||
SHR rm8,unity [m-: d0 /5] 8086
|
||||
SHR rm8,reg_cl [m-: d2 /5] 8086
|
||||
SHR rm8,imm8 [mi: c0 /5 ib,u] 186
|
||||
SHR rm16,unity [m-: o16 d1 /5] 8086
|
||||
SHR rm16,reg_cl [m-: o16 d3 /5] 8086
|
||||
SHR rm16,imm8 [mi: o16 c1 /5 ib,u] 186
|
||||
SHR rm32,unity [m-: o32 d1 /5] 386
|
||||
SHR rm32,reg_cl [m-: o32 d3 /5] 386
|
||||
SHR rm32,imm8 [mi: o32 c1 /5 ib,u] 386
|
||||
SHR rm64,unity [m-: o64 d1 /5] X86_64,LONG
|
||||
SHR rm64,reg_cl [m-: o64 d3 /5] X86_64,LONG
|
||||
SHR rm64,imm8 [mi: o64 c1 /5 ib,u] X86_64,LONG
|
||||
SHRD mem,reg16,imm [mri: o16 0f ac /r ib,u] 386,SM0-1,SB,AR2
|
||||
SHRD reg16,reg16,imm [mri: o16 0f ac /r ib,u] 386,SM0-1,SB,AR2
|
||||
SHRD mem,reg32,imm [mri: o32 0f ac /r ib,u] 386,SM0-1,SB,AR2
|
||||
|
||||
250
x86/preinsns.pl
250
x86/preinsns.pl
@@ -19,35 +19,36 @@ our %macros;
|
||||
our($macro, $outfile, $infile, $line); # Public for error messages
|
||||
|
||||
# Common pattern for the basic 8 arithmetric functions
|
||||
$macros{'arith'} = sub {
|
||||
return eightfold(<<'EOL', {}, @_);
|
||||
$op rm8,reg8 [mr: $hle $o0 /r ] 8086,SM,$lock
|
||||
$op rm16,reg16 [mr: $hle o16 $o1 /r ] 8086,SM,$lock
|
||||
$op rm32,reg32 [mr: $hle o32 $o1 /r ] 386,SM,$lock,$zu
|
||||
$op rm64,reg64 [mr: $hle o64 $o1 /r ] X86_64,LONG,SM,$lock,$zu
|
||||
$op reg8,rm8 [rm: $o2 /r ] 8086,SM
|
||||
$op reg16,rm16 [rm: o16 $o3 /r ] 8086,SM
|
||||
$op reg32,rm32 [rm: o32 $o3 /r ] 386,SM,$zu
|
||||
$op reg64,rm64 [rm: o64 $o3 /r ] X86_64,LONG,SM,$zu
|
||||
$op reg_al,imm8 [-i: $o4 ib ] 8086,SM
|
||||
$macros{'arith'} = {
|
||||
'def' => *def_eightfold,
|
||||
'txt' => <<'EOL'
|
||||
$op rm8,reg8 [mr: $hle $00 /r ] 8086,SM,$lock
|
||||
$op rm16,reg16 [mr: $hle o16 $01 /r ] 8086,SM,$lock
|
||||
$op rm32,reg32 [mr: $hle o32 $01 /r ] 386,SM,$lock,$zu
|
||||
$op rm64,reg64 [mr: $hle o64 $01 /r ] X86_64,LONG,SM,$lock,$zu
|
||||
$op reg8,rm8 [rm: $02 /r ] 8086,SM
|
||||
$op reg16,rm16 [rm: o16 $03 /r ] 8086,SM
|
||||
$op reg32,rm32 [rm: o32 $03 /r ] 386,SM,$zu
|
||||
$op reg64,rm64 [rm: o64 $03 /r ] X86_64,LONG,SM,$zu
|
||||
$op reg_al,imm8 [-i: $04 ib ] 8086,SM
|
||||
$op rm8,imm8 [mi: $hle 80 /$n ib ] 8086,SM,$lock
|
||||
$op rm16,sbyteword16 [mi: $hle o16 83 /$n ib,s ] 8086,SM,$lock
|
||||
$op reg_ax,imm16 [-i: o16 $o5 iw ] 8086,SM
|
||||
$op reg_ax,imm16 [-i: o16 $05 iw ] 8086,SM
|
||||
$op rm16,imm16 [mi: $hle o16 81 /$n iw ] 8086,SM,$lock
|
||||
$op rm32,sbytedword32 [mi: $hle o32 83 /$n ib,s ] 386,SM,$lock,$zu
|
||||
$op reg_eax,imm32 [-i: o32 $o5 id ] 386,SM,$zu
|
||||
$op reg_eax,imm32 [-i: o32 $05 id ] 386,SM,$zu
|
||||
$op rm32,imm32 [mi: $hle o32 81 /$n id ] 386,SM,$lock,$zu
|
||||
$op rm64,sbytedword64 [mi: $hle o64 83 /$n ib,s ] X86_64,LONG,SM,$lock,$zu
|
||||
$op reg_rax,sdword64 [-i: o64 $o5 id,s ] X86_64,LONG,SM,$zu
|
||||
$op reg_rax,sdword64 [-i: o64 $05 id,s ] X86_64,LONG,SM,$zu
|
||||
$op rm64,sdword64 [mi: $hle o64 81 /$n id,s ] X86_64,LONG,SM,$lock,$zu
|
||||
$op reg8?,reg8,rm8 [vrm: evex.ndx.nf.l0.m4.o8 $o2 /r ] $apx,SM
|
||||
$op reg16?,reg16,rm16 [vrm: evex.ndx.nf.l0.m4.o16 $o3 /r ] $apx,SM
|
||||
$op reg32?,reg32,rm32 [vrm: evex.ndx.nf.l0.m4.o32 $o3 /r ] $apx,SM
|
||||
$op reg64?,reg64,rm64 [vrm: evex.ndx.nf.l0.m4.o64 $o3 /r ] $apx,SM
|
||||
$op reg8?,rm8,reg8 [vmr: evex.ndx.nf.l0.m4.o8 $o0 /r ] $apx,SM
|
||||
$op reg16?,rm16,reg16 [vmr: evex.ndx.nf.l0.m4.o16 $o1 /r ] $apx,SM
|
||||
$op reg32?,rm32,reg32 [vmr: evex.ndx.nf.l0.m4.o32 $o1 /r ] $apx,SM,$zu
|
||||
$op reg64?,rm64,reg64 [vmr: evex.ndx.nf.l0.m4.o64 $o1 /r ] $apx,SM,$zu
|
||||
$op reg8?,reg8,rm8 [vrm: evex.ndx.nf.l0.m4.o8 $02 /r ] $apx,SM
|
||||
$op reg16?,reg16,rm16 [vrm: evex.ndx.nf.l0.m4.o16 $03 /r ] $apx,SM
|
||||
$op reg32?,reg32,rm32 [vrm: evex.ndx.nf.l0.m4.o32 $03 /r ] $apx,SM
|
||||
$op reg64?,reg64,rm64 [vrm: evex.ndx.nf.l0.m4.o64 $03 /r ] $apx,SM
|
||||
$op reg8?,rm8,reg8 [vmr: evex.ndx.nf.l0.m4.o8 $00 /r ] $apx,SM
|
||||
$op reg16?,rm16,reg16 [vmr: evex.ndx.nf.l0.m4.o16 $01 /r ] $apx,SM
|
||||
$op reg32?,rm32,reg32 [vmr: evex.ndx.nf.l0.m4.o32 $01 /r ] $apx,SM,$zu
|
||||
$op reg64?,rm64,reg64 [vmr: evex.ndx.nf.l0.m4.o64 $01 /r ] $apx,SM,$zu
|
||||
$op reg8?,rm8,imm8 [vmi: evex.ndx.nf.l0.m4.o8 80 /$n ib ] $apx,SM
|
||||
$op reg16?,rm16,sbyteword16 [vmi: evex.ndx.nf.l0.m4.o16 83 /$n ib,s ] $apx,SM
|
||||
$op reg16?,rm16,imm16 [vmi: evex.ndx.nf.l0.m4.o16 81 /$n iw ] $apx,SM
|
||||
@@ -59,8 +60,9 @@ EOL
|
||||
};
|
||||
|
||||
# Common pattern for the basic shift and rotate instructions
|
||||
$macros{'shift'} = sub {
|
||||
return eightfold(<<'EOL', {}, @_);
|
||||
$macros{'shift'} = {
|
||||
'def' => *def_eightfold,
|
||||
'txt' => <<'EOL'
|
||||
$op rm8,unity [m-: d0 /$n] 8086
|
||||
$op rm8,reg_cl [m-: d2 /$n] 8086
|
||||
$op rm8,imm8 [mi: c0 /$n ib,u] 186
|
||||
@@ -92,34 +94,69 @@ $op reg64?,rm64,imm8 [vmi: evex.ndx.nf.l0.m4.o64 c1 /$n ib,u] $apx,SM0-1
|
||||
EOL
|
||||
};
|
||||
|
||||
#
|
||||
# Common pattern for 8/16/32/64 or 16/32/64 instructions
|
||||
#
|
||||
$macros{'trio'} = { 'func' => *func_trio_quad, 'first' => 16 };
|
||||
$macros{'quad'} = { 'func' => *func_trio_quad, 'first' => 8 };
|
||||
|
||||
sub func_trio_quad($$$) {
|
||||
my($mac, $args, $rawargs) = @_;
|
||||
|
||||
my @ol;
|
||||
|
||||
my %sizename = ( 8 => 'B', 16 => 'W', 32 => 'D', 64 => 'Q' );
|
||||
|
||||
for (my $i = $mac->{'first'}; $i <= 64; $i <<= 1) {
|
||||
my $o;
|
||||
my $ins = join("\t", @$rawargs);
|
||||
while ($ins =~ /^(.*?)((?:\b[0-9a-f]{2})?\#|\%)(.*)$/) {
|
||||
$o .= $1;
|
||||
my $mw = $2;
|
||||
$ins = $3;
|
||||
if ($mw eq '%') {
|
||||
$o .= $sizename{$i};
|
||||
} elsif ($mw =~ /^([0-9a-f]{2})\#$/) {
|
||||
$o .= sprintf('%02x', hex($1) | ($i >= 16));
|
||||
} else {
|
||||
$o .= $i;
|
||||
}
|
||||
}
|
||||
$o .= $ins;
|
||||
$o =~ s/\bNOLONG${i}\b/NOLONG/;
|
||||
$o =~ s/\bNOLONG[0-9]+\b//;
|
||||
if ($i >= 64) {
|
||||
next if ($o =~ /\bNOLONG\b/);
|
||||
$o .= ',X86_64,LONG';
|
||||
} elsif ($i >= 32) {
|
||||
$o .= ',386';
|
||||
}
|
||||
push(@ol, $o);
|
||||
}
|
||||
|
||||
return @ol;
|
||||
}
|
||||
|
||||
#
|
||||
# Macro helper functions for common constructs
|
||||
#
|
||||
|
||||
# "8-fold" or similar sequential instruction patterns
|
||||
sub eightfold($$@) {
|
||||
my $pat = shift(@_);
|
||||
# Parse arguments handling variable setting
|
||||
sub parse_args($@) {
|
||||
my $uvars = shift(@_);
|
||||
my @l;
|
||||
|
||||
my $n = 0;
|
||||
|
||||
my %initvars = ('shift' => 3, %$uvars);
|
||||
my %initvars = defined($uvars) ? %$uvars : ();
|
||||
my @oa;
|
||||
my $n = 0; # Argument counter
|
||||
|
||||
foreach my $ops (@_) {
|
||||
my %vars = %initvars;
|
||||
$vars{'n'} = $n;
|
||||
for (my $i = 0; $i < (1 << $vars{'shift'}); $i++) {
|
||||
$vars{"o$i"} = sprintf("%02x", $vars{'base'}+($n << $vars{'shift'})+$i);
|
||||
}
|
||||
my $nd = 0;
|
||||
my $outdata = 0;
|
||||
$vars{'n'} = $n;
|
||||
$vars{'nd'} = 0;
|
||||
my @oaa;
|
||||
foreach my $op ($ops =~ /(?:[^\,\[\]\"]+|\[.*?\]|\".*?\")+/g) {
|
||||
$op =~ s/\"//g;
|
||||
|
||||
if ($op =~ s/^\@//) {
|
||||
$nd = 1;
|
||||
}
|
||||
$vars{'nd'} = 'nd' if ($op =~ s/^\@//);
|
||||
if ($op =~ /^(\w+)\=(.*)$/) {
|
||||
$vars{$1} = $2;
|
||||
next;
|
||||
@@ -135,38 +172,63 @@ sub eightfold($$@) {
|
||||
}
|
||||
|
||||
$vars{'op'} = $op;
|
||||
my $sp = substitute($pat, \%vars);
|
||||
if ($nd) {
|
||||
$sp =~ s/^(\w.*)$/$1,ND/gm;
|
||||
}
|
||||
push(@l, $sp);
|
||||
$outdata = $nd = 1;
|
||||
push(@oaa, {%vars});
|
||||
$vars{'nd'} = 'nd';
|
||||
}
|
||||
if ($outdata) {
|
||||
$n++;
|
||||
if (scalar(@oaa)) {
|
||||
push(@oa, [@oaa]);
|
||||
} else {
|
||||
# Global variable setting
|
||||
%initvars = %vars;
|
||||
}
|
||||
}
|
||||
|
||||
return @l;
|
||||
return @oa;
|
||||
}
|
||||
|
||||
# "8-fold" or similar sequential instruction patterns
|
||||
sub def_eightfold($$$) {
|
||||
my($var, $arg, $mac) = @_;
|
||||
|
||||
my $shift = $arg->{'shift'};
|
||||
$shift = 3 unless (defined($shift));
|
||||
|
||||
if ($var =~ /^[0-9a-f]{1,2}$/) {
|
||||
return sprintf('%02x', hex($var) + ($arg->{'n'} << $shift));
|
||||
} else {
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Substitute variables in a pattern
|
||||
#
|
||||
sub substitute($$) {
|
||||
my($pat, $vars) = @_;
|
||||
sub substitute($$;$) {
|
||||
my($pat, $vars, $defs) = @_;
|
||||
my $o = '';
|
||||
my $def;
|
||||
my @defargs;
|
||||
|
||||
while ($pat =~ /^(.*?)\$(?:(\w+)\b|\{(\w+)\})(.*)$/s) {
|
||||
if (defined($defs)) {
|
||||
@defargs = @$defs;
|
||||
$def = shift(@defargs);
|
||||
}
|
||||
|
||||
while ($pat =~ /^(.*?)\$(?:(\w+\b|\$+)|\{(\w+|\$+)\})(.*)$/s) {
|
||||
$o .= $1;
|
||||
$pat = $4;
|
||||
my $vn = $2.$3;
|
||||
my $vv = $vars->{$vn};
|
||||
if (!defined($vv)) {
|
||||
# warn "$0:$infile:$line: no variable \$$vn in macro \$$macro\n";
|
||||
$vv = $vn;
|
||||
my $vv;
|
||||
if ($vn =~ /^\$/) {
|
||||
$vv = $vn; # Reduce by one $
|
||||
} else {
|
||||
$vv = $vars->{$vn};
|
||||
if (!defined($vv)) {
|
||||
if (defined($def)) {
|
||||
$vv = $def->($vn, @defargs);
|
||||
}
|
||||
$vv = $vn unless(defined($vv));
|
||||
}
|
||||
}
|
||||
$vv =~ s/\s+$// if ($pat =~ /^\s/);
|
||||
$o .= $vv;
|
||||
@@ -176,23 +238,50 @@ sub substitute($$) {
|
||||
return $o;
|
||||
}
|
||||
|
||||
#
|
||||
# Build output by substituting the variables for each argument,
|
||||
#
|
||||
sub subst_list($$;$$) {
|
||||
my($pat, $args, $def, $mac) = @_;
|
||||
my @o = ();
|
||||
|
||||
foreach my $a0 (@$args) {
|
||||
foreach my $arg (@$a0) {
|
||||
push(@o, substitute($pat, $arg, [$def, $arg, $mac]));
|
||||
}
|
||||
}
|
||||
|
||||
return @o;
|
||||
}
|
||||
|
||||
#
|
||||
# Actually invoke a macro
|
||||
#
|
||||
sub process_macro(@) {
|
||||
$macro = shift(@_);
|
||||
my $mac = $macros{$macro};
|
||||
|
||||
if (!defined($mac)) {
|
||||
die "$0:$infile:$line: no macro named \$$macro\n";
|
||||
}
|
||||
|
||||
my @args = parse_args($mac->{'vars'}, @_);
|
||||
my $func = $mac->{'func'};
|
||||
my @o;
|
||||
if (defined($func)) {
|
||||
@o = $func->($mac, \@args, \@_);
|
||||
} else {
|
||||
@o = subst_list($mac->{'txt'}, \@args, $mac->{'def'}, $mac);
|
||||
}
|
||||
return map { split(/\n/, $_) } @o;
|
||||
}
|
||||
|
||||
#
|
||||
# Main program
|
||||
#
|
||||
($infile, $outfile) = @ARGV;
|
||||
$line = 0;
|
||||
|
||||
sub process_macro(@) {
|
||||
$macro = shift(@_);
|
||||
my $mfunc = $macros{$macro};
|
||||
|
||||
if (!defined($mfunc)) {
|
||||
die "$0:$infile:$line: no macro named \$$macro\n";
|
||||
}
|
||||
|
||||
return map { split(/\n/, $_) } $mfunc->(@_);
|
||||
}
|
||||
|
||||
## XXX: fix special case: XCHG
|
||||
## XXX: check: CMPSS, CMPSD
|
||||
## XXX: check VEX encoded instructions that do not write
|
||||
@@ -209,14 +298,11 @@ umwait|ver[rw]|vtestp[ps]|xadd|xor|xtest|getsec|rsm|sbb|cmps[bwdq]|hint_.*)$';
|
||||
my $nozero = '^(jmp|call|bt|test|cmp|ud[012].*|ptwrite|tpause|u?monitor.*|u?mwait.*|incssp.*|\
|
||||
enqcmds?|senduipi|hint_.*|jmpe|nop|inv.*|push2?p?|vmwrite|clzero|clflush|clwb|lkgs)$';
|
||||
|
||||
my $_last_flag; # Simple uniqueness counter
|
||||
sub add_flag($@) {
|
||||
my $flags = shift(@_);
|
||||
|
||||
foreach my $fl (@_) {
|
||||
unless ($fl =~ /^\s*$/) {
|
||||
$flags->{$fl} = $flags->{$fl} || ++$_last_flag;
|
||||
}
|
||||
$flags->{$fl}++ unless ($fl =~ /^\s*$/);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,18 +388,16 @@ open(my $out, '>', $outfile) or die "$0:$outfile: $!\n";
|
||||
while (defined(my $l = <$in>)) {
|
||||
$line++;
|
||||
chomp $l;
|
||||
my @insl;
|
||||
my @insi = ($l);
|
||||
|
||||
if ($l =~ /^\s*\$(\w+[^\;]*?)\s*(\;.*)?$/) {
|
||||
print $out $2, "\n" if ($2 ne ''); # Comment
|
||||
my @args = ($1 =~ /(?:\[.*?\]|\".*?\"|[^\[\]\"\s]+)+/g);
|
||||
@insl = process_macro(@args);
|
||||
} else {
|
||||
@insl = ($l);
|
||||
}
|
||||
|
||||
foreach my $ins (@insl) {
|
||||
process_insn($out, $ins);
|
||||
while (defined(my $li = shift(@insi))) {
|
||||
if ($li =~ /^\s*\$(\w+[^\;]*?)\s*(\;.*)?$/) {
|
||||
print $out $2, "\n" unless ($2 eq ''); # Retain comment
|
||||
my @args = ($1 =~ /(?:\[[^\]]*\]|\"[^\"]*\"|[^\[\]\"\s])+/g);
|
||||
push(@insi, process_macro(@args));
|
||||
} else {
|
||||
process_insn($out, $li);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,11 +54,11 @@ ah REG_HIGH reg8 4
|
||||
ax REG_AX reg16 0
|
||||
eax REG_EAX reg32 0
|
||||
rax REG_RAX reg64 0
|
||||
bl REG8NA reg8,reg8_rex 3
|
||||
bl REG_BL reg8,reg8_rex 3
|
||||
bh REG_HIGH reg8 7
|
||||
bx REG16NA reg16 3
|
||||
ebx REG32NA reg32 3
|
||||
rbx REG64NA reg64 3
|
||||
bx REG_BX reg16 3
|
||||
ebx REG_EBX reg32 3
|
||||
rbx REG_RBX reg64 3
|
||||
cl REG_CL reg8,reg8_rex 1
|
||||
ch REG_HIGH reg8 5
|
||||
cx REG_CX reg16 1
|
||||
|
||||
Reference in New Issue
Block a user