Merge [2121], [2122], [2123], [2124], [2125], [2126], and [2127] from trunk.
[2121]: Mark gen_x86_insn.py outputs as generated.
[2122]: Don't read past end of string in parsers (not bug).
[2123]: Fix expression simplification bug.
[2124]: Warn if unused groups are detected in gen_x86_insn.py.
[2125]: VPBLENDVB doesn't have a 256-bit form; remove it.
[2126]: Generate GOTPCREL relocation for [rel foo wrt ..gotpc].
[2127]: Optimize non-strict push with 66 override to byte size if possible.
svn path=/branches/yasm-0.7.x/; revision=2148
diff --git a/libyasm/expr.c b/libyasm/expr.c
index 14a5226..20e5247 100644
--- a/libyasm/expr.c
+++ b/libyasm/expr.c
@@ -741,7 +741,7 @@
* ordering as was present originally.
* Combine integer terms as necessary.
*/
- for (i=e->numterms-1, o=level_numterms-1; i>=0; i--) {
+ for (i=fold_numterms-1, o=level_numterms-1; i>=0; i--) {
if (e->terms[i].type == YASM_EXPR_EXPR &&
e->terms[i].data.expn->op == e->op) {
/* bring up subexpression */
diff --git a/libyasm/tests/Makefile.inc b/libyasm/tests/Makefile.inc
index ad65464..23f422b 100644
--- a/libyasm/tests/Makefile.inc
+++ b/libyasm/tests/Makefile.inc
@@ -23,6 +23,8 @@
EXTRA_DIST += libyasm/tests/emptydata.hex
EXTRA_DIST += libyasm/tests/equ-expand.asm
EXTRA_DIST += libyasm/tests/equ-expand.hex
+EXTRA_DIST += libyasm/tests/expr-fold-level.asm
+EXTRA_DIST += libyasm/tests/expr-fold-level.hex
EXTRA_DIST += libyasm/tests/expr-wide-ident.asm
EXTRA_DIST += libyasm/tests/expr-wide-ident.hex
EXTRA_DIST += libyasm/tests/externdef.asm
diff --git a/libyasm/tests/expr-fold-level.asm b/libyasm/tests/expr-fold-level.asm
new file mode 100644
index 0000000..814a62c
--- /dev/null
+++ b/libyasm/tests/expr-fold-level.asm
@@ -0,0 +1,4 @@
+begin
+A equ 09000h
+a dd (A+(end-begin)+3)
+end
diff --git a/libyasm/tests/expr-fold-level.hex b/libyasm/tests/expr-fold-level.hex
new file mode 100644
index 0000000..aba10f6
--- /dev/null
+++ b/libyasm/tests/expr-fold-level.hex
@@ -0,0 +1,4 @@
+07
+90
+00
+00
diff --git a/modules/arch/x86/gen_x86_insn.py b/modules/arch/x86/gen_x86_insn.py
index a361c48..4a7c715 100755
--- a/modules/arch/x86/gen_x86_insn.py
+++ b/modules/arch/x86/gen_x86_insn.py
@@ -1,5 +1,4 @@
#! /usr/bin/env python
-# $Id$
# x86 instructions and prefixes data and code generation
#
# Copyright (C) 2002-2007 Peter Johnson
@@ -26,6 +25,9 @@
# POSSIBILITY OF SUCH DAMAGE.
#
# NOTE: operands are arranged in NASM / Intel order (e.g. dest, src)
+rcstag = "$Id$"
+scriptname = rcstag.split()[1]
+scriptrev = rcstag.split()[2]
ordered_cpus = [
"086", "186", "286", "386", "486", "586", "686", "K6", "Athlon", "P3",
@@ -492,9 +494,11 @@
nasm_insns[name] = prefix
def finalize_insns():
+ unused_groups = set(groups.keys())
for name, opts in insns.iteritems():
for insn in opts:
group = groups[insn.groupname]
+ unused_groups.discard(insn.groupname)
parsers = set()
for form in group:
@@ -537,7 +541,14 @@
newinsn.auto_misc_flags("nasm")
nasm_insns[keyword] = newinsn
+ unused_groups.discard("empty")
+ unused_groups.discard("not64")
+ if unused_groups:
+ print "warning: unused groups: %s" % ", ".join(unused_groups)
+
def output_insns(f, parser, insns):
+ print >>f, "/* Generated by %s r%s, do not edit */" % \
+ (scriptname, scriptrev)
print >>f, """%%ignore-case
%%language=ANSI-C
%%compare-strncmp
@@ -573,6 +584,8 @@
all_operands.extend(form.operands)
# Output operands list
+ print >>f, "/* Generated by %s r%s, do not edit */" % \
+ (scriptname, scriptrev)
print >>f, "static const x86_info_operand insn_operands[] = {"
print >>f, " ",
print >>f, ",\n ".join(str(x) for x in all_operands)
@@ -1126,25 +1139,6 @@
opcode=[0x6A],
operands=[Operand(type="Imm", size=8, relaxed=True, dest="SImm")])
add_group("push",
- suffix="w",
- cpu=["186"],
- parsers=["gas"],
- opersize=16,
- def_opersize_64=64,
- opcode1=[0x6A],
- opcode2=[0x68],
- operands=[Operand(type="Imm", size=16, relaxed=True, dest="Imm",
- opt="SImm8")])
-add_group("push",
- suffix="l",
- not64=True,
- parsers=["gas"],
- opersize=32,
- opcode1=[0x6A],
- opcode2=[0x68],
- operands=[Operand(type="Imm", size=32, relaxed=True, dest="Imm",
- opt="SImm8")])
-add_group("push",
suffix="q",
only64=True,
opersize=64,
@@ -1161,6 +1155,23 @@
opcode2=[0x68],
operands=[Operand(type="Imm", size="BITS", relaxed=True, dest="Imm",
opt="SImm8")])
+add_group("push",
+ suffix="w",
+ cpu=["186"],
+ opersize=16,
+ def_opersize_64=64,
+ opcode1=[0x6A],
+ opcode2=[0x68],
+ operands=[Operand(type="Imm", size=16, relaxed=True, dest="Imm",
+ opt="SImm8")])
+add_group("push",
+ suffix="l",
+ not64=True,
+ opersize=32,
+ opcode1=[0x6A],
+ opcode2=[0x68],
+ operands=[Operand(type="Imm", size=32, relaxed=True, dest="Imm",
+ opt="SImm8")])
# Need these when we don't match the BITS size, but they need to be
# below the above line so the optimizer can kick in by default.
add_group("push",
@@ -5510,7 +5521,20 @@
add_insn("vblendvpd", "avx_sse4xmm0", modifiers=[0x4B])
add_insn("vblendvps", "avx_sse4xmm0", modifiers=[0x4A])
-add_insn("vpblendvb", "avx_sse4xmm0", modifiers=[0x4C])
+
+# vpblendvb doesn't have a 256-bit form
+add_group("avx_sse4xmm0_128",
+ cpu=["AVX"],
+ modifiers=["Op2Add"],
+ vex=128,
+ prefix=0x66,
+ opcode=[0x0F, 0x3A, 0x00],
+ operands=[Operand(type="SIMDReg", size=128, dest="Spare"),
+ Operand(type="SIMDReg", size=128, dest="VEX"),
+ Operand(type="SIMDRM", size=128, relaxed=True, dest="EA"),
+ Operand(type="SIMDReg", size=128, dest="VEXImmSrc")])
+
+add_insn("vpblendvb", "avx_sse4xmm0_128", modifiers=[0x4C])
for sfx, sz in zip("bwl", [8, 16, 32]):
add_group("crc32",
diff --git a/modules/arch/x86/tests/pushnosize.asm b/modules/arch/x86/tests/pushnosize.asm
index 3d99977..ada9be1 100644
--- a/modules/arch/x86/tests/pushnosize.asm
+++ b/modules/arch/x86/tests/pushnosize.asm
@@ -2,7 +2,7 @@
push 0 ; 6A 00 - equivalent to push byte 0
push byte 0 ; 6A 00
push word 0 ; 6A 00 - optimized
-push dword 0 ; 66 68 00000000
+push dword 0 ; 66 6A 00 - optimized
push strict byte 0 ; 6A 00
push strict word 0 ; 68 0000
push strict dword 0 ; 66 68 00000000
@@ -17,7 +17,7 @@
[bits 32]
push 0 ; 6A 00 - equivalent to push byte 0
push byte 0 ; 6A 00
-push word 0 ; 66 68 0000
+push word 0 ; 66 6A 00 - optimized
push dword 0 ; 6A 00 - optimized
push strict byte 0 ; 6A 00
push strict word 0 ; 66 68 0000
@@ -32,12 +32,12 @@
[bits 64]
push 0 ; same as bits 32 output
-push byte 0
-push word 0
-push dword 0 ; optimized to byte
-push strict byte 0
-push strict word 0
-push strict dword 0
+push byte 0 ; 6A 00; 64 bits pushed onto stack
+push word 0 ; 66 6A 00 - 66h prefix, optimized to byte
+push dword 0 ; 6A 00 - optimized to byte; note 64 bits pushed onto stack
+push strict byte 0 ; 6A 00; 64 bits pushed onto stack
+push strict word 0 ; 66 68 0000
+push strict dword 0 ; 68 00000000; note 64 bits pushed onto stack
push 128
push byte 128 ; warning
push word 128
diff --git a/modules/arch/x86/tests/pushnosize.hex b/modules/arch/x86/tests/pushnosize.hex
index de28feb..0896020 100644
--- a/modules/arch/x86/tests/pushnosize.hex
+++ b/modules/arch/x86/tests/pushnosize.hex
@@ -5,10 +5,7 @@
6a
00
66
-68
-00
-00
-00
+6a
00
6a
00
@@ -51,8 +48,7 @@
6a
00
66
-68
-00
+6a
00
6a
00
@@ -99,8 +95,7 @@
6a
00
66
-68
-00
+6a
00
6a
00
diff --git a/modules/objfmts/elf/elf-x86-amd64.c b/modules/objfmts/elf/elf-x86-amd64.c
index b99f089..caa20a5 100644
--- a/modules/objfmts/elf/elf-x86-amd64.c
+++ b/modules/objfmts/elf/elf-x86-amd64.c
@@ -156,6 +156,10 @@
if (esym)
esym->type = STT_TLS;
}
+ /* Map PC-relative GOT to appropriate relocation */
+ if (reloc->rtype_rel &&
+ elf_x86_amd64_ssyms[i].reloc == R_X86_64_GOT32)
+ return (unsigned char) R_X86_64_GOTPCREL;
return (unsigned char) elf_x86_amd64_ssyms[i].reloc;
}
}
diff --git a/modules/objfmts/elf/tests/amd64/Makefile.inc b/modules/objfmts/elf/tests/amd64/Makefile.inc
index d069592..58b6156 100644
--- a/modules/objfmts/elf/tests/amd64/Makefile.inc
+++ b/modules/objfmts/elf/tests/amd64/Makefile.inc
@@ -7,3 +7,5 @@
EXTRA_DIST += modules/objfmts/elf/tests/amd64/elf-rip.hex
EXTRA_DIST += modules/objfmts/elf/tests/amd64/elfso64.asm
EXTRA_DIST += modules/objfmts/elf/tests/amd64/elfso64.hex
+EXTRA_DIST += modules/objfmts/elf/tests/amd64/gotpcrel.asm
+EXTRA_DIST += modules/objfmts/elf/tests/amd64/gotpcrel.hex
diff --git a/modules/objfmts/elf/tests/amd64/gotpcrel.asm b/modules/objfmts/elf/tests/amd64/gotpcrel.asm
new file mode 100644
index 0000000..c3d1238
--- /dev/null
+++ b/modules/objfmts/elf/tests/amd64/gotpcrel.asm
@@ -0,0 +1,6 @@
+var:
+mov rax, [var wrt ..got]
+mov rax, [var wrt ..gotpcrel] ; should be error/warning?
+mov rax, [rel var wrt ..got] ; automatic promotion to GOTPCREL
+mov rax, [rel var wrt ..gotpcrel]
+
diff --git a/modules/objfmts/elf/tests/amd64/gotpcrel.hex b/modules/objfmts/elf/tests/amd64/gotpcrel.hex
new file mode 100644
index 0000000..1ad9424
--- /dev/null
+++ b/modules/objfmts/elf/tests/amd64/gotpcrel.hex
@@ -0,0 +1,720 @@
+7f
+45
+4c
+46
+02
+01
+01
+00
+00
+00
+00
+00
+00
+00
+00
+00
+01
+00
+3e
+00
+01
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+50
+01
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+40
+00
+00
+00
+00
+00
+40
+00
+06
+00
+01
+00
+48
+8b
+04
+25
+00
+00
+00
+00
+48
+8b
+04
+25
+00
+00
+00
+00
+48
+8b
+05
+00
+00
+00
+00
+48
+8b
+05
+00
+00
+00
+00
+00
+00
+04
+00
+00
+00
+00
+00
+00
+00
+03
+00
+00
+00
+02
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+0c
+00
+00
+00
+00
+00
+00
+00
+09
+00
+00
+00
+02
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+13
+00
+00
+00
+00
+00
+00
+00
+09
+00
+00
+00
+02
+00
+00
+00
+fc
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+1a
+00
+00
+00
+00
+00
+00
+00
+09
+00
+00
+00
+02
+00
+00
+00
+fc
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+00
+2e
+74
+65
+78
+74
+00
+2e
+72
+65
+6c
+61
+2e
+74
+65
+78
+74
+00
+2e
+73
+74
+72
+74
+61
+62
+00
+2e
+73
+79
+6d
+74
+61
+62
+00
+2e
+73
+68
+73
+74
+72
+74
+61
+62
+00
+00
+2d
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+01
+00
+00
+00
+04
+00
+f1
+ff
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+04
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+03
+00
+04
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+22
+00
+00
+00
+03
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+c0
+00
+00
+00
+00
+00
+00
+00
+2c
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+12
+00
+00
+00
+03
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ec
+00
+00
+00
+00
+00
+00
+00
+03
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+1a
+00
+00
+00
+02
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+f0
+00
+00
+00
+00
+00
+00
+00
+60
+00
+00
+00
+00
+00
+00
+00
+02
+00
+00
+00
+04
+00
+00
+00
+08
+00
+00
+00
+00
+00
+00
+00
+18
+00
+00
+00
+00
+00
+00
+00
+01
+00
+00
+00
+01
+00
+00
+00
+06
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+40
+00
+00
+00
+00
+00
+00
+00
+1e
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+10
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+07
+00
+00
+00
+04
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+60
+00
+00
+00
+00
+00
+00
+00
+60
+00
+00
+00
+00
+00
+00
+00
+03
+00
+00
+00
+04
+00
+00
+00
+08
+00
+00
+00
+00
+00
+00
+00
+18
+00
+00
+00
+00
+00
+00
+00
diff --git a/modules/parsers/nasm/nasm-token.re b/modules/parsers/nasm/nasm-token.re
index 931dbdc..cc589b1 100644
--- a/modules/parsers/nasm/nasm-token.re
+++ b/modules/parsers/nasm/nasm-token.re
@@ -139,6 +139,8 @@
scan:
SCANINIT();
+ if (*cursor == '\0')
+ goto endofinput;
/*!re2c
/* standard decimal integer */
@@ -387,10 +389,7 @@
ws+ { goto scan; }
- [\000] {
- parser_nasm->state = INITIAL;
- RETURN(s->tok[0]);
- }
+ [\000] { goto endofinput; }
any {
yasm_warn_set(YASM_WARN_UNREC_CHAR,
@@ -403,6 +402,8 @@
/* %line linenum+lineinc filename */
linechg:
SCANINIT();
+ if (*cursor == '\0')
+ goto endofinput;
/*!re2c
digit+ {
@@ -414,10 +415,7 @@
RETURN(INTNUM);
}
- [\000] {
- parser_nasm->state = INITIAL;
- RETURN(s->tok[0]);
- }
+ [\000] { goto endofinput; }
"+" {
RETURN(s->tok[0]);
@@ -441,14 +439,13 @@
linechg2:
SCANINIT();
+ if (*cursor == '\0')
+ goto endofinput;
/*!re2c
- [\000] {
- parser_nasm->state = INITIAL;
- RETURN(s->tok[0]);
- }
+ [\000] { goto endofinput; }
- "\r" { }
+ "\r" { goto linechg2; }
(any \ [\000])+ {
parser_nasm->state = LINECHG;
@@ -460,12 +457,11 @@
/* directive: [name value] */
directive:
SCANINIT();
+ if (*cursor == '\0')
+ goto endofinput;
/*!re2c
- [\]\000] {
- parser_nasm->state = INITIAL;
- RETURN(s->tok[0]);
- }
+ [\]\000] { goto endofinput; }
[a-zA-Z_][a-zA-Z_0-9]* {
lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
@@ -488,6 +484,8 @@
/* section directive (the section name portion thereof) */
section_directive:
SCANINIT();
+ if (*cursor == '\0')
+ goto endofinput;
/*!re2c
[a-zA-Z0-9_$#@~.?-]+ {
@@ -508,15 +506,7 @@
goto section_directive;
}
- "]" {
- parser_nasm->state = INITIAL;
- RETURN(s->tok[0]);
- }
-
- [\000] {
- parser_nasm->state = INITIAL;
- RETURN(s->tok[0]);
- }
+ [\]\000] { goto endofinput; }
any {
yasm_warn_set(YASM_WARN_UNREC_CHAR,
@@ -529,6 +519,8 @@
/* inner part of directive */
directive2:
SCANINIT();
+ if (*cursor == '\0')
+ goto endofinput;
/*!re2c
/* standard decimal integer */
@@ -589,10 +581,7 @@
[-+|^*&/%~$():=,\[] { RETURN(s->tok[0]); }
/* handle ] for directives */
- "]" {
- parser_nasm->state = INITIAL;
- RETURN(s->tok[0]);
- }
+ "]" { goto endofinput; }
/* forced identifier; within directive, don't strip '$', this is
* handled later.
@@ -625,10 +614,7 @@
ws+ { goto directive2; }
- [\000] {
- parser_nasm->state = INITIAL;
- RETURN(s->tok[0]);
- }
+ [\000] { goto endofinput; }
any {
yasm_warn_set(YASM_WARN_UNREC_CHAR,
@@ -646,23 +632,15 @@
stringconst_scan:
SCANINIT();
+ if (*cursor == '\0')
+ goto stringconst_error;
/*!re2c
- [\000] {
- yasm_error_set(YASM_ERROR_SYNTAX, N_("unterminated string"));
- strbuf[count] = '\0';
- lvalp->str.contents = (char *)strbuf;
- lvalp->str.len = count;
- RETURN(STRING);
- }
+ [\000] { goto stringconst_error; }
any {
- if (s->tok[0] == endch) {
- strbuf[count] = '\0';
- lvalp->str.contents = (char *)strbuf;
- lvalp->str.len = count;
- RETURN(STRING);
- }
+ if (s->tok[0] == endch)
+ goto stringconst_end;
strbuf[count++] = s->tok[0];
if (count >= strbuf_size) {
@@ -673,4 +651,17 @@
goto stringconst_scan;
}
*/
+
+stringconst_error:
+ yasm_error_set(YASM_ERROR_SYNTAX, N_("unterminated string"));
+
+stringconst_end:
+ strbuf[count] = '\0';
+ lvalp->str.contents = (char *)strbuf;
+ lvalp->str.len = count;
+ RETURN(STRING);
+
+endofinput:
+ parser_nasm->state = INITIAL;
+ RETURN(s->tok[0]);
}