You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(71) |
Aug
(152) |
Sep
(123) |
Oct
(49) |
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(3) |
Oct
|
Nov
|
Dec
|
2002 |
Jan
|
Feb
|
Mar
|
Apr
(37) |
May
(554) |
Jun
(301) |
Jul
(84) |
Aug
(39) |
Sep
(44) |
Oct
(99) |
Nov
(41) |
Dec
(52) |
2003 |
Jan
(15) |
Feb
(32) |
Mar
(19) |
Apr
(4) |
May
(8) |
Jun
(30) |
Jul
(122) |
Aug
(100) |
Sep
(120) |
Oct
(4) |
Nov
(39) |
Dec
(32) |
2004 |
Jan
(38) |
Feb
(87) |
Mar
(11) |
Apr
(23) |
May
(7) |
Jun
(6) |
Jul
(18) |
Aug
(2) |
Sep
(22) |
Oct
(2) |
Nov
(7) |
Dec
(48) |
2005 |
Jan
(74) |
Feb
(29) |
Mar
(28) |
Apr
(1) |
May
(24) |
Jun
(16) |
Jul
(9) |
Aug
(7) |
Sep
(69) |
Oct
(11) |
Nov
(13) |
Dec
(13) |
2006 |
Jan
(5) |
Feb
(3) |
Mar
(7) |
Apr
|
May
(12) |
Jun
(12) |
Jul
(5) |
Aug
(1) |
Sep
(4) |
Oct
(61) |
Nov
(68) |
Dec
(46) |
2007 |
Jan
(16) |
Feb
(15) |
Mar
(46) |
Apr
(171) |
May
(78) |
Jun
(109) |
Jul
(61) |
Aug
(71) |
Sep
(189) |
Oct
(219) |
Nov
(162) |
Dec
(91) |
2008 |
Jan
(49) |
Feb
(41) |
Mar
(43) |
Apr
(31) |
May
(70) |
Jun
(98) |
Jul
(39) |
Aug
(8) |
Sep
(75) |
Oct
(47) |
Nov
(11) |
Dec
(17) |
2009 |
Jan
(9) |
Feb
(12) |
Mar
(8) |
Apr
(11) |
May
(27) |
Jun
(25) |
Jul
(161) |
Aug
(28) |
Sep
(66) |
Oct
(36) |
Nov
(49) |
Dec
(22) |
2010 |
Jan
(34) |
Feb
(20) |
Mar
(3) |
Apr
(12) |
May
(1) |
Jun
(10) |
Jul
(28) |
Aug
(98) |
Sep
(7) |
Oct
(25) |
Nov
(4) |
Dec
(9) |
2011 |
Jan
|
Feb
(12) |
Mar
(7) |
Apr
(16) |
May
(11) |
Jun
(59) |
Jul
(120) |
Aug
(7) |
Sep
(4) |
Oct
(5) |
Nov
(3) |
Dec
(2) |
2012 |
Jan
|
Feb
(6) |
Mar
(21) |
Apr
|
May
|
Jun
|
Jul
(9) |
Aug
|
Sep
(5) |
Oct
(3) |
Nov
(6) |
Dec
(1) |
2013 |
Jan
|
Feb
(19) |
Mar
(10) |
Apr
|
May
(2) |
Jun
|
Jul
(7) |
Aug
(62) |
Sep
(14) |
Oct
(44) |
Nov
(38) |
Dec
(47) |
2014 |
Jan
(14) |
Feb
(1) |
Mar
(4) |
Apr
|
May
(20) |
Jun
|
Jul
|
Aug
(8) |
Sep
(6) |
Oct
(11) |
Nov
(9) |
Dec
(9) |
2015 |
Jan
(3) |
Feb
(2) |
Mar
(2) |
Apr
(3) |
May
(2) |
Jun
(5) |
Jul
|
Aug
(2) |
Sep
(1) |
Oct
(1) |
Nov
(10) |
Dec
(2) |
2016 |
Jan
(12) |
Feb
(13) |
Mar
(9) |
Apr
(45) |
May
(9) |
Jun
(2) |
Jul
(15) |
Aug
(32) |
Sep
(6) |
Oct
(28) |
Nov
(1) |
Dec
|
2017 |
Jan
(1) |
Feb
|
Mar
|
Apr
(13) |
May
(8) |
Jun
(2) |
Jul
(3) |
Aug
(10) |
Sep
|
Oct
(2) |
Nov
|
Dec
(1) |
2018 |
Jan
(2) |
Feb
(4) |
Mar
(2) |
Apr
(7) |
May
|
Jun
(8) |
Jul
|
Aug
(8) |
Sep
(2) |
Oct
(2) |
Nov
(8) |
Dec
(6) |
2019 |
Jan
(2) |
Feb
|
Mar
(1) |
Apr
|
May
(1) |
Jun
(2) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(3) |
2020 |
Jan
(3) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(3) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2022 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Cyrill G. <gor...@gm...> - 2013-10-28 07:34:27
|
On Mon, Oct 28, 2013 at 11:30:51AM +0400, Cyrill Gorcunov wrote: > > > make: Remove generated files on clean target > > > > > > Signed-off-by: Cyrill Gorcunov <gor...@gm...> > > > > I'm not sure if that is a good idea, or if that is better left to "make > > spotless". On the other hand if you don't have Perl on your system > > you're probably just building from a clean tarball anyway. > > Hmm, maybe add cleanout target which would call clean first and > remove generated files as well? Ah, I misread your email. I'll move it to spotless then. |
From: Cyrill G. <gor...@gm...> - 2013-10-28 07:31:02
|
On Mon, Oct 28, 2013 at 12:20:58AM -0700, H. Peter Anvin wrote: > On 10/27/2013 10:18 AM, nasm-bot for Cyrill Gorcunov wrote: > > Commit-ID: b6c7291b3d1f904b20955c3f9829b8cc92801227 > > Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=b6c7291b3d1f904b20955c3f9829b8cc92801227 > > Author: Cyrill Gorcunov <gor...@gm...> > > AuthorDate: Sun, 27 Oct 2013 21:15:47 +0400 > > Committer: Cyrill Gorcunov <gor...@gm...> > > CommitDate: Sun, 27 Oct 2013 21:15:47 +0400 > > > > make: Remove generated files on clean target > > > > Signed-off-by: Cyrill Gorcunov <gor...@gm...> > > I'm not sure if that is a good idea, or if that is better left to "make > spotless". On the other hand if you don't have Perl on your system > you're probably just building from a clean tarball anyway. Hmm, maybe add cleanout target which would call clean first and remove generated files as well? Cyrill |
From: H. P. A. <hp...@zy...> - 2013-10-28 07:21:13
|
On 10/27/2013 10:18 AM, nasm-bot for Cyrill Gorcunov wrote: > Commit-ID: b6c7291b3d1f904b20955c3f9829b8cc92801227 > Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=b6c7291b3d1f904b20955c3f9829b8cc92801227 > Author: Cyrill Gorcunov <gor...@gm...> > AuthorDate: Sun, 27 Oct 2013 21:15:47 +0400 > Committer: Cyrill Gorcunov <gor...@gm...> > CommitDate: Sun, 27 Oct 2013 21:15:47 +0400 > > make: Remove generated files on clean target > > Signed-off-by: Cyrill Gorcunov <gor...@gm...> I'm not sure if that is a good idea, or if that is better left to "make spotless". On the other hand if you don't have Perl on your system you're probably just building from a clean tarball anyway. -hpa |
From: Cyrill G. <gor...@gm...> - 2013-10-16 20:53:12
|
Hi guys! I've just pushed insns-flags branch which has semi-done rework for instruction flags. The main problem which remains unhandled is cpu family bits used for both -- assembler and diassembler. Hope I manage to handle them on the weekend (too busy at moment, sigh :( Anyway, from the commits it should be more less clear what I wanted to achieve, any feedback is appreciated ;) Cyrill |
From: H. P. A. <hp...@zy...> - 2013-10-16 08:29:40
|
On 10/16/2013 12:36 AM, anonymous coward wrote: >> BND prefix support is also added. I did not know of a case using bnd and jcc8 >> at the same time. So I left that unresolved. Please let me know if this should >> be resolved. > > BND works for these: > > Jcc Jb/Jz, CALL/JMP Jz/Ev, RET(N), RET(N) Iw > > BND should warn for anything else, including JMP Jb. > BND JMP is actually a bit of a headache. JMP Jb doesn't require BND because JMP Jb is used for intramodule jumps, so arguably: BND JMP foo ... should drop the BND prefix if the JMP is relaxed to the Jb form, as the programmer doesn't know a priori if the Jb or Jz form will be generated. BND JMP short foo ... should be a warning, though. -hpa |
From: anonymous c. <nas...@us...> - 2013-10-16 07:36:33
|
> BND prefix support is also added. I did not know of a case using bnd and jcc8 > at the same time. So I left that unresolved. Please let me know if this should > be resolved. BND works for these: Jcc Jb/Jz, CALL/JMP Jz/Ev, RET(N), RET(N) Iw BND should warn for anything else, including JMP Jb. |
From: anonymous c. <nas...@us...> - 2013-10-16 07:33:21
|
> + bndstx [rax+0x3,rbx], bnd0 ; NASM - split EA > + bndstx [rax+rbx*1+0x3], bnd0 ; GAS > + bndstx [rax+rbx+3], bnd0 ; GAS > + bndstx [rax+0x3], bnd0, rbx ; ICC-1 > + bndstx [rax+0x3], rbx, bnd0 ; ICC-2 The GAS one is the only one that follows traditional NASM syntax. I see zero reason to clutter NASM with the 3-op or the comma syntax -- both of them can be implemented via fairly trivial macros, if a user really wants to code that way. As a result, you will end up with much less intrusive NASM changes for MPX support. All you really need is (a) warn for 16-bit address size for MPX memory instructions, (b) warn for EIP/RIP-relative address size for BND{LDX,STX,MK}, as well as (c) don't permit the EAF_TIMESTWO optimizations. |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:56
|
32bit and 64bit test asm files. Signed-off-by: Jin Kyu Song <jin...@in...> --- test/sha-64.asm | 31 +++++++++++++++++++++++++++++++ test/sha.asm | 31 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 test/sha-64.asm create mode 100644 test/sha.asm diff --git a/test/sha-64.asm b/test/sha-64.asm new file mode 100644 index 0000000..2874dfd --- /dev/null +++ b/test/sha-64.asm @@ -0,0 +1,31 @@ +;Testname=sha-64; Arguments=-felf64 -osha-64.o -O0; Files=stdout stderr sha-64.o +BITS 64 + sha1rnds4 xmm1, xmm2, 9 + sha1rnds4 xmm2, [rax], 7 + sha1rnds4 xmm3, [rax+0x12], 5 + sha1rnds4 xmm4, [rax+rbx*2], 1 + sha1nexte xmm1, xmm2 + sha1nexte xmm2, [rax] + sha1nexte xmm3, [rax+0x12] + sha1nexte xmm4, [rax+rbx*2] + sha1msg1 xmm1, xmm2 + sha1msg1 xmm2, [rax] + sha1msg1 xmm3, [rax+0x12] + sha1msg1 xmm4, [rax+rbx*2] + sha1msg2 xmm1, xmm2 + sha1msg2 xmm2, [rax] + sha1msg2 xmm3, [rax+0x12] + sha1msg2 xmm4, [rax+rbx*2] + sha256rnds2 xmm1, xmm2, xmm0 + sha256rnds2 xmm2, [rax], xmm0 + sha256rnds2 xmm3, [rax+0x12], xmm0 + sha256rnds2 xmm4, [rax+rbx*2], xmm0 + sha256msg1 xmm1, xmm2 + sha256msg1 xmm2, [rax] + sha256msg1 xmm3, [rax+0x12] + sha256msg1 xmm4, [rax+rbx*2] + sha256msg2 xmm1, xmm2 + sha256msg2 xmm2, [rax] + sha256msg2 xmm3, [rax+0x12] + sha256msg2 xmm4, [rax+rbx*2] + diff --git a/test/sha.asm b/test/sha.asm new file mode 100644 index 0000000..684cadd --- /dev/null +++ b/test/sha.asm @@ -0,0 +1,31 @@ +;Testname=sha; Arguments=-felf -osha.o -O0; Files=stdout stderr sha.o +BITS 32 + + sha1rnds4 xmm1, xmm2, 9 + sha1rnds4 xmm2, [eax], 7 + sha1rnds4 xmm3, [eax+0x12], 5 + sha1rnds4 xmm4, [eax+ebx*2], 1 + sha1nexte xmm1, xmm2 + sha1nexte xmm2, [eax] + sha1nexte xmm3, [eax+0x12] + sha1nexte xmm4, [eax+ebx*2] + sha1msg1 xmm1, xmm2 + sha1msg1 xmm2, [eax] + sha1msg1 xmm3, [eax+0x12] + sha1msg1 xmm4, [eax+ebx*2] + sha1msg2 xmm1, xmm2 + sha1msg2 xmm2, [eax] + sha1msg2 xmm3, [eax+0x12] + sha1msg2 xmm4, [eax+ebx*2] + sha256rnds2 xmm1, xmm2, xmm0 + sha256rnds2 xmm2, [eax], xmm0 + sha256rnds2 xmm3, [eax+0x12], xmm0 + sha256rnds2 xmm4, [eax+ebx*2], xmm0 + sha256msg1 xmm1, xmm2 + sha256msg1 xmm2, [eax] + sha256msg1 xmm3, [eax+0x12] + sha256msg1 xmm4, [eax+ebx*2] + sha256msg2 xmm1, xmm2 + sha256msg2 xmm2, [eax] + sha256msg2 xmm3, [eax+0x12] + sha256msg2 xmm4, [eax+ebx*2] -- 1.7.9.5 |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:55
|
MPX test asm files are added. These include all three different styles of mib syntax (NASM, ICC and gas). Signed-off-by: Jin Kyu Song <jin...@in...> --- test/mpx-64.asm | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/mpx.asm | 85 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 test/mpx-64.asm create mode 100644 test/mpx.asm diff --git a/test/mpx-64.asm b/test/mpx-64.asm new file mode 100644 index 0000000..50cc4da --- /dev/null +++ b/test/mpx-64.asm @@ -0,0 +1,117 @@ +;Testname=mpx-64; Arguments=-felf64 -ompx-64.o -O0; Files=stdout stderr mpx-64.o +BITS 64 + + bndmk bnd1, [r11] + bndmk bnd1, [rax] + bndmk bnd1, [0x399] + bndmk bnd1, [r9+0x3] + bndmk bnd1, [rax+0x3] + bndmk bnd1, [3,1*r12] + bndmk bnd1, [rax+rcx] + bndmk bnd1, [r11+1*rax+0x3] + bndmk bnd1, [rbx+1*r9+0x3] + + ; bndmov + bndmov bnd1, [r11] + bndmov bnd1, [rax] + bndmov bnd1, [0x399] + bndmov bnd2, [r9+0x3] + bndmov bnd2, [rax+0x3] + bndmov bnd0, [1*r12+0x3] + bndmov bnd2, [rax+rdx] + bndmov bnd1, [r11+1*rax+0x3] + bndmov bnd1, [rbx+1*r9+0x3] + bndmov bnd0, bnd2 + + bndmov [r11], bnd1 + bndmov [rax], bnd1 + bndmov [0x399], bnd1 + bndmov [r9+0x3], bnd2 + bndmov [rax+0x3], bnd2 + bndmov [1*r12+0x3], bnd0 + bndmov [rax+rdx], bnd2 + bndmov [r11+1*rax+0x3], bnd1 + bndmov [rbx+1*r9+0x3], bnd1 + bndmov bnd2, bnd0 + + ; bndcl + bndcl bnd1, [r11] + bndcl bnd1, [rax] + bndcl bnd1, r11 + bndcl bnd1, rcx + bndcl bnd1, [0x399] + bndcl bnd1, [r9+0x3] + bndcl bnd1, [rax+0x3] + bndcl bnd1, [1*r12+0x3] + bndcl bnd1, [rax+rcx] + bndcl bnd1, [r11+1*rax+0x3] + bndcl bnd1, [rbx+1*r9+0x3] + + ; bndcu + bndcu bnd1, [r11] + bndcu bnd1, [rax] + bndcu bnd1, r11 + bndcu bnd1, rcx + bndcu bnd1, [0x399] + bndcu bnd1, [r9+0x3] + bndcu bnd1, [rax+0x3] + bndcu bnd1, [1*r12+0x3] + bndcu bnd1, [rax+rcx] + bndcu bnd1, [r11+1*rax+0x3] + bndcu bnd1, [rbx+1*r9+0x3] + + ; bndcn + bndcn bnd1, [r11] + bndcn bnd1, [rax] + bndcn bnd1, r11 + bndcn bnd1, rcx + bndcn bnd1, [0x399] + bndcn bnd1, [r9+0x3] + bndcn bnd1, [rax+0x3] + bndcn bnd1, [1*r9+0x3] + bndcn bnd1, [rax+rcx] + bndcn bnd1, [r11+1*rax+0x3] + bndcn bnd1, [rbx+1*r9+0x3] + + ; bndstx + ; next 5 lines should be parsed same + bndstx [rax+0x3,rbx], bnd0 ; NASM - split EA + bndstx [rax+rbx*1+0x3], bnd0 ; GAS + bndstx [rax+rbx+3], bnd0 ; GAS + bndstx [rax+0x3], bnd0, rbx ; ICC-1 + bndstx [rax+0x3], rbx, bnd0 ; ICC-2 + + ; GAS's confusing EA - rcx is base reg in NASM + bndstx [rcx*1], bnd2 + ; next 4 lines should be parsed same + bndstx [,rcx*1], bnd2 ; NASM + bndstx [0,rcx*1], bnd2 ; NASM + bndstx [0], bnd2, rcx ; ICC-1 + bndstx [0], rcx, bnd2 ; ICC-2 + + bndstx [1*r12+3], bnd2 ; GAS's confusing EA again + bndstx [3,1*r12], bnd2 ; NASM + bndstx [3], r12, bnd2 ; ICC + + bndstx [r12+0x399], bnd3 + bndstx [r11+0x1234], bnd1 + bndstx [rbx+0x1234], bnd2 + bndstx [rdx], bnd1 + + ; bndldx + bndldx bnd0, [rax+rbx*1+0x3] + bndldx bnd2, [rbx+rdx+3] + bndldx bnd3, [r12+0x399] + bndldx bnd1, [r11+0x1234] + bndldx bnd2, [rbx+0x1234] + bndldx bnd2, [1*rbx+3] + bndldx bnd2, [1*r12+3] + bndldx bnd1, [rdx] + + ; bnd + bnd ret + bnd call foo + bnd jmp foo + bnd jno foo + +foo: bnd ret diff --git a/test/mpx.asm b/test/mpx.asm new file mode 100644 index 0000000..24ffcc8 --- /dev/null +++ b/test/mpx.asm @@ -0,0 +1,85 @@ +;Testname=mpx; Arguments=-felf -ompx.o -O0; Files=stdout stderr mpx.o +BITS 32 + + bndmk bnd1, [eax] + bndmk bnd1, [0x399] + bndmk bnd1, [ecx+0x3] + bndmk bnd1, [eax+ecx] + bndmk bnd1, [ecx*1] + bndmk bnd1, [edx+1*eax+0x3] + + ; bndmov + bndmov bnd1, [eax] + bndmov bnd1, [0x399] + bndmov bnd1, [ecx+0x3] + bndmov bnd1, [eax+ecx] + bndmov bnd1, [ecx*1] + bndmov bnd1, [edx+1*eax+0x3] + bndmov bnd0, bnd1 + + bndmov [eax], bnd1 + bndmov [0x399], bnd1 + bndmov [ecx+0x3], bnd1 + bndmov [eax+ecx], bnd1 + bndmov [ecx*1], bnd1 + bndmov [edx+1*eax+0x3], bnd1 + bndmov bnd1, bnd0 + + ; bndcl + bndcl bnd1, [eax] + bndcl bnd1, ecx + bndcl bnd1, [0x399] + bndcl bnd1, [ecx+0x3] + bndcl bnd1, [eax+ecx] + bndcl bnd1, [ecx*1] + bndcl bnd1, [edx+1*eax+0x3] + + ; bndcu + bndcu bnd1, [eax] + bndcu bnd1, ecx + bndcu bnd1, [0x399] + bndcu bnd1, [ecx+0x3] + bndcu bnd1, [eax+ecx] + bndcu bnd1, [ecx*1] + bndcu bnd1, [edx+1*eax+0x3] + + ; bndcn + bndcn bnd1, [eax] + bndcn bnd1, ecx + bndcn bnd1, [0x399] + bndcn bnd1, [ecx+0x3] + bndcn bnd1, [eax+ecx] + bndcn bnd1, [ecx*1] + bndcn bnd1, [edx+1*eax+0x3] + + ; bndstx + bndstx [eax+ebx*1+0x3], bnd0 + bndstx [eax+0x3,ebx], bnd0 + bndstx [eax+0x3], bnd0, ebx + bndstx [eax+0x3], ebx, bnd0 + bndstx [ecx*1], bnd2 + bndstx [,ecx*1], bnd2 + bndstx [0,ecx*1], bnd2 + bndstx [0], bnd2, ecx + bndstx [0], ecx, bnd2 + bndstx [edx+0x399], bnd3 + bndstx [1*ebx+3], bnd2 + bndstx [3,1*ebx], bnd2 + bndstx [3], ebx, bnd2 + bndstx [edx], bnd1 + + ; bndldx + bndldx bnd0, [eax+ebx*1+0x3] + bndldx bnd2, [ebx+edx+3] + bndldx bnd2, [ecx*1] + bndldx bnd3, [edx+0x399] + bndldx bnd2, [1*ebx+3] + bndldx bnd1, [edx] + + ; bnd + bnd ret + bnd call foo + bnd jmp foo + bnd jno foo + +foo: bnd ret -- 1.7.9.5 |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:55
|
BND prefix is used for adding bounds checking protection across flow control changes such as call, ret, jmp and jcc calls. Signed-off-by: Jin Kyu Song <jin...@in...> --- assemble.c | 13 +++++++++++-- disasm.c | 5 +++++ insns.dat | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ insns.pl | 1 + nasm.h | 1 + nasmlib.c | 2 +- parser.c | 1 + tokens.dat | 1 + 8 files changed, 75 insertions(+), 3 deletions(-) diff --git a/assemble.c b/assemble.c index 5a1602e..07e4723 100644 --- a/assemble.c +++ b/assemble.c @@ -162,6 +162,7 @@ * \367 - address-size prefix (0x67) used as opcode extension * \370,\371 - match only if operand 0 meets byte jump criteria. * 370 is used for Jcc, 371 is used for JMP. + * \372 - BND prefix (0xF2 byte) used for preserving bnd0..3 * \373 - assemble 0x03 if bits==16, 0x05 if bits==32; * used for conditional jump over longer jump * \374 - this instruction takes an XMM VSIB memory EA @@ -193,6 +194,7 @@ enum match_result { MERR_BADMODE, MERR_BADHLE, MERR_ENCMISMATCH, + MERR_BADBND, /* * Matching success; the conditional ones first */ @@ -547,6 +549,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, iflags_t cp, case P_REPNE: case P_REPNZ: case P_XACQUIRE: + case P_BND: c = 0xF2; break; case P_REPE: @@ -1739,8 +1742,7 @@ static void gencode(int32_t segment, int64_t offset, int bits, offset += 1; break; - case 0370: - case 0371: + case3(0370): break; case 0373: @@ -2227,6 +2229,13 @@ static enum match_result matches(const struct itemplate *itemp, if ((itemp->code[0] & ~1) == 0370) return MOK_JUMP; + /* + * Check if BND prefix is allowed + */ + if ((itemp->code[0] != 0372) && + has_prefix(instruction, PPS_REP, P_BND)) + return MERR_BADBND; + return MOK_GOOD; } diff --git a/disasm.c b/disasm.c index f50ceb9..eace1e9 100644 --- a/disasm.c +++ b/disasm.c @@ -862,6 +862,11 @@ static int matches(const struct itemplate *t, uint8_t *data, case 0371: break; + case 0372: + if (prefix->rep == 0xF2) + drep = P_BND; + break; + case 0374: eat = EA_XMMVSIB; break; diff --git a/insns.dat b/insns.dat index 8b29cc4..e52cb46 100644 --- a/insns.dat +++ b/insns.dat @@ -273,6 +273,24 @@ CALL mem [m: odf ff /2] 8086 CALL rm16 [m: o16 ff /2] 8086,NOLONG CALL rm32 [m: o32 ff /2] 386,NOLONG CALL rm64 [m: o64nw ff /2] X64 +; BND + CALL +CALL imm [i: bnd odf e8 rel] 8086,MPX +CALL imm|near [i: bnd odf e8 rel] 8086,ND,MPX +CALL imm16 [i: bnd o16 e8 rel] 8086,NOLONG,MPX +CALL imm16|near [i: bnd o16 e8 rel] 8086,ND,NOLONG,MPX +CALL imm32 [i: bnd o32 e8 rel] 386,NOLONG,MPX +CALL imm32|near [i: bnd o32 e8 rel] 386,ND,NOLONG,MPX +CALL imm64 [i: bnd o64nw e8 rel] X64,MPX +CALL imm64|near [i: bnd o64nw e8 rel] X64,ND,MPX +CALL mem|near [m: bnd odf ff /2] 8086,ND,MPX +CALL rm16|near [m: bnd o16 ff /2] 8086,NOLONG,ND,MPX +CALL rm32|near [m: bnd o32 ff /2] 386,NOLONG,ND,MPX +CALL rm64|near [m: bnd o64nw ff /2] X64,ND,MPX +CALL mem [m: bnd odf ff /2] 8086,MPX +CALL rm16 [m: bnd o16 ff /2] 8086,NOLONG,MPX +CALL rm32 [m: bnd o32 ff /2] 386,NOLONG,MPX +CALL rm64 [m: bnd o64nw ff /2] X64,MPX + CBW void [ o16 98] 8086 CDQ void [ o32 99] 386 CDQE void [ o64 98] X64 @@ -706,6 +724,24 @@ JMP mem [m: odf ff /4] 8086 JMP rm16 [m: o16 ff /4] 8086,NOLONG JMP rm32 [m: o32 ff /4] 386,NOLONG JMP rm64 [m: o64nw ff /4] X64 +; BND + JMP +JMP imm [i: bnd odf e9 rel] 8086,MPX +JMP imm|near [i: bnd odf e9 rel] 8086,ND,MPX +JMP imm16 [i: bnd o16 e9 rel] 8086,NOLONG,MPX +JMP imm16|near [i: bnd o16 e9 rel] 8086,ND,NOLONG,MPX +JMP imm32 [i: bnd o32 e9 rel] 386,NOLONG,MPX +JMP imm32|near [i: bnd o32 e9 rel] 386,ND,NOLONG,MPX +JMP imm64 [i: bnd o64nw e9 rel] X64,MPX +JMP imm64|near [i: bnd o64nw e9 rel] X64,ND,MPX +JMP mem|near [m: bnd odf ff /4] 8086,ND,MPX +JMP rm16|near [m: bnd o16 ff /4] 8086,NOLONG,ND,MPX +JMP rm32|near [m: bnd o32 ff /4] 386,NOLONG,ND,MPX +JMP rm64|near [m: bnd o64nw ff /4] X64,ND,MPX +JMP mem [m: bnd odf ff /4] 8086,MPX +JMP rm16 [m: bnd o16 ff /4] 8086,NOLONG,MPX +JMP rm32 [m: bnd o32 ff /4] 386,NOLONG,MPX +JMP rm64 [m: bnd o64nw ff /4] X64,MPX + JMPE imm [i: odf 0f b8 rel] IA64 JMPE imm16 [i: o16 0f b8 rel] IA64 JMPE imm32 [i: o32 0f b8 rel] IA64 @@ -1117,6 +1153,12 @@ RETF void [ cb] 8086 RETF imm [i: ca iw] 8086,SW RETN void [ c3] 8086 RETN imm [i: c2 iw] 8086,SW +; BND + RET +RET void [ bnd c3] 8086,MPX +RET imm [i: bnd c2 iw] 8086,SW,MPX +RETN void [ bnd c3] 8086,MPX +RETN imm [i: bnd c2 iw] 8086,SW,MPX + ROL rm8,unity [m-: d0 /0] 8086 ROL rm8,reg_cl [m-: d2 /0] 8086 ROL rm8,imm8 [mi: c0 /0 ib,u] 186 @@ -1483,6 +1525,18 @@ Jcc imm [i: jcc8 70+c rel8] 8086,ND Jcc imm [i: 0f 80+c rel] 386,ND Jcc imm [i: 71+c jlen e9 rel] 8086,ND Jcc imm [i: 70+c rel8] 8086 +; BND + Jcc +Jcc imm|near [i: bnd odf 0f 80+c rel] 386,MPX +Jcc imm16|near [i: bnd o16 0f 80+c rel] 386,NOLONG,MPX +Jcc imm32|near [i: bnd o32 0f 80+c rel] 386,NOLONG,MPX +Jcc imm64|near [i: bnd o64nw 0f 80+c rel] X64,MPX +Jcc imm|short [i: bnd 70+c rel8] 8086,ND,MPX +; TODO: check if bnd and jcc8 can be used together +;Jcc imm [i: bnd jcc8 70+c rel8] 8086,ND,MPX +Jcc imm [i: bnd 0f 80+c rel] 386,ND,MPX +Jcc imm [i: bnd 71+c jlen e9 rel] 8086,ND,MPX +Jcc imm [i: bnd 70+c rel8] 8086,MPX + SETcc mem [m: 0f 90+c /0] 386,SB SETcc reg8 [m: 0f 90+c /0] 386 diff --git a/insns.pl b/insns.pl index f897794..40478df 100755 --- a/insns.pl +++ b/insns.pl @@ -765,6 +765,7 @@ sub byte_code_compile($$) { 'resb' => 0340, 'jcc8' => 0370, # Match only if Jcc possible with single byte 'jmp8' => 0371, # Match only if JMP possible with single byte + 'bnd' => 0372, # BND (0xF2) prefix available 'jlen' => 0373, # Length of jump 'hlexr' => 0271, 'hlenl' => 0272, diff --git a/nasm.h b/nasm.h index 50e4b63..5ca2aa5 100644 --- a/nasm.h +++ b/nasm.h @@ -552,6 +552,7 @@ enum prefixes { /* instruction prefixes */ P_WAIT, P_XACQUIRE, P_XRELEASE, + P_BND, PREFIX_ENUM_LIMIT }; diff --git a/nasmlib.c b/nasmlib.c index 2367ff3..8464c5d 100644 --- a/nasmlib.c +++ b/nasmlib.c @@ -564,7 +564,7 @@ void standard_extension(char *inname, char *outname, char *extension) static const char *prefix_names[] = { "a16", "a32", "a64", "asp", "lock", "o16", "o32", "o64", "osp", "rep", "repe", "repne", "repnz", "repz", "times", "wait", - "xacquire", "xrelease" + "xacquire", "xrelease", "bnd" }; const char *prefix_name(int token) diff --git a/parser.c b/parser.c index 93a1cd2..092135d 100644 --- a/parser.c +++ b/parser.c @@ -89,6 +89,7 @@ static int prefix_slot(int prefix) case P_REPNZ: case P_XACQUIRE: case P_XRELEASE: + case P_BND: return PPS_REP; case P_O16: case P_O32: diff --git a/tokens.dat b/tokens.dat index d12b296..211eb09 100644 --- a/tokens.dat +++ b/tokens.dat @@ -54,6 +54,7 @@ times wait xacquire xrelease +bnd % TOKEN_SPECIAL, 0, 0, S_* abs -- 1.7.9.5 |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:55
|
UINT64_C() macro is used for iflags as it becomes 64bit. Signed-off-by: Jin Kyu Song <jin...@in...> --- insns.h | 158 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/insns.h b/insns.h index 8b725ae..a170533 100644 --- a/insns.h +++ b/insns.h @@ -76,88 +76,88 @@ extern const uint8_t nasm_bytecodes[]; * iflags_t is defined to store these flags. */ -#define IF_SM 0x00000001UL /* size match */ -#define IF_SM2 0x00000002UL /* size match first two operands */ -#define IF_SB 0x00000004UL /* unsized operands can't be non-byte */ -#define IF_SW 0x00000008UL /* unsized operands can't be non-word */ -#define IF_SD 0x0000000CUL /* unsized operands can't be non-dword */ -#define IF_SQ 0x00000010UL /* unsized operands can't be non-qword */ -#define IF_SO 0x00000014UL /* unsized operands can't be non-oword */ -#define IF_SY 0x00000018UL /* unsized operands can't be non-yword */ -#define IF_SZ 0x0000001CUL /* unsized operands can't be non-zword */ -#define IF_SIZE 0x00000038UL /* unsized operands must match the bitsize */ -#define IF_SX 0x0000003CUL /* unsized operands not allowed */ -#define IF_SMASK 0x0000003CUL /* mask for unsized argument size */ -#define IF_AR0 0x00000040UL /* SB, SW, SD applies to argument 0 */ -#define IF_AR1 0x00000080UL /* SB, SW, SD applies to argument 1 */ -#define IF_AR2 0x000000C0UL /* SB, SW, SD applies to argument 2 */ -#define IF_AR3 0x00000100UL /* SB, SW, SD applies to argument 3 */ -#define IF_AR4 0x00000140UL /* SB, SW, SD applies to argument 4 */ -#define IF_ARMASK 0x000001C0UL /* mask for unsized argument spec */ -#define IF_ARSHFT 6 /* LSB in IF_ARMASK */ -#define IF_OPT 0x00000200UL /* optimizing assembly only */ +#define IF_SM UINT64_C(0x00000001) /* size match */ +#define IF_SM2 UINT64_C(0x00000002) /* size match first two operands */ +#define IF_SB UINT64_C(0x00000004) /* unsized operands can't be non-byte */ +#define IF_SW UINT64_C(0x00000008) /* unsized operands can't be non-word */ +#define IF_SD UINT64_C(0x0000000C) /* unsized operands can't be non-dword */ +#define IF_SQ UINT64_C(0x00000010) /* unsized operands can't be non-qword */ +#define IF_SO UINT64_C(0x00000014) /* unsized operands can't be non-oword */ +#define IF_SY UINT64_C(0x00000018) /* unsized operands can't be non-yword */ +#define IF_SZ UINT64_C(0x0000001C) /* unsized operands can't be non-zword */ +#define IF_SIZE UINT64_C(0x00000038) /* unsized operands must match the bitsize */ +#define IF_SX UINT64_C(0x0000003C) /* unsized operands not allowed */ +#define IF_SMASK UINT64_C(0x0000003C) /* mask for unsized argument size */ +#define IF_AR0 UINT64_C(0x00000040) /* SB, SW, SD applies to argument 0 */ +#define IF_AR1 UINT64_C(0x00000080) /* SB, SW, SD applies to argument 1 */ +#define IF_AR2 UINT64_C(0x000000C0) /* SB, SW, SD applies to argument 2 */ +#define IF_AR3 UINT64_C(0x00000100) /* SB, SW, SD applies to argument 3 */ +#define IF_AR4 UINT64_C(0x00000140) /* SB, SW, SD applies to argument 4 */ +#define IF_ARMASK UINT64_C(0x000001C0) /* mask for unsized argument spec */ +#define IF_ARSHFT 6 /* LSB in IF_ARMASK */ +#define IF_OPT UINT64_C(0x00000200) /* optimizing assembly only */ /* The next 3 bits aren't actually used for anything */ -#define IF_PRIV 0x00000000UL /* it's a privileged instruction */ -#define IF_SMM 0x00000000UL /* it's only valid in SMM */ -#define IF_PROT 0x00000000UL /* it's protected mode only */ -#define IF_LOCK 0x00000400UL /* lockable if operand 0 is memory */ -#define IF_NOLONG 0x00000800UL /* it's not available in long mode */ -#define IF_LONG 0x00001000UL /* long mode instruction */ -#define IF_NOHLE 0x00002000UL /* HLE prefixes forbidden */ -#define IF_MIB 0x00004000UL /* Disassemble with split EA */ +#define IF_PRIV UINT64_C(0x00000000) /* it's a privileged instruction */ +#define IF_SMM UINT64_C(0x00000000) /* it's only valid in SMM */ +#define IF_PROT UINT64_C(0x00000000) /* it's protected mode only */ +#define IF_LOCK UINT64_C(0x00000400) /* lockable if operand 0 is memory */ +#define IF_NOLONG UINT64_C(0x00000800) /* it's not available in long mode */ +#define IF_LONG UINT64_C(0x00001000) /* long mode instruction */ +#define IF_NOHLE UINT64_C(0x00002000) /* HLE prefixes forbidden */ +#define IF_MIB UINT64_C(0x00004000) /* Disassemble with split EA */ /* These flags are currently not used for anything - intended for insn set */ -#define IF_UNDOC 0x8000000000UL /* it's an undocumented instruction */ -#define IF_HLE 0x4000000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_AVX512 0x2000000000UL /* it's an AVX-512F (512b) instruction */ -#define IF_FPU 0x0100000000UL /* it's an FPU instruction */ -#define IF_MMX 0x0200000000UL /* it's an MMX instruction */ -#define IF_3DNOW 0x0300000000UL /* it's a 3DNow! instruction */ -#define IF_SSE 0x0400000000UL /* it's a SSE (KNI, MMX2) instruction */ -#define IF_SSE2 0x0500000000UL /* it's a SSE2 instruction */ -#define IF_SSE3 0x0600000000UL /* it's a SSE3 (PNI) instruction */ -#define IF_VMX 0x0700000000UL /* it's a VMX instruction */ -#define IF_SSSE3 0x0800000000UL /* it's an SSSE3 instruction */ -#define IF_SSE4A 0x0900000000UL /* AMD SSE4a */ -#define IF_SSE41 0x0A00000000UL /* it's an SSE4.1 instruction */ -#define IF_SSE42 0x0B00000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_SSE5 0x0C00000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_AVX 0x0D00000000UL /* it's an AVX (128b) instruction */ -#define IF_AVX2 0x0E00000000UL /* it's an AVX2 (256b) instruction */ -#define IF_FMA 0x1000000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_BMI1 0x1100000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_BMI2 0x1200000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_TBM 0x1300000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_RTM 0x1400000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_INVPCID 0x1500000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_AVX512CD (0x1600000000UL|IF_AVX512) /* AVX-512 Conflict Detection insns */ -#define IF_AVX512ER (0x1700000000UL|IF_AVX512) /* AVX-512 Exponential and Reciprocal */ -#define IF_AVX512PF (0x1800000000UL|IF_AVX512) /* AVX-512 Prefetch instructions */ -#define IF_MPX 0x1900000000UL /* MPX instructions */ -#define IF_SHA 0x1A00000000UL /* SHA instructions */ -#define IF_INSMASK 0xFF00000000UL /* the mask for instruction set types */ -#define IF_PMASK 0xFF000000UL /* the mask for processor types */ -#define IF_PLEVEL 0x0F000000UL /* the mask for processor instr. level */ - /* also the highest possible processor */ -#define IF_8086 0x00000000UL /* 8086 instruction */ -#define IF_186 0x01000000UL /* 186+ instruction */ -#define IF_286 0x02000000UL /* 286+ instruction */ -#define IF_386 0x03000000UL /* 386+ instruction */ -#define IF_486 0x04000000UL /* 486+ instruction */ -#define IF_PENT 0x05000000UL /* Pentium instruction */ -#define IF_P6 0x06000000UL /* P6 instruction */ -#define IF_KATMAI 0x07000000UL /* Katmai instructions */ -#define IF_WILLAMETTE 0x08000000UL /* Willamette instructions */ -#define IF_PRESCOTT 0x09000000UL /* Prescott instructions */ -#define IF_X86_64 0x0A000000UL /* x86-64 instruction (long or legacy mode) */ -#define IF_NEHALEM 0x0B000000UL /* Nehalem instruction */ -#define IF_WESTMERE 0x0C000000UL /* Westmere instruction */ -#define IF_SANDYBRIDGE 0x0D000000UL /* Sandy Bridge instruction */ -#define IF_FUTURE 0x0E000000UL /* Future processor (not yet disclosed) */ +#define IF_UNDOC UINT64_C(0x8000000000) /* it's an undocumented instruction */ +#define IF_HLE UINT64_C(0x4000000000) /* HACK NEED TO REORGANIZE THESE BITS */ +#define IF_AVX512 UINT64_C(0x2000000000) /* it's an AVX-512F (512b) instruction */ +#define IF_FPU UINT64_C(0x0100000000) /* it's an FPU instruction */ +#define IF_MMX UINT64_C(0x0200000000) /* it's an MMX instruction */ +#define IF_3DNOW UINT64_C(0x0300000000) /* it's a 3DNow! instruction */ +#define IF_SSE UINT64_C(0x0400000000) /* it's a SSE (KNI, MMX2) instruction */ +#define IF_SSE2 UINT64_C(0x0500000000) /* it's a SSE2 instruction */ +#define IF_SSE3 UINT64_C(0x0600000000) /* it's a SSE3 (PNI) instruction */ +#define IF_VMX UINT64_C(0x0700000000) /* it's a VMX instruction */ +#define IF_SSSE3 UINT64_C(0x0800000000) /* it's an SSSE3 instruction */ +#define IF_SSE4A UINT64_C(0x0900000000) /* AMD SSE4a */ +#define IF_SSE41 UINT64_C(0x0A00000000) /* it's an SSE4.1 instruction */ +#define IF_SSE42 UINT64_C(0x0B00000000) /* HACK NEED TO REORGANIZE THESE BITS */ +#define IF_SSE5 UINT64_C(0x0C00000000) /* HACK NEED TO REORGANIZE THESE BITS */ +#define IF_AVX UINT64_C(0x0D00000000) /* it's an AVX (128b) instruction */ +#define IF_AVX2 UINT64_C(0x0E00000000) /* it's an AVX2 (256b) instruction */ +#define IF_FMA UINT64_C(0x1000000000) /* HACK NEED TO REORGANIZE THESE BITS */ +#define IF_BMI1 UINT64_C(0x1100000000) /* HACK NEED TO REORGANIZE THESE BITS */ +#define IF_BMI2 UINT64_C(0x1200000000) /* HACK NEED TO REORGANIZE THESE BITS */ +#define IF_TBM UINT64_C(0x1300000000) /* HACK NEED TO REORGANIZE THESE BITS */ +#define IF_RTM UINT64_C(0x1400000000) /* HACK NEED TO REORGANIZE THESE BITS */ +#define IF_INVPCID UINT64_C(0x1500000000) /* HACK NEED TO REORGANIZE THESE BITS */ +#define IF_AVX512CD (UINT64_C(0x1600000000)|IF_AVX512) /* AVX-512 Conflict Detection insns */ +#define IF_AVX512ER (UINT64_C(0x1700000000)|IF_AVX512) /* AVX-512 Exponential and Reciprocal */ +#define IF_AVX512PF (UINT64_C(0x1800000000)|IF_AVX512) /* AVX-512 Prefetch instructions */ +#define IF_MPX UINT64_C(0x1900000000) /* MPX instructions */ +#define IF_SHA UINT64_C(0x1A00000000) /* SHA instructions */ +#define IF_INSMASK UINT64_C(0xFF00000000) /* the mask for instruction set types */ +#define IF_PMASK UINT64_C(0xFF000000) /* the mask for processor types */ +#define IF_PLEVEL UINT64_C(0x0F000000) /* the mask for processor instr. level */ + /* also the highest possible processor */ +#define IF_8086 UINT64_C(0x00000000) /* 8086 instruction */ +#define IF_186 UINT64_C(0x01000000) /* 186+ instruction */ +#define IF_286 UINT64_C(0x02000000) /* 286+ instruction */ +#define IF_386 UINT64_C(0x03000000) /* 386+ instruction */ +#define IF_486 UINT64_C(0x04000000) /* 486+ instruction */ +#define IF_PENT UINT64_C(0x05000000) /* Pentium instruction */ +#define IF_P6 UINT64_C(0x06000000) /* P6 instruction */ +#define IF_KATMAI UINT64_C(0x07000000) /* Katmai instructions */ +#define IF_WILLAMETTE UINT64_C(0x08000000) /* Willamette instructions */ +#define IF_PRESCOTT UINT64_C(0x09000000) /* Prescott instructions */ +#define IF_X86_64 UINT64_C(0x0A000000) /* x86-64 instruction (long or legacy mode) */ +#define IF_NEHALEM UINT64_C(0x0B000000) /* Nehalem instruction */ +#define IF_WESTMERE UINT64_C(0x0C000000) /* Westmere instruction */ +#define IF_SANDYBRIDGE UINT64_C(0x0D000000) /* Sandy Bridge instruction */ +#define IF_FUTURE UINT64_C(0x0E000000) /* Future processor (not yet disclosed) */ #define IF_X64 (IF_LONG|IF_X86_64) -#define IF_IA64 0x0F000000UL /* IA64 instructions (in x86 mode) */ -#define IF_CYRIX 0x10000000UL /* Cyrix-specific instruction */ -#define IF_AMD 0x20000000UL /* AMD-specific instruction */ -#define IF_SPMASK 0x30000000UL /* specific processor types mask */ +#define IF_IA64 UINT64_C(0x0F000000) /* IA64 instructions (in x86 mode) */ +#define IF_CYRIX UINT64_C(0x10000000) /* Cyrix-specific instruction */ +#define IF_AMD UINT64_C(0x20000000) /* AMD-specific instruction */ +#define IF_SPMASK UINT64_C(0x30000000) /* specific processor types mask */ #define IF_PFMASK (IF_INSMASK|IF_SPMASK) /* disassembly "prefer" mask */ #endif /* NASM_INSNS_H */ -- 1.7.9.5 |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:54
|
From: "H. Peter Anvin" <hp...@li...> Add support for emitting split EA format in the disassembler, indicated by the MIB instruction flag. Signed-off-by: H. Peter Anvin <hp...@li...> Signed-off-by: Jin Kyu Song <jin...@in...> --- disasm.c | 17 +++++++++++++++-- insns.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/disasm.c b/disasm.c index 9a5f9ad..f50ceb9 100644 --- a/disasm.c +++ b/disasm.c @@ -955,7 +955,7 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize, uint8_t *origdata; int works; insn tmp_ins, ins; - iflags_t goodness, best; + iflags_t goodness, best, flags; int best_pref; struct prefix_info prefix; bool end_prefix; @@ -1174,6 +1174,7 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize, /* Pick the best match */ p = best_p; length = best_length; + flags = (*p)->flags; slen = 0; @@ -1331,7 +1332,7 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize, nasm_reg_names[(o->basereg-EXPR_REG_START)]); started = true; } - if (o->indexreg != -1) { + if (o->indexreg != -1 && !(flags & IF_MIB)) { if (started) output[slen++] = '+'; slen += snprintf(output + slen, outbufsize - slen, "%s", @@ -1395,6 +1396,18 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize, "%s0x%"PRIx32"", prefix, offset); } } + + if (o->indexreg != -1 && (flags & IF_MIB)) { + output[slen++] = ','; + slen += snprintf(output + slen, outbufsize - slen, "%s", + nasm_reg_names[(o->indexreg-EXPR_REG_START)]); + if (o->scale > 1) + slen += + snprintf(output + slen, outbufsize - slen, "*%d", + o->scale); + started = true; + } + output[slen++] = ']'; } else { slen += diff --git a/insns.h b/insns.h index b12d4eb..61b04cc 100644 --- a/insns.h +++ b/insns.h @@ -104,6 +104,7 @@ extern const uint8_t nasm_bytecodes[]; #define IF_NOLONG 0x00000800UL /* it's not available in long mode */ #define IF_LONG 0x00001000UL /* long mode instruction */ #define IF_NOHLE 0x00002000UL /* HLE prefixes forbidden */ +#define IF_MIB 0x00004000UL /* Disassemble with split EA */ /* These flags are currently not used for anything - intended for insn set */ #define IF_UNDOC 0x8000000000UL /* it's an undocumented instruction */ #define IF_HLE 0x4000000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -- 1.7.9.5 |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:54
|
From: "H. Peter Anvin" <hp...@li...> There is an awful lot of syntax-heavy "result->oprs[operand]" going on; simplify by making a pointer to the current operand. Signed-off-by: H. Peter Anvin <hp...@li...> Signed-off-by: Jin Kyu Song <jin...@in...> --- parser.c | 284 +++++++++++++++++++++++++++++--------------------------------- 1 file changed, 132 insertions(+), 152 deletions(-) diff --git a/parser.c b/parser.c index 1b08657..3450e77 100644 --- a/parser.c +++ b/parser.c @@ -106,7 +106,7 @@ static int prefix_slot(int prefix) } } -static void process_size_override(insn *result, int operand) +static void process_size_override(insn *result, operand *op) { if (tasm_compatible_mode) { switch ((int)tokval.t_integer) { @@ -123,23 +123,23 @@ static void process_size_override(insn *result, int operand) * but 32-bit flat model addressing in our code. */ case S_BYTE: - result->oprs[operand].type |= BITS8; + op->type |= BITS8; break; case S_WORD: - result->oprs[operand].type |= BITS16; + op->type |= BITS16; break; case S_DWORD: case S_LONG: - result->oprs[operand].type |= BITS32; + op->type |= BITS32; break; case S_QWORD: - result->oprs[operand].type |= BITS64; + op->type |= BITS64; break; case S_TWORD: - result->oprs[operand].type |= BITS80; + op->type |= BITS80; break; case S_OWORD: - result->oprs[operand].type |= BITS128; + op->type |= BITS128; break; default: nasm_error(ERR_NONFATAL, @@ -150,17 +150,17 @@ static void process_size_override(insn *result, int operand) /* Standard NASM compatible syntax */ switch ((int)tokval.t_integer) { case S_NOSPLIT: - result->oprs[operand].eaflags |= EAF_TIMESTWO; + op->eaflags |= EAF_TIMESTWO; break; case S_REL: - result->oprs[operand].eaflags |= EAF_REL; + op->eaflags |= EAF_REL; break; case S_ABS: - result->oprs[operand].eaflags |= EAF_ABS; + op->eaflags |= EAF_ABS; break; case S_BYTE: - result->oprs[operand].disp_size = 8; - result->oprs[operand].eaflags |= EAF_BYTEOFFS; + op->disp_size = 8; + op->eaflags |= EAF_BYTEOFFS; break; case P_A16: case P_A32: @@ -173,17 +173,17 @@ static void process_size_override(insn *result, int operand) result->prefixes[PPS_ASIZE] = tokval.t_integer; break; case S_WORD: - result->oprs[operand].disp_size = 16; - result->oprs[operand].eaflags |= EAF_WORDOFFS; + op->disp_size = 16; + op->eaflags |= EAF_WORDOFFS; break; case S_DWORD: case S_LONG: - result->oprs[operand].disp_size = 32; - result->oprs[operand].eaflags |= EAF_WORDOFFS; + op->disp_size = 32; + op->eaflags |= EAF_WORDOFFS; break; case S_QWORD: - result->oprs[operand].disp_size = 64; - result->oprs[operand].eaflags |= EAF_WORDOFFS; + op->disp_size = 64; + op->eaflags |= EAF_WORDOFFS; break; default: nasm_error(ERR_NONFATAL, "invalid size specification in" @@ -246,7 +246,7 @@ insn *parse_line(int pass, char *buffer, insn *result, ldfunc ldef) { bool insn_is_label = false; struct eval_hints hints; - int operand; + int opnum; int critical; bool first; bool recover; @@ -266,10 +266,8 @@ restart_parse: result->evex_brerop = -1; /* Reset EVEX broadcasting/ER op position */ /* Ignore blank lines */ - if (i == TOKEN_EOS) { - result->opcode = I_none; - return result; - } + if (i == TOKEN_EOS) + goto fail; if (i != TOKEN_ID && i != TOKEN_INSN && @@ -277,8 +275,7 @@ restart_parse: (i != TOKEN_REG || !IS_SREG(tokval.t_integer))) { nasm_error(ERR_NONFATAL, "label or instruction expected at start of line"); - result->opcode = I_none; - return result; + goto fail; } if (i == TOKEN_ID || (insn_is_label && i == TOKEN_INSN)) { @@ -306,10 +303,8 @@ restart_parse: } /* Just a label here */ - if (i == TOKEN_EOS) { - result->opcode = I_none; - return result; - } + if (i == TOKEN_EOS) + goto fail; nasm_build_assert(P_none != 0); memset(result->prefixes, P_none, sizeof(result->prefixes)); @@ -328,10 +323,8 @@ restart_parse: i = stdscan(NULL, &tokval); value = evaluate(stdscan, NULL, &tokval, NULL, pass0, nasm_error, NULL); i = tokval.t_type; - if (!value) { /* but, error in evaluator */ - result->opcode = I_none; /* unrecoverable parse error: */ - return result; /* ignore this instruction */ - } + if (!value) /* Error in evaluator */ + goto fail; if (!is_simple(value)) { nasm_error(ERR_NONFATAL, "non-constant argument supplied to TIMES"); @@ -382,8 +375,7 @@ restart_parse: return result; } else { nasm_error(ERR_NONFATAL, "parser: instruction expected"); - result->opcode = I_none; - return result; + goto fail; } } @@ -525,10 +517,8 @@ is_expression: value = evaluate(stdscan, NULL, &tokval, NULL, critical, nasm_error, NULL); i = tokval.t_type; - if (!value) { /* error in evaluator */ - result->opcode = I_none; /* unrecoverable parse error: */ - return result; /* ignore this instruction */ - } + if (!value) /* Error in evaluator */ + goto fail; if (is_unknown(value)) { eop->type = EOT_DB_NUMBER; eop->offset = 0; /* doesn't matter what we put */ @@ -556,8 +546,7 @@ is_expression: if (i != ',') { nasm_error(ERR_NONFATAL, "comma expected after operand %d", oper_num); - result->opcode = I_none;/* unrecoverable parse error: */ - return result; /* ignore this instruction */ + goto fail; } } @@ -587,8 +576,7 @@ is_expression: * If we reach here, one of the above errors happened. * Throw the instruction away. */ - result->opcode = I_none; - return result; + goto fail; } else /* DB ... */ if (oper_num == 0) nasm_error(ERR_WARNING | ERR_PASS1, "no operand for data declaration"); @@ -603,17 +591,18 @@ is_expression: * of these, separated by commas, and terminated by a zero token. */ - for (operand = 0; operand < MAX_OPERANDS; operand++) { + for (opnum = 0; opnum < MAX_OPERANDS; opnum++) { + operand *op = &result->oprs[opnum]; expr *value; /* used most of the time */ int mref; /* is this going to be a memory ref? */ int bracket; /* is it a [] mref, or a & mref? */ int setsize = 0; decoflags_t brace_flags = 0; /* flags for decorators in braces */ - result->oprs[operand].disp_size = 0; /* have to zero this whatever */ - result->oprs[operand].eaflags = 0; /* and this */ - result->oprs[operand].opflags = 0; - result->oprs[operand].decoflags = 0; + op->disp_size = 0; /* have to zero this whatever */ + op->eaflags = 0; /* and this */ + op->opflags = 0; + op->decoflags = 0; i = stdscan(NULL, &tokval); if (i == TOKEN_EOS) @@ -623,64 +612,64 @@ is_expression: goto restart_parse; } first = false; - result->oprs[operand].type = 0; /* so far, no override */ + op->type = 0; /* so far, no override */ while (i == TOKEN_SPECIAL) { /* size specifiers */ switch ((int)tokval.t_integer) { case S_BYTE: if (!setsize) /* we want to use only the first */ - result->oprs[operand].type |= BITS8; + op->type |= BITS8; setsize = 1; break; case S_WORD: if (!setsize) - result->oprs[operand].type |= BITS16; + op->type |= BITS16; setsize = 1; break; case S_DWORD: case S_LONG: if (!setsize) - result->oprs[operand].type |= BITS32; + op->type |= BITS32; setsize = 1; break; case S_QWORD: if (!setsize) - result->oprs[operand].type |= BITS64; + op->type |= BITS64; setsize = 1; break; case S_TWORD: if (!setsize) - result->oprs[operand].type |= BITS80; + op->type |= BITS80; setsize = 1; break; case S_OWORD: if (!setsize) - result->oprs[operand].type |= BITS128; + op->type |= BITS128; setsize = 1; break; case S_YWORD: if (!setsize) - result->oprs[operand].type |= BITS256; + op->type |= BITS256; setsize = 1; break; case S_ZWORD: if (!setsize) - result->oprs[operand].type |= BITS512; + op->type |= BITS512; setsize = 1; break; case S_TO: - result->oprs[operand].type |= TO; + op->type |= TO; break; case S_STRICT: - result->oprs[operand].type |= STRICT; + op->type |= STRICT; break; case S_FAR: - result->oprs[operand].type |= FAR; + op->type |= FAR; break; case S_NEAR: - result->oprs[operand].type |= NEAR; + op->type |= NEAR; break; case S_SHORT: - result->oprs[operand].type |= SHORT; + op->type |= SHORT; break; default: nasm_error(ERR_NONFATAL, "invalid operand size specification"); @@ -693,7 +682,7 @@ is_expression: bracket = (i == '['); i = stdscan(NULL, &tokval); /* then skip the colon */ while (i == TOKEN_SPECIAL || i == TOKEN_PREFIX) { - process_size_override(result, operand); + process_size_override(result, op); i = stdscan(NULL, &tokval); } } else { /* immediate operand, or register */ @@ -701,22 +690,20 @@ is_expression: bracket = false; /* placate optimisers */ } - if ((result->oprs[operand].type & FAR) && !mref && + if ((op->type & FAR) && !mref && result->opcode != I_JMP && result->opcode != I_CALL) { nasm_error(ERR_NONFATAL, "invalid use of FAR operand specifier"); } value = evaluate(stdscan, NULL, &tokval, - &result->oprs[operand].opflags, + &op->opflags, critical, nasm_error, &hints); i = tokval.t_type; - if (result->oprs[operand].opflags & OPFLAG_FORWARD) { + if (op->opflags & OPFLAG_FORWARD) { result->forw_ref = true; } - if (!value) { /* nasm_error in evaluator */ - result->opcode = I_none; /* unrecoverable parse error: */ - return result; /* ignore this instruction */ - } + if (!value) /* Error in evaluator */ + goto fail; if (i == ':' && mref) { /* it was seg:offset */ /* * Process the segment override. @@ -731,26 +718,24 @@ is_expression: else { result->prefixes[PPS_SEG] = value->type; if (IS_FSGS(value->type)) - result->oprs[operand].eaflags |= EAF_FSGS; + op->eaflags |= EAF_FSGS; } i = stdscan(NULL, &tokval); /* then skip the colon */ while (i == TOKEN_SPECIAL || i == TOKEN_PREFIX) { - process_size_override(result, operand); + process_size_override(result, op); i = stdscan(NULL, &tokval); } value = evaluate(stdscan, NULL, &tokval, - &result->oprs[operand].opflags, + &op->opflags, critical, nasm_error, &hints); i = tokval.t_type; - if (result->oprs[operand].opflags & OPFLAG_FORWARD) { + if (op->opflags & OPFLAG_FORWARD) { result->forw_ref = true; } /* and get the offset */ - if (!value) { /* but, error in evaluator */ - result->opcode = I_none; /* unrecoverable parse error: */ - return result; /* ignore this instruction */ - } + if (!value) /* Error in evaluator */ + goto fail; } recover = false; @@ -790,7 +775,7 @@ is_expression: "line expected after operand"); recover = true; } else if (i == ':') { - result->oprs[operand].type |= COLON; + op->type |= COLON; } else if (i == TOKEN_DECORATOR || i == TOKEN_OPMASK) { /* parse opmask (and zeroing) after an operand */ recover = parse_braces(&brace_flags); @@ -813,8 +798,8 @@ is_expression: int64_t o; /* offset */ b = i = -1, o = s = 0; - result->oprs[operand].hintbase = hints.base; - result->oprs[operand].hinttype = hints.type; + op->hintbase = hints.base; + op->hinttype = hints.type; if (e->type && e->type <= EXPR_REG_END) { /* this bit's a register */ bool is_gpr = is_class(REG_GPR,nasm_reg_flags[e->type]); @@ -835,8 +820,7 @@ is_expression: /* If both want to be index */ nasm_error(ERR_NONFATAL, "invalid effective address: two index registers"); - result->opcode = I_none; - return result; + goto fail; } else b = e->type; e++; @@ -845,14 +829,13 @@ is_expression: if (e->type <= EXPR_REG_END) { /* in fact, is there an error? */ nasm_error(ERR_NONFATAL, "beroset-p-603-invalid effective address"); - result->opcode = I_none; - return result; + goto fail; } else { if (e->type == EXPR_UNKNOWN) { - result->oprs[operand].opflags |= OPFLAG_UNKNOWN; + op->opflags |= OPFLAG_UNKNOWN; o = 0; /* doesn't matter what */ - result->oprs[operand].wrt = NO_SEG; /* nor this */ - result->oprs[operand].segment = NO_SEG; /* or this */ + op->wrt = NO_SEG; /* nor this */ + op->segment = NO_SEG; /* or this */ while (e->type) e++; /* go to the end of the line */ } else { @@ -861,118 +844,114 @@ is_expression: e++; } if (e->type == EXPR_WRT) { - result->oprs[operand].wrt = e->value; + op->wrt = e->value; e++; } else - result->oprs[operand].wrt = NO_SEG; + op->wrt = NO_SEG; /* * Look for a segment base type. */ if (e->type && e->type < EXPR_SEGBASE) { nasm_error(ERR_NONFATAL, "beroset-p-630-invalid effective address"); - result->opcode = I_none; - return result; + goto fail; } while (e->type && e->value == 0) e++; if (e->type && e->value != 1) { nasm_error(ERR_NONFATAL, "beroset-p-637-invalid effective address"); - result->opcode = I_none; - return result; + goto fail; } if (e->type) { - result->oprs[operand].segment = + op->segment = e->type - EXPR_SEGBASE; e++; } else - result->oprs[operand].segment = NO_SEG; + op->segment = NO_SEG; while (e->type && e->value == 0) e++; if (e->type) { nasm_error(ERR_NONFATAL, "beroset-p-650-invalid effective address"); - result->opcode = I_none; - return result; + goto fail; } } } } else { o = 0; - result->oprs[operand].wrt = NO_SEG; - result->oprs[operand].segment = NO_SEG; + op->wrt = NO_SEG; + op->segment = NO_SEG; } if (e->type != 0) { /* there'd better be nothing left! */ nasm_error(ERR_NONFATAL, "beroset-p-663-invalid effective address"); - result->opcode = I_none; - return result; + goto fail; } /* It is memory, but it can match any r/m operand */ - result->oprs[operand].type |= MEMORY_ANY; + op->type |= MEMORY_ANY; if (b == -1 && (i == -1 || s == 0)) { int is_rel = globalbits == 64 && - !(result->oprs[operand].eaflags & EAF_ABS) && + !(op->eaflags & EAF_ABS) && ((globalrel && - !(result->oprs[operand].eaflags & EAF_FSGS)) || - (result->oprs[operand].eaflags & EAF_REL)); + !(op->eaflags & EAF_FSGS)) || + (op->eaflags & EAF_REL)); - result->oprs[operand].type |= is_rel ? IP_REL : MEM_OFFS; + op->type |= is_rel ? IP_REL : MEM_OFFS; } if (i != -1) { opflags_t iclass = nasm_reg_flags[i]; if (is_class(XMMREG,iclass)) - result->oprs[operand].type |= XMEM; + op->type |= XMEM; else if (is_class(YMMREG,iclass)) - result->oprs[operand].type |= YMEM; + op->type |= YMEM; else if (is_class(ZMMREG,iclass)) - result->oprs[operand].type |= ZMEM; + op->type |= ZMEM; } - result->oprs[operand].basereg = b; - result->oprs[operand].indexreg = i; - result->oprs[operand].scale = s; - result->oprs[operand].offset = o; - result->oprs[operand].decoflags |= brace_flags; + op->basereg = b; + op->indexreg = i; + op->scale = s; + op->offset = o; + op->decoflags |= brace_flags; } else { /* it's not a memory reference */ if (is_just_unknown(value)) { /* it's immediate but unknown */ - result->oprs[operand].type |= IMMEDIATE; - result->oprs[operand].opflags |= OPFLAG_UNKNOWN; - result->oprs[operand].offset = 0; /* don't care */ - result->oprs[operand].segment = NO_SEG; /* don't care again */ - result->oprs[operand].wrt = NO_SEG; /* still don't care */ + op->type |= IMMEDIATE; + op->opflags |= OPFLAG_UNKNOWN; + op->offset = 0; /* don't care */ + op->segment = NO_SEG; /* don't care again */ + op->wrt = NO_SEG; /* still don't care */ - if(optimizing >= 0 && !(result->oprs[operand].type & STRICT)) { + if(optimizing >= 0 && !(op->type & STRICT)) { /* Be optimistic */ - result->oprs[operand].type |= + op->type |= UNITY | SBYTEWORD | SBYTEDWORD | UDWORD | SDWORD; } } else if (is_reloc(value)) { /* it's immediate */ - result->oprs[operand].type |= IMMEDIATE; - result->oprs[operand].offset = reloc_value(value); - result->oprs[operand].segment = reloc_seg(value); - result->oprs[operand].wrt = reloc_wrt(value); + op->type |= IMMEDIATE; + op->offset = reloc_value(value); + op->segment = reloc_seg(value); + op->wrt = reloc_wrt(value); if (is_simple(value)) { uint64_t n = reloc_value(value); if (n == 1) - result->oprs[operand].type |= UNITY; + op->type |= UNITY; if (optimizing >= 0 && - !(result->oprs[operand].type & STRICT)) { + !(op->type & STRICT)) { if ((uint32_t) (n + 128) <= 255) - result->oprs[operand].type |= SBYTEDWORD; + op->type |= SBYTEDWORD; if ((uint16_t) (n + 128) <= 255) - result->oprs[operand].type |= SBYTEWORD; + op->type |= SBYTEWORD; if (n <= 0xFFFFFFFF) - result->oprs[operand].type |= UDWORD; + op->type |= UDWORD; if (n + 0x80000000 <= 0xFFFFFFFF) - result->oprs[operand].type |= SDWORD; + op->type |= SDWORD; } } } else if(value->type == EXPR_RDSAE) { @@ -981,15 +960,14 @@ is_expression: * put the decorator information in the (opflag_t) type field * of previous operand. */ - operand --; + opnum--; op--; switch (value->value) { case BRC_RN: case BRC_RU: case BRC_RD: case BRC_RZ: case BRC_SAE: - result->oprs[operand].decoflags |= - (value->value == BRC_SAE ? SAE : ER); + op->decoflags |= (value->value == BRC_SAE ? SAE : ER); result->evex_rm = value->value; break; default: @@ -1001,8 +979,7 @@ is_expression: if (value->type >= EXPR_SIMPLE || value->value != 1) { nasm_error(ERR_NONFATAL, "invalid operand type"); - result->opcode = I_none; - return result; + goto fail; } /* @@ -1011,42 +988,41 @@ is_expression: for (i = 1; value[i].type; i++) if (value[i].value) { nasm_error(ERR_NONFATAL, "invalid operand type"); - result->opcode = I_none; - return result; + goto fail; } /* clear overrides, except TO which applies to FPU regs */ - if (result->oprs[operand].type & ~TO) { + if (op->type & ~TO) { /* * we want to produce a warning iff the specified size * is different from the register size */ - rs = result->oprs[operand].type & SIZE_MASK; + rs = op->type & SIZE_MASK; } else rs = 0; - result->oprs[operand].type &= TO; - result->oprs[operand].type |= REGISTER; - result->oprs[operand].type |= nasm_reg_flags[value->type]; - result->oprs[operand].decoflags |= brace_flags; - result->oprs[operand].basereg = value->type; + op->type &= TO; + op->type |= REGISTER; + op->type |= nasm_reg_flags[value->type]; + op->decoflags |= brace_flags; + op->basereg = value->type; - if (rs && (result->oprs[operand].type & SIZE_MASK) != rs) + if (rs && (op->type & SIZE_MASK) != rs) nasm_error(ERR_WARNING | ERR_PASS1, "register size specification ignored"); } } /* remember the position of operand having broadcasting/ER mode */ - if (result->oprs[operand].decoflags & (BRDCAST_MASK | ER | SAE)) - result->evex_brerop = operand; + if (op->decoflags & (BRDCAST_MASK | ER | SAE)) + result->evex_brerop = opnum; } - result->operands = operand; /* set operand count */ + result->operands = opnum; /* set operand count */ /* clear remaining operands */ - while (operand < MAX_OPERANDS) - result->oprs[operand++].type = 0; + while (opnum < MAX_OPERANDS) + result->oprs[opnum++].type = 0; /* * Transform RESW, RESD, RESQ, REST, RESO, RESY into RESB. @@ -1081,6 +1057,10 @@ is_expression: } return result; + +fail: + result->opcode = I_none; + return result; } static int is_comma_next(void) -- 1.7.9.5 |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:52
|
From: "H. Peter Anvin" <hp...@li...> Mostly intended for the "mib" expressions in BNDLDX/BNDSTX. Signed-off-by: H. Peter Anvin <hp...@li...> Signed-off-by: Jin Kyu Song <jin...@in...> --- parser.c | 97 ++++++++++++++++++++++++++++++++++++++++++++---------- test/splitea.asm | 11 +++++++ 2 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 test/splitea.asm diff --git a/parser.c b/parser.c index 180a439..697c727 100644 --- a/parser.c +++ b/parser.c @@ -242,15 +242,13 @@ static bool parse_braces(decoflags_t *decoflags) return recover; } -static int parse_mref(operand *op, const expr *e, - const struct eval_hints *hints, decoflags_t brace_flags) +static int parse_mref(operand *op, const expr *e) { int b, i, s; /* basereg, indexreg, scale */ int64_t o; /* offset */ - b = i = -1, o = s = 0; - op->hintbase = hints->base; - op->hinttype = hints->type; + b = i = -1; + o = s = 0; if (e->type && e->type <= EXPR_REG_END) { /* this bit's a register */ bool is_gpr = is_class(REG_GPR,nasm_reg_flags[e->type]); @@ -315,8 +313,7 @@ static int parse_mref(operand *op, const expr *e, return -1; } if (e->type) { - op->segment = - e->type - EXPR_SEGBASE; + op->segment = e->type - EXPR_SEGBASE; e++; } else op->segment = NO_SEG; @@ -341,6 +338,19 @@ static int parse_mref(operand *op, const expr *e, return -1; } + op->basereg = b; + op->indexreg = i; + op->scale = s; + op->offset = o; + return 0; +} + +static void mref_set_optype(operand *op) +{ + int b = op->basereg; + int i = op->indexreg; + int s = op->scale; + /* It is memory, but it can match any r/m operand */ op->type |= MEMORY_ANY; @@ -364,13 +374,6 @@ static int parse_mref(operand *op, const expr *e, else if (is_class(ZMMREG,iclass)) op->type |= ZMEM; } - - op->basereg = b; - op->indexreg = i; - op->scale = s; - op->offset = o; - op->decoflags |= brace_flags; - return 0; } insn *parse_line(int pass, char *buffer, insn *result, ldfunc ldef) @@ -725,8 +728,9 @@ is_expression: for (opnum = 0; opnum < MAX_OPERANDS; opnum++) { operand *op = &result->oprs[opnum]; expr *value; /* used most of the time */ - int mref; /* is this going to be a memory ref? */ - int bracket; /* is it a [] mref, or a & mref? */ + bool mref; /* is this going to be a memory ref? */ + bool bracket; /* is it a [] mref, or a & mref? */ + bool mib; /* compound (mib) mref? */ int setsize = 0; decoflags_t brace_flags = 0; /* flags for decorators in braces */ @@ -869,6 +873,56 @@ is_expression: goto fail; } + mib = false; + if (mref && bracket && i == ',') { + /* [seg:base+offset,index*scale] syntax (mib) */ + + operand o1, o2; /* Partial operands */ + + if (parse_mref(&o1, value)) + goto fail; + + i = stdscan(NULL, &tokval); /* Eat comma */ + value = evaluate(stdscan, NULL, &tokval, &op->opflags, + critical, nasm_error, &hints); + i = tokval.t_type; + + if (parse_mref(&o2, value)) + goto fail; + + if (o2.basereg != -1 && o2.indexreg == -1) { + o2.indexreg = o2.basereg; + o2.scale = 1; + o2.basereg = -1; + } + + if (o1.indexreg != -1 || o2.basereg != -1 || o2.offset != 0 || + o2.segment != NO_SEG || o2.wrt != NO_SEG) { + nasm_error(ERR_NONFATAL, "invalid mib expression"); + goto fail; + } + + op->basereg = o1.basereg; + op->indexreg = o2.indexreg; + op->scale = o2.scale; + op->offset = o1.offset; + op->segment = o1.segment; + op->wrt = o1.wrt; + + if (op->basereg != -1) { + op->hintbase = op->basereg; + op->hinttype = EAH_MAKEBASE; + } else if (op->indexreg != -1) { + op->hintbase = op->indexreg; + op->hinttype = EAH_NOTBASE; + } else { + op->hintbase = -1; + op->hinttype = EAH_NOHINT; + } + + mib = true; + } + recover = false; if (mref && bracket) { /* find ] at the end */ if (i != ']') { @@ -922,10 +976,17 @@ is_expression: * now convert the exprs returned from evaluate() * into operand descriptions... */ + op->decoflags |= brace_flags; if (mref) { /* it's a memory reference */ - if (parse_mref(op, value, &hints, brace_flags)) - goto fail; + /* A mib reference was fully parsed already */ + if (!mib) { + if (parse_mref(op, value)) + goto fail; + op->hintbase = hints.base; + op->hinttype = hints.type; + } + mref_set_optype(op); } else { /* it's not a memory reference */ if (is_just_unknown(value)) { /* it's immediate but unknown */ op->type |= IMMEDIATE; diff --git a/test/splitea.asm b/test/splitea.asm new file mode 100644 index 0000000..a2d980b --- /dev/null +++ b/test/splitea.asm @@ -0,0 +1,11 @@ + bits 32 + + mov eax,[eax] + mov eax,[eax+ecx] + mov eax,[eax+ecx*4] + mov eax,[eax+ecx*4+8] + + mov eax,[eax] + mov eax,[eax,ecx] + mov eax,[eax,ecx*4] + mov eax,[eax+8,ecx*4] -- 1.7.9.5 |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:52
|
New instruction extensions of SHA family are added. Signed-off-by: Jin Kyu Song <jin...@in...> --- insns.dat | 9 +++++++++ insns.h | 1 + 2 files changed, 10 insertions(+) diff --git a/insns.dat b/insns.dat index e52cb46..3906dba 100644 --- a/insns.dat +++ b/insns.dat @@ -4169,6 +4169,15 @@ BNDSTX mem128,bndreg [mr: 0f 1b /r ] MPX,MIB,SO,FUTURE BNDSTX mem128,reg64,bndreg [mxr: 0f 1b /r ] MPX,MIB,FUTURE BNDSTX mem128,bndreg,reg64 [mrx: 0f 1b /r ] MPX,MIB,FUTURE +; SHA instructions +SHA1RNDS4 xmmreg,xmmrm128,imm8 [rmi: 0f 3a cc /r ib ] SHA,FUTURE +SHA1NEXTE xmmreg,xmmrm128 [rm: 0f 38 c8 /r ] SHA,FUTURE +SHA1MSG1 xmmreg,xmmrm128 [rm: 0f 38 c9 /r ] SHA,FUTURE +SHA1MSG2 xmmreg,xmmrm128 [rm: 0f 38 ca /r ] SHA,FUTURE +SHA256RNDS2 xmmreg,xmmrm128,xmm0 [rm-: 0f 38 cb /r ] SHA,FUTURE +SHA256MSG1 xmmreg,xmmrm128 [rm: 0f 38 cc /r ] SHA,FUTURE +SHA256MSG2 xmmreg,xmmrm128 [rm: 0f 38 cd /r ] SHA,FUTURE + ;# Systematic names for the hinting nop instructions ; These should be last in the file HINT_NOP0 rm16 [m: o16 0f 18 /0] P6,UNDOC diff --git a/insns.h b/insns.h index 6e94f3d..8b725ae 100644 --- a/insns.h +++ b/insns.h @@ -133,6 +133,7 @@ extern const uint8_t nasm_bytecodes[]; #define IF_AVX512ER (0x1700000000UL|IF_AVX512) /* AVX-512 Exponential and Reciprocal */ #define IF_AVX512PF (0x1800000000UL|IF_AVX512) /* AVX-512 Prefetch instructions */ #define IF_MPX 0x1900000000UL /* MPX instructions */ +#define IF_SHA 0x1A00000000UL /* SHA instructions */ #define IF_INSMASK 0xFF00000000UL /* the mask for instruction set types */ #define IF_PMASK 0xFF000000UL /* the mask for processor types */ #define IF_PLEVEL 0x0F000000UL /* the mask for processor instr. level */ -- 1.7.9.5 |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:51
|
From: "H. Peter Anvin" <hp...@li...> Factor out the parsing of an mref from parse_line(). In order to support the [base,index] syntax we need to be able to parse an mref in two steps. Signed-off-by: H. Peter Anvin <hp...@li...> Signed-off-by: Jin Kyu Song <jin...@in...> --- parser.c | 257 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 132 insertions(+), 125 deletions(-) diff --git a/parser.c b/parser.c index 3450e77..180a439 100644 --- a/parser.c +++ b/parser.c @@ -242,6 +242,137 @@ static bool parse_braces(decoflags_t *decoflags) return recover; } +static int parse_mref(operand *op, const expr *e, + const struct eval_hints *hints, decoflags_t brace_flags) +{ + int b, i, s; /* basereg, indexreg, scale */ + int64_t o; /* offset */ + + b = i = -1, o = s = 0; + op->hintbase = hints->base; + op->hinttype = hints->type; + + if (e->type && e->type <= EXPR_REG_END) { /* this bit's a register */ + bool is_gpr = is_class(REG_GPR,nasm_reg_flags[e->type]); + + if (is_gpr && e->value == 1) + b = e->type; /* It can be basereg */ + else /* No, it has to be indexreg */ + i = e->type, s = e->value; + e++; + } + if (e->type && e->type <= EXPR_REG_END) { /* it's a 2nd register */ + bool is_gpr = is_class(REG_GPR,nasm_reg_flags[e->type]); + + if (b != -1) /* If the first was the base, ... */ + i = e->type, s = e->value; /* second has to be indexreg */ + + else if (!is_gpr || e->value != 1) { + /* If both want to be index */ + nasm_error(ERR_NONFATAL, + "invalid effective address: two index registers"); + return -1; + } else + b = e->type; + e++; + } + if (e->type != 0) { /* is there an offset? */ + if (e->type <= EXPR_REG_END) { /* in fact, is there an error? */ + nasm_error(ERR_NONFATAL, + "beroset-p-603-invalid effective address"); + return -1; + } else { + if (e->type == EXPR_UNKNOWN) { + op->opflags |= OPFLAG_UNKNOWN; + o = 0; /* doesn't matter what */ + op->wrt = NO_SEG; /* nor this */ + op->segment = NO_SEG; /* or this */ + while (e->type) + e++; /* go to the end of the line */ + } else { + if (e->type == EXPR_SIMPLE) { + o = e->value; + e++; + } + if (e->type == EXPR_WRT) { + op->wrt = e->value; + e++; + } else + op->wrt = NO_SEG; + /* + * Look for a segment base type. + */ + if (e->type && e->type < EXPR_SEGBASE) { + nasm_error(ERR_NONFATAL, + "beroset-p-630-invalid effective address"); + return -1; + } + while (e->type && e->value == 0) + e++; + if (e->type && e->value != 1) { + nasm_error(ERR_NONFATAL, + "beroset-p-637-invalid effective address"); + return -1; + } + if (e->type) { + op->segment = + e->type - EXPR_SEGBASE; + e++; + } else + op->segment = NO_SEG; + while (e->type && e->value == 0) + e++; + if (e->type) { + nasm_error(ERR_NONFATAL, + "beroset-p-650-invalid effective address"); + return -1; + } + } + } + } else { + o = 0; + op->wrt = NO_SEG; + op->segment = NO_SEG; + } + + if (e->type != 0) { /* there'd better be nothing left! */ + nasm_error(ERR_NONFATAL, + "beroset-p-663-invalid effective address"); + return -1; + } + + /* It is memory, but it can match any r/m operand */ + op->type |= MEMORY_ANY; + + if (b == -1 && (i == -1 || s == 0)) { + int is_rel = globalbits == 64 && + !(op->eaflags & EAF_ABS) && + ((globalrel && + !(op->eaflags & EAF_FSGS)) || + (op->eaflags & EAF_REL)); + + op->type |= is_rel ? IP_REL : MEM_OFFS; + } + + if (i != -1) { + opflags_t iclass = nasm_reg_flags[i]; + + if (is_class(XMMREG,iclass)) + op->type |= XMEM; + else if (is_class(YMMREG,iclass)) + op->type |= YMEM; + else if (is_class(ZMMREG,iclass)) + op->type |= ZMEM; + } + + op->basereg = b; + op->indexreg = i; + op->scale = s; + op->offset = o; + op->decoflags |= brace_flags; + return 0; +} + insn *parse_line(int pass, char *buffer, insn *result, ldfunc ldef) { bool insn_is_label = false; @@ -793,132 +924,8 @@ is_expression: */ if (mref) { /* it's a memory reference */ - expr *e = value; - int b, i, s; /* basereg, indexreg, scale */ - int64_t o; /* offset */ - - b = i = -1, o = s = 0; - op->hintbase = hints.base; - op->hinttype = hints.type; - - if (e->type && e->type <= EXPR_REG_END) { /* this bit's a register */ - bool is_gpr = is_class(REG_GPR,nasm_reg_flags[e->type]); - - if (is_gpr && e->value == 1) - b = e->type; /* It can be basereg */ - else /* No, it has to be indexreg */ - i = e->type, s = e->value; - e++; - } - if (e->type && e->type <= EXPR_REG_END) { /* it's a 2nd register */ - bool is_gpr = is_class(REG_GPR,nasm_reg_flags[e->type]); - - if (b != -1) /* If the first was the base, ... */ - i = e->type, s = e->value; /* second has to be indexreg */ - - else if (!is_gpr || e->value != 1) { - /* If both want to be index */ - nasm_error(ERR_NONFATAL, - "invalid effective address: two index registers"); - goto fail; - } else - b = e->type; - e++; - } - if (e->type != 0) { /* is there an offset? */ - if (e->type <= EXPR_REG_END) { /* in fact, is there an error? */ - nasm_error(ERR_NONFATAL, - "beroset-p-603-invalid effective address"); - goto fail; - } else { - if (e->type == EXPR_UNKNOWN) { - op->opflags |= OPFLAG_UNKNOWN; - o = 0; /* doesn't matter what */ - op->wrt = NO_SEG; /* nor this */ - op->segment = NO_SEG; /* or this */ - while (e->type) - e++; /* go to the end of the line */ - } else { - if (e->type == EXPR_SIMPLE) { - o = e->value; - e++; - } - if (e->type == EXPR_WRT) { - op->wrt = e->value; - e++; - } else - op->wrt = NO_SEG; - /* - * Look for a segment base type. - */ - if (e->type && e->type < EXPR_SEGBASE) { - nasm_error(ERR_NONFATAL, - "beroset-p-630-invalid effective address"); - goto fail; - } - while (e->type && e->value == 0) - e++; - if (e->type && e->value != 1) { - nasm_error(ERR_NONFATAL, - "beroset-p-637-invalid effective address"); - goto fail; - } - if (e->type) { - op->segment = - e->type - EXPR_SEGBASE; - e++; - } else - op->segment = NO_SEG; - while (e->type && e->value == 0) - e++; - if (e->type) { - nasm_error(ERR_NONFATAL, - "beroset-p-650-invalid effective address"); - goto fail; - } - } - } - } else { - o = 0; - op->wrt = NO_SEG; - op->segment = NO_SEG; - } - - if (e->type != 0) { /* there'd better be nothing left! */ - nasm_error(ERR_NONFATAL, - "beroset-p-663-invalid effective address"); + if (parse_mref(op, value, &hints, brace_flags)) goto fail; - } - - /* It is memory, but it can match any r/m operand */ - op->type |= MEMORY_ANY; - - if (b == -1 && (i == -1 || s == 0)) { - int is_rel = globalbits == 64 && - !(op->eaflags & EAF_ABS) && - ((globalrel && - !(op->eaflags & EAF_FSGS)) || - (op->eaflags & EAF_REL)); - - op->type |= is_rel ? IP_REL : MEM_OFFS; - } - - if (i != -1) { - opflags_t iclass = nasm_reg_flags[i]; - - if (is_class(XMMREG,iclass)) - op->type |= XMEM; - else if (is_class(YMMREG,iclass)) - op->type |= YMEM; - else if (is_class(ZMMREG,iclass)) - op->type |= ZMEM; - } - - op->basereg = b; - op->indexreg = i; - op->scale = s; - op->offset = o; - op->decoflags |= brace_flags; } else { /* it's not a memory reference */ if (is_just_unknown(value)) { /* it's immediate but unknown */ op->type |= IMMEDIATE; -- 1.7.9.5 |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:51
|
Added MPX instructions and corresponding parser and encoder. ICC style mib - base + disp and index are separate - is supported. E.g. bndstx [ebx+3], bnd2, edx -> ebx+3 : base+disp, edx : index As a supplement to NASM style mib - split EA - parser, omitted base+disp is now treated as 0 displacement. E.g. bndstx [,edx], bnd2 -> bndstx [0,edx], bnd2 Signed-off-by: Jin Kyu Song <jin...@in...> --- assemble.c | 23 ++++++++++++++++++++++- insns.dat | 21 +++++++++++++++++++++ insns.h | 1 + insns.pl | 3 +++ opflags.h | 5 ++++- parser.c | 7 +++++++ regs.dat | 3 +++ 7 files changed, 61 insertions(+), 2 deletions(-) diff --git a/assemble.c b/assemble.c index a38e56e..5a1602e 100644 --- a/assemble.c +++ b/assemble.c @@ -42,6 +42,7 @@ * \7 - add 4 to both the primary and the secondary operand number * \10..\13 - a literal byte follows in the code stream, to be added * to the register value of operand 0..3 + * \14..\17 - the position of index register operand in MIB (BND insns) * \20..\23 - a byte immediate operand, from operand 0..3 * \24..\27 - a zero-extended byte immediate operand, from operand 0..3 * \30..\33 - a word immediate operand, from operand 0..3 @@ -852,6 +853,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, enum ea_type eat; uint8_t hleok = 0; bool lockcheck = true; + enum reg_enum mib_index = R_none; /* For a separate index MIB reg form */ ins->rex = 0; /* Ensure REX is reset */ eat = EA_SCALAR; /* Expect a scalar EA */ @@ -885,6 +887,11 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, codes++, length++; break; + case4(014): + /* this is an index reg of MIB operand */ + mib_index = opx->basereg; + break; + case4(020): case4(024): length++; @@ -1184,6 +1191,17 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, } } + /* + * if a separate form of MIB (ICC style) is used, + * the index reg info is merged into mem operand + */ + if (mib_index != R_none) { + opy->indexreg = mib_index; + opy->scale = 1; + opy->hintbase = mib_index; + opy->hinttype = EAH_NOTBASE; + } + if (process_ea(opy, &ea_data, bits, rfield, rflags, ins) != eat) { errfunc(ERR_NONFATAL, "invalid effective address"); @@ -1336,6 +1354,9 @@ static void gencode(int32_t segment, int64_t offset, int bits, offset += 1; break; + case4(014): + break; + case4(020): if (opx->offset < -256 || opx->offset > 255) { errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV, @@ -2545,7 +2566,7 @@ static enum ea_type process_ea(operand *input, ea *output, int bits, } if (bt == it) /* convert EAX+2*EAX to 3*EAX */ bt = -1, bx = 0, s++; - if (bt == -1 && s == 1 && !(hb == it && ht == EAH_NOTBASE)) { + if (bt == -1 && s == 1 && !(hb == i && ht == EAH_NOTBASE)) { /* make single reg base, unless hint */ bt = it, bx = ix, it = -1, ix = 0; } diff --git a/insns.dat b/insns.dat index 2439a9d..8b29cc4 100644 --- a/insns.dat +++ b/insns.dat @@ -4093,6 +4093,27 @@ VSCATTERPF1QPD zmem64|mask [m:t1s: vsibz evex.512.66.0f38.w1 c7 /6 ] AVX51 VSCATTERPF1QPS zmem32|mask [m:t1s: vsibz evex.512.66.0f38.w0 c7 /6 ] AVX512PF,FUTURE PREFETCHWT1 mem8 [m: 0f 0d /2 ] FUTURE +; MPX instructions +BNDMK bndreg,mem32 [rm: o32 f3 0f 1b /r ] MPX,SD,FUTURE +BNDMK bndreg,mem64 [rm: o64nw f3 0f 1b /r ] MPX,SQ,FUTURE +BNDCL bndreg,rm32 [rm: o32 f3 0f 1a /r ] MPX,SD,FUTURE +BNDCL bndreg,rm64 [rm: o64nw f3 0f 1a /r ] MPX,SQ,FUTURE +BNDCU bndreg,rm32 [rm: o32 f2 0f 1a /r ] MPX,SD,FUTURE +BNDCU bndreg,rm64 [rm: o64nw f2 0f 1a /r ] MPX,SQ,FUTURE +BNDCN bndreg,rm32 [rm: o32 f2 0f 1b /r ] MPX,SD,FUTURE +BNDCN bndreg,rm64 [rm: o64nw f2 0f 1b /r ] MPX,SQ,FUTURE +BNDMOV bndreg,bndrm64 [rm: 66 0f 1a /r ] MPX,SQ,FUTURE +BNDMOV bndreg,bndrm128 [rm: 66 0f 1a /r ] MPX,SO,FUTURE +BNDMOV bndrm64,bndreg [mr: 66 0f 1b /r ] MPX,SQ,FUTURE +BNDMOV bndrm128,bndreg [mr: 66 0f 1b /r ] MPX,SO,FUTURE +BNDLDX bndreg,mem128 [rm: 0f 1a /r ] MPX,MIB,FUTURE +BNDLDX bndreg,mem128,reg64 [rmx: 0f 1a /r ] MPX,MIB,FUTURE +BNDSTX mem64,bndreg [mr: 0f 1b /r ] MPX,MIB,SQ,FUTURE +BNDSTX mem64,reg32,bndreg [mxr: 0f 1b /r ] MPX,MIB,FUTURE +BNDSTX mem64,bndreg,reg32 [mrx: 0f 1b /r ] MPX,MIB,FUTURE +BNDSTX mem128,bndreg [mr: 0f 1b /r ] MPX,MIB,SO,FUTURE +BNDSTX mem128,reg64,bndreg [mxr: 0f 1b /r ] MPX,MIB,FUTURE +BNDSTX mem128,bndreg,reg64 [mrx: 0f 1b /r ] MPX,MIB,FUTURE ;# Systematic names for the hinting nop instructions ; These should be last in the file diff --git a/insns.h b/insns.h index 61b04cc..6e94f3d 100644 --- a/insns.h +++ b/insns.h @@ -132,6 +132,7 @@ extern const uint8_t nasm_bytecodes[]; #define IF_AVX512CD (0x1600000000UL|IF_AVX512) /* AVX-512 Conflict Detection insns */ #define IF_AVX512ER (0x1700000000UL|IF_AVX512) /* AVX-512 Exponential and Reciprocal */ #define IF_AVX512PF (0x1800000000UL|IF_AVX512) /* AVX-512 Prefetch instructions */ +#define IF_MPX 0x1900000000UL /* MPX instructions */ #define IF_INSMASK 0xFF00000000UL /* the mask for instruction set types */ #define IF_PMASK 0xFF000000UL /* the mask for processor types */ #define IF_PLEVEL 0x0F000000UL /* the mask for processor instr. level */ diff --git a/insns.pl b/insns.pl index 60f7dd3..f897794 100755 --- a/insns.pl +++ b/insns.pl @@ -704,6 +704,7 @@ sub tupletype($) { # i = immediate # s = register field of is4/imz2 field # - = implicit (unencoded) operand +# x = indeX register of mib. 014..017 bytecodes are used. # # For an operand that should be filled into more than one field, # enter it as e.g. "r+v". @@ -843,6 +844,8 @@ sub byte_code_compile($$) { $opex = (($oppos{'m'} & 4) ? 06 : 0) | (($oppos{'r'} & 4) ? 05 : 0); push(@codes, $opex) if ($opex); + # if mib is composed with two separate operands - ICC style + push(@codes, 014 + ($oppos{'x'} & 3)) if (defined($oppos{'x'})); push(@codes, 0100 + (($oppos{'m'} & 3) << 3) + ($oppos{'r'} & 3)); $prefix_ok = 0; } elsif ($op =~ m:^/([0-7])$:) { diff --git a/opflags.h b/opflags.h index 014abe8..16c65cb 100644 --- a/opflags.h +++ b/opflags.h @@ -163,6 +163,7 @@ #define REG_CLASS_RM_YMM GEN_REG_CLASS(6) #define REG_CLASS_RM_ZMM GEN_REG_CLASS(7) #define REG_CLASS_OPMASK GEN_REG_CLASS(8) +#define REG_CLASS_BND GEN_REG_CLASS(9) #define is_class(class, op) (!((opflags_t)(class) & ~(opflags_t)(op))) #define is_reg_class(class, reg) is_class((class), nasm_reg_flags[(reg)]) @@ -196,6 +197,8 @@ #define OPMASK0 (GEN_SUBCLASS(1) | REG_CLASS_OPMASK | REGMEM | REGISTER) /* Opmask register zero (k0) */ #define RM_K RM_OPMASK #define KREG OPMASKREG +#define RM_BND ( REG_CLASS_BND | REGMEM) /* Bounds operand */ +#define BNDREG ( REG_CLASS_BND | REGMEM | REGISTER) /* Bounds register */ #define REG_CDT ( REG_CLASS_CDT | BITS32 | REGISTER) /* CRn, DRn and TRn */ #define REG_CREG (GEN_SUBCLASS(1) | REG_CLASS_CDT | BITS32 | REGISTER) /* CRn */ #define REG_DREG (GEN_SUBCLASS(2) | REG_CLASS_CDT | BITS32 | REGISTER) /* DRn */ @@ -243,7 +246,7 @@ #define ZMEM (GEN_SUBCLASS(5) | MEMORY) /* 512-bit vector SIB */ /* memory which matches any type of r/m operand */ -#define MEMORY_ANY (MEMORY | RM_GPR | RM_MMX | RM_XMM | RM_YMM | RM_ZMM | RM_OPMASK) +#define MEMORY_ANY (MEMORY | RM_GPR | RM_MMX | RM_XMM | RM_YMM | RM_ZMM | RM_OPMASK | RM_BND) /* special immediate values */ #define UNITY (GEN_SUBCLASS(0) | IMMEDIATE) /* operand equals 1 */ diff --git a/parser.c b/parser.c index 697c727..93a1cd2 100644 --- a/parser.c +++ b/parser.c @@ -820,6 +820,13 @@ is_expression: process_size_override(result, op); i = stdscan(NULL, &tokval); } + /* when a comma follows an opening bracket - [ , eax*4] */ + if (i == ',') { + /* treat as if there is a zero displacement virtually */ + tokval.t_type = TOKEN_NUM; + tokval.t_integer = 0; + stdscan_set(stdscan_get() - 1); /* rewind the comma */ + } } else { /* immediate operand, or register */ mref = false; bracket = false; /* placate optimisers */ diff --git a/regs.dat b/regs.dat index 7861119..46d5409 100644 --- a/regs.dat +++ b/regs.dat @@ -130,3 +130,6 @@ zmm1-31 ZMMREG zmmreg 1 # Opmask registers k0 OPMASK0 opmaskreg 0 k1-7 OPMASKREG opmaskreg 1 TFLAG_BRC_OPT + +# Bounds registers +bnd0-3 BNDREG bndreg 0 -- 1.7.9.5 |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:49
|
test/avx512*.asm files are now tested by using perfomtest.pl Refer to pefomtest help message for the usage. Signed-off-by: Jin Kyu Song <jin...@in...> --- test/avx512cd.asm | 1 + test/avx512er.asm | 1 + test/avx512f.asm | 3 ++- test/avx512pf.asm | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/test/avx512cd.asm b/test/avx512cd.asm index 670a6fc..b7322b2 100644 --- a/test/avx512cd.asm +++ b/test/avx512cd.asm @@ -1,3 +1,4 @@ +;Testname=avx512cd; Arguments=-fbin -oavx512cd.bin -O0 -DSRC; Files=stdout stderr avx512cd.bin ; AVX-512CD testcases from gas ;------------------------ ; diff --git a/test/avx512er.asm b/test/avx512er.asm index 6e08e60..8561aaa 100644 --- a/test/avx512er.asm +++ b/test/avx512er.asm @@ -1,3 +1,4 @@ +;Testname=avx512er; Arguments=-fbin -oavx512er.bin -O0 -DSRC; Files=stdout stderr avx512er.bin ; AVX-512ER testcases from gas ;------------------------ ; diff --git a/test/avx512f.asm b/test/avx512f.asm index 282dbea..c9307c7 100644 --- a/test/avx512f.asm +++ b/test/avx512f.asm @@ -1,4 +1,5 @@ -; AVX-512 testcases from gas +;Testname=avx512f; Arguments=-fbin -oavx512f.bin -O0 -DSRC; Files=stdout stderr avx512f.bin +; AVX-512F testcases from gas ;------------------------ ; ; This file is taken from there diff --git a/test/avx512pf.asm b/test/avx512pf.asm index 5227123..b00ed35 100644 --- a/test/avx512pf.asm +++ b/test/avx512pf.asm @@ -1,3 +1,4 @@ +;Testname=avx512pf; Arguments=-fbin -oavx512pf.bin -O0 -DSRC; Files=stdout stderr avx512pf.bin ; AVX-512PF testcases from gas ;------------------------ ; -- 1.7.9.5 |
From: Jin K. S. <jin...@in...> - 2013-10-16 03:57:48
|
This patch set includes Peter's patches for parsing a new split EA syntax. - [base + disp, index * scale] On top of these patches, I implemented MPX assembler. To encode ICC style mib operand - separate EA : [base + disp], index, a new 'x' operand type is added in insns.dat. This is for the separate index register. BND prefix support is also added. I did not know of a case using bnd and jcc8 at the same time. So I left that unresolved. Please let me know if this should be resolved. Test cases for MPX and SHA are also included. H. Peter Anvin (4): parser: simplify code by keeping a pointer to the current operand parse: factor out mref parsing parser: support split base,index effective address disasm: add support for emitting split EA format Jin Kyu Song (7): AVX-512: Add perfomtest-compliant headers to test cases MPX: Add MPX instructions MPX: Add BND prefix for brach instructions MPX: Add test cases for MPX SHA: Add SHA instructions SHA: SHA test cases iflags: Use UINT64_C() for 64bit values assemble.c | 36 +++- disasm.c | 22 ++- insns.dat | 84 ++++++++ insns.h | 155 +++++++-------- insns.pl | 4 + nasm.h | 1 + nasmlib.c | 2 +- opflags.h | 5 +- parser.c | 552 +++++++++++++++++++++++++++++------------------------ regs.dat | 3 + test/avx512cd.asm | 1 + test/avx512er.asm | 1 + test/avx512f.asm | 3 +- test/avx512pf.asm | 1 + test/mpx-64.asm | 117 ++++++++++++ test/mpx.asm | 85 +++++++++ test/sha-64.asm | 31 +++ test/sha.asm | 31 +++ test/splitea.asm | 11 ++ tokens.dat | 1 + 20 files changed, 814 insertions(+), 332 deletions(-) create mode 100644 test/mpx-64.asm create mode 100644 test/mpx.asm create mode 100644 test/sha-64.asm create mode 100644 test/sha.asm create mode 100644 test/splitea.asm -- 1.7.9.5 |
From: H. P. A. <hp...@zy...> - 2013-10-06 22:21:15
|
On 10/06/2013 02:39 PM, Cyrill Gorcunov wrote: >> >> Either way, good work on this! > > Lets do a deal, I'll try to finish all this on the week, and then > once everything work as expected (ie at least all tests get passed), > we re-think about moving these "specific" flags into separate entry, > ok? > Totally sounds like a plan. -hpa |
From: Cyrill G. <gor...@gm...> - 2013-10-06 21:39:38
|
On Sun, Oct 06, 2013 at 02:34:10PM -0700, H. Peter Anvin wrote: > I would like to suggest that we pick out the flags that are actually used by the > assembler for other than CPU feature determination, like the Sx flags, > and move them to a separate word and have the rest indirect. > On the other hand, perhaps that is a pretty useless distinction? I think, yes, it makes sence. Note that in first place I intentionally moved Sx, ARG and etc into first dword my %insns_flag_bit = ( # # dword bound, index 0 - specific flags # "SM" => [ 0, "size match"], "SM2" => [ 1, "size match first two operands"], "SB" => [ 2, "unsized operands can't be non-byte"], "SW" => [ 3, "unsized operands can't be non-word"], "SD" => [ 4, "unsized operands can't be non-dword"], "SQ" => [ 5, "unsized operands can't be non-qword"], "SO" => [ 6, "unsized operands can't be non-oword"], "SY" => [ 7, "unsized operands can't be non-yword"], "SZ" => [ 8, "unsized operands can't be non-zword"], "SIZE" => [ 9, "unsized operands must match the bitsize"], "SX" => [ 10, "unsized operands not allowed"], "AR0" => [ 11, "SB, SW, SD applies to argument 0"], "AR1" => [ 12, "SB, SW, SD applies to argument 1"], "AR2" => [ 13, "SB, SW, SD applies to argument 2"], "AR3" => [ 14, "SB, SW, SD applies to argument 3"], "AR4" => [ 15, "SB, SW, SD applies to argument 4"], "OPT" => [ 16, "optimizing assembly only"], > > Either way, good work on this! Lets do a deal, I'll try to finish all this on the week, and then once everything work as expected (ie at least all tests get passed), we re-think about moving these "specific" flags into separate entry, ok? |
From: Cyrill G. <gor...@gm...> - 2013-10-06 21:34:51
|
On Mon, Oct 07, 2013 at 01:28:23AM +0400, Cyrill Gorcunov wrote: > + > +sub insns_flag_index(@) { > + return undef if $_[0] eq "ignore"; > + > + my @prekey = @_; there should be @prekey = sort(@_); > + my $key = join("", @prekey); |
From: H. P. A. <hp...@zy...> - 2013-10-06 21:34:48
|
I would like to suggest that we pick out the flags that are actually used by the assembler for other than CPU feature determination, like the Sx flags, and move them to a separate word and have the rest indirect. On the other hand, perhaps that is a pretty useless distinction? Either way, good work on this! Cyrill Gorcunov <gor...@gm...> wrote: >Hi guys, here is early draft for instruction flags generator, >it might look somewhat ugly since I'm far from been perl experienced, >still take a look, and tell me what you think. > >There are some problem remains which I've not yet addressed > > - need to add flags into AVX512 templates > - need to address somehow "goodneds" in disassembler > (see second patch and fixme in the code) > >Cyrill Gorcunov (2): > insns-iflags.pl: Introduce instruction flags bitvector generator > insns.pl: Start using instruction flags generator > > Makefile.in | 9 +- > assemble.c | 27 +++--- > disasm.c | 6 +- >insns-iflags.pl | 295 >++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > insns.h | 113 +--------------------- > insns.pl | 22 +++-- > 6 files changed, 341 insertions(+), 131 deletions(-) > create mode 100644 insns-iflags.pl -- Sent from my mobile phone. Please pardon brevity and lack of formatting. |
From: Cyrill G. <gor...@gm...> - 2013-10-06 21:28:49
|
Hi guys, here is early draft for instruction flags generator, it might look somewhat ugly since I'm far from been perl experienced, still take a look, and tell me what you think. There are some problem remains which I've not yet addressed - need to add flags into AVX512 templates - need to address somehow "goodneds" in disassembler (see second patch and fixme in the code) Cyrill Gorcunov (2): insns-iflags.pl: Introduce instruction flags bitvector generator insns.pl: Start using instruction flags generator Makefile.in | 9 +- assemble.c | 27 +++--- disasm.c | 6 +- insns-iflags.pl | 295 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ insns.h | 113 +--------------------- insns.pl | 22 +++-- 6 files changed, 341 insertions(+), 131 deletions(-) create mode 100644 insns-iflags.pl -- 1.8.3.1 |
From: Cyrill G. <gor...@gm...> - 2013-10-06 21:28:35
|
There are known problems FIXME'ed in the code Signed-off-by: Cyrill Gorcunov <gor...@gm...> --- Makefile.in | 9 +++-- assemble.c | 27 ++++++++------- disasm.c | 6 ++-- insns.h | 113 +++--------------------------------------------------------- insns.pl | 22 ++++++++---- 5 files changed, 46 insertions(+), 131 deletions(-) diff --git a/Makefile.in b/Makefile.in index e1846ce..b25b0e2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -83,10 +83,11 @@ NASM = nasm.$(O) nasmlib.$(O) ver.$(O) \ strfunc.$(O) tokhash.$(O) regvals.$(O) regflags.$(O) \ ilog2.$(O) \ lib/strlcpy.$(O) \ - preproc-nop.$(O) + preproc-nop.$(O) \ + iflag.$(O) NDISASM = ndisasm.$(O) disasm.$(O) sync.$(O) nasmlib.$(O) ver.$(O) \ - insnsd.$(O) insnsb.$(O) insnsn.$(O) regs.$(O) regdis.$(O) + insnsd.$(O) insnsb.$(O) insnsn.$(O) regs.$(O) regdis.$(O) iflag.$(O) #-- End File Lists --# all: nasm$(X) ndisasm$(X) nasm.1 ndisasm.1 rdf @@ -102,6 +103,10 @@ ndisasm$(X): $(NDISASM) $(XOBJS) # though, so it isn't necessary to have Perl just to recompile NASM # from the distribution. +insns.pl: insns-iflags.pl + +iflag.c iflag.h: insns.dat insns.pl + $(PERL) $(srcdir)/insns.pl -t $(srcdir)/insns.dat insnsb.c: insns.dat insns.pl $(PERL) $(srcdir)/insns.pl -b $(srcdir)/insns.dat insnsa.c: insns.dat insns.pl diff --git a/assemble.c b/assemble.c index a38e56e..249be31 100644 --- a/assemble.c +++ b/assemble.c @@ -1267,7 +1267,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, } if (has_prefix(ins, PPS_LOCK, P_LOCK) && lockcheck && - (!(temp->flags & IF_LOCK) || !is_class(MEMORY, ins->oprs[0].type))) { + (!itemp_has(temp,IF_LOCK) || !is_class(MEMORY, ins->oprs[0].type))) { errfunc(ERR_WARNING | ERR_WARN_LOCK | ERR_PASS2 , "instruction is not lockable"); } @@ -1947,7 +1947,7 @@ static enum match_result find_match(const struct itemplate **tempp, else m = MERR_INVALOP; } else if (m == MERR_OPSIZEMISSING && - (temp->flags & IF_SMASK) != IF_SX) { + itemp_smask(temp) != IF_SMASK) { /* * Missing operand size and a candidate for fuzzy matching... */ @@ -2030,7 +2030,7 @@ static enum match_result matches(const struct itemplate *itemp, /* * Is it legal? */ - if (!(optimizing > 0) && (itemp->flags & IF_OPT)) + if (!(optimizing > 0) && itemp_has(itemp, IF_OPT)) return MERR_INVALOP; /* @@ -2043,7 +2043,7 @@ static enum match_result matches(const struct itemplate *itemp, /* * Process size flags */ - switch (itemp->flags & IF_SMASK) { + switch (itemp_smask(itemp)) { case IF_SB: asize = BITS8; break; @@ -2086,9 +2086,9 @@ static enum match_result matches(const struct itemplate *itemp, break; } - if (itemp->flags & IF_ARMASK) { + if (itemp_has(itemp, IF_ARMASK)) { /* S- flags only apply to a specific operand */ - i = ((itemp->flags & IF_ARMASK) >> IF_ARSHFT) - 1; + i = itemp_arg(itemp); memset(size, 0, sizeof size); size[i] = asize; } else { @@ -2149,7 +2149,7 @@ static enum match_result matches(const struct itemplate *itemp, } } else if (is_register(instruction->oprs[i].basereg) && nasm_regvals[instruction->oprs[i].basereg] >= 16 && - !(itemp->flags & IF_AVX512)) { + !itemp_has(itemp, IF_AVX512)) { return MERR_ENCMISMATCH; } } @@ -2160,8 +2160,8 @@ static enum match_result matches(const struct itemplate *itemp, /* * Check operand sizes */ - if (itemp->flags & (IF_SM | IF_SM2)) { - oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands); + if (itemp_has(itemp, IF_SM) || itemp_has(itemp, IF_SM2)) { + oprs = (itemp_has(itemp, IF_SM2) ? 2 : itemp->operands); for (i = 0; i < oprs; i++) { asize = itemp->opd[i] & SIZE_MASK; if (asize) { @@ -2182,20 +2182,21 @@ static enum match_result matches(const struct itemplate *itemp, /* * Check template is okay at the set cpu level + * FIXME */ - if (((itemp->flags & IF_PLEVEL) > cpu)) - return MERR_BADCPU; +// if (((itemp->flags & IF_PLEVEL) > cpu)) +// return MERR_BADCPU; /* * Verify the appropriate long mode flag. */ - if ((itemp->flags & (bits == 64 ? IF_NOLONG : IF_LONG))) + if (itemp_has(itemp, (bits == 64 ? IF_NOLONG : IF_LONG))) return MERR_BADMODE; /* * If we have a HLE prefix, look for the NOHLE flag */ - if ((itemp->flags & IF_NOHLE) && + if (itemp_has(itemp, IF_NOHLE) && (has_prefix(instruction, PPS_REP, P_XACQUIRE) || has_prefix(instruction, PPS_REP, P_XRELEASE))) return MERR_BADHLE; diff --git a/disasm.c b/disasm.c index 9a5f9ad..de50e5f 100644 --- a/disasm.c +++ b/disasm.c @@ -404,7 +404,7 @@ static int matches(const struct itemplate *t, uint8_t *data, ins->rex = prefix->rex; memset(ins->prefixes, 0, sizeof ins->prefixes); - if (t->flags & (segsize == 64 ? IF_NOLONG : IF_LONG)) + if (itemp_has(t, (segsize == 64 ? IF_NOLONG : IF_LONG))) return false; if (prefix->rep == 0xF2) @@ -1150,7 +1150,9 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize, */ if (works) { int i, nprefix; - goodness = ((*p)->flags & IF_PFMASK) ^ prefer; + /* FIXME */ +// goodness = ((*p)->flags & IF_PFMASK) ^ prefer; + goodness = 0; nprefix = 0; for (i = 0; i < MAXPREFIX; i++) if (tmp_ins.prefixes[i]) diff --git a/insns.h b/insns.h index b12d4eb..5d39a97 100644 --- a/insns.h +++ b/insns.h @@ -11,6 +11,7 @@ #include "nasm.h" #include "tokens.h" +#include "iflag.h" /* if changed, ITEMPLATE_END should be also changed accordingly */ struct itemplate { @@ -19,7 +20,7 @@ struct itemplate { opflags_t opd[MAX_OPERANDS]; /* bit flags for operand types */ decoflags_t deco[MAX_OPERANDS]; /* bit flags for operand decorators */ const uint8_t *code; /* the code it assembles to */ - iflags_t flags; /* some flags */ + uint32_t iflag_idx; /* some flags referenced by index */ }; /* Disassembler table structure */ @@ -48,113 +49,9 @@ extern const uint8_t nasm_bytecodes[]; #define ITEMPLATE_END {-1,-1,{-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1},NULL,0} /* - * Instruction template flags. These specify which processor - * targets the instruction is eligible for, whether it is - * privileged or undocumented, and also specify extra error - * checking on the matching of the instruction. - * - * IF_SM stands for Size Match: any operand whose size is not - * explicitly specified by the template is `really' intended to be - * the same size as the first size-specified operand. - * Non-specification is tolerated in the input instruction, but - * _wrong_ specification is not. - * - * IF_SM2 invokes Size Match on only the first _two_ operands, for - * three-operand instructions such as SHLD: it implies that the - * first two operands must match in size, but that the third is - * required to be _unspecified_. - * - * IF_SB invokes Size Byte: operands with unspecified size in the - * template are really bytes, and so no non-byte specification in - * the input instruction will be tolerated. IF_SW similarly invokes - * Size Word, and IF_SD invokes Size Doubleword. - * - * (The default state if neither IF_SM nor IF_SM2 is specified is - * that any operand with unspecified size in the template is - * required to have unspecified size in the instruction too...) - * - * iflags_t is defined to store these flags. + * FIXME This are to get rid off! */ - -#define IF_SM 0x00000001UL /* size match */ -#define IF_SM2 0x00000002UL /* size match first two operands */ -#define IF_SB 0x00000004UL /* unsized operands can't be non-byte */ -#define IF_SW 0x00000008UL /* unsized operands can't be non-word */ -#define IF_SD 0x0000000CUL /* unsized operands can't be non-dword */ -#define IF_SQ 0x00000010UL /* unsized operands can't be non-qword */ -#define IF_SO 0x00000014UL /* unsized operands can't be non-oword */ -#define IF_SY 0x00000018UL /* unsized operands can't be non-yword */ -#define IF_SZ 0x0000001CUL /* unsized operands can't be non-zword */ -#define IF_SIZE 0x00000038UL /* unsized operands must match the bitsize */ -#define IF_SX 0x0000003CUL /* unsized operands not allowed */ -#define IF_SMASK 0x0000003CUL /* mask for unsized argument size */ -#define IF_AR0 0x00000040UL /* SB, SW, SD applies to argument 0 */ -#define IF_AR1 0x00000080UL /* SB, SW, SD applies to argument 1 */ -#define IF_AR2 0x000000C0UL /* SB, SW, SD applies to argument 2 */ -#define IF_AR3 0x00000100UL /* SB, SW, SD applies to argument 3 */ -#define IF_AR4 0x00000140UL /* SB, SW, SD applies to argument 4 */ -#define IF_ARMASK 0x000001C0UL /* mask for unsized argument spec */ -#define IF_ARSHFT 6 /* LSB in IF_ARMASK */ -#define IF_OPT 0x00000200UL /* optimizing assembly only */ -/* The next 3 bits aren't actually used for anything */ -#define IF_PRIV 0x00000000UL /* it's a privileged instruction */ -#define IF_SMM 0x00000000UL /* it's only valid in SMM */ -#define IF_PROT 0x00000000UL /* it's protected mode only */ -#define IF_LOCK 0x00000400UL /* lockable if operand 0 is memory */ -#define IF_NOLONG 0x00000800UL /* it's not available in long mode */ -#define IF_LONG 0x00001000UL /* long mode instruction */ -#define IF_NOHLE 0x00002000UL /* HLE prefixes forbidden */ -/* These flags are currently not used for anything - intended for insn set */ -#define IF_UNDOC 0x8000000000UL /* it's an undocumented instruction */ -#define IF_HLE 0x4000000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_AVX512 0x2000000000UL /* it's an AVX-512F (512b) instruction */ -#define IF_FPU 0x0100000000UL /* it's an FPU instruction */ -#define IF_MMX 0x0200000000UL /* it's an MMX instruction */ -#define IF_3DNOW 0x0300000000UL /* it's a 3DNow! instruction */ -#define IF_SSE 0x0400000000UL /* it's a SSE (KNI, MMX2) instruction */ -#define IF_SSE2 0x0500000000UL /* it's a SSE2 instruction */ -#define IF_SSE3 0x0600000000UL /* it's a SSE3 (PNI) instruction */ -#define IF_VMX 0x0700000000UL /* it's a VMX instruction */ -#define IF_SSSE3 0x0800000000UL /* it's an SSSE3 instruction */ -#define IF_SSE4A 0x0900000000UL /* AMD SSE4a */ -#define IF_SSE41 0x0A00000000UL /* it's an SSE4.1 instruction */ -#define IF_SSE42 0x0B00000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_SSE5 0x0C00000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_AVX 0x0D00000000UL /* it's an AVX (128b) instruction */ -#define IF_AVX2 0x0E00000000UL /* it's an AVX2 (256b) instruction */ -#define IF_FMA 0x1000000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_BMI1 0x1100000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_BMI2 0x1200000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_TBM 0x1300000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_RTM 0x1400000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_INVPCID 0x1500000000UL /* HACK NEED TO REORGANIZE THESE BITS */ -#define IF_AVX512CD (0x1600000000UL|IF_AVX512) /* AVX-512 Conflict Detection insns */ -#define IF_AVX512ER (0x1700000000UL|IF_AVX512) /* AVX-512 Exponential and Reciprocal */ -#define IF_AVX512PF (0x1800000000UL|IF_AVX512) /* AVX-512 Prefetch instructions */ -#define IF_INSMASK 0xFF00000000UL /* the mask for instruction set types */ -#define IF_PMASK 0xFF000000UL /* the mask for processor types */ -#define IF_PLEVEL 0x0F000000UL /* the mask for processor instr. level */ - /* also the highest possible processor */ -#define IF_8086 0x00000000UL /* 8086 instruction */ -#define IF_186 0x01000000UL /* 186+ instruction */ -#define IF_286 0x02000000UL /* 286+ instruction */ -#define IF_386 0x03000000UL /* 386+ instruction */ -#define IF_486 0x04000000UL /* 486+ instruction */ -#define IF_PENT 0x05000000UL /* Pentium instruction */ -#define IF_P6 0x06000000UL /* P6 instruction */ -#define IF_KATMAI 0x07000000UL /* Katmai instructions */ -#define IF_WILLAMETTE 0x08000000UL /* Willamette instructions */ -#define IF_PRESCOTT 0x09000000UL /* Prescott instructions */ -#define IF_X86_64 0x0A000000UL /* x86-64 instruction (long or legacy mode) */ -#define IF_NEHALEM 0x0B000000UL /* Nehalem instruction */ -#define IF_WESTMERE 0x0C000000UL /* Westmere instruction */ -#define IF_SANDYBRIDGE 0x0D000000UL /* Sandy Bridge instruction */ -#define IF_FUTURE 0x0E000000UL /* Future processor (not yet disclosed) */ -#define IF_X64 (IF_LONG|IF_X86_64) -#define IF_IA64 0x0F000000UL /* IA64 instructions (in x86 mode) */ -#define IF_CYRIX 0x10000000UL /* Cyrix-specific instruction */ -#define IF_AMD 0x20000000UL /* AMD-specific instruction */ -#define IF_SPMASK 0x30000000UL /* specific processor types mask */ -#define IF_PFMASK (IF_INSMASK|IF_SPMASK) /* disassembly "prefer" mask */ +#define iflags_t uint64_t +#define IF_PLEVEL 1 #endif /* NASM_INSNS_H */ diff --git a/insns.pl b/insns.pl index 60f7dd3..333251b 100755 --- a/insns.pl +++ b/insns.pl @@ -37,6 +37,8 @@ # # Parse insns.dat and produce generated source code files +require 'insns-iflags.pl'; + # Opcode prefixes which need their own opcode tables # LONGER PREFIXES FIRST! @disasm_prefixes = qw(0F24 0F25 0F38 0F3A 0F7A 0FA6 0FA7 0F); @@ -67,7 +69,7 @@ print STDERR "Reading insns.dat...\n"; undef $output; foreach $arg ( @ARGV ) { if ( $arg =~ /^\-/ ) { - if ( $arg =~ /^\-([abdin])$/ ) { + if ( $arg =~ /^\-([abdint])$/ ) { $output = $1; } else { die "$0: Unknown option: ${arg}\n"; @@ -393,6 +395,10 @@ if ( !defined($output) || $output eq 'n' ) { close N; } +if ( !defined($output) || $output eq 't') { + write_iflags(); +} + printf STDERR "Done: %d instructions\n", $insns; # Count primary bytecodes, for statistics @@ -424,7 +430,7 @@ sub count_bytecodes(@) { sub format_insn($$$$$) { my ($opcode, $operands, $codes, $flags, $relax) = @_; - my $num, $nd = 0; + my $num, $nd = 0, $rawflags, $flagsindex; my @bytecode; my $op, @ops, $opp, @opx, @oppx, @decos, @opevex; my @iflags = ( "FPU", "MMX", "3DNOW", "SSE", "SSE2", @@ -492,16 +498,20 @@ sub format_insn($$$$$) { } # format the flags - $flags =~ s/,/|IF_/g; - $flags =~ s/(\|IF_ND|IF_ND\|)//, $nd = 1 if $flags =~ /IF_ND/; - $flags = "IF_" . $flags; + $nd = 1 if $flags =~ /(^|\,)ND($|\,)/; + $flags =~ s/(^|\,)ND($|\,)/\1/g; + $flags =~ s/(^|\,)X64($|\,)/\1LONG,X86_64\2/g; + $rawflags = $flags; + $flagsindex = insns_flag_index(split(',',$flags)); + + die "Error in flags $rawflags" if not defined($flagsindex); @bytecode = (decodify($codes, $relax), 0); push(@bytecode_list, [@bytecode]); $codes = hexstr(@bytecode); count_bytecodes(@bytecode); - ("{I_$opcode, $num, {$operands}, $decorators, \@\@CODES-$codes\@\@, $flags},", $nd); + ("{I_$opcode, $num, {$operands}, $decorators, \@\@CODES-$codes\@\@, $flagsindex},", $nd); } # -- 1.8.3.1 |