| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
| |
the avoidance of mov im32->reg64 wasn't working when reg64 was rax.
While fixing this also fix instructions which had the REX prefix
hardcoded in opcode and so didn't support extended registers which
would have added another REX prefix.
|
| |
|
|
|
|
|
| |
Our preprocessor throws away # line-comments in asm mode.
It did so also inside preprocessor directives, thereby
removing stringification. Parse defines in non-asm mode (but
retain '.' as identifier character inside macro definitions).
|
| |
|
|
|
| |
In particular don't care if they're signed or unsigned, they're all
acceptable as immediates.
|
| | |
|
| |
|
|
|
|
|
|
|
|
| |
That, as well as "sym = expr", if expr contains symbols.
Slightly tricky because a definition from .set is overridable,
whereas proper definitions aren't.
This doesn't yet allow using this for override tricks from C
and global asm blocks because the symbol tables from C and asm
are separate.
|
| |
|
|
|
| |
str accepts rm16/r32/r64, and push/pop defaults to 64 when given
memory operands (to 32 on i386).
|
| | |
|
| |
|
|
|
|
|
| |
This requires correctly handling the REX prefix.
As bonus we now also support the four 8bit registers
spl,bpl,sil,dil, which are decoded as ah,ch,dh,bh in non-long-mode
(and require a REX prefix as well).
|
| | |
|
| |
|
|
|
|
|
| |
lar can accept multiple sizes as well (wlx), like lsl. When using
autosize it's important to look at the destination operand first;
when it's a register that one determines the size, not the input
operand.
|
| |
|
|
|
| |
Some new opcodes and some aliases: ljmp[wl], prefetch{nta,t0,t1,t2},
bswap[lq], sysretq, swapgs.
|
| |
|
|
|
| |
GAS has alias lgdtq for lgdt (similar for saves and GDT). It doesn't
have the same for LDT.
|
| | |
|
| | |
|
| |
|
|
| |
Implement some more opcodes, syscall, sysret, lfence, mfence, sfence.
|
| |
|
|
|
| |
I.e. implement < > <= >= == !=. Comparisons are signed and result
is -1 if true, 0 if false.
|
| |
|
|
|
| |
The x86-64 target has 64bit relocs, and hence can accept
generic expressions for '.quad'.
|
| | |
|
| |
|
|
|
|
| |
In particular subtracting a defined symbol from current section
makes the value PC relative, and .org accepts symbolic expressions
as well, if the symbol is from the current section.
|
| | |
|
| | |
|
| |
|
|
|
|
| |
Now we can express prefixes with 0x0fxx opcodes we can correct the
movq mem64->xmm opcode, and restrict the movq xmm->mem64 movq to
not invalidly accept mmx.
|
| |
|
|
|
|
|
|
| |
In particular those that are extensions of existing mmx (or sse1)
instructions by a simple 0x66 prefix. There's one caveat for
x86-64: as we don't yet correctly handle the 0xf3 prefix
the movq mem64->xmm is wrong (tested in asmtest.S). Needs
some refactoring of the instr_type member.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This was causing assembler bugs in a tcc compiled by itself
at i386-asm.c:352 when ExprValue.v was changed to uint64_t:
if (op->e.v == (int8_t)op->e.v)
op->type |= OP_IM8S;
A general test case:
#include <stdio.h>
int main(int argc, char **argv)
{
long long ll = 4000;
int i = (char)ll;
printf("%d\n", i);
return 0;
}
Output was "4000", now "-96".
Also: add "asmtest2" as asmtest with tcc compiled by itself
|
| |
|
|
|
|
|
| |
There were two errors in the arithmetic imm8 instruction. They accept
only REGW, and in case the user write a xxxb opcode that variant
needs to be rejected as well (it's not automatically rejected by REGW
in case the destination is memory).
|
| | |
|
| |
|
|
|
|
|
|
| |
Two things: negative constants were rejected (e.g. "add $-15,%eax").
Second the insn order was such that the arithmetic IM8S forms
weren't used (always the IM32 ones). Switching them prefers those
but requires a fix for size calculation in case the opcodes were
OPC_ARITH and OPC_WLX (whose size starts with 1, not zero).
|
| |
|
|
| |
This adds the zero/sign-extending opcodes with 64bit destinations.
|
| |
|
|
|
|
|
|
|
| |
Fix it to actually be able to parse 64bit immediates (enlarge
operand value type). Then, generally there's no need for accepting
IM64 anywhere, except in the 0xba+r mov opcodes, so OP_IM is
unnecessary, as is OPT_IMNO64. Improve the generated code a bit
by preferring the 0xc7 opcode for im32->reg64, instead of the
im64->reg64 form (which we therefore hardcode).
|
| |
|
|
|
| |
Also remove the hacky mod/rm byte emission during
disp/imm writing.
|
| |
|
|
|
| |
cmov can accept multi sizes, but is also a OPC_TEST opcode,
deal with this.
|
| |
|
|
|
|
|
|
|
|
|
| |
A bag of assembler fixes, to be either compatible with GAS
(e.g. order of 'test' operands), accept more instructions,
count correct foo{bwlq} variants on x86_64, fix modrm/sib bytes
on x86_64 to not use %rip relative addressing mode, to not use
invalid insns in tests/asmtest.S for x86_64.
Result is that now output of GAS and of tcc on tests/asmtest.S
is mostly the same.
|
| |
|
|
|
|
| |
PS: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20101122/112576.html
This is fix PR8686 for llvm: accepting a 'b' suffix at the end
of all the setcc instructions.
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
.align #,0x90 in gas ignores the 0x90 and outputs any kind
of nop it feels like. the one avoided by this patch is a 7
byte nop, which gas has been doing since at least 1999:
http://sourceware.org/ml/binutils/1999-10/msg00083.html
In order to match what gas does, we would need to make
code alignment target-specific, import a lot of code, and
face the question: exactly which gas {version,target,tune}
combo are we trying to match? see i386_align_code in:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gas/config/tc-i386.c?annotate=1.460&cvsroot=src
The smart noppery is turned on via the special casing of 0x90
at line 438 in md_do_align in:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gas/config/tc-i386.h?annotate=1.1&cvsroot=src
|
| | |
|
| |
|
|
| |
gas does
|
| | |
|
| |
|