It again can be inferred from other information.
The vpopcntd templates all need to have Dword added to their memory
operands; the lack thereof was actually a bug preventing certain Intel
syntax code to assemble, so test cases get extended.
Since they're shorter to encode, the 0xa0...0xa3 encodings are preferred
for moves between accumulator and absolute address outside of 64-bit
mode. With HLE release semantics this encoding is unsupported though,
with the assembler raising an error. The operation is valid though, we
merely need to pick the longer encoding in that case.
While many templates allowing multiple suitably matching XMM/YMM/ZMM
operand sizes can be folded, a few need to be split in order to not
wrongly accept "xmmword ptr" operands when only XMM registers are
permitted (and memory operands are more narrow). Add a test case
validating this.
Since the addition of pseudo prefixes changed how the scrubber treats
'{', we need to explicitly strip whitespace in check_VecOperations ().
* config/tc-i386.c (check_VecOperations): Strip whitespace.
* testsuite/gas/i386/optimize-1.s: Add whitespaces before
{%k7} and {z},
* testsuite/gas/i386/x86-64-optimize-2.s: Likewise.
We can optimize AVX512 instructions with EVEX128 only if AVX512VL is
enabled:
1. Instruction is an AVX512VL instruction. Or
2. AVX512VL is enabled explicitly by -march=+avx512vl/".arch .avx512vl".
We should optimize EVEX instructions with EVEX128 encoding when pseudo
{evex} prefix is used.
* config/tc-i386.c (set_cpu_arch): Set cpu_arch_isa_flags.
(md_parse_option): Likewise.
(optimize_encoding): Check i.tm.cpu_flags and cpu_arch_isa_flags
for cpuavx512vl instead of cpu_arch_flags. Optimize EVEX with
EVEX128 when EVEX encoding is required.
* testsuite/gas/i386/i386.exp: Run optimize-4, optimize-5,
x86-64-optimize-5 and x86-64-optimize-6.
* testsuite/gas/i386/optimize-1.d: Updated.
* testsuite/gas/i386/x86-64-optimize-2.d: Likewise.
* testsuite/gas/i386/optimize-4.d: New file.
* testsuite/gas/i386/optimize-4.s: Likewise.
* testsuite/gas/i386/optimize-5.d: Likewise.
* testsuite/gas/i386/optimize-5.s: Likewise.
* testsuite/gas/i386/x86-64-optimize-5.d: Likewise.
* testsuite/gas/i386/x86-64-optimize-5.s: Likewise.
* testsuite/gas/i386/x86-64-optimize-6.d: Likewise.
* testsuite/gas/i386/x86-64-optimize-6.s: Likewise.
"clr reg" is an alias of "xor reg, reg". We can encode "clr reg64" as
"xor reg32, reg32".
gas/
* config/tc-i386.c (optimize_encoding): Also encode "clr reg64"
as "xor reg32, reg32".
* testsuite/gas/i386/x86-64-optimize-1.s: Add "clr reg64" tests.
* testsuite/gas/i386/x86-64-optimize-1.d: Updated.
opcodes/
* i386-opc.tbl: Add Optimize to clr.
* i386-tbl.h: Regenerated.
The differences between some of the register and memory forms of the
same insn often don't really require the templates to be separate. For
example, Disp8MemShift is simply irrelevant to register forms. Fold
these as far as possible, and also fold register-only forms. Further
folding is possible, but needs other prereq work done first.
A note regarding EVEXDYN: This is intended to be used only when no other
properties of the template would make is_evex_encoding() return true. In
all "normal" cases I think it is preferable to omit this indicator, to
keep the table half way readable.
Their memory forms were bogusly using VexLWP instead of VexNDD. Adjust
VexNDD handling to cope with these, allowing their register and memory
forms to be folded.
They aren't really useful (anymore?): The conflicting operand size check
isn't applicable to any insn validly using respective memory operand
sizes (and if they're used wrongly, another error would result), and the
logic in process_suffix() can be easily changed to work without them.
While re-structuring conditionals in process_suffix() also drop the
CMPXCHG8B special case in favor of a NoRex64 attribute in the opcode
table.
Some BMI/BMI2 insns allow their middle operands to be a memory one. In
such a case, matching register types between operands 0 and 1 as well as
1 and 2 won't help - operands 0 and 2 also need to be checked.
Make more obvious what the success and failure paths are, and in
particular that what used to be at the "skip" label can't be reached
by what used to be straight line code.
Just like for the AVX/AES and AVX/PCLMUL combinations, AVX/GFN,
AVX512F/GFNI, AVX512F/VAES, and AVX512F/PCLMUL need special handling to
deal with the pair of required checks specified in the templates.
Drop "second": For one there's no other source register (the other
source operand is in memory), and in Intel syntax such numbering would
also be wrong.
Take the opportunity and also
- properly place declarations ahead of statements
- use %u format for unsigned int arguments
- fix indentation
This requires a change to ModR/M handling: Recording of displacement
types must not discard operand size information. Change the respective
code to alter only .disp<N>.
On x86, some instructions have alternate shorter encodings:
1. When the upper 32 bits of destination registers of
andq $imm31, %r64
testq $imm31, %r64
xorq %r64, %r64
subq %r64, %r64
known to be zero, we can encode them without the REX_W bit:
andl $imm31, %r32
testl $imm31, %r32
xorl %r32, %r32
subl %r32, %r32
This optimization is enabled with -O, -O2 and -Os.
2. Since 0xb0 mov with 32-bit destination registers zero-extends 32-bit
immediate to 64-bit destination register, we can use it to encode 64-bit
mov with 32-bit immediates. This optimization is enabled with -O, -O2
and -Os.
3. Since the upper bits of destination registers of VEX128 and EVEX128
instructions are extended to zero, if all bits of destination registers
of AVX256 or AVX512 instructions are zero, we can use VEX128 or EVEX128
encoding to encode AVX256 or AVX512 instructions. When 2 source
registers are identical, AVX256 and AVX512 andn and xor instructions:
VOP %reg, %reg, %dest_reg
can be encoded with
VOP128 %reg, %reg, %dest_reg
This optimization is enabled with -O2 and -Os.
4. 16-bit, 32-bit and 64-bit register tests with immediate may be
encoded as 8-bit register test with immediate. This optimization is
enabled with -Os.
This patch does:
1. Add {nooptimize} pseudo prefix to disable instruction size
optimization.
2. Add optimize to i386_opcode_modifier to tell assembler that encoding
of an instruction may be optimized.
gas/
PR gas/22871
* NEWS: Mention -O[2|s].
* config/tc-i386.c (_i386_insn): Add no_optimize.
(optimize): New.
(optimize_for_space): Likewise.
(fits_in_imm7): New function.
(fits_in_imm31): Likewise.
(optimize_encoding): Likewise.
(md_assemble): Call optimize_encoding to optimize encoding.
(parse_insn): Handle {nooptimize}.
(md_shortopts): Append "O::".
(md_parse_option): Handle -On.
* doc/c-i386.texi: Document -O0, -O, -O1, -O2 and -Os as well
as {nooptimize}.
* testsuite/gas/cfi/cfi-x86_64.d: Pass -O0 to assembler.
* testsuite/gas/i386/ilp32/cfi/cfi-x86_64.d: Likewise.
* testsuite/gas/i386/i386.exp: Run optimize-1, optimize-2,
optimize-3, x86-64-optimize-1, x86-64-optimize-2,
x86-64-optimize-3 and x86-64-optimize-4.
* testsuite/gas/i386/optimize-1.d: New file.
* testsuite/gas/i386/optimize-1.s: Likewise.
* testsuite/gas/i386/optimize-2.d: Likewise.
* testsuite/gas/i386/optimize-2.s: Likewise.
* testsuite/gas/i386/optimize-3.d: Likewise.
* testsuite/gas/i386/optimize-3.s: Likewise.
* testsuite/gas/i386/x86-64-optimize-1.s: Likewise.
* testsuite/gas/i386/x86-64-optimize-1.d: Likewise.
* testsuite/gas/i386/x86-64-optimize-2.d: Likewise.
* testsuite/gas/i386/x86-64-optimize-2.s: Likewise.
* testsuite/gas/i386/x86-64-optimize-3.d: Likewise.
* testsuite/gas/i386/x86-64-optimize-3.s: Likewise.
* testsuite/gas/i386/x86-64-optimize-4.d: Likewise.
* testsuite/gas/i386/x86-64-optimize-4.s: Likewise.
opcodes/
PR gas/22871
* i386-gen.c (opcode_modifiers): Add Optimize.
* i386-opc.h (Optimize): New enum.
(i386_opcode_modifier): Add optimize.
* i386-opc.tbl: Add "Optimize" to "mov $imm, reg",
"sub reg, reg/mem", "test $imm, acc", "test $imm, reg/mem",
"and $imm, acc", "and $imm, reg/mem", "xor reg, reg/mem",
"movq $imm, reg" and AVX256 and AVX512 versions of vandnps,
vandnpd, vpandn, vpandnd, vpandnq, vxorps, vxorpd, vpxor,
vpxord and vpxorq.
* i386-tbl.h: Regenerated.
Add {rex} pseudo prefix to generate a REX byte for integer and legacy
vector instructions if possible. Note that this differs from the rex
prefix which generates REX prefix unconditionally.
gas/
* config/tc-i386.c (_i386_insn): Add rex_encoding.
(md_assemble): When i.rex_encoding is true, generate a REX byte
if possible.
(parse_insn): Set i.rex_encoding for {rex}.
* doc/c-i386.texi: Document {rex}.
* testsuite/gas/i386/x86-64-pseudos.s: Add {rex} tests.
* testsuite/gas/i386/x86-64-pseudos.d: Updated.
opcodes/
* i386-opc.tbl: Add {rex},
* i386-tbl.h: Regenerated.
Implement the '.nop SIZE[, CONTROL]' assembler directive, which emits
SIZE bytes filled with no-op instructions. SIZE is absolute expression.
The optional CONTROL byte controls how no-op instructions should be
generated. If the comma and @var{control} are omitted, CONTROL is
assumed to be zero.
For Intel 80386 and AMD x86-64 targets, CONTROL byte specifies the size
limit of a single no-op instruction. The valid values of CONTROL byte
are between 0 and 8 for 16-bit mode, between 0 and 10 for 32-bit mode,
between 0 and 11 for 64-bit mode. When 0 is used, the no-op size limit
is set to the maximum supported size.
2 new relax states, rs_space_nop and rs_fill_nop, are added to enum
_relax_state, which are similar to rs_space and rs_fill, respectively,
but they fill with no-op instructions, instead of a single byte. A
target backend must override the default md_generate_nops to generate
proper no-op instructions. Otherwise, an error of unimplemented .nop
directive will be issued whenever .nop directive is used.
* NEWS: Mention .nop directive.
* as.h (_relax_state): Add rs_space_nop and rs_fill_nop.
* read.c (potable): Add .nop.
(s_nop): New function.
* read.h (s_nop): New prototype.
* write.c (cvt_frag_to_fill): Handle rs_space_nop and
rs_fill_nop.
(md_generate_nops): New function.
(relax_segment): Likewise.
(write_contents): Use md_generate_nops for rs_fill_nop.
* config/tc-i386.c (alt64_11): New.
(alt64_patt): Likewise.
(md_convert_frag): Handle rs_space_nop.
(i386_output_nops): New function.
(i386_generate_nops): Likewise.
(i386_align_code): Call i386_output_nops.
* config/tc-i386.h (i386_generate_nops): New.
(md_generate_nops): Likewise.
* doc/as.texinfo: Document .nop directive.
* testsuite/gas/i386/i386.exp: Run .nop directive tests.
* testsuite/gas/i386/nop-1.d: New file.
* testsuite/gas/i386/nop-1.s: Likewise.
* testsuite/gas/i386/nop-2.d: Likewise.
* testsuite/gas/i386/nop-2.s: Likewise.
* testsuite/gas/i386/nop-3.d: Likewise.
* testsuite/gas/i386/nop-3.s: Likewise.
* testsuite/gas/i386/nop-4.d: Likewise.
* testsuite/gas/i386/nop-4.s: Likewise.
* testsuite/gas/i386/nop-5.d: Likewise.
* testsuite/gas/i386/nop-5.s: Likewise.
* testsuite/gas/i386/nop-6.d: Likewise.
* testsuite/gas/i386/nop-6.s: Likewise.
* testsuite/gas/i386/nop-bad-1.l: Likewise.
* testsuite/gas/i386/nop-bad-1.s: Likewise.
* testsuite/gas/i386/x86-64-nop-1.d: Likewise.
* testsuite/gas/i386/x86-64-nop-2.d: Likewise.
* testsuite/gas/i386/x86-64-nop-3.d: Likewise.
* testsuite/gas/i386/x86-64-nop-4.d: Likewise.
* testsuite/gas/i386/x86-64-nop-5.d: Likewise.
* testsuite/gas/i386/x86-64-nop-6.d: Likewise.
Since there is no need to prepare for PLT branch on x86-64, generate
R_X86_64_PLT32, instead of R_X86_64_PC32, if possible, which can be
used as a marker for 32-bit PC-relative branches.
To compile Linux kernel, this patch:
From: "H.J. Lu" <hjl.tools@gmail.com>
Subject: [PATCH] x86: Treat R_X86_64_PLT32 as R_X86_64_PC32
On i386, there are 2 types of PLTs, PIC and non-PIC. PIE and shared
objects must use PIC PLT. To use PIC PLT, you need to load
_GLOBAL_OFFSET_TABLE_ into EBX first. There is no need for that on
x86-64 since x86-64 uses PC-relative PLT.
On x86-64, for 32-bit PC-relative branches, we can generate PLT32
relocation, instead of PC32 relocation, which can also be used as
a marker for 32-bit PC-relative branches. Linker can always reduce
PLT32 relocation to PC32 if function is defined locally. Local
functions should use PC32 relocation. As far as Linux kernel is
concerned, R_X86_64_PLT32 can be treated the same as R_X86_64_PC32
since Linux kernel doesn't use PLT.
is needed. It is available on hjl/plt32/master branch at
https://github.com/hjl-tools/linux
bfd/
PR gas/22791
* elf64-x86-64.c (is_32bit_relative_branch): Removed.
(elf_x86_64_relocate_section): Check PIC relocations in PIE.
Remove is_32bit_relative_branch usage. Disallow PC32 reloc
against protected function in shared object.
gas/
PR gas/22791
* config/tc-i386.c (need_plt32_p): New function.
(output_jump): Generate BFD_RELOC_X86_64_PLT32 if possible.
(md_estimate_size_before_relax): Likewise.
* testsuite/gas/i386/reloc64.d: Updated.
* testsuite/gas/i386/x86-64-jump.d: Likewise.
* testsuite/gas/i386/x86-64-mpx-branch-1.d: Likewise.
* testsuite/gas/i386/x86-64-mpx-branch-2.d: Likewise.
* testsuite/gas/i386/x86-64-relax-2.d: Likewise.
* testsuite/gas/i386/x86-64-relax-3.d: Likewise.
* testsuite/gas/i386/ilp32/reloc64.d: Likewise.
* testsuite/gas/i386/ilp32/x86-64-branch.d: Likewise.
ld/
PR gas/22791
* testsuite/ld-x86-64/mpx1c.rd: Updated.
* testsuite/ld-x86-64/pr22791-1.err: New file.
* testsuite/ld-x86-64/pr22791-1a.c: Likewise.
* testsuite/ld-x86-64/pr22791-1b.s: Likewise.
* testsuite/ld-x86-64/pr22791-2.rd: Likewise.
* testsuite/ld-x86-64/pr22791-2a.s: Likewise.
* testsuite/ld-x86-64/pr22791-2b.c: Likewise.
* testsuite/ld-x86-64/pr22791-2c.s: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run PR ld/22791 tests.
Just like for instructions in GPRs, there's no need to have separate
templates for otherwise identical insns acting on XMM or YMM registers
(or memory of the same size).
Use a combination of a single new Reg bit and Byte, Word, Dword, or
Qword instead.
Besides shrinking the number of operand type bits this has the benefit
of making register handling more similar to accumulator handling (a
generic flag is being accompanied by a "size qualifier"). It requires,
however, to split a few insn templates, as it is no longer correct to
have combinations like Reg32|Reg64|Byte. This slight growth in size will
hopefully be outweighed by this change paving the road for folding a
presumably much larger number of templates later on.
Pseudo prefixes must be used on an instruction. Issue an error when
pseudo prefix is used without instruction.
PR gas/22623
* gas/config/tc-i386.c (output_insn): Check pseudo prefix
without instruction.
* testsuite/gas/i386/i386.exp: Run inval-pseudo.
* testsuite/gas/i386/inval-pseudo.l: New file.
* testsuite/gas/i386/inval-pseudo.s: Likewise.
Again these look to be typos: No template currently allows for any two
(or all three) of RegXMM, RegYMM, and RegZMM in a single operand. Quite
clearly ! are missing, after the addition of which the checks for the
first and (if present) second operands also fully match up.
I'm rather certain the missing ! was just a typo, the more with the
similar check in mind that's in the same function a few hundred lines
down (in the body of "if (vex_reg != (unsigned int) ~0)"). Of course
this can't be demonstrated by a test case - internal data structure
consistency is being checked here, and neither form of the check
triggers with any current template.
It is also not really clear to me why operand_type_equal() is being used
in the {X,Y,Z}MM register check here, rather than just testing the
respective bits: Just like Reg32|Reg64 is legal in an operand template,
I don't see why e.g. RegXMM|RegYMM wouldn't be. For example it ought to
be possible to combine
vaddpd, 3, 0x6658, None, 1, CpuAVX, Modrm|Vex|VexOpcode=0|VexVVVV=1|VexW=1|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Xmmword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|Disp32S|RegXMM, RegXMM, RegXMM }
vaddpd, 3, 0x6658, None, 1, CpuAVX, Modrm|Vex=2|VexOpcode=0|VexVVVV=1|VexW=1|IgnoreSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Ymmword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|Disp32S|RegYMM, RegYMM, RegYMM }
into a single template (with setting of VEX.L suitably handled elsewhere
if that's not already happening anyway).
Additionally I don't understand why this uses abort() instead of
gas_assert().
Both of these latter considerations then also apply to the
aforementioned other check in the same function.
For one the register type used for masking should be validated. And then
we shouldn't accept input producing encodings which will #UD when
executed, as is the case when EVEX.Z is set while EVEX.AAA is zero.
Despite EVEX encodings not being available in real and VM86 modes,
16-bit addressing still needs to be handled properly for 16-bit
protected mode as well as 16-bit addressing in 32-bit mode. Neither
should displacements be dropped silently by the assembler, nor should
the disassembler fail to correctly scale 8-bit displacements.