Skip to content

Commit 240a39b

Browse files
author
H. Peter Anvin (Intel)
committed
sse2avx: add an [SSE2AVX] directive to generate AVX (V-) instructions
It can preferable to generate AVX code over SSE code, since the AVX code clears the upper part of registers and so on. Add a [sse2avx on] directive that does this. This is handled by yet another layer of instruction database preprocessing, which looking for V... instructions with the same operand signature as a corresponding SSE instruction. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
1 parent 80ce049 commit 240a39b

12 files changed

Lines changed: 126 additions & 20 deletions

File tree

Makefile.in

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ PERLREQ_CLEANABLE = \
276276
x86/insnsb.c x86/insnsa.c x86/insnsd.c x86/insnsi.h x86/insnsn.c \
277277
x86/regs.c x86/regs.h x86/regflags.c x86/regdis.c x86/regdis.h \
278278
x86/regvals.c asm/tokhash.c asm/tokens.h asm/pptok.h asm/pptok.c \
279-
x86/iflag.c x86/iflaggen.h \
279+
x86/iflag.c x86/iflaggen.h x86/insns.xd1 \
280280
macros/macros.c \
281281
asm/pptok.ph asm/directbl.c asm/directiv.h \
282282
$(WARNFILES) \
@@ -286,8 +286,11 @@ PERLREQ = $(PERLREQ_CLEANABLE)
286286

287287
INSDEP = x86/insns.xda x86/insns.pl x86/insns-iflags.ph x86/iflags.ph
288288

289-
x86/insns.xda: x86/insns.dat x86/preinsns.pl $(DIRS)
290-
$(RUNPERL) $(srcdir)/x86/preinsns.pl $(srcdir)/x86/insns.dat $@
289+
x86/insns.xd1: x86/insns.dat x86/preinsns.pl $(DIRS)
290+
$(RUNPERL) $(srcdir)/x86/preinsns.pl $(srcdir)/x86/insns.dat x86/insns.xd1
291+
292+
x86/insns.xda: x86/insns.xd1 x86/sse2avx.pl $(DIRS)
293+
$(RUNPERL) $(srcdir)/x86/sse2avx.pl x86/insns.xda x86/insns.xd1
291294

292295
x86/iflag.c: $(INSDEP)
293296
$(RUNPERL) $(srcdir)/x86/insns.pl -fc \

Mkfiles/msvc.mak

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ PERLREQ_CLEANABLE = \
219219
x86\insnsb.c x86\insnsa.c x86\insnsd.c x86\insnsi.h x86\insnsn.c \
220220
x86\regs.c x86\regs.h x86\regflags.c x86\regdis.c x86\regdis.h \
221221
x86\regvals.c asm\tokhash.c asm\tokens.h asm\pptok.h asm\pptok.c \
222-
x86\iflag.c x86\iflaggen.h \
222+
x86\iflag.c x86\iflaggen.h x86\insns.xd1 \
223223
macros\macros.c \
224224
asm\pptok.ph asm\directbl.c asm\directiv.h \
225225
$(WARNFILES) \
@@ -229,8 +229,11 @@ PERLREQ = $(PERLREQ_CLEANABLE)
229229

230230
INSDEP = x86\insns.xda x86\insns.pl x86\insns-iflags.ph x86\iflags.ph
231231

232-
x86\insns.xda: x86\insns.dat x86\preinsns.pl $(DIRS)
233-
$(RUNPERL) $(srcdir)\x86\preinsns.pl $(srcdir)\x86\insns.dat $@
232+
x86\insns.xd1: x86\insns.dat x86\preinsns.pl $(DIRS)
233+
$(RUNPERL) $(srcdir)\x86\preinsns.pl $(srcdir)\x86\insns.dat x86\insns.xd1
234+
235+
x86\insns.xda: x86\insns.xd1 x86\sse2avx.pl $(DIRS)
236+
$(RUNPERL) $(srcdir)\x86\sse2avx.pl x86\insns.xda x86\insns.xd1
234237

235238
x86\iflag.c: $(INSDEP)
236239
$(RUNPERL) $(srcdir)\x86\insns.pl -fc \

Mkfiles/openwcom.mak

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ PERLREQ_CLEANABLE = &
248248
x86/insnsb.c x86/insnsa.c x86/insnsd.c x86/insnsi.h x86/insnsn.c &
249249
x86/regs.c x86/regs.h x86/regflags.c x86/regdis.c x86/regdis.h &
250250
x86/regvals.c asm/tokhash.c asm/tokens.h asm/pptok.h asm/pptok.c &
251-
x86/iflag.c x86/iflaggen.h &
251+
x86/iflag.c x86/iflaggen.h x86/insns.xd1 &
252252
macros/macros.c &
253253
asm/pptok.ph asm/directbl.c asm/directiv.h &
254254
$(WARNFILES) &
@@ -258,8 +258,11 @@ PERLREQ = $(PERLREQ_CLEANABLE)
258258

259259
INSDEP = x86/insns.xda x86/insns.pl x86/insns-iflags.ph x86/iflags.ph
260260

261-
x86/insns.xda: x86/insns.dat x86/preinsns.pl $(DIRS)
262-
$(RUNPERL) $(srcdir)/x86/preinsns.pl $(srcdir)/x86/insns.dat $@
261+
x86/insns.xd1: x86/insns.dat x86/preinsns.pl $(DIRS)
262+
$(RUNPERL) $(srcdir)/x86/preinsns.pl $(srcdir)/x86/insns.dat x86/insns.xd1
263+
264+
x86/insns.xda: x86/insns.xd1 x86/sse2avx.pl $(DIRS)
265+
$(RUNPERL) $(srcdir)/x86/sse2avx.pl x86/insns.xda x86/insns.xd1
263266

264267
x86/iflag.c: $(INSDEP)
265268
$(RUNPERL) $(srcdir)/x86/insns.pl -fc &

asm/assemble.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ enum match_result {
5656
MOK_FIRST, /* First successful anything */
5757

5858
MOK_FUZZY8,
59-
MOK_FUZZY7, /* Matching unconditionally OK */
59+
MOK_FUZZY7,
6060
MOK_FUZZY6,
6161
MOK_FUZZY5,
6262
MOK_FUZZY4,
6363
MOK_FUZZY3,
6464
MOK_FUZZY2,
6565
MOK_FUZZY1,
66-
MOK_GOOD
66+
MOK_GOOD /* Matching unconditionally OK */
6767
};
6868

6969
#define GEN_SIB(scale, index, base) \
@@ -3352,6 +3352,12 @@ static enum match_result matches(const struct itemplate * const itemp,
33523352
if (itemp_has(itemp, (bits == 64 ? IF_NOLONG : IF_LONG)))
33533353
return MERR_BADMODE;
33543354

3355+
/*
3356+
* Verify SSE2AVX flag
3357+
*/
3358+
if (itemp_has(itemp, globl.sse2avx ? IF_NOSSE2AVX : IF_SSE2AVX))
3359+
return MERR_INVALOP;
3360+
33553361
/*
33563362
* If we have a HLE prefix, look for the NOHLE flag
33573363
*/

asm/directiv.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ struct cpunames {
3232

3333
static void iflag_set_cpu(iflag_t *a, unsigned int lvl)
3434
{
35-
a->field[0] = 0; /* Not applicable to the CPU type */
36-
iflag_set_all_features(a); /* All feature masking bits set for now */
35+
a->field[0] = 0; /* Not applicable to the CPU type */
36+
iflag_set_all_features(a); /* All feature masking bits set for now */
3737
if (lvl >= IF_ANY) {
3838
/* This is a hack for now */
3939
iflag_set(a, IF_LATEVEX);
@@ -85,6 +85,7 @@ void set_cpu(const char *value)
8585
{ "apx", IF_APX },
8686
{ "evex", IF_EVEX },
8787
{ "vex", IF_VEX },
88+
{ "sse2avx", IF_SSE2AVX },
8889
{ NULL, 0 }
8990
};
9091

@@ -626,6 +627,10 @@ bool process_directives(char *directive)
626627
get_boolean_option(value, &globl.dollarhex);
627628
break;
628629

630+
case D_SSE2AVX:
631+
get_boolean_option(value, &globl.sse2avx);
632+
break;
633+
629634
case D_PRAGMA:
630635
process_pragma(value);
631636
break;

asm/directiv.dat

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ required
5757
sectalign
5858
section
5959
segment
60+
sse2avx
6061
static
6162
warning
6263

@@ -113,9 +114,6 @@ uppercase ; outieee, outobj
113114
; They will not be accepted as directives.
114115
#special pragma_tokens
115116

116-
; --- Assembler pragmas
117-
limit
118-
119117
; --- Listing pragmas
120118
options
121119

common/common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ void reset_global_defaults(int bits)
2222
globl.rel = 0;
2323
globl.reldef = EAF_FS|EAF_GS;
2424
globl.dollarhex = true;
25+
globl.sse2avx = false;
2526
}
2627

2728
/*

doc/inslist.pl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,13 @@
5454
my @nflags;
5555
undef $isavx512;
5656
undef @avx512fl;
57+
my $skip = 0;
5758
for my $fl (@flags) {
58-
next if ($fl =~ /^(ignore|SB|SM|SM2|SQ|AR2|FUTURE)$/);
59+
next if ($fl =~ /^(ignore|S[BWDQOYZM]|SM[0-9].*|AR[0-9].*|FUTURE|NOSSE2AVX)$/);
60+
if ($fl =~ /^(SSE2AVX|SKIPMAN)$/) {
61+
$skip = 1;
62+
last;
63+
}
5964

6065
if ($fl =~ /^AVX512(.*)$/) {
6166
$isavx512 = 1;
@@ -65,6 +70,8 @@
6570
}
6671
}
6772

73+
next if ($skip);
74+
6875
if ($isavx512) {
6976
unshift(@nflags, "AVX512".join('/', @avx512fl));
7077
}

include/nasm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,7 @@ struct globalopt {
15711571
enum ea_flags reldef; /* default rel/abs explicitly defined? */
15721572
bool bnd; /* default to using bnd prefix? */
15731573
bool dollarhex; /* $-prefixed hexadecimal numbers? */
1574+
bool sse2avx; /* SSE2AVX mode */
15741575
};
15751576
extern struct globalopt globl;
15761577
void reset_global_defaults(int bits);

x86/iflags.ph

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ if_("FL", "Instruction modifies the flags");
7979
if_("MOPVEC", "M operand is a vector"); # Autodetected
8080
if_("SCC", "EVEX[27:24] is special condition code");
8181
if_("BESTDIS", "Preferred disassembly pattern");
82+
if_("SKIPMAN", "Don't list in the NASM manual");
8283

8384
#
8485
# Special immediates types like {dfv=}
@@ -97,6 +98,9 @@ if_align('FEATURE');
9798
if_("VEX", "VEX or XOP encoded instruction");
9899
if_("EVEX", "EVEX encoded instruction");
99100

101+
if_("NOSSE2AVX", "Avoid this pattern in SSE-to-AVX mode");
102+
if_("SSE2AVX", "Pattern for SSE-to-AVX mode");
103+
100104
#
101105
# Feature filtering flags
102106
#
@@ -146,7 +150,7 @@ if_("AVX512VPOPCNTDQ", "AVX-512 VPOPCNTD/VPOPCNTQ");
146150
if_("AVX5124FMAPS", "AVX-512 4-iteration multiply-add");
147151
if_("AVX5124VNNIW", "AVX-512 4-iteration dot product");
148152
if_("AVX512FP16", "AVX-512 FP16 instructions");
149-
if_("AVX512BMM", "AVX-512 BMM instructions");
153+
if_("AVX512BMM", "AVX-512 BMM instructions");
150154
if_("F16C", "F16C instructions");
151155
if_("SGX", "Intel Software Guard Extensions (SGX)");
152156
if_("CET", "Intel Control-Flow Enforcement Technology (CET)");

0 commit comments

Comments
 (0)