You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(208) |
Jun
(43) |
Jul
|
Aug
(2) |
Sep
(17) |
Oct
|
Nov
(4) |
Dec
(9) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
|
Feb
(11) |
Mar
(3) |
Apr
(2) |
May
|
Jun
(3) |
Jul
(29) |
Aug
(29) |
Sep
(48) |
Oct
|
Nov
|
Dec
(5) |
2004 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2005 |
Jan
(12) |
Feb
(1) |
Mar
(1) |
Apr
|
May
(1) |
Jun
(2) |
Jul
|
Aug
|
Sep
(4) |
Oct
(3) |
Nov
(1) |
Dec
(2) |
2006 |
Jan
(1) |
Feb
(2) |
Mar
(1) |
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
(1) |
Sep
(2) |
Oct
(21) |
Nov
(25) |
Dec
(16) |
2007 |
Jan
(26) |
Feb
(26) |
Mar
(18) |
Apr
(51) |
May
(45) |
Jun
(26) |
Jul
(6) |
Aug
(85) |
Sep
(161) |
Oct
(111) |
Nov
(83) |
Dec
(18) |
2008 |
Jan
(31) |
Feb
(27) |
Mar
|
Apr
(16) |
May
(142) |
Jun
(136) |
Jul
(51) |
Aug
(21) |
Sep
(47) |
Oct
(428) |
Nov
(19) |
Dec
(6) |
2009 |
Jan
(11) |
Feb
(37) |
Mar
(17) |
Apr
(15) |
May
(13) |
Jun
(61) |
Jul
(127) |
Aug
(15) |
Sep
(22) |
Oct
(28) |
Nov
(37) |
Dec
(10) |
2010 |
Jan
(18) |
Feb
(22) |
Mar
(10) |
Apr
(41) |
May
|
Jun
(48) |
Jul
(61) |
Aug
(54) |
Sep
(34) |
Oct
(15) |
Nov
(49) |
Dec
(11) |
2011 |
Jan
|
Feb
(24) |
Mar
(10) |
Apr
(9) |
May
|
Jun
(33) |
Jul
(41) |
Aug
(20) |
Sep
|
Oct
|
Nov
|
Dec
|
2012 |
Jan
|
Feb
(86) |
Mar
(12) |
Apr
|
May
(10) |
Jun
|
Jul
(9) |
Aug
(4) |
Sep
(11) |
Oct
(3) |
Nov
(3) |
Dec
(10) |
2013 |
Jan
(1) |
Feb
(23) |
Mar
(15) |
Apr
(7) |
May
(20) |
Jun
(3) |
Jul
(15) |
Aug
|
Sep
(29) |
Oct
(16) |
Nov
(69) |
Dec
(18) |
2014 |
Jan
|
Feb
(8) |
Mar
|
Apr
|
May
(16) |
Jun
(7) |
Jul
|
Aug
(5) |
Sep
(2) |
Oct
(4) |
Nov
(25) |
Dec
(8) |
2015 |
Jan
(6) |
Feb
(6) |
Mar
|
Apr
(1) |
May
(2) |
Jun
(1) |
Jul
(7) |
Aug
|
Sep
(2) |
Oct
(1) |
Nov
(6) |
Dec
|
2016 |
Jan
(12) |
Feb
(97) |
Mar
(57) |
Apr
(52) |
May
(33) |
Jun
(1) |
Jul
(1) |
Aug
|
Sep
|
Oct
(3) |
Nov
(3) |
Dec
|
2017 |
Jan
(4) |
Feb
|
Mar
(23) |
Apr
(5) |
May
|
Jun
(2) |
Jul
(3) |
Aug
(2) |
Sep
|
Oct
(6) |
Nov
(3) |
Dec
(3) |
2018 |
Jan
(4) |
Feb
(11) |
Mar
|
Apr
(1) |
May
(3) |
Jun
(6) |
Jul
|
Aug
(5) |
Sep
(5) |
Oct
(36) |
Nov
(128) |
Dec
(18) |
2019 |
Jan
|
Feb
|
Mar
(1) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2020 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(24) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: nasm-bot f. J. K. S. <jin...@in...> - 2013-12-05 04:57:24
|
Commit-ID: 009e54e0a1a297f05814a7c7a60f3b6ac2c597be Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=009e54e0a1a297f05814a7c7a60f3b6ac2c597be Author: Jin Kyu Song <jin...@in...> AuthorDate: Wed, 4 Dec 2013 20:51:13 -0800 Committer: Jin Kyu Song <jin...@in...> CommitDate: Wed, 4 Dec 2013 20:51:13 -0800 doc: Update nasmdoc Added bnd warning and nobnd prefix. DEFAULT directive section has got more description about BND-related settings. Signed-off-by: Jin Kyu Song <jin...@in...> --- doc/nasmdoc.src | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src index 09e06fa..327e3cf 100644 --- a/doc/nasmdoc.src +++ b/doc/nasmdoc.src @@ -956,6 +956,10 @@ Enabled by default. prefixes. Enabled by default. +\b \i\c{bnd} warns about ineffective use of the \c{BND} prefix when a relaxed +form of jmp instruction becomes jmp short form. +Enabled by default. + \b \i\c{error} causes warnings to be treated as errors. Disabled by default. @@ -1214,7 +1218,7 @@ The instruction field may contain any machine instruction: Pentium and P6 instructions, FPU instructions, MMX instructions and even undocumented instructions are all supported. The instruction may be prefixed by \c{LOCK}, \c{REP}, \c{REPE}/\c{REPZ}, \c{REPNE}/\c{REPNZ}, -\c{XACQUIRE}/\c{XRELEASE} or \c{BND}, in the usual way. Explicit +\c{XACQUIRE}/\c{XRELEASE} or \c{BND}/\c{NOBND}, in the usual way. Explicit \I{address-size prefixes}address-size and \i{operand-size prefixes} \i\c{A16}, \i\c{A32}, \i\c{A64}, \i\c{O16} and \i\c{O32}, \i\c{O64} are provided - one example of their use is given in \k{mixsize}. You can also use the name of a \I{segment @@ -4434,9 +4438,12 @@ specify most features directly. However, this is occationally obnoxious, as the explicit form is pretty much the only one one wishes to use. -Currently, the only \c{DEFAULT} that is settable is whether or not -registerless instructions in 64-bit mode are \c{RIP}-relative or not. -By default, they are absolute unless overridden with the \i\c{REL} +Currently, \c{DEFAULT} can set \c{REL} & \c{ABS} and \c{BND} & \c{NOBND}. + +\S{REL & ABS} \i\c{REL} & \i\c{ABS}: RIP-relative addressing + +This sets whether registerless instructions in 64-bit mode are \c{RIP}-relative +or not. By default, they are absolute unless overridden with the \i\c{REL} specifier (see \k{effaddr}). However, if \c{DEFAULT REL} is specified, \c{REL} is default, unless overridden with the \c{ABS} specifier, \e{except when used with an FS or GS segment override}. @@ -4448,6 +4455,19 @@ other special functions in 64-bit mode, and generating \c{DEFAULT REL} is disabled with \c{DEFAULT ABS}. +\S{BND & NOBND} \i\c{BND} & \i\c{NOBND}: \c{BND} prefix + +If \c{DEFAULT BND} is set, all bnd-prefix available instructions following +this directive are prefixed with bnd. To override it, \c{NOBND} prefix can +be used. + +\c DEFAULT BND +\c call foo ; BND will be prefixed +\c nobnd call foo ; BND will NOT be prefixed + +DEFAULT NOBND can disable DEFAULT BND and then \c{BND} prefix will be added +only when explicitly specified in code. + \H{section} \i\c{SECTION} or \i\c{SEGMENT}: Changing and \i{Defining Sections} |
From: nasm-bot f. J. K. S. <jin...@in...> - 2013-12-03 02:45:22
|
Commit-ID: 0873ef5626d7cdfcb87bf4c8643cc508e79549b8 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=0873ef5626d7cdfcb87bf4c8643cc508e79549b8 Author: Jin Kyu Song <jin...@in...> AuthorDate: Sat, 30 Nov 2013 16:38:42 -0800 Committer: Jin Kyu Song <jin...@in...> CommitDate: Mon, 2 Dec 2013 18:42:19 -0800 pfmask: Limit the preferred mask to the vendor specific flags In ndisasm, the priority follows the order of instructions in insns.dat. Other iflags could affect this mechanism when a proper instruction form had a higher iflag bit set. The preferred mask bits are now limited to vendor flags (Cyrix and AMD) and other flags do not affect disassembler any more. Signed-off-by: Jin Kyu Song <jin...@in...> --- iflag.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/iflag.h b/iflag.h index 8754174..7bc31cc 100644 --- a/iflag.h +++ b/iflag.h @@ -143,10 +143,9 @@ static inline int iflag_cmp_cpu_level(const iflag_t *a, const iflag_t *b) static inline iflag_t _iflag_pfmask(const iflag_t *a) { - iflag_t r = (iflag_t) { - .field[1] = a->field[1], - .field[2] = a->field[2], - }; + iflag_t r; + + memset(&r, 0, sizeof(r)); if (iflag_test(a, IF_CYRIX)) iflag_set(&r, IF_CYRIX); |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-29 05:30:22
|
Commit-ID: 50137b82748b4fad54591571bf756d9c3a2746b5 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=50137b82748b4fad54591571bf756d9c3a2746b5 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Thu, 28 Nov 2013 21:26:26 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Thu, 28 Nov 2013 21:26:26 -0800 doc: Make the bit about mib operands a bit clearer Clean up the text about what a mib is. Signed-off-by: H. Peter Anvin <hp...@zy...> --- doc/nasmdoc.src | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src index 2ba24c2..09e06fa 100644 --- a/doc/nasmdoc.src +++ b/doc/nasmdoc.src @@ -1462,9 +1462,10 @@ In 64-bit mode, NASM will by default generate absolute addresses. The this is frequently the normally desired behaviour, see the \c{DEFAULT} directive (\k{default}). The keyword \i\c{ABS} overrides \i\c{REL}. -A new form of split effective addres syntax is also supported. This is mainly -intended for mib operand but can be used for any memory reference. The basic -concept of this form is splitting base and index. +A new form of split effective addres syntax is also supported. This is +mainly intended for mib operands as used by MPX instructions, but can +be used for any memory reference. The basic concept of this form is +splitting base and index. \c mov eax,[ebx+8,ecx*4] ; ebx=base, ecx=index, 4=scale, 8=disp |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-29 05:27:25
|
Commit-ID: ebfa6a645204cffc9bbdac7e2b9d5149c8af118d Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=ebfa6a645204cffc9bbdac7e2b9d5149c8af118d Author: H. Peter Anvin <hp...@zy...> AuthorDate: Thu, 28 Nov 2013 21:24:09 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Thu, 28 Nov 2013 21:24:09 -0800 doc: Clean up changelog for 2.11 - We don't need to list internal infrastructure improvements. - We don't list rc releases separately. Signed-off-by: H. Peter Anvin <hp...@zy...> --- doc/changes.src | 58 +++++++++++++++++++++++++-------------------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/doc/changes.src b/doc/changes.src index fcf6f2a..98da2b1 100644 --- a/doc/changes.src +++ b/doc/changes.src @@ -9,38 +9,7 @@ since 2007. \S{cl-2.11} Version 2.11 -\b Instruction flags use bitvectors as 64-bit bitfields were doomed -to be cramped soon. All possible bitvectors are sorted and hashed. So -each unique bitvector occupies only one hash index. - -\b Add support for \c{DZ} and \c{RESZ} - -\b Better handling of section redefinition - -\b Generate manpages when running \c{'make dist'} - -\b Handle all token chains in mmacro params range - -\b Support split [base,index] effective address - -\c mov eax,[eax+8,ecx*4] ; eax=base, ecx=index, 4=scale, 8=disp - -\b Add support for MPX/SHA instructions - -\b Support \c{BND} prefix for branch instructions - -\b Add \c{{evex}}, \c{{vex3}} and \c{{vex2}} instruction prefixes to -have NASM encode the corresponding instruction, if possible, with an EVEX, -3-byte VEX, or 2-byte VEX prefix, respectively. - -\b Ndisasm supports AVX-512/MPX/SHA instructions - -\S{cl-2.11rc1} Version 2.11rc1 - -\b Support for Intel AVX-512 instruction set. The document introducing these -instrustions can be found at -\W{http://download-software.intel.com/sites/default/files/319433-016.pdf}{intel.com} -. Added features are as follows : +\b Add support for the Intel AVX-512 instruction set: \b 16 new, 512-bit SIMD registers. Total 32 \c{(ZMM0 ~ ZMM31)} @@ -63,7 +32,30 @@ displacements. \c ; is used as if a separate operand. \c ; it comes after the last SIMD operand -\b Support for section names longer than 8 bytes +\b Add support for \c{ZWORD} (512 bits), \c{DZ} and \c{RESZ}. + +\b Add support for the MPX and SHA instruction sets. + +\b Better handling of section redefinition. + +\b Generate manpages when running \c{'make dist'}. + +\b Handle all token chains in mmacro params range. + +\b Support split [base,index] effective address: + +\c mov eax,[eax+8,ecx*4] ; eax=base, ecx=index, 4=scale, 8=disp + +This is expected to be most useful for the MPX instructions. + +\b Support \c{BND} prefix for branch instructions (for MPX). + +\b Add \c{{evex}}, \c{{vex3}} and \c{{vex2}} instruction prefixes to +have NASM encode the corresponding instruction, if possible, with an EVEX, +3-byte VEX, or 2-byte VEX prefix, respectively. + + +\b Support for section names longer than 8 bytes in Win32/Win64 COFF. \S{cl-2.10.09} Version 2.10.09 |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-28 20:24:37
|
Commit-ID: 9a066520394dd36381cdec0f164785d450a42c40 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=9a066520394dd36381cdec0f164785d450a42c40 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Thu, 28 Nov 2013 12:22:05 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Thu, 28 Nov 2013 12:22:05 -0800 NASM 2.11rc3 --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index 0ca7159..2a8ed36 100644 --- a/version +++ b/version @@ -1 +1 @@ -2.11rc2 +2.11rc3 |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-28 20:24:27
|
Commit-ID: 621a69ac5c2c2e3339c0bc0cb3e9cbf2c136bebf Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=621a69ac5c2c2e3339c0bc0cb3e9cbf2c136bebf Author: H. Peter Anvin <hp...@zy...> AuthorDate: Thu, 28 Nov 2013 12:11:24 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Thu, 28 Nov 2013 12:21:11 -0800 Add {vex3} and {vex2} prefixes by analogy with {evex} Allow specifying {vex3} or {vex2} (the latter is currently always redundant, unless we end up with instructions at some point can be specified with legacy prefixes or VEX) to select a specific encoding of VEX-encoded instructions. Signed-off-by: H. Peter Anvin <hp...@li...> --- assemble.c | 40 ++++++++++++++++++++++++++++++++++------ doc/changes.src | 5 +++-- insns-iflags.pl | 3 ++- insns.pl | 6 +++++- nasm.h | 4 +++- parser.c | 4 +++- test/vex.asm | 9 +++++++++ tokens.dat | 4 +++- 8 files changed, 62 insertions(+), 13 deletions(-) diff --git a/assemble.c b/assemble.c index 759e4b5..bf1490d 100644 --- a/assemble.c +++ b/assemble.c @@ -643,8 +643,8 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, iflag_t cp, c = 0x66; break; case P_EVEX: - /* EVEX */ - break; + case P_VEX3: + case P_VEX2: case P_none: break; default: @@ -810,6 +810,8 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, iflag_t cp, case P_A64: case P_O64: case P_EVEX: + case P_VEX3: + case P_VEX2: case P_none: break; default: @@ -1270,6 +1272,20 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, ins->rex &= ~REX_P; /* Don't force REX prefix due to high reg */ } + switch (ins->prefixes[PPS_VEX]) { + case P_EVEX: + if (!(ins->rex & REX_EV)) + return -1; + break; + case P_VEX3: + case P_VEX2: + if (!(ins->rex & REX_V)) + return -1; + break; + default: + break; + } + if (ins->rex & (REX_V | REX_EV)) { int bad32 = REX_R|REX_W|REX_X|REX_B; @@ -1301,7 +1317,8 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, } if (ins->rex & REX_EV) length += 4; - else if (ins->vex_cm != 1 || (ins->rex & (REX_W|REX_X|REX_B))) + else if (ins->vex_cm != 1 || (ins->rex & (REX_W|REX_X|REX_B)) || + ins->prefixes[PPS_VEX] == P_VEX3) length += 3; else length += 2; @@ -1600,7 +1617,8 @@ static void gencode(int32_t segment, int64_t offset, int bits, case4(0260): case 0270: codes += 2; - if (ins->vex_cm != 1 || (ins->rex & (REX_W|REX_X|REX_B))) { + if (ins->vex_cm != 1 || (ins->rex & (REX_W|REX_X|REX_B)) || + ins->prefixes[PPS_VEX] == P_VEX3) { bytes[0] = (ins->vex_cm >> 6) ? 0x8f : 0xc4; bytes[1] = (ins->vex_cm & 31) | ((~ins->rex & 7) << 5); bytes[2] = ((ins->rex & REX_W) << (7-3)) | @@ -2098,8 +2116,18 @@ static enum match_result matches(const struct itemplate *itemp, /* * {evex} available? */ - if (instruction->prefixes[PPS_EVEX] && !itemp_has(itemp, IF_EVEX)) { - return MERR_ENCMISMATCH; + switch (instruction->prefixes[PPS_VEX]) { + case P_EVEX: + if (!itemp_has(itemp, IF_EVEX)) + return MERR_ENCMISMATCH; + break; + case P_VEX3: + case P_VEX2: + if (!itemp_has(itemp, IF_VEX)) + return MERR_ENCMISMATCH; + break; + default: + break; } /* diff --git a/doc/changes.src b/doc/changes.src index 91e3078..fcf6f2a 100644 --- a/doc/changes.src +++ b/doc/changes.src @@ -29,8 +29,9 @@ each unique bitvector occupies only one hash index. \b Support \c{BND} prefix for branch instructions -\b Add \c{{evex}} instruction prefix to have nasm encode the corresponding -instruction line with EVEX +\b Add \c{{evex}}, \c{{vex3}} and \c{{vex2}} instruction prefixes to +have NASM encode the corresponding instruction, if possible, with an EVEX, +3-byte VEX, or 2-byte VEX prefix, respectively. \b Ndisasm supports AVX-512/MPX/SHA instructions diff --git a/insns-iflags.pl b/insns-iflags.pl index be36193..97c0863 100644 --- a/insns-iflags.pl +++ b/insns-iflags.pl @@ -120,7 +120,6 @@ my %insns_flag_bit = ( "TBM" => [ 60, ""], "RTM" => [ 61, ""], "INVPCID" => [ 62, ""], - "EVEX" => [ 63, ""], # # dword bound, index 2 - instruction filtering flags @@ -132,6 +131,8 @@ my %insns_flag_bit = ( "MPX" => [ 68 ,"MPX"], "SHA" => [ 69 ,"SHA"], "PREFETCHWT1" => [ 70 ,"PREFETCHWT1"], + "VEX" => [ 94, "VEX or XOP encoded instruction"], + "EVEX" => [ 95, "EVEX encoded instruction"], # # dword bound, index 3 - cpu type flags diff --git a/insns.pl b/insns.pl index 67333ad..451c4f2 100755 --- a/insns.pl +++ b/insns.pl @@ -495,7 +495,11 @@ sub format_insn($$$$$) { $nd = 1 if $flags =~ /(^|\,)ND($|\,)/; $flags =~ s/(^|\,)ND($|\,)/\1/g; $flags =~ s/(^|\,)X64($|\,)/\1LONG,X86_64\2/g; - $flags .= ",EVEX" if ($codes =~ /evex\./); + if ($codes =~ /evex\./) { + $flags .= ",EVEX"; + } elsif ($codes =~ /(vex|xop)\./) { + $flags .= ",VEX"; + } $rawflags = $flags; $flagsindex = insns_flag_index(split(',',$flags)); diff --git a/nasm.h b/nasm.h index 87e82d2..f499c49 100644 --- a/nasm.h +++ b/nasm.h @@ -565,6 +565,8 @@ enum prefixes { /* instruction prefixes */ P_XRELEASE, P_BND, P_EVEX, + P_VEX3, + P_VEX2, PREFIX_ENUM_LIMIT }; @@ -647,7 +649,7 @@ enum prefix_pos { PPS_SEG, /* Segment override prefix */ PPS_OSIZE, /* Operand size prefix */ PPS_ASIZE, /* Address size prefix */ - PPS_EVEX, /* EVEX prefix */ + PPS_VEX, /* VEX type */ MAXPREFIX /* Total number of prefix slots */ }; diff --git a/parser.c b/parser.c index f73c7b5..4f0898c 100644 --- a/parser.c +++ b/parser.c @@ -102,7 +102,9 @@ static int prefix_slot(int prefix) case P_ASP: return PPS_ASIZE; case P_EVEX: - return PPS_EVEX; + case P_VEX3: + case P_VEX2: + return PPS_VEX; default: nasm_error(ERR_PANIC, "Invalid value %d passed to prefix_slot()", prefix); return -1; diff --git a/test/vex.asm b/test/vex.asm new file mode 100644 index 0000000..6772c7c --- /dev/null +++ b/test/vex.asm @@ -0,0 +1,9 @@ + bits 64 + vcomisd xmm0,xmm31 + vcomisd xmm0,xmm1 + {vex2} vcomisd xmm0,xmm1 + {vex3} vcomisd xmm0,xmm1 + {evex} vcomisd xmm0,xmm1 +%ifdef ERROR + {vex3} add eax,edx +%endif diff --git a/tokens.dat b/tokens.dat index 284cf30..09d4b9f 100644 --- a/tokens.dat +++ b/tokens.dat @@ -1,6 +1,6 @@ ## -------------------------------------------------------------------------- ## -## Copyright 1996-2012 The NASM Authors - All Rights Reserved +## Copyright 1996-2013 The NASM Authors - All Rights Reserved ## See the file AUTHORS included with the NASM distribution for ## the specific copyright holders. ## @@ -125,3 +125,5 @@ z % TOKEN_PREFIX, 0, TFLAG_BRC, P_* evex +vex3 +vex2 |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-28 19:39:17
|
Commit-ID: 2e15eca688ac1550ab26be0a071df1e868776449 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=2e15eca688ac1550ab26be0a071df1e868776449 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Thu, 28 Nov 2013 11:36:26 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Thu, 28 Nov 2013 11:36:26 -0800 NASM 2.11rc2 --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index fd21486..0ca7159 100644 --- a/version +++ b/version @@ -1 +1 @@ -2.11rc1 +2.11rc2 |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-28 19:36:25
|
Commit-ID: ed8df3eaef50c84aa134d9c6af4342cc3cf1bfee Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=ed8df3eaef50c84aa134d9c6af4342cc3cf1bfee Author: H. Peter Anvin <hp...@zy...> AuthorDate: Thu, 28 Nov 2013 11:33:28 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Thu, 28 Nov 2013 11:35:34 -0800 Remove "high 16" register class macros for xmm/ymm/zmm The "high 16" register class macros were actually incorrect, as they simply aliased the corresponding whole set class. In oder to keep someone from getting confused and making mistakes, remove them. Signed-off-by: H. Peter Anvin <hp...@zy...> --- opflags.h | 12 +++--------- regs.dat | 6 +++--- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/opflags.h b/opflags.h index 707452e..ef2838c 100644 --- a/opflags.h +++ b/opflags.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2012 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -253,25 +253,19 @@ #define UDWORD (GEN_SUBCLASS(4) | IMMEDIATE) /* operand is in the range 0..0xFFFFFFFF */ /* - * split vector registers - low 16 and high 16. - * avoid a conflict in subclass bitfield with any of special EA types. + * Subset of vector registers: register 0 only and registers 0-15. + * Avoid conflicts in subclass bitfield with any of special EA types! */ #define RM_XMM_L16 (GEN_SUBCLASS(6) | RM_XMM) /* XMM r/m operand 0 ~ 15 */ -#define RM_XMM_H16 ( RM_XMM) /* XMM r/m operand 16 ~ 31 */ #define XMM0 (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | XMMREG) /* XMM register zero */ #define XMM_L16 ( GEN_SUBCLASS(6) | XMMREG) /* XMM register 0 ~ 15 */ -#define XMM_H16 ( XMMREG) /* XMM register 16 ~ 31 */ #define RM_YMM_L16 (GEN_SUBCLASS(6) | RM_YMM) /* YMM r/m operand 0 ~ 15 */ -#define RM_YMM_H16 ( RM_YMM) /* YMM r/m operand 16 ~ 31 */ #define YMM0 (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | YMMREG) /* YMM register zero */ #define YMM_L16 ( GEN_SUBCLASS(6) | YMMREG) /* YMM register 0 ~ 15 */ -#define YMM_H16 ( YMMREG) /* YMM register 16 ~ 31 */ #define RM_ZMM_L16 (GEN_SUBCLASS(6) | RM_ZMM) /* ZMM r/m operand 0 ~ 15 */ -#define RM_ZMM_H16 ( RM_ZMM) /* ZMM r/m operand 16 ~ 31 */ #define ZMM0 (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | ZMMREG) /* ZMM register zero */ #define ZMM_L16 ( GEN_SUBCLASS(6) | ZMMREG) /* ZMM register 0 ~ 15 */ -#define ZMM_H16 ( ZMMREG) /* ZMM register 16 ~ 31 */ #endif /* NASM_OPFLAGS_H */ diff --git a/regs.dat b/regs.dat index 51682d6..723f6a4 100644 --- a/regs.dat +++ b/regs.dat @@ -118,17 +118,17 @@ mm0-7 MMXREG mmxreg 0 # SSE registers xmm0 XMM0 xmmreg 0 xmm1-15 XMM_L16 xmmreg 1 -xmm16-31 XMM_H16 xmmreg 16 +xmm16-31 XMMREG xmmreg 16 # AVX registers ymm0 YMM0 ymmreg 0 ymm1-15 YMM_L16 ymmreg 1 -ymm16-31 YMM_H16 ymmreg 16 +ymm16-31 YMMREG ymmreg 16 # AVX512 registers zmm0 ZMM0 zmmreg 0 zmm1-15 ZMM_L16 zmmreg 1 -zmm16-31 ZMM_H16 zmmreg 16 +zmm16-31 ZMMREG zmmreg 16 # Opmask registers k0 OPMASK0 opmaskreg 0 |
From: nasm-bot f. J. K. S. <jin...@in...> - 2013-11-28 05:06:19
|
Commit-ID: 5eac14bb0e5597d2bee902bee3a8ec981fa5ca03 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=5eac14bb0e5597d2bee902bee3a8ec981fa5ca03 Author: Jin Kyu Song <jin...@in...> AuthorDate: Wed, 27 Nov 2013 20:52:16 -0800 Committer: Jin Kyu Song <jin...@in...> CommitDate: Wed, 27 Nov 2013 20:54:07 -0800 preproc: Handle curly braces in multi-line macro parameters Multi-line macro uses curly braces for enclosing a parameter containing comma(s). Passing curly braces as a part of a parameter which is already enclosed with braces confuses the macro expander. The number of braces in a group parameter is counted and any brace in the outmost enclosing braces is treated as a part of parameter. e.g.) mmacro {1,2,3}, {4,{5,6}} mmacro gets 2 parameters of '1,2,3' and '4,{5,6}' Signed-off-by: Jin Kyu Song <jin...@in...> --- preproc.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/preproc.c b/preproc.c index 4fa9aeb..6e52d57 100644 --- a/preproc.c +++ b/preproc.c @@ -1632,19 +1632,24 @@ static void count_mmac_params(Token * t, int *nparam, Token *** params) *params = nasm_realloc(*params, sizeof(**params) * paramsize); } skip_white_(t); - brace = false; + brace = 0; if (tok_is_(t, "{")) - brace = true; + brace++; (*params)[(*nparam)++] = t; - while (tok_isnt_(t, brace ? "}" : ",")) - t = t->next; - if (t) { /* got a comma/brace */ - t = t->next; - if (brace) { + if (brace) { + while (brace && (t = t->next) != NULL) { + if (tok_is_(t, "{")) + brace++; + else if (tok_is_(t, "}")) + brace--; + } + + if (t) { /* * Now we've found the closing brace, look further * for the comma. */ + t = t->next; skip_white_(t); if (tok_isnt_(t, ",")) { error(ERR_NONFATAL, @@ -1652,9 +1657,13 @@ static void count_mmac_params(Token * t, int *nparam, Token *** params) while (tok_isnt_(t, ",")) t = t->next; } - if (t) - t = t->next; /* eat the comma */ } + } else { + while (tok_isnt_(t, ",")) + t = t->next; + } + if (t) { /* got a comma/brace */ + t = t->next; /* eat the comma */ } } } @@ -4640,13 +4649,13 @@ static int expand_mmacro(Token * tline) paramlen = nparam ? nasm_malloc(nparam * sizeof(*paramlen)) : NULL; for (i = 0; params[i]; i++) { - int brace = false; + int brace = 0; int comma = (!m->plus || i < nparam - 1); t = params[i]; skip_white_(t); if (tok_is_(t, "{")) - t = t->next, brace = true, comma = false; + t = t->next, brace++, comma = false; params[i] = t; paramlen[i] = 0; while (t) { @@ -4655,11 +4664,18 @@ static int expand_mmacro(Token * tline) if (comma && t->type == TOK_WHITESPACE && tok_is_(t->next, ",")) break; /* ... or a space then a comma */ - if (brace && t->type == TOK_OTHER && !strcmp(t->text, "}")) - break; /* ... or a brace */ + if (brace && t->type == TOK_OTHER) { + if (t->text[0] == '{') + brace++; /* ... or a nested opening brace */ + else if (t->text[0] == '}') + if (!--brace) + break; /* ... or a brace */ + } t = t->next; paramlen[i]++; } + if (brace) + error(ERR_NONFATAL, "macro params should be enclosed in braces"); } /* |
From: nasm-bot f. J. K. S. <jin...@in...> - 2013-11-28 05:06:19
|
Commit-ID: 28f95668e070d4cbe81c48f22e0a931e23ab4919 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=28f95668e070d4cbe81c48f22e0a931e23ab4919 Author: Jin Kyu Song <jin...@in...> AuthorDate: Wed, 27 Nov 2013 20:23:53 -0800 Committer: Jin Kyu Song <jin...@in...> CommitDate: Wed, 27 Nov 2013 20:23:53 -0800 Revert "AVX-512: Handle curly braces in multi-line macro parameters" This reverts commit a800aed7b75d56114f2e1e4928cbc48ecf96a4a0. As recommended by the community, braces inside a group parameter of multi-line macro should be parsed without a need of a leading escape character such as "\{ab,c\}". Signed-off-by: Jin Kyu Song <jin...@in...> --- preproc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/preproc.c b/preproc.c index 3a0f67b..4fa9aeb 100644 --- a/preproc.c +++ b/preproc.c @@ -208,7 +208,6 @@ enum pp_token_type { TOK_PREPROC_Q, TOK_PREPROC_QQ, TOK_PASTE, /* %+ */ TOK_INDIRECT, /* %[...] */ - TOK_BRACE, /* \{...\} */ TOK_SMAC_PARAM, /* MUST BE LAST IN THE LIST!!! */ TOK_MAX = INT_MAX /* Keep compiler from reducing the range */ }; @@ -1104,10 +1103,6 @@ static Token *tokenize(char *line) type = TOK_COMMENT; while (*p) p++; - } else if (p[0] == '\\' && (p[1] == '{' || p[1] == '}')) { - type = TOK_BRACE; - p += 2; - line++; } else { /* * Anything else is an operator of some kind. We check |
From: nasm-bot f. J. K. S. <jin...@in...> - 2013-11-27 23:51:26
|
Commit-ID: 6cfa968e8d3ef6344ef3e92b37d64a277124ee29 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=6cfa968e8d3ef6344ef3e92b37d64a277124ee29 Author: Jin Kyu Song <jin...@in...> AuthorDate: Tue, 26 Nov 2013 17:27:48 -0800 Committer: Jin Kyu Song <jin...@in...> CommitDate: Wed, 27 Nov 2013 15:43:33 -0800 iflags: Add IF_EVEX for checking {evex} availability For checking the availability of {evex} prefix, AVX512 iflag has been used. But this is a flag for an instruction set not for an encoding scheme. And there are some AVX512 instructions encoded with VEX prefix. So a new instruction flag (IF_EVEX) is added for the instructions which are actually encoded with EVEX prefix. This flag is automatically added by insns.pl, so no need to add manually in insns.dat. Signed-off-by: Jin Kyu Song <jin...@in...> --- assemble.c | 13 ++++++++++--- insns-iflags.pl | 1 + insns.pl | 4 +--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/assemble.c b/assemble.c index a7ca1aa..759e4b5 100644 --- a/assemble.c +++ b/assemble.c @@ -692,6 +692,9 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, iflag_t cp, error(ERR_NONFATAL, "instruction not supported in %d-bit mode", bits); break; + case MERR_ENCMISMATCH: + error(ERR_NONFATAL, "specific encoding scheme not available"); + break; case MERR_BADBND: error(ERR_NONFATAL, "bnd prefix is not allowed"); break; @@ -2093,6 +2096,13 @@ static enum match_result matches(const struct itemplate *itemp, return MERR_INVALOP; /* + * {evex} available? + */ + if (instruction->prefixes[PPS_EVEX] && !itemp_has(itemp, IF_EVEX)) { + return MERR_ENCMISMATCH; + } + + /* * Check that no spurious colons or TOs are present */ for (i = 0; i < itemp->operands; i++) @@ -2232,9 +2242,6 @@ static enum match_result matches(const struct itemplate *itemp, */ return MERR_BRNUMMISMATCH; } - } else if (instruction->prefixes[PPS_EVEX] && - !itemp_has(itemp, IF_AVX512)) { - return MERR_ENCMISMATCH; } } diff --git a/insns-iflags.pl b/insns-iflags.pl index da2fd9b..be36193 100644 --- a/insns-iflags.pl +++ b/insns-iflags.pl @@ -120,6 +120,7 @@ my %insns_flag_bit = ( "TBM" => [ 60, ""], "RTM" => [ 61, ""], "INVPCID" => [ 62, ""], + "EVEX" => [ 63, ""], # # dword bound, index 2 - instruction filtering flags diff --git a/insns.pl b/insns.pl index 2ce9a51..67333ad 100755 --- a/insns.pl +++ b/insns.pl @@ -495,9 +495,7 @@ sub format_insn($$$$$) { $nd = 1 if $flags =~ /(^|\,)ND($|\,)/; $flags =~ s/(^|\,)ND($|\,)/\1/g; $flags =~ s/(^|\,)X64($|\,)/\1LONG,X86_64\2/g; - $flags =~ s/(^|\,)AVX512CD($|\,)/\1AVX512CD,AVX512\2/g; - $flags =~ s/(^|\,)AVX512ER($|\,)/\1AVX512ER,AVX512\2/g; - $flags =~ s/(^|\,)AVX512PF($|\,)/\1AVX512PF,AVX512\2/g; + $flags .= ",EVEX" if ($codes =~ /evex\./); $rawflags = $flags; $flagsindex = insns_flag_index(split(',',$flags)); |
From: nasm-bot f. J. K. S. <jin...@in...> - 2013-11-27 23:51:25
|
Commit-ID: 08ae610ec96d2f07543eb0caf90ec429ddf89f32 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=08ae610ec96d2f07543eb0caf90ec429ddf89f32 Author: Jin Kyu Song <jin...@in...> AuthorDate: Tue, 26 Nov 2013 17:14:07 -0800 Committer: Jin Kyu Song <jin...@in...> CommitDate: Wed, 27 Nov 2013 15:43:32 -0800 opflags: Separate vector registers into low-16 and high-16 Since only EVEX supports all 32 vector registers encoding for now, VEX/REX encoded instructions should not take high-16 registers as operands. This filtering had been done using instruction flag so far, but using the opflags makes more sense. [XYZ]MMREG operands used for non-EVEX instructions are automatically converted to [XYZ]MM_L16 in insns.pl Signed-off-by: Jin Kyu Song <jin...@in...> --- assemble.c | 4 ---- insns.pl | 5 +++++ opflags.h | 27 +++++++++++++++++++++++---- regs.dat | 9 ++++++--- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/assemble.c b/assemble.c index 193c487..a7ca1aa 100644 --- a/assemble.c +++ b/assemble.c @@ -2232,10 +2232,6 @@ static enum match_result matches(const struct itemplate *itemp, */ return MERR_BRNUMMISMATCH; } - } else if (is_register(instruction->oprs[i].basereg) && - nasm_regvals[instruction->oprs[i].basereg] >= 16 && - !itemp_has(itemp, IF_AVX512)) { - return MERR_ENCMISMATCH; } else if (instruction->prefixes[PPS_EVEX] && !itemp_has(itemp, IF_AVX512)) { return MERR_ENCMISMATCH; diff --git a/insns.pl b/insns.pl index 8515c02..2ce9a51 100755 --- a/insns.pl +++ b/insns.pl @@ -464,6 +464,11 @@ sub format_insn($$$$$) { $opp =~ s/^([a-z]+)rm$/rm_$1/; $opp =~ s/^rm$/rm_gpr/; $opp =~ s/^reg$/reg_gpr/; + # only for evex insns, high-16 regs are allowed + if ($codes !~ /(^|\s)evex\./) { + $opp =~ s/^(rm_[xyz]mm)$/$1_l16/; + $opp =~ s/^([xyz]mm)reg$/$1_l16/; + } push(@opx, $opp, @oppx) if $opp; } $op = join('|', @opx); diff --git a/opflags.h b/opflags.h index 16c65cb..707452e 100644 --- a/opflags.h +++ b/opflags.h @@ -185,13 +185,10 @@ #define MMXREG ( REG_CLASS_RM_MMX | REGMEM | REGISTER) /* MMX register */ #define RM_XMM ( REG_CLASS_RM_XMM | REGMEM) /* XMM (SSE) operand */ #define XMMREG ( REG_CLASS_RM_XMM | REGMEM | REGISTER) /* XMM (SSE) register */ -#define XMM0 (GEN_SUBCLASS(1) | REG_CLASS_RM_XMM | REGMEM | REGISTER) /* XMM register zero */ #define RM_YMM ( REG_CLASS_RM_YMM | REGMEM) /* YMM (AVX) operand */ #define YMMREG ( REG_CLASS_RM_YMM | REGMEM | REGISTER) /* YMM (AVX) register */ -#define YMM0 (GEN_SUBCLASS(1) | REG_CLASS_RM_YMM | REGMEM | REGISTER) /* YMM register zero */ #define RM_ZMM ( REG_CLASS_RM_ZMM | REGMEM) /* ZMM (AVX512) operand */ #define ZMMREG ( REG_CLASS_RM_ZMM | REGMEM | REGISTER) /* ZMM (AVX512) register */ -#define ZMM0 (GEN_SUBCLASS(1) | REG_CLASS_RM_ZMM | REGMEM | REGISTER) /* ZMM register zero */ #define RM_OPMASK ( REG_CLASS_OPMASK | REGMEM) /* Opmask operand */ #define OPMASKREG ( REG_CLASS_OPMASK | REGMEM | REGISTER) /* Opmask register */ #define OPMASK0 (GEN_SUBCLASS(1) | REG_CLASS_OPMASK | REGMEM | REGISTER) /* Opmask register zero (k0) */ @@ -246,7 +243,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 | RM_BND) +#define MEMORY_ANY (MEMORY | RM_GPR | RM_MMX | RM_XMM_L16 | RM_YMM_L16 | RM_ZMM_L16 | RM_OPMASK | RM_BND) /* special immediate values */ #define UNITY (GEN_SUBCLASS(0) | IMMEDIATE) /* operand equals 1 */ @@ -255,4 +252,26 @@ #define SDWORD (GEN_SUBCLASS(3) | IMMEDIATE) /* operand is in the range -0x80000000..0x7FFFFFFF */ #define UDWORD (GEN_SUBCLASS(4) | IMMEDIATE) /* operand is in the range 0..0xFFFFFFFF */ +/* + * split vector registers - low 16 and high 16. + * avoid a conflict in subclass bitfield with any of special EA types. + */ +#define RM_XMM_L16 (GEN_SUBCLASS(6) | RM_XMM) /* XMM r/m operand 0 ~ 15 */ +#define RM_XMM_H16 ( RM_XMM) /* XMM r/m operand 16 ~ 31 */ +#define XMM0 (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | XMMREG) /* XMM register zero */ +#define XMM_L16 ( GEN_SUBCLASS(6) | XMMREG) /* XMM register 0 ~ 15 */ +#define XMM_H16 ( XMMREG) /* XMM register 16 ~ 31 */ + +#define RM_YMM_L16 (GEN_SUBCLASS(6) | RM_YMM) /* YMM r/m operand 0 ~ 15 */ +#define RM_YMM_H16 ( RM_YMM) /* YMM r/m operand 16 ~ 31 */ +#define YMM0 (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | YMMREG) /* YMM register zero */ +#define YMM_L16 ( GEN_SUBCLASS(6) | YMMREG) /* YMM register 0 ~ 15 */ +#define YMM_H16 ( YMMREG) /* YMM register 16 ~ 31 */ + +#define RM_ZMM_L16 (GEN_SUBCLASS(6) | RM_ZMM) /* ZMM r/m operand 0 ~ 15 */ +#define RM_ZMM_H16 ( RM_ZMM) /* ZMM r/m operand 16 ~ 31 */ +#define ZMM0 (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | ZMMREG) /* ZMM register zero */ +#define ZMM_L16 ( GEN_SUBCLASS(6) | ZMMREG) /* ZMM register 0 ~ 15 */ +#define ZMM_H16 ( ZMMREG) /* ZMM register 16 ~ 31 */ + #endif /* NASM_OPFLAGS_H */ diff --git a/regs.dat b/regs.dat index 46d5409..51682d6 100644 --- a/regs.dat +++ b/regs.dat @@ -117,15 +117,18 @@ mm0-7 MMXREG mmxreg 0 # SSE registers xmm0 XMM0 xmmreg 0 -xmm1-31 XMMREG xmmreg 1 +xmm1-15 XMM_L16 xmmreg 1 +xmm16-31 XMM_H16 xmmreg 16 # AVX registers ymm0 YMM0 ymmreg 0 -ymm1-31 YMMREG ymmreg 1 +ymm1-15 YMM_L16 ymmreg 1 +ymm16-31 YMM_H16 ymmreg 16 # AVX512 registers zmm0 ZMM0 zmmreg 0 -zmm1-31 ZMMREG zmmreg 1 +zmm1-15 ZMM_L16 zmmreg 1 +zmm16-31 ZMM_H16 zmmreg 16 # Opmask registers k0 OPMASK0 opmaskreg 0 |
From: nasm-bot f. J. K. S. <jin...@in...> - 2013-11-27 23:51:25
|
Commit-ID: 487f352b6222c79fd6c719d2c00ab6087c6b6b3c Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=487f352b6222c79fd6c719d2c00ab6087c6b6b3c Author: Jin Kyu Song <jin...@in...> AuthorDate: Wed, 27 Nov 2013 14:10:40 -0800 Committer: Jin Kyu Song <jin...@in...> CommitDate: Wed, 27 Nov 2013 15:43:33 -0800 stdscan: Rework curly brace parsing routines As recommended by the community, a comma-separated decorators ({k1,z}) and nested braces ({{k1},{z}}) are dropped out. So only standard syntax is supported from now. This rework made source code neat and easy to maintain. Most of the codes for handling corner cases are removed. Signed-off-by: Jin Kyu Song <jin...@in...> --- nasm.h | 6 ++++ parser.c | 2 +- stdscan.c | 110 ++++++++++++++++++++++++++----------------------------------- tokhash.pl | 1 + 4 files changed, 54 insertions(+), 65 deletions(-) diff --git a/nasm.h b/nasm.h index cb786f8..87e82d2 100644 --- a/nasm.h +++ b/nasm.h @@ -65,6 +65,7 @@ #endif #define IDLEN_MAX 4096 +#define DECOLEN_MAX 32 /* * Name pollution problems: <time.h> on Digital UNIX pulls in some @@ -421,6 +422,8 @@ extern struct preproc_ops preproc_nop; * identifier. E.g. a period may only appear at the start of an identifier * (for local labels), whereas a number may appear anywhere *but* at the * start. + * isbrcchar matches any character that may placed inside curly braces as a + * decorator. E.g. {rn-sae}, {1to8}, {k1}{z} */ #define isidstart(c) (nasm_isalpha(c) || \ @@ -435,6 +438,9 @@ extern struct preproc_ops preproc_nop; (c) == '#' || \ (c) == '~') +#define isbrcchar(c) (isidchar(c) || \ + (c) == '-') + /* Ditto for numeric constants. */ #define isnumstart(c) (nasm_isdigit(c) || (c) == '$') diff --git a/parser.c b/parser.c index 343f35e..f73c7b5 100644 --- a/parser.c +++ b/parser.c @@ -200,7 +200,7 @@ static void process_size_override(insn *result, operand *op) * when two or more decorators follow a register operand, * consecutive decorators are parsed here. * opmask and zeroing decorators can be placed in any order. - * e.g. zmm1 {k2}{z} or zmm2 {z,k3} + * e.g. zmm1 {k2}{z} or zmm2 {z}{k3} * decorator(s) are placed at the end of an operand. */ static bool parse_braces(decoflags_t *decoflags) diff --git a/stdscan.c b/stdscan.c index b5e389d..ea7537d 100644 --- a/stdscan.c +++ b/stdscan.c @@ -53,8 +53,6 @@ static char *stdscan_bufptr = NULL; static char **stdscan_tempstorage = NULL; static int stdscan_tempsize = 0, stdscan_templen = 0; -static int brace = 0; /* nested brace counter */ -static bool brace_opened = false; /* if brace is just opened */ #define STDSCAN_TEMP_DELTA 256 void stdscan_set(char *str) @@ -110,7 +108,6 @@ static char *stdscan_copy(char *p, int len) /* * a token is enclosed with braces. proper token type will be assigned * accordingly with the token flag. - * a closing brace is treated as an ending character of corresponding token. */ static int stdscan_handle_brace(struct tokenval *tv) { @@ -126,18 +123,6 @@ static int stdscan_handle_brace(struct tokenval *tv) } } - stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); - - if (stdscan_bufptr[0] == '}') { - stdscan_bufptr ++; /* skip the closing brace */ - brace --; - } else if (stdscan_bufptr[0] != ',') { - /* treat {foo,bar} as {foo}{bar} - * by regarding ',' as a mere separator between decorators - */ - nasm_error(ERR_NONFATAL, "closing brace expected"); - tv->t_type = TOKEN_INVALID; - } return tv->t_type; } @@ -148,23 +133,16 @@ int stdscan(void *private_data, struct tokenval *tv) (void)private_data; /* Don't warn that this parameter is unused */ stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); - if (!*stdscan_bufptr) { - /* nested brace shouldn't affect following lines */ - brace = 0; + if (!*stdscan_bufptr) return tv->t_type = TOKEN_EOS; - } /* we have a token; either an id, a number or a char */ if (isidstart(*stdscan_bufptr) || - (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1])) || - (brace && isidchar(*stdscan_bufptr))) { /* because of {1to8} */ + (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1]))) { /* now we've got an identifier */ bool is_sym = false; int token_type; - /* opening brace is followed by any letter */ - brace_opened = false; - if (*stdscan_bufptr == '$') { is_sym = true; stdscan_bufptr++; @@ -172,8 +150,7 @@ int stdscan(void *private_data, struct tokenval *tv) r = stdscan_bufptr++; /* read the entire buffer to advance the buffer pointer but... */ - /* {rn-sae}, {rd-sae}, {ru-sae}, {rz-sae} contain '-' in tokens. */ - while (isidchar(*stdscan_bufptr) || (brace && *stdscan_bufptr == '-')) + while (isidchar(*stdscan_bufptr)) stdscan_bufptr++; /* ... copy only up to IDLEN_MAX-1 characters */ @@ -190,16 +167,11 @@ int stdscan(void *private_data, struct tokenval *tv) * is it actually a register or instruction name, or what? */ token_type = nasm_token_hash(ourcopy, tv); - if (likely(!brace)) { - if (likely(!(tv->t_flag & TFLAG_BRC))) { - /* most of the tokens fall into this case */ - return token_type; - } else { - return tv->t_type = TOKEN_ID; - } + if (likely(!(tv->t_flag & TFLAG_BRC))) { + /* most of the tokens fall into this case */ + return token_type; } else { - /* handle tokens inside braces */ - return stdscan_handle_brace(tv); + return tv->t_type = TOKEN_ID; } } else if (*stdscan_bufptr == '$' && !isnumchar(stdscan_bufptr[1])) { /* @@ -285,6 +257,45 @@ int stdscan(void *private_data, struct tokenval *tv) return tv->t_type = TOKEN_ERRSTR; stdscan_bufptr++; /* Skip final quote */ return tv->t_type = TOKEN_STR; + } else if (*stdscan_bufptr == '{') { + /* now we've got a decorator */ + int token_len; + + stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); + + r = ++stdscan_bufptr; + /* + * read the entire buffer to advance the buffer pointer + * {rn-sae}, {rd-sae}, {ru-sae}, {rz-sae} contain '-' in tokens. + */ + while (isbrcchar(*stdscan_bufptr)) + stdscan_bufptr++; + + token_len = stdscan_bufptr - r; + + /* ... copy only up to DECOLEN_MAX-1 characters */ + tv->t_charptr = stdscan_copy(r, token_len < DECOLEN_MAX ? + token_len : DECOLEN_MAX - 1); + + stdscan_bufptr = nasm_skip_spaces(stdscan_bufptr); + /* if brace is not closed properly or token is too long */ + if ((*stdscan_bufptr != '}') || (token_len > MAX_KEYWORD)) { + nasm_error(ERR_NONFATAL, + "invalid decorator token inside braces"); + return tv->t_type = TOKEN_INVALID; + } + + stdscan_bufptr++; /* skip closing brace */ + + for (s = tv->t_charptr, r = ourcopy; *s; s++) + *r++ = nasm_tolower(*s); + *r = '\0'; + + /* right, so we have a decorator sitting in temp storage. */ + nasm_token_hash(ourcopy, tv); + + /* handle tokens inside braces */ + return stdscan_handle_brace(tv); } else if (*stdscan_bufptr == ';') { /* a comment has happened - stay */ return tv->t_type = TOKEN_EOS; @@ -324,35 +335,6 @@ int stdscan(void *private_data, struct tokenval *tv) } else if (stdscan_bufptr[0] == '|' && stdscan_bufptr[1] == '|') { stdscan_bufptr += 2; return tv->t_type = TOKEN_DBL_OR; - } else if (stdscan_bufptr[0] == '{') { - stdscan_bufptr ++; /* skip the opening brace */ - brace ++; /* in case of nested braces */ - brace_opened = true; /* brace is just opened */ - return stdscan(private_data, tv); - } else if (stdscan_bufptr[0] == ',' && brace) { - /* - * a comma inside braces should be treated just as a separator. - * this is almost same as an opening brace except increasing counter. - */ - stdscan_bufptr ++; - brace_opened = true; /* brace is just opened */ - return stdscan(private_data, tv); - } else if (stdscan_bufptr[0] == '}') { - stdscan_bufptr ++; /* skip the closing brace */ - if (brace) { - /* unhandled nested closing brace */ - brace --; - /* if brace is closed without any content in it */ - if (brace_opened) { - brace_opened = false; - nasm_error(ERR_NONFATAL, "nothing inside braces"); - } - return stdscan(private_data, tv); - } else { - /* redundant closing brace */ - return tv->t_type = TOKEN_INVALID; - } - return stdscan(private_data, tv); } else /* just an ordinary char */ return tv->t_type = (uint8_t)(*stdscan_bufptr++); } diff --git a/tokhash.pl b/tokhash.pl index 4ea387d..60bd258 100755 --- a/tokhash.pl +++ b/tokhash.pl @@ -260,6 +260,7 @@ if ($output eq 'h') { print " uint16_t ix;\n"; print " const struct tokendata *data;\n"; print "\n"; + printf " tv->t_flag = 0;\n"; printf " crc = crc64(UINT64_C(0x%08x%08x), token);\n", $$sv[0], $$sv[1]; print " k1 = (uint32_t)crc;\n"; |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-27 21:48:21
|
Commit-ID: fd52c277dd6d768545cee39b154e706904581966 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=fd52c277dd6d768545cee39b154e706904581966 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Tue, 26 Nov 2013 18:09:56 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Tue, 26 Nov 2013 18:12:39 -0800 output: Allow OUT_ADDRESS with a negative size to mean signed relocation This only matters for ELF64/ELFx32, at least for now. Signed-off-by: H. Peter Anvin <hp...@zy...> --- output/outaout.c | 18 ++++++++---------- output/outas86.c | 9 +++++---- output/outbin.c | 10 +++++++--- output/outcoff.c | 15 ++++++++------- output/outdbg.c | 11 +++++++---- output/outelf32.c | 49 +++++++++++++++++++++++++++++-------------------- output/outelf64.c | 31 +++++++++++++++++++++++++------ output/outelfx32.c | 29 ++++++++++++++++++++++++----- output/outieee.c | 6 ++++-- output/outmac32.c | 34 +++++++++++++++++++--------------- output/outmac64.c | 14 +++++++++----- output/outobj.c | 5 ++++- output/outrdf2.c | 9 +++++---- 13 files changed, 154 insertions(+), 86 deletions(-) diff --git a/output/outaout.c b/output/outaout.c index e096392..b9f21ec 100644 --- a/output/outaout.c +++ b/output/outaout.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -635,6 +635,7 @@ static void aout_out(int32_t segto, const void *data, nasm_error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG"); aout_sect_write(s, data, size); } else if (type == OUT_ADDRESS) { + int asize = abs(size); addr = *(int64_t *)data; if (segment != NO_SEG) { if (segment % 2) { @@ -642,8 +643,7 @@ static void aout_out(int32_t segto, const void *data, " segment base references"); } else { if (wrt == NO_SEG) { - aout_add_reloc(s, segment, RELTYPE_ABSOLUTE, - size); + aout_add_reloc(s, segment, RELTYPE_ABSOLUTE, asize); } else if (!bsd) { nasm_error(ERR_NONFATAL, "Linux a.out format does not support" @@ -651,19 +651,17 @@ static void aout_out(int32_t segto, const void *data, wrt = NO_SEG; /* we can at least _try_ to continue */ } else if (wrt == aout_gotpc_sect + 1) { is_pic = 0x40; - aout_add_reloc(s, segment, RELTYPE_GOTPC, size); + aout_add_reloc(s, segment, RELTYPE_GOTPC, asize); } else if (wrt == aout_gotoff_sect + 1) { is_pic = 0x40; - addr = aout_add_gotoff_reloc(s, segment, - addr, size); + addr = aout_add_gotoff_reloc(s, segment, addr, asize); } else if (wrt == aout_got_sect + 1) { is_pic = 0x40; - addr = - aout_add_gsym_reloc(s, segment, addr, RELTYPE_GOT, - size, true); + addr = aout_add_gsym_reloc(s, segment, addr, RELTYPE_GOT, + asize, true); } else if (wrt == aout_sym_sect + 1) { addr = aout_add_gsym_reloc(s, segment, addr, - RELTYPE_ABSOLUTE, size, + RELTYPE_ABSOLUTE, asize, false); } else if (wrt == aout_plt_sect + 1) { is_pic = 0x40; diff --git a/output/outas86.c b/output/outas86.c index b288637..7af8d78 100644 --- a/output/outas86.c +++ b/output/outas86.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -345,19 +345,20 @@ static void as86_out(int32_t segto, const void *data, as86_sect_write(s, data, size); as86_add_piece(s, 0, 0L, 0L, size, 0); } else if (type == OUT_ADDRESS) { + int asize = abs(size); if (segment != NO_SEG) { if (segment % 2) { nasm_error(ERR_NONFATAL, "as86 format does not support" " segment base references"); } else { offset = *(int64_t *)data; - as86_add_piece(s, 1, offset, segment, size, 0); + as86_add_piece(s, 1, offset, segment, asize, 0); } } else { p = mydata; WRITELONG(p, *(int64_t *)data); - as86_sect_write(s, data, size); - as86_add_piece(s, 0, 0L, 0L, size, 0); + as86_sect_write(s, data, asize); + as86_add_piece(s, 0, 0L, 0L, asize, 0); } } else if (type == OUT_REL2ADR) { if (segment == segto) diff --git a/output/outbin.c b/output/outbin.c index 21c042d..6dc4b2a 100644 --- a/output/outbin.c +++ b/output/outbin.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -762,6 +762,9 @@ static void bin_out(int32_t segto, const void *data, switch (type) { case OUT_ADDRESS: + { + int asize = abs(size); + if (segment != NO_SEG && !find_section_by_index(segment)) { if (segment % 2) nasm_error(ERR_NONFATAL, "binary output format does not support" @@ -775,10 +778,11 @@ static void bin_out(int32_t segto, const void *data, if (segment != NO_SEG) add_reloc(s, size, segment, -1L); p = mydata; - WRITEADDR(p, *(int64_t *)data, size); - saa_wbytes(s->contents, mydata, size); + WRITEADDR(p, *(int64_t *)data, asize); + saa_wbytes(s->contents, mydata, asize); } break; + } case OUT_RAWDATA: if (s->flags & TYPE_PROGBITS) diff --git a/output/outcoff.c b/output/outcoff.c index d0fcb77..3949028 100644 --- a/output/outcoff.c +++ b/output/outcoff.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2010 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -646,8 +646,9 @@ static void coff_out(int32_t segto, const void *data, nasm_error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG"); coff_sect_write(s, data, size); } else if (type == OUT_ADDRESS) { - if (!(win64)) { - if (size != 4 && (segment != NO_SEG || wrt != NO_SEG)) { + int asize = abs(size); + if (!win64) { + if (asize != 4 && (segment != NO_SEG || wrt != NO_SEG)) { nasm_error(ERR_NONFATAL, "COFF format does not support non-32-bit" " relocations"); } else { @@ -664,25 +665,25 @@ static void coff_out(int32_t segto, const void *data, } p = mydata; WRITELONG(p, *(int64_t *)data + fix); - coff_sect_write(s, mydata, size); + coff_sect_write(s, mydata, asize); } } else { int32_t fix = 0; p = mydata; - if (size == 8) { + if (asize == 8) { if (wrt == imagebase_sect) { nasm_error(ERR_NONFATAL, "operand size mismatch: 'wrt " WRT_IMAGEBASE "' is a 32-bit operand"); } fix = coff_add_reloc(s, segment, IMAGE_REL_AMD64_ADDR64); WRITEDLONG(p, *(int64_t *)data + fix); - coff_sect_write(s, mydata, size); + coff_sect_write(s, mydata, asize); } else { fix = coff_add_reloc(s, segment, wrt == imagebase_sect ? IMAGE_REL_AMD64_ADDR32NB: IMAGE_REL_AMD64_ADDR32); WRITELONG(p, *(int64_t *)data + fix); - coff_sect_write(s, mydata, size); + coff_sect_write(s, mydata, asize); } } } else if (type == OUT_REL2ADR) { diff --git a/output/outdbg.c b/output/outdbg.c index 2b75039..bf14558 100644 --- a/output/outdbg.c +++ b/output/outdbg.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -127,7 +127,10 @@ static void dbg_out(int32_t segto, const void *data, int32_t ldata; int id; - fprintf(ofile, "out to %"PRIx32", len = %"PRIu64": ", segto, size); + if (type == OUT_ADDRESS) + fprintf(ofile, "out to %"PRIx32", len = %d: ", segto, (int)size); + else + fprintf(ofile, "out to %"PRIx32", len = %"PRIu64": ", segto, size); switch (type) { case OUT_RESERVE: @@ -144,8 +147,8 @@ static void dbg_out(int32_t segto, const void *data, break; case OUT_ADDRESS: ldata = *(int64_t *)data; - fprintf(ofile, "addr %08"PRIx32" (seg %08"PRIx32", wrt %08"PRIx32")\n", ldata, - segment, wrt); + fprintf(ofile, "addr %08"PRIx32" (seg %08"PRIx32", wrt %08"PRIx32")\n", + ldata, segment, wrt); break; case OUT_REL1ADR: fprintf(ofile, "rel1adr %02"PRIx8" (seg %08"PRIx32")\n", diff --git a/output/outelf32.c b/output/outelf32.c index 48f9177..413270b 100644 --- a/output/outelf32.c +++ b/output/outelf32.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2010 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -767,6 +767,7 @@ static void elf_out(int32_t segto, const void *data, case OUT_ADDRESS: { bool gnu16 = false; + int asize = abs(size); addr = *(int64_t *)data; if (segment != NO_SEG) { if (segment % 2) { @@ -779,22 +780,20 @@ static void elf_out(int32_t segto, const void *data, * don't handle switch() statements with 64-bit * expressions. */ - if (size < UINT_MAX) { - switch ((unsigned int)size) { - case 1: - gnu16 = true; - elf_add_reloc(s, segment, R_386_8); - break; - case 2: - gnu16 = true; - elf_add_reloc(s, segment, R_386_16); - break; - case 4: - elf_add_reloc(s, segment, R_386_32); - break; - default: /* Error issued further down */ - break; - } + switch (asize) { + case 1: + gnu16 = true; + elf_add_reloc(s, segment, R_386_8); + break; + case 2: + gnu16 = true; + elf_add_reloc(s, segment, R_386_16); + break; + case 4: + elf_add_reloc(s, segment, R_386_32); + break; + default: /* Error issued further down */ + break; } } else if (wrt == elf_gotpc_sect + 1) { /* @@ -813,13 +812,23 @@ static void elf_out(int32_t segto, const void *data, addr = elf_add_gsym_reloc(s, segment, addr, R_386_GOT32, true); } else if (wrt == elf_sym_sect + 1) { - if (size == 2) { + switch (asize) { + case 1: + gnu16 = true; + addr = elf_add_gsym_reloc(s, segment, addr, + R_386_8, false); + break; + case 2: gnu16 = true; addr = elf_add_gsym_reloc(s, segment, addr, R_386_16, false); - } else { + break; + case 4: addr = elf_add_gsym_reloc(s, segment, addr, R_386_32, false); + break; + default: + break; } } else if (wrt == elf_plt_sect + 1) { nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-" @@ -835,7 +844,7 @@ static void elf_out(int32_t segto, const void *data, if (gnu16) { nasm_error(ERR_WARNING | ERR_WARN_GNUELF, "8- or 16-bit relocations in ELF32 is a GNU extension"); - } else if (size != 4 && segment != NO_SEG) { + } else if (asize != 4 && segment != NO_SEG) { nasm_error(ERR_NONFATAL, "Unsupported non-32-bit ELF relocation"); } WRITEADDR(p, addr, size); diff --git a/output/outelf64.c b/output/outelf64.c index 8175aed..9f93fc8 100644 --- a/output/outelf64.c +++ b/output/outelf64.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2010 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -785,6 +785,10 @@ static void elf_out(int32_t segto, const void *data, break; case OUT_ADDRESS: + { + int isize = (int)size; + int asize = abs(size); + addr = *(int64_t *)data; if (segment == NO_SEG) { /* Do nothing */ @@ -793,17 +797,23 @@ static void elf_out(int32_t segto, const void *data, " segment base references"); } else { if (wrt == NO_SEG) { - switch ((int)size) { + switch (isize) { case 1: + case -1: elf_add_reloc(s, segment, addr, R_X86_64_8); break; case 2: + case -2: elf_add_reloc(s, segment, addr, R_X86_64_16); break; case 4: elf_add_reloc(s, segment, addr, R_X86_64_32); break; + case -4: + elf_add_reloc(s, segment, addr, R_X86_64_32S); + break; case 8: + case -8: elf_add_reloc(s, segment, addr, R_X86_64_64); break; default: @@ -821,7 +831,7 @@ static void elf_out(int32_t segto, const void *data, elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32); addr = 0; } else if (wrt == elf_gotoff_sect + 1) { - if (size != 8) { + if (asize != 8) { nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff " "references to be qword"); } else { @@ -829,7 +839,7 @@ static void elf_out(int32_t segto, const void *data, addr = 0; } } else if (wrt == elf_got_sect + 1) { - switch ((int)size) { + switch (asize) { case 4: elf_add_gsym_reloc(s, segment, addr, 0, R_X86_64_GOT32, true); @@ -845,13 +855,15 @@ static void elf_out(int32_t segto, const void *data, break; } } else if (wrt == elf_sym_sect + 1) { - switch ((int)size) { + switch (isize) { case 1: + case -1: elf_add_gsym_reloc(s, segment, addr, 0, R_X86_64_8, false); addr = 0; break; case 2: + case -2: elf_add_gsym_reloc(s, segment, addr, 0, R_X86_64_16, false); addr = 0; @@ -861,7 +873,13 @@ static void elf_out(int32_t segto, const void *data, R_X86_64_32, false); addr = 0; break; + case -4: + elf_add_gsym_reloc(s, segment, addr, 0, + R_X86_64_32S, false); + addr = 0; + break; case 8: + case -8: elf_add_gsym_reloc(s, segment, addr, 0, R_X86_64_64, false); addr = 0; @@ -878,8 +896,9 @@ static void elf_out(int32_t segto, const void *data, " use of WRT"); } } - elf_sect_writeaddr(s, addr, size); + elf_sect_writeaddr(s, addr, asize); break; + } case OUT_REL1ADR: reltype = R_X86_64_PC8; diff --git a/output/outelfx32.c b/output/outelfx32.c index 57bbf75..bbedc48 100644 --- a/output/outelfx32.c +++ b/output/outelfx32.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 2012 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -783,6 +783,10 @@ static void elf_out(int32_t segto, const void *data, break; case OUT_ADDRESS: + { + int isize = (int)size; + int asize = abs(size); + addr = *(int64_t *)data; if (segment == NO_SEG) { /* Do nothing */ @@ -791,17 +795,23 @@ static void elf_out(int32_t segto, const void *data, " segment base references"); } else { if (wrt == NO_SEG) { - switch ((int)size) { + switch (isize) { case 1: + case -1: elf_add_reloc(s, segment, addr, R_X86_64_8); break; case 2: + case -2: elf_add_reloc(s, segment, addr, R_X86_64_16); break; case 4: elf_add_reloc(s, segment, addr, R_X86_64_32); break; + case -4: + elf_add_reloc(s, segment, addr, R_X86_64_32S); + break; case 8: + case -8: elf_add_reloc(s, segment, addr, R_X86_64_64); break; default: @@ -822,7 +832,7 @@ static void elf_out(int32_t segto, const void *data, nasm_error(ERR_NONFATAL, "ELFX32 doesn't support " "R_X86_64_GOTOFF64"); } else if (wrt == elf_got_sect + 1) { - switch ((int)size) { + switch (asize) { case 4: elf_add_gsym_reloc(s, segment, addr, 0, R_X86_64_GOT32, true); @@ -833,13 +843,15 @@ static void elf_out(int32_t segto, const void *data, break; } } else if (wrt == elf_sym_sect + 1) { - switch ((int)size) { + switch (isize) { case 1: + case -1: elf_add_gsym_reloc(s, segment, addr, 0, R_X86_64_8, false); addr = 0; break; case 2: + case -2: elf_add_gsym_reloc(s, segment, addr, 0, R_X86_64_16, false); addr = 0; @@ -849,7 +861,13 @@ static void elf_out(int32_t segto, const void *data, R_X86_64_32, false); addr = 0; break; + case -4: + elf_add_gsym_reloc(s, segment, addr, 0, + R_X86_64_32S, false); + addr = 0; + break; case 8: + case -8: elf_add_gsym_reloc(s, segment, addr, 0, R_X86_64_64, false); addr = 0; @@ -866,8 +884,9 @@ static void elf_out(int32_t segto, const void *data, " use of WRT"); } } - elf_sect_writeaddr(s, addr, size); + elf_sect_writeaddr(s, addr, asize); break; + } case OUT_REL1ADR: reltype = R_X86_64_PC8; diff --git a/output/outieee.c b/output/outieee.c index 94d5e59..5377ec6 100644 --- a/output/outieee.c +++ b/output/outieee.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -437,7 +437,9 @@ static void ieee_out(int32_t segto, const void *data, ieee_write_byte(seg, *ucdata++); } else if (type == OUT_ADDRESS || type == OUT_REL2ADR || type == OUT_REL4ADR) { - if (segment == NO_SEG && type != OUT_ADDRESS) + if (type == OUT_ADDRESS) + size = abs(size); + else if (segment == NO_SEG) nasm_error(ERR_NONFATAL, "relative call to absolute address not" " supported by IEEE format"); ldata = *(int64_t *)data; diff --git a/output/outmac32.c b/output/outmac32.c index a13e0d9..c2c91b4 100644 --- a/output/outmac32.c +++ b/output/outmac32.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -431,20 +431,24 @@ static void macho_output(int32_t secto, const void *data, break; case OUT_ADDRESS: - addr = *(int64_t *)data; - - if (section != NO_SEG) { - if (section % 2) { - nasm_error(ERR_NONFATAL, "Mach-O format does not support" - " section base references"); - } else - add_reloc(s, section, 0, size); - } - - p = mydata; - WRITEADDR(p, addr, size); - sect_write(s, mydata, size); - break; + { + int asize = abs(size); + + addr = *(int64_t *)data; + + if (section != NO_SEG) { + if (section % 2) { + nasm_error(ERR_NONFATAL, "Mach-O format does not support" + " section base references"); + } else + add_reloc(s, section, 0, asize); + } + + p = mydata; + WRITEADDR(p, addr, asize); + sect_write(s, mydata, asize); + break; + } case OUT_REL2ADR: if (section == secto) diff --git a/output/outmac64.c b/output/outmac64.c index 358ae6e..abad84a 100644 --- a/output/outmac64.c +++ b/output/outmac64.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -528,6 +528,9 @@ static void macho_output(int32_t secto, const void *data, break; case OUT_ADDRESS: + { + int asize = abs(size); + addr = *(int64_t *)data; if (section != NO_SEG) { if (section % 2) { @@ -535,7 +538,7 @@ static void macho_output(int32_t secto, const void *data, " section base references"); } else { if (wrt == NO_SEG) { - if (size < 8) { + if (asize < 8) { nasm_error(ERR_NONFATAL, "Mach-O 64-bit format does not support" " 32-bit absolute addresses"); /* @@ -544,7 +547,7 @@ static void macho_output(int32_t secto, const void *data, making it impractical for use in intermediate object files */ } else { - addr -= add_reloc(s, section, 0, size, addr); // X86_64_RELOC_UNSIGNED + addr -= add_reloc(s, section, 0, asize, addr); // X86_64_RELOC_UNSIGNED } } else { nasm_error(ERR_NONFATAL, "Mach-O format does not support" @@ -554,9 +557,10 @@ static void macho_output(int32_t secto, const void *data, } p = mydata; - WRITEADDR(p, addr, size); - sect_write(s, mydata, size); + WRITEADDR(p, addr, asize); + sect_write(s, mydata, asize); break; + } case OUT_REL2ADR: p = mydata; diff --git a/output/outobj.c b/output/outobj.c index 6fa5419..7fa29b2 100644 --- a/output/outobj.c +++ b/output/outobj.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -1086,6 +1086,9 @@ static void obj_out(int32_t segto, const void *data, { int rsize; + if (type == OUT_ADDRESS) + size = abs(size); + if (segment == NO_SEG && type != OUT_ADDRESS) nasm_error(ERR_NONFATAL, "relative call to absolute address not" " supported by OBJ format"); diff --git a/output/outrdf2.c b/output/outrdf2.c index 02518a1..c7aeb28 100644 --- a/output/outrdf2.c +++ b/output/outrdf2.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2013 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -583,6 +583,7 @@ static void rdf2_out(int32_t segto, const void *data, membufwrite(segto, data, size); } else if (type == OUT_ADDRESS) { + int asize = abs(size); /* if segment == NO_SEG then we are writing an address of an object within the same segment - do not produce reloc rec. */ @@ -597,14 +598,14 @@ static void rdf2_out(int32_t segto, const void *data, rr.reclen = 8; rr.segment = segto; /* segment we're currently in */ rr.offset = getsegmentlength(segto); /* current offset */ - rr.length = size; /* length of reference */ + rr.length = asize; /* length of reference */ rr.refseg = segment; /* segment referred to */ write_reloc_rec(&rr); } pd = databuf; /* convert address to little-endian */ - WRITEADDR(pd, *(int64_t *)data, size); - membufwrite(segto, databuf, size); + WRITEADDR(pd, *(int64_t *)data, asize); + membufwrite(segto, databuf, asize); } else if (type == OUT_REL2ADR) { if (segment == segto) nasm_error(ERR_PANIC, "intra-segment OUT_REL2ADR"); |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-27 21:48:20
|
Commit-ID: 72bf3fe98c8cc6f0ebcc9329b28fe02d9ddeef57 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=72bf3fe98c8cc6f0ebcc9329b28fe02d9ddeef57 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Tue, 26 Nov 2013 20:19:53 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Tue, 26 Nov 2013 20:19:53 -0800 assemble: Only treat a displacement as signed if it is < asize Only generate a signed relocation if the displacement size is less than the address size. This matters when involving address size overrides. It is technically impossible to do this one perfectly, because it is never really knowable if the displacement offset is used as a base or an index. Signed-off-by: H. Peter Anvin <hp...@zy...> --- assemble.c | 32 +++++++++++++++----------------- test/relocs.asm | 7 +++++++ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/assemble.c b/assemble.c index 52a352f..364e6c9 100644 --- a/assemble.c +++ b/assemble.c @@ -1849,13 +1849,7 @@ static void gencode(int32_t segment, int64_t offset, int bits, offset += s; s = 0; - switch (ea_data.bytes) { - case 0: - break; - case 1: - case 2: - case 4: - case 8: + if (ea_data.bytes) { /* use compressed displacement, if available */ data = ea_data.disp8 ? ea_data.disp8 : opy->offset; s += ea_data.bytes; @@ -1872,21 +1866,25 @@ static void gencode(int32_t segment, int64_t offset, int bits, insn_end - offset, opy->segment, opy->wrt); } } else { - if (overflow_general(data, ins->addr_size >> 3) || + int asize = ins->addr_size >> 3; + int atype = ea_data.bytes; + + if (overflow_general(data, asize) || signed_bits(data, ins->addr_size) != - signed_bits(data, ea_data.bytes * 8)) + signed_bits(data, ea_data.bytes << 3)) warn_overflow(ERR_PASS2, ea_data.bytes); + if (asize > ea_data.bytes) { + /* + * If the address isn't the full width of + * the address size, treat is as signed... + */ + atype = -atype; + } + out(offset, segment, &data, OUT_ADDRESS, - -ea_data.bytes, opy->segment, opy->wrt); + atype, opy->segment, opy->wrt); } - break; - default: - /* Impossible! */ - errfunc(ERR_PANIC, - "Invalid amount of bytes (%d) for offset?!", - ea_data.bytes); - break; } offset += s; } diff --git a/test/relocs.asm b/test/relocs.asm index a293f50..cc560f2 100644 --- a/test/relocs.asm +++ b/test/relocs.asm @@ -5,6 +5,13 @@ mov rax,[foo] mov rax,[qword foo] + mov eax,[a32 foo] + mov rax,[a32 foo] + mov rax,[a32 qword foo] + + mov eax,foo + mov rax,dword foo + mov rax,qword foo mov eax,foo mov rax,dword foo mov rax,qword foo |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-27 21:48:20
|
Commit-ID: 186b533425405ac4e1172c7f0e6751848f04aabd Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=186b533425405ac4e1172c7f0e6751848f04aabd Author: H. Peter Anvin <hp...@zy...> AuthorDate: Tue, 26 Nov 2013 18:24:22 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Tue, 26 Nov 2013 18:24:22 -0800 test: Add a test for various 32- and 64-bit relocations Test signedness in a couple of different contexts. Signed-off-by: H. Peter Anvin <hp...@zy...> --- test/relocs.asm | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/relocs.asm b/test/relocs.asm new file mode 100644 index 0000000..a293f50 --- /dev/null +++ b/test/relocs.asm @@ -0,0 +1,13 @@ + bits 64 + extern foo + + mov eax,[foo] + mov rax,[foo] + mov rax,[qword foo] + + mov eax,foo + mov rax,dword foo + mov rax,qword foo + + dd foo + dq foo |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-27 21:48:18
|
Commit-ID: d35f23011334d0693b48f16757e3971069ad7328 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=d35f23011334d0693b48f16757e3971069ad7328 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Tue, 26 Nov 2013 18:22:45 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Tue, 26 Nov 2013 18:22:45 -0800 listing: handle negative (signed) address size values The listing module also needs to know about this new convention. Signed-off-by: H. Peter Anvin <hp...@zy...> --- listing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/listing.c b/listing.c index 38d7908..18e949b 100644 --- a/listing.c +++ b/listing.c @@ -216,7 +216,7 @@ static void list_output(int32_t offset, const void *data, break; } case OUT_ADDRESS: - list_address(offset, "[]", *(int64_t *)data, size); + list_address(offset, "[]", *(int64_t *)data, abs(size)); break; case OUT_REL1ADR: list_address(offset, "()", *(int64_t *)data, 1); |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-27 21:48:16
|
Commit-ID: 89a2ac0d0aabb586f0f6f051a721a1f2256c7492 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=89a2ac0d0aabb586f0f6f051a721a1f2256c7492 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Tue, 26 Nov 2013 18:23:20 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Tue, 26 Nov 2013 18:23:20 -0800 assemble: Emit signed relocations where appropriate Emit signed relocations where we know they are necessary. This is not at all exhaustive; in particular we are missing this for a number of 8- and 16-bit cases, and probably others. Signed-off-by: H. Peter Anvin <hp...@zy...> --- assemble.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/assemble.c b/assemble.c index 193c487..52a352f 100644 --- a/assemble.c +++ b/assemble.c @@ -173,6 +173,7 @@ #include <stdio.h> #include <string.h> +#include <stdlib.h> #include <inttypes.h> #include "nasm.h" @@ -316,7 +317,8 @@ static void out(int64_t offset, int32_t segto, const void *data, * convert it into RAWDATA format. */ uint8_t *q = p; - + + size = abs((int)size); if (size > 8) { errfunc(ERR_PANIC, "OUT_ADDRESS with size > 8"); return; @@ -344,11 +346,12 @@ static void out(int64_t offset, int32_t segto, const void *data, outfmt->output(segto, data, type, size, segment, wrt); } -static void out_imm8(int64_t offset, int32_t segment, struct operand *opx) +static void out_imm8(int64_t offset, int32_t segment, + struct operand *opx, int asize) { if (opx->segment != NO_SEG) { uint64_t data = opx->offset; - out(offset, segment, &data, OUT_ADDRESS, 1, opx->segment, opx->wrt); + out(offset, segment, &data, OUT_ADDRESS, asize, opx->segment, opx->wrt); } else { uint8_t byte = opx->offset; out(offset, segment, &byte, OUT_RAWDATA, 1, NO_SEG, NO_SEG); @@ -1399,7 +1402,7 @@ static void gencode(int32_t segment, int64_t offset, int bits, errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV, "byte value exceeds bounds"); } - out_imm8(offset, segment, opx); + out_imm8(offset, segment, opx, -1); offset += 1; break; @@ -1407,7 +1410,7 @@ static void gencode(int32_t segment, int64_t offset, int bits, if (opx->offset < 0 || opx->offset > 255) errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV, "unsigned byte value exceeds bounds"); - out_imm8(offset, segment, opx); + out_imm8(offset, segment, opx, 1); offset += 1; break; @@ -1570,7 +1573,7 @@ static void gencode(int32_t segment, int64_t offset, int bits, errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV, "signed dword immediate exceeds bounds"); } - out(offset, segment, &data, OUT_ADDRESS, 4, + out(offset, segment, &data, OUT_ADDRESS, -4, opx->segment, opx->wrt); offset += 4; break; @@ -1865,7 +1868,7 @@ static void gencode(int32_t segment, int64_t offset, int bits, ea_data.bytes, NO_SEG, NO_SEG); } else { /* overflow check in output/linker? */ - out(offset, segment, &data, OUT_REL4ADR, + out(offset, segment, &data, OUT_REL4ADR, insn_end - offset, opy->segment, opy->wrt); } } else { @@ -1875,7 +1878,7 @@ static void gencode(int32_t segment, int64_t offset, int bits, warn_overflow(ERR_PASS2, ea_data.bytes); out(offset, segment, &data, OUT_ADDRESS, - ea_data.bytes, opy->segment, opy->wrt); + -ea_data.bytes, opy->segment, opy->wrt); } break; default: |
From: nasm-bot f. H. P. A. <hp...@li...> - 2013-11-27 21:45:25
|
Commit-ID: afcb66f41281104c8dc70f628eeaedda67b13b97 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=afcb66f41281104c8dc70f628eeaedda67b13b97 Author: H. Peter Anvin <hp...@li...> AuthorDate: Wed, 27 Nov 2013 13:41:50 -0800 Committer: H. Peter Anvin <hp...@li...> CommitDate: Wed, 27 Nov 2013 13:41:50 -0800 iflag: Do the equality test in iflag_cmp() first The equality test indicates how long we spin, so do that first. Signed-off-by: H. Peter Anvin <hp...@li...> --- iflag.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iflag.h b/iflag.h index b1144be..8754174 100644 --- a/iflag.h +++ b/iflag.h @@ -46,10 +46,10 @@ static inline int iflag_cmp(const iflag_t *a, const iflag_t *b) int i; for (i = sizeof(a->field) / sizeof(a->field[0]) - 1; i >= 0; i--) { - if (a->field[i] < b->field[i]) - return -1; - else if (a->field[i] > b->field[i]) - return 1; + if (a->field[i] == b->field[i]) + continue; + + return (a->field[i] > b->field[i]) ? 1 : -1; } return 0; |
From: nasm-bot f. H. P. A. <hp...@li...> - 2013-11-27 21:45:24
|
Commit-ID: 3143a462c261fb3a4d38ef504e855ebfc1514c6d Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=3143a462c261fb3a4d38ef504e855ebfc1514c6d Author: H. Peter Anvin <hp...@li...> AuthorDate: Wed, 27 Nov 2013 13:43:45 -0800 Committer: H. Peter Anvin <hp...@li...> CommitDate: Wed, 27 Nov 2013 13:43:45 -0800 disasm: Don't rely on iflag_cmp() returning +/-1 It is safer to just rely on the sign, for future options. Signed-off-by: H. Peter Anvin <hp...@li...> --- disasm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/disasm.c b/disasm.c index b7c5027..bb53b4c 100644 --- a/disasm.c +++ b/disasm.c @@ -1338,7 +1338,8 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize, if (tmp_ins.prefixes[i]) nprefix++; if (nprefix < best_pref || - (nprefix == best_pref && iflag_cmp(&goodness, &best) == -1)) { + (nprefix == best_pref && + iflag_cmp(&goodness, &best) < 0)) { /* This is the best one found so far */ best = goodness; best_p = p; |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-26 23:27:20
|
Commit-ID: 80d18b55551e43f0c3e390550ecd396b90265fd3 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=80d18b55551e43f0c3e390550ecd396b90265fd3 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Tue, 26 Nov 2013 15:21:15 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Tue, 26 Nov 2013 15:21:15 -0800 iflag: In iflag_cmp() scan from the most significant word down In order for iflag_cmp() to return an ordering that makes sense, we need to scan from the most significant word downward. That way the bits with the higher index consistently are the more significant. This fixes the disassembler vendor selection algorithm. While we are doing that, make that dependency more explicit in the comments. Signed-off-by: H. Peter Anvin <hp...@zy...> --- iflag.h | 4 ++-- insns-iflags.pl | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/iflag.h b/iflag.h index 0764a05..b1144be 100644 --- a/iflag.h +++ b/iflag.h @@ -43,9 +43,9 @@ static inline void iflag_set_all(iflag_t *f) static inline int iflag_cmp(const iflag_t *a, const iflag_t *b) { - unsigned int i; + int i; - for (i = 0; i < sizeof(a->field) / sizeof(a->field[0]); i++) { + for (i = sizeof(a->field) / sizeof(a->field[0]) - 1; i >= 0; i--) { if (a->field[i] < b->field[i]) return -1; else if (a->field[i] > b->field[i]) diff --git a/insns-iflags.pl b/insns-iflags.pl index 8f8e009..da2fd9b 100644 --- a/insns-iflags.pl +++ b/insns-iflags.pl @@ -135,6 +135,9 @@ my %insns_flag_bit = ( # # dword bound, index 3 - cpu type flags # + # The CYRIX and AMD flags should have the highest bit values; the + # disassembler selection algorithm depends on it. + # "8086" => [ 96, "8086"], "186" => [ 97, "186+"], "286" => [ 98, "286+"], @@ -151,8 +154,8 @@ my %insns_flag_bit = ( "SANDYBRIDGE" => [109, "Sandy Bridge"], "FUTURE" => [110, "Future processor (not yet disclosed)"], "IA64" => [111, "IA64 (in x86 mode)"], - "CYRIX" => [112, "Cyrix-specific"], - "AMD" => [113, "AMD-specific"], + "CYRIX" => [126, "Cyrix-specific"], + "AMD" => [127, "AMD-specific"], ); my %insns_flag_hash = (); |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-26 23:18:30
|
Commit-ID: 54c7711858e458c4cd0817b21fc4351f9714a7c1 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=54c7711858e458c4cd0817b21fc4351f9714a7c1 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Sun, 24 Nov 2013 17:07:33 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Sun, 24 Nov 2013 17:07:33 -0800 insns.dat: Fix a typo in a comment isnsn-iflags.pl not insns-iflag.pl. Signed-off-by: H. Peter Anvin <hp...@zy...> --- insns.dat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/insns.dat b/insns.dat index 1d15997..156abfd 100644 --- a/insns.dat +++ b/insns.dat @@ -41,7 +41,7 @@ ; ; For a detailed description of the code string (third field), please ; see insns.pl and the comment at the top of assemble.c. For a detailed -; description of the flags (fourth field), please see insns-iflag.pl. +; description of the flags (fourth field), please see insns-iflags.pl. ; ; Comments with a pound sign after the semicolon generate section ; subheaders in the NASM documentation. |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-26 23:18:30
|
Commit-ID: 4b47c77d89adac7abd81f6a99a04d85d853d84d9 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=4b47c77d89adac7abd81f6a99a04d85d853d84d9 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Sun, 24 Nov 2013 17:14:34 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Sun, 24 Nov 2013 17:14:34 -0800 iflag: Drop the use of double underscores Double underscores are reserved for the implementation, i.e. the C compiler and its libraries. NASM is an application and should not use this namespace. Signed-off-by: H. Peter Anvin <hp...@zy...> --- iflag.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/iflag.h b/iflag.h index f73f99c..0764a05 100644 --- a/iflag.h +++ b/iflag.h @@ -114,13 +114,13 @@ IF_GEN_HELPER(xor, ^) IF_GENBIT(IF_AR3) |\ IF_GENBIT(IF_AR4)) -#define __itemp_smask(idx) (insns_flags[(idx)].field[0] & IF_SMASK) -#define __itemp_armask(idx) (insns_flags[(idx)].field[0] & IF_ARMASK) -#define __itemp_arg(idx) ((__itemp_armask(idx) >> IF_AR0) - 1) +#define _itemp_smask(idx) (insns_flags[(idx)].field[0] & IF_SMASK) +#define _itemp_armask(idx) (insns_flags[(idx)].field[0] & IF_ARMASK) +#define _itemp_arg(idx) ((_itemp_armask(idx) >> IF_AR0) - 1) -#define itemp_smask(itemp) __itemp_smask((itemp)->iflag_idx) -#define itemp_arg(itemp) __itemp_arg((itemp)->iflag_idx) -#define itemp_armask(itemp) __itemp_armask((itemp)->iflag_idx) +#define itemp_smask(itemp) _itemp_smask((itemp)->iflag_idx) +#define itemp_arg(itemp) _itemp_arg((itemp)->iflag_idx) +#define itemp_armask(itemp) _itemp_armask((itemp)->iflag_idx) static inline int iflag_cmp_cpu_level(const iflag_t *a, const iflag_t *b) { @@ -141,7 +141,7 @@ static inline int iflag_cmp_cpu_level(const iflag_t *a, const iflag_t *b) return 0; } -static inline iflag_t __iflag_pfmask(const iflag_t *a) +static inline iflag_t _iflag_pfmask(const iflag_t *a) { iflag_t r = (iflag_t) { .field[1] = a->field[1], @@ -156,6 +156,6 @@ static inline iflag_t __iflag_pfmask(const iflag_t *a) return r; } -#define iflag_pfmask(itemp) __iflag_pfmask(&insns_flags[(itemp)->iflag_idx]) +#define iflag_pfmask(itemp) _iflag_pfmask(&insns_flags[(itemp)->iflag_idx]) -#endif /* NASM_IFLAG_H__ */ +#endif /* NASM_IFLAG_H */ |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-26 23:18:29
|
Commit-ID: af90d3520fe647e390638f93e020c9b2712fd280 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=af90d3520fe647e390638f93e020c9b2712fd280 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Sun, 24 Nov 2013 17:13:20 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Sun, 24 Nov 2013 17:13:20 -0800 iflag: Make the insns_flags array const Make the insns_flags array const, and change the helper functions to match. Signed-off-by: H. Peter Anvin <hp...@zy...> --- iflag.h | 14 +++++++------- insns-iflags.pl | 6 ++++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/iflag.h b/iflag.h index 066149a..f73f99c 100644 --- a/iflag.h +++ b/iflag.h @@ -13,7 +13,7 @@ int ilog2_32(uint32_t v); #define IF_GENBIT(bit) (UINT32_C(1) << (bit)) -static inline unsigned int iflag_test(iflag_t *f,unsigned int bit) +static inline unsigned int iflag_test(const iflag_t *f, unsigned int bit) { unsigned int index = bit / 32; return f->field[index] & (UINT32_C(1) << (bit - (index * 32))); @@ -41,7 +41,7 @@ static inline void iflag_set_all(iflag_t *f) memset(f, 0xff, sizeof(*f)); } -static inline int iflag_cmp(iflag_t *a, iflag_t *b) +static inline int iflag_cmp(const iflag_t *a, const iflag_t *b) { unsigned int i; @@ -55,7 +55,7 @@ static inline int iflag_cmp(iflag_t *a, iflag_t *b) return 0; } -static inline int iflag_cmp_cpu(iflag_t *a, iflag_t *b) +static inline int iflag_cmp_cpu(const iflag_t *a, const iflag_t *b) { if (a->field[3] < b->field[3]) return -1; @@ -64,7 +64,7 @@ static inline int iflag_cmp_cpu(iflag_t *a, iflag_t *b) return 0; } -static inline unsigned int iflag_ffs(iflag_t *a) +static inline unsigned int iflag_ffs(const iflag_t *a) { unsigned int i; @@ -77,7 +77,7 @@ static inline unsigned int iflag_ffs(iflag_t *a) } #define IF_GEN_HELPER(name, op) \ - static inline iflag_t iflag_##name(iflag_t *a, iflag_t *b) \ + static inline iflag_t iflag_##name(const iflag_t *a, const iflag_t *b) \ { \ unsigned int i; \ iflag_t res; \ @@ -122,7 +122,7 @@ IF_GEN_HELPER(xor, ^) #define itemp_arg(itemp) __itemp_arg((itemp)->iflag_idx) #define itemp_armask(itemp) __itemp_armask((itemp)->iflag_idx) -static inline int iflag_cmp_cpu_level(iflag_t *a, iflag_t *b) +static inline int iflag_cmp_cpu_level(const iflag_t *a, const iflag_t *b) { iflag_t v1 = *a; iflag_t v2 = *b; @@ -141,7 +141,7 @@ static inline int iflag_cmp_cpu_level(iflag_t *a, iflag_t *b) return 0; } -static inline iflag_t __iflag_pfmask(iflag_t *a) +static inline iflag_t __iflag_pfmask(const iflag_t *a) { iflag_t r = (iflag_t) { .field[1] = a->field[1], diff --git a/insns-iflags.pl b/insns-iflags.pl index b954c73..8f8e009 100644 --- a/insns-iflags.pl +++ b/insns-iflags.pl @@ -215,7 +215,8 @@ sub write_iflaggen_h() { print N "} iflag_t;\n"; print N "\n"; - printf N "extern iflag_t insns_flags[%d];\n\n", $#insns_flag_values + 1; + printf N "extern const iflag_t insns_flags[%d];\n\n", + $#insns_flag_values + 1; print N "#endif /* NASM_IFLAGGEN_H */\n"; close N; @@ -229,7 +230,8 @@ sub write_iflag_c() { print N "/* This file is auto-generated. Don't edit. */\n"; print N "#include \"iflag.h\"\n\n"; print N "/* Global flags referenced from instruction templates */\n"; - print N sprintf("iflag_t insns_flags[%d] = {\n", $#insns_flag_values + 1); + printf N "const iflag_t insns_flags[%d] = {\n", + $#insns_flag_values + 1; foreach my $i (0 .. $#insns_flag_values) { print N sprintf(" /* %4d */ {{ %s }},\n", $i, $insns_flag_values[$i]); } |
From: nasm-bot f. H. P. A. <hp...@zy...> - 2013-11-24 19:54:40
|
Commit-ID: 45a22d9a6147c320b6754679de54a8290de3c5e3 Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=45a22d9a6147c320b6754679de54a8290de3c5e3 Author: H. Peter Anvin <hp...@zy...> AuthorDate: Sun, 24 Nov 2013 11:13:10 -0800 Committer: H. Peter Anvin <hp...@zy...> CommitDate: Sun, 24 Nov 2013 11:13:10 -0800 iflag: Fix dependencies, factor out static components of iflag.h Multi-dependencies don't work as expected, especially not across Make versions, this is why we don't use them and read the instructions list multiple times. iflag.h has a lot of static content, so factor out the static content. Signed-off-by: H. Peter Anvin <hp...@zy...> --- .gitignore | 2 +- Makefile.in | 21 +++--- iflag.h | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++ insns-iflags.pl | 213 +++----------------------------------------------------- insns.pl | 10 ++- 5 files changed, 223 insertions(+), 216 deletions(-) diff --git a/.gitignore b/.gitignore index 82d926f..1fb29c2 100644 --- a/.gitignore +++ b/.gitignore @@ -79,4 +79,4 @@ TAGS /version.nsh /version.sed /iflag.c -/iflag.h +/iflaggen.h diff --git a/Makefile.in b/Makefile.in index 2f46d3b..310c79a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -110,20 +110,21 @@ ndisasm$(X): $(NDISASM) $(XOBJS) # instruction-table file by a Perl script. They're distributed, # though, so it isn't necessary to have Perl just to recompile NASM # from the distribution. +INSDEP = insns.dat insns.pl insns-iflags.pl -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 +iflag.c: $(INSDEP) + $(PERL) $(srcdir)/insns.pl -fc $(srcdir)/insns.dat +iflaggen.h: $(INSDEP) + $(PERL) $(srcdir)/insns.pl -fh $(srcdir)/insns.dat +insnsb.c: $(INSDEP) $(PERL) $(srcdir)/insns.pl -b $(srcdir)/insns.dat -insnsa.c: insns.dat insns.pl +insnsa.c: $(INSDEP) $(PERL) $(srcdir)/insns.pl -a $(srcdir)/insns.dat -insnsd.c: insns.dat insns.pl +insnsd.c: $(INSDEP) $(PERL) $(srcdir)/insns.pl -d $(srcdir)/insns.dat -insnsi.h: insns.dat insns.pl +insnsi.h: $(INSDEP) $(PERL) $(srcdir)/insns.pl -i $(srcdir)/insns.dat -insnsn.c: insns.dat insns.pl +insnsn.c: $(INSDEP) $(PERL) $(srcdir)/insns.pl -n $(srcdir)/insns.dat # These files contains all the standard macros that are derived from @@ -193,7 +194,7 @@ PERLREQ = macros.c insnsb.c insnsa.c insnsd.c insnsi.h insnsn.c \ tokhash.c tokens.h pptok.h pptok.c pptok.ph \ directiv.c directiv.h \ version.h version.mac version.mak version.nsh \ - iflag.c iflag.h + iflag.c iflaggen.h perlreq: $(PERLREQ) # Generated manpages, also pregenerated for distribution diff --git a/iflag.h b/iflag.h new file mode 100644 index 0000000..d08249e --- /dev/null +++ b/iflag.h @@ -0,0 +1,193 @@ +#ifndef NASM_IFLAG_H +#define NASM_IFLAG_H + +#include <inttypes.h> + +#include <string.h> + +#include "compiler.h" + +int ilog2_32(uint32_t v); + +/* + * 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...) + * + * iflag_t is defined to store these flags. + */ +typedef struct { + uint32_t field[4]; +} iflag_t; + +#include "iflaggen.h" + +#define IF_GENBIT(bit) (UINT32_C(1) << (bit)) + +static inline unsigned int iflag_test(iflag_t *f,unsigned int bit) +{ + unsigned int index = bit / 32; + return f->field[index] & (UINT32_C(1) << (bit - (index * 32))); +} + +static inline void iflag_set(iflag_t *f, unsigned int bit) +{ + unsigned int index = bit / 32; + f->field[index] |= (UINT32_C(1) << (bit - (index * 32))); +} + +static inline void iflag_clear(iflag_t *f, unsigned int bit) +{ + unsigned int index = bit / 32; + f->field[index] &= ~(UINT32_C(1) << (bit - (index * 32))); +} + +static inline void iflag_clear_all(iflag_t *f) +{ + memset(f, 0, sizeof(*f)); +} + +static inline void iflag_set_all(iflag_t *f) +{ + memset(f, 0xff, sizeof(*f)); +} + +static inline int iflag_cmp(iflag_t *a, iflag_t *b) +{ + unsigned int i; + + for (i = 0; i < sizeof(a->field) / sizeof(a->field[0]); i++) { + if (a->field[i] < b->field[i]) + return -1; + else if (a->field[i] > b->field[i]) + return 1; + } + + return 0; +} + +static inline int iflag_cmp_cpu(iflag_t *a, iflag_t *b) +{ + if (a->field[3] < b->field[3]) + return -1; + else if (a->field[3] > b->field[3]) + return 1; + return 0; +} + +static inline unsigned int iflag_ffs(iflag_t *a) +{ + unsigned int i; + + for (i = 0; i < sizeof(a->field) / sizeof(a->field[0]); i++) { + if (a->field[i]) + return ilog2_32(a->field[i]) + (i * 32); + } + + return 0; +} + +#define IF_GEN_HELPER(name, op) \ + static inline iflag_t iflag_##name(iflag_t *a, iflag_t *b) \ + { \ + unsigned int i; \ + iflag_t res; \ + \ + for (i = 0; i < sizeof(a->field) / sizeof(a->field[0]); i++) \ + res.field[i] = a->field[i] op b->field[i]; \ + \ + return res; \ + } + +IF_GEN_HELPER(xor, ^) + + +/* Use this helper to test instruction template flags */ +#define itemp_has(itemp, bit) iflag_test(&insns_flags[(itemp)->iflag_idx], bit) + + +/* Maximum processor level at moment */ +#define IF_PLEVEL IF_IA64 +/* Some helpers which are to work with predefined masks */ +#define IF_SMASK \ + (IF_GENBIT(IF_SB) |\ + IF_GENBIT(IF_SW) |\ + IF_GENBIT(IF_SD) |\ + IF_GENBIT(IF_SQ) |\ + IF_GENBIT(IF_SO) |\ + IF_GENBIT(IF_SY) |\ + IF_GENBIT(IF_SZ) |\ + IF_GENBIT(IF_SIZE)) +#define IF_ARMASK \ + (IF_GENBIT(IF_AR0) |\ + IF_GENBIT(IF_AR1) |\ + IF_GENBIT(IF_AR2) |\ + IF_GENBIT(IF_AR3) |\ + IF_GENBIT(IF_AR4)) + +#define __itemp_smask(idx) (insns_flags[(idx)].field[0] & IF_SMASK) +#define __itemp_armask(idx) (insns_flags[(idx)].field[0] & IF_ARMASK) +#define __itemp_arg(idx) ((__itemp_armask(idx) >> IF_AR0) - 1) + +#define itemp_smask(itemp) __itemp_smask((itemp)->iflag_idx) +#define itemp_arg(itemp) __itemp_arg((itemp)->iflag_idx) +#define itemp_armask(itemp) __itemp_armask((itemp)->iflag_idx) + +static inline int iflag_cmp_cpu_level(iflag_t *a, iflag_t *b) +{ + iflag_t v1 = *a; + iflag_t v2 = *b; + + iflag_clear(&v1, IF_CYRIX); + iflag_clear(&v1, IF_AMD); + + iflag_clear(&v2, IF_CYRIX); + iflag_clear(&v2, IF_AMD); + + if (v1.field[3] < v2.field[3]) + return -1; + else if (v1.field[3] > v2.field[3]) + return 1; + + return 0; +} + +static inline iflag_t __iflag_pfmask(iflag_t *a) +{ + iflag_t r = (iflag_t) { + .field[1] = a->field[1], + .field[2] = a->field[2], + }; + + if (iflag_test(a, IF_CYRIX)) + iflag_set(&r, IF_CYRIX); + if (iflag_test(a, IF_AMD)) + iflag_set(&r, IF_AMD); + + return r; +} + +#define iflag_pfmask(itemp) __iflag_pfmask(&insns_flags[(itemp)->iflag_idx]) + +#endif /* NASM_IFLAG_H__ */ diff --git a/insns-iflags.pl b/insns-iflags.pl index 56da134..77eefee 100644 --- a/insns-iflags.pl +++ b/insns-iflags.pl @@ -178,220 +178,29 @@ sub insns_flag_index(@) { return $insns_flag_hash{$key}; } -sub write_iflags() { - print STDERR "Writing iflag.h ...\n"; +sub write_iflaggen_h() { + print STDERR "Writing iflaggen.h ...\n"; - open N, ">iflag.h"; + open(N, ">iflaggen.h") or die "$0: $!\n"; print N "/* This file is auto-generated. Don't edit. */\n"; - print N "#ifndef NASM_IFLAG_H__\n"; - print N "#define NASM_IFLAG_H__\n\n"; + print N "#ifndef NASM_IFLAGGEN_H\n"; + print N "#define NASM_IFLAGGEN_H 1\n\n"; - print N "#include <inttypes.h>\n\n"; - print N "#include <string.h>\n\n"; - - print N "#include \"compiler.h\"\n"; - - print N "extern int ilog2_32(uint32_t v);\n\n"; - - print N "/*\n"; - print N " * Instruction template flags. These specify which processor\n"; - print N " * targets the instruction is eligible for, whether it is\n"; - print N " * privileged or undocumented, and also specify extra error\n"; - print N " * checking on the matching of the instruction.\n"; - print N " *\n"; - print N " * IF_SM stands for Size Match: any operand whose size is not\n"; - print N " * explicitly specified by the template is `really' intended to be\n"; - print N " * the same size as the first size-specified operand.\n"; - print N " * Non-specification is tolerated in the input instruction, but\n"; - print N " * _wrong_ specification is not.\n"; - print N " *\n"; - print N " * IF_SM2 invokes Size Match on only the first _two_ operands, for\n"; - print N " * three-operand instructions such as SHLD: it implies that the\n"; - print N " * first two operands must match in size, but that the third is\n"; - print N " * required to be _unspecified_.\n"; - print N " *\n"; - print N " * IF_SB invokes Size Byte: operands with unspecified size in the\n"; - print N " * template are really bytes, and so no non-byte specification in\n"; - print N " * the input instruction will be tolerated. IF_SW similarly invokes\n"; - print N " * Size Word, and IF_SD invokes Size Doubleword.\n"; - print N " *\n"; - print N " * (The default state if neither IF_SM nor IF_SM2 is specified is\n"; - print N " * that any operand with unspecified size in the template is\n"; - print N " * required to have unspecified size in the instruction too...)\n"; - print N " *\n"; - print N " * iflag_t is defined to store these flags.\n"; - print N " */\n"; foreach my $key (sort { $insns_flag_bit{$a}[0] <=> $insns_flag_bit{$b}[0] } keys(%insns_flag_bit)) { - print N sprintf("#define IF_%-16s (%3d) /* %-64s */\n", + print N sprintf("#define IF_%-16s %3d /* %-64s */\n", $key, $insns_flag_bit{$key}[0], $insns_flag_bit{$key}[1]); } print N "\n"; - print N "typedef struct {\n"; - print N " uint32_t field[4];\n"; - print N "} iflag_t;\n\n"; - - print N "\n"; - print N sprintf("extern iflag_t insns_flags[%d];\n\n", $#insns_flag_values + 1); - - print N "#define IF_GENBIT(bit) (UINT32_C(1) << (bit))\n\n"; - - print N "static inline unsigned int iflag_test(iflag_t *f,unsigned int bit)\n"; - print N "{\n"; - print N " unsigned int index = bit / 32;\n"; - print N " return f->field[index] & (UINT32_C(1) << (bit - (index * 32)));\n"; - print N "}\n\n"; - - print N "static inline void iflag_set(iflag_t *f, unsigned int bit)\n"; - print N "{\n"; - print N " unsigned int index = bit / 32;\n"; - print N " f->field[index] |= (UINT32_C(1) << (bit - (index * 32)));\n"; - print N "}\n\n"; - - print N "static inline void iflag_clear(iflag_t *f, unsigned int bit)\n"; - print N "{\n"; - print N " unsigned int index = bit / 32;\n"; - print N " f->field[index] &= ~(UINT32_C(1) << (bit - (index * 32)));\n"; - print N "}\n\n"; - - print N "static inline void iflag_clear_all(iflag_t *f)\n"; - print N "{\n"; - print N " memset(f, 0, sizeof(*f));\n"; - print N "}\n\n"; - - print N "static inline void iflag_set_all(iflag_t *f)\n"; - print N "{\n"; - print N " memset(f, 0xff, sizeof(*f));\n"; - print N "}\n\n"; - - print N "static inline int iflag_cmp(iflag_t *a, iflag_t *b)\n"; - print N "{\n"; - print N " unsigned int i;\n"; - print N "\n"; - print N " for (i = 0; i < sizeof(a->field) / sizeof(a->field[0]); i++) {\n"; - print N " if (a->field[i] < b->field[i])\n"; - print N " return -1;\n"; - print N " else if (a->field[i] > b->field[i])\n"; - print N " return 1;\n"; - print N " }\n"; - print N "\n"; - print N " return 0;\n"; - print N "}\n\n"; - - print N "static inline int iflag_cmp_cpu(iflag_t *a, iflag_t *b)\n"; - print N "{\n"; - print N " if (a->field[3] < b->field[3])\n"; - print N " return -1;\n"; - print N " else if (a->field[3] > b->field[3])\n"; - print N " return 1;\n"; - print N " return 0;\n"; - print N "}\n\n"; - - print N "static inline unsigned int iflag_ffs(iflag_t *a)\n"; - print N "{\n"; - print N " unsigned int i;\n"; - print N "\n"; - print N " for (i = 0; i < sizeof(a->field) / sizeof(a->field[0]); i++) {\n"; - print N " if (a->field[i])\n"; - print N " return ilog2_32(a->field[i]) + (i * 32);\n"; - print N " }\n"; - print N "\n"; - print N " return 0;\n"; - print N "}\n\n"; - - print N "#define IF_GEN_HELPER(name, op) \\\n"; - print N " static inline iflag_t iflag_##name(iflag_t *a, iflag_t *b) \\\n"; - print N " { \\\n"; - print N " unsigned int i; \\\n"; - print N " iflag_t res; \\\n"; - print N " \\\n"; - print N " for (i = 0; i < sizeof(a->field) / sizeof(a->field[0]); i++) \\\n"; - print N " res.field[i] = a->field[i] op b->field[i]; \\\n"; - print N " \\\n"; - print N " return res; \\\n"; - print N " }\n"; - print N "\n"; - print N "IF_GEN_HELPER(xor, ^)\n"; - print N "\n\n"; - - print N "/* Use this helper to test instruction template flags */\n"; - print N "#define itemp_has(itemp, bit) iflag_test(&insns_flags[(itemp)->iflag_idx], bit)\n\n"; - - print N "\n"; - print N "/* Maximum processor level at moment */\n"; - print N "#define IF_PLEVEL IF_IA64\n"; - - print N "/* Some helpers which are to work with predefined masks */\n"; - print N "#define IF_SMASK \\\n"; - print N " (IF_GENBIT(IF_SB) |\\\n"; - print N " IF_GENBIT(IF_SW) |\\\n"; - print N " IF_GENBIT(IF_SD) |\\\n"; - print N " IF_GENBIT(IF_SQ) |\\\n"; - print N " IF_GENBIT(IF_SO) |\\\n"; - print N " IF_GENBIT(IF_SY) |\\\n"; - print N " IF_GENBIT(IF_SZ) |\\\n"; - print N " IF_GENBIT(IF_SIZE))\n"; - print N "#define IF_ARMASK \\\n"; - print N " (IF_GENBIT(IF_AR0) |\\\n"; - print N " IF_GENBIT(IF_AR1) |\\\n"; - print N " IF_GENBIT(IF_AR2) |\\\n"; - print N " IF_GENBIT(IF_AR3) |\\\n"; - print N " IF_GENBIT(IF_AR4))\n"; - - print N "\n"; - print N "#define __itemp_smask(idx) (insns_flags[(idx)].field[0] & IF_SMASK)\n"; - print N "#define __itemp_armask(idx) (insns_flags[(idx)].field[0] & IF_ARMASK)\n"; - print N "#define __itemp_arg(idx) ((__itemp_armask(idx) >> IF_AR0) - 1)\n"; - print N "\n"; - print N "#define itemp_smask(itemp) __itemp_smask((itemp)->iflag_idx)\n"; - print N "#define itemp_arg(itemp) __itemp_arg((itemp)->iflag_idx)\n"; - print N "#define itemp_armask(itemp) __itemp_armask((itemp)->iflag_idx)\n"; + print N sprintf("extern iflag_t insns_flags[%d];\n\n", + $#insns_flag_values + 1); - print N "\n"; - print N "static inline int iflag_cmp_cpu_level(iflag_t *a, iflag_t *b)\n"; - print N "{\n"; - print N " iflag_t v1 = *a;\n"; - print N " iflag_t v2 = *b;\n"; - print N "\n"; - print N " iflag_clear(&v1, IF_CYRIX);\n"; - print N " iflag_clear(&v1, IF_AMD);\n"; - print N "\n"; - print N " iflag_clear(&v2, IF_CYRIX);\n"; - print N " iflag_clear(&v2, IF_AMD);\n"; - print N "\n"; - print N " if (v1.field[3] < v2.field[3])\n"; - print N " return -1;\n"; - print N " else if (v1.field[3] > v2.field[3])\n"; - print N " return 1;\n"; - print N "\n"; - print N " return 0;\n"; - print N "}\n"; - - - print N "\n"; - print N "static inline iflag_t __iflag_pfmask(iflag_t *a)\n"; - print N "{\n"; - print N " iflag_t r = (iflag_t) {\n"; - print N " .field[1] = a->field[1],\n"; - print N " .field[2] = a->field[2],\n"; - print N " };\n"; - print N "\n"; - print N " if (iflag_test(a, IF_CYRIX))\n"; - print N " iflag_set(&r, IF_CYRIX);\n"; - print N " if (iflag_test(a, IF_AMD))\n"; - print N " iflag_set(&r, IF_AMD);\n"; - print N "\n"; - print N " return r;\n"; - print N "}\n"; - - print N "\n"; - print N "#define iflag_pfmask(itemp) __iflag_pfmask(&insns_flags[(itemp)->iflag_idx])\n"; - - print N "\n"; - print N "#endif /* NASM_IFLAG_H__ */\n"; + print N "#endif /* NASM_IFLAGGEN_H */\n"; close N; +} +sub write_iflag_c() { print STDERR "Writing iflag.c ...\n"; open N, ">iflag.c"; diff --git a/insns.pl b/insns.pl index c9d7b7f..8515c02 100755 --- a/insns.pl +++ b/insns.pl @@ -69,7 +69,7 @@ print STDERR "Reading insns.dat...\n"; undef $output; foreach $arg ( @ARGV ) { if ( $arg =~ /^\-/ ) { - if ( $arg =~ /^\-([abdint])$/ ) { + if ( $arg =~ /^\-([abdin]|f[hc])$/ ) { $output = $1; } else { die "$0: Unknown option: ${arg}\n"; @@ -395,8 +395,12 @@ if ( !defined($output) || $output eq 'n' ) { close N; } -if ( !defined($output) || $output eq 't') { - write_iflags(); +if ( !defined($output) || $output eq 'fh') { + write_iflaggen_h(); +} + +if ( !defined($output) || $output eq 'fc') { + write_iflag_c(); } printf STDERR "Done: %d instructions\n", $insns; |