x86 assembler fixes:

* mkx86ins.pp: 'regmem' operand type in x86ins.dat must be converted to OT_RM_GPR, not OT_REGMEM. The latter does not restrict register type, allowing to use e.g. xmm registers in place of regular ones. 
* Finished 'movd' and 'movq', added some tests for them to tasm2.pp.

git-svn-id: trunk@17515 -
This commit is contained in:
sergei 2011-05-20 20:39:35 +00:00
parent cf57b81561
commit 504e0c6816
7 changed files with 531 additions and 565 deletions

View File

@ -1,2 +1,2 @@
{ don't edit, this file is generated from x86ins.dat }
1210;
1202;

File diff suppressed because it is too large Load Diff

View File

@ -59,12 +59,12 @@ function formatop(s:string;allowsizeonly:boolean):string;
replacetab : array[1..replaces,1..2] of string[32]=(
(':',' or ot_colon'),
('reg','regnorm'),
('regmem','regmem'),
('rm8','regmem or ot_bits8'),
('rm16','regmem or ot_bits16'),
('rm32','regmem or ot_bits32'),
('rm64','regmem or ot_bits64'),
('rm80','regmem or ot_bits80'),
('regmem','rm_gpr'),
('rm8','rm_gpr or ot_bits8'),
('rm16','rm_gpr or ot_bits16'),
('rm32','rm_gpr or ot_bits32'),
('rm64','rm_gpr or ot_bits64'),
('rm80','rm_gpr or ot_bits80'),
('mem8','memory or ot_bits8'),
('mem16','memory or ot_bits16'),
('mem32','memory or ot_bits32'),
@ -445,5 +445,5 @@ begin
writeln(nopfile,insns,';');
close(nopfile);
closeinc(propfile);
writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
writeln(insns,' nodes processed (maxinfolen=',maxinfolen,')');
end.

View File

@ -1063,23 +1063,21 @@ reg_treg,reg64 \2\x0F\x26\110 386,PRIV,X86_64
[MOVD,movd]
(Ch_Rop1, Ch_Wop2, Ch_None)
mmxreg,mem \2\x0F\x6E\110 PENT,MMX,SD
mmxreg,reg32 \2\x0F\x6E\110 PENT,MMX
mem,mmxreg \2\x0F\x7E\101 PENT,MMX,SD
reg32,mmxreg \2\x0F\x7E\101 PENT,MMX
xmmreg,reg32 \361\2\x0F\x6E\110 WILLAMETTE,SSE2
reg32,xmmreg \361\2\x0F\x7E\101 WILLAMETTE,SSE2
mem,xmmreg \361\325\2\x0F\x7E\101 WILLAMETTE,SSE2
xmmreg,mem \361\325\2\x0F\x6E\110 WILLAMETTE,SSE2
mmxreg,rm32 \2\x0F\x6E\110 PENT,MMX,SD
rm32,mmxreg \2\x0F\x7E\101 PENT,MMX,SD
xmmreg,rm32 \361\2\x0F\x6E\110 WILLAMETTE,SSE2
rm32,xmmreg \361\2\x0F\x7E\101 WILLAMETTE,SSE2
[MOVQ,movq]
(Ch_Rop1, Ch_Wop2, Ch_None)
mmxreg,mmxrm \2\x0F\x6F\110 PENT,MMX,SM
mmxrm,mmxreg \2\x0F\x7F\101 PENT,MMX,SM
mmxreg,rm64 \326\2\x0F\x6E\110 X86_64,MMX
rm64,mmxreg \326\2\x0F\x7E\101 X86_64,MMX
xmmreg,xmmrm \333\2\x0F\x7E\110 WILLAMETTE,SSE2
xmmrm,xmmreg \361\2\x0F\xD6\101 WILLAMETTE,SSE2
xmmreg,reg64 \361\326\2\x0F\x6E\110 WILLAMETTE,SSE2
reg64,xmmreg \361\326\2\x0F\x7E\101 WILLAMETTE,SSE2
xmmreg,reg64 \361\326\2\x0F\x6E\110 WILLAMETTE,SSE2,X86_64
reg64,xmmreg \361\326\2\x0F\x7E\101 WILLAMETTE,SSE2,X86_64
[MOVSB]
(Ch_All, Ch_None, Ch_None)
@ -1089,10 +1087,8 @@ void \1\xA4 8086
; Ch_All isn't correct for the sse move, but how can it be solved? (FK)
(Ch_All, Ch_None, Ch_None)
void \325\1\xA5 386
xmmreg,xmmreg \334\2\x0F\x10\110 WILLAMETTE,SSE2
xmmreg,xmmreg \334\2\x0F\x11\110 WILLAMETTE,SSE2
mem,xmmreg \334\2\x0F\x11\101 WILLAMETTE,SSE2
xmmreg,mem \334\2\x0F\x10\110 WILLAMETTE,SSE2
xmmreg,xmmrm \334\2\x0F\x10\110 WILLAMETTE,SSE2
xmmrm,xmmreg \334\2\x0F\x11\101 WILLAMETTE,SSE2
[MOVSQ]
(Ch_All, Ch_None, Ch_None)
@ -3029,10 +3025,6 @@ mem \326\2\x0F\xC7\201 X86_64
;
; SSE4a (AMD Barcelona CPUs, n/a on Intel)
;
; note: \333=F3h, \334=F2h, \336=66h, \325=no REX.W=1 for qword, \375=unsigned
[MOVNTSS]
(Ch_All, Ch_None, Ch_None)
mem,xmmreg \333\2\x0F\x2B\101 SSE4,SD
@ -3045,11 +3037,11 @@ mem,xmmreg \334\325\2\x0F\x2B\101 SSE4 ;,SQ
(Ch_All, Ch_None, Ch_None)
xmmreg,xmmreg \334\2\x0F\x79\110 SSE4
; four operands are not possible yet
; xmmreg,xmmreg,imm,imm \110\334\76\2\x0F\x78\77\375\22\375\23 SSE4,SB
; xmmreg,xmmreg,imm,imm \334\2\x0F\x78\110\26\27 SSE4,SB
[EXTRQ]
(Ch_All, Ch_None, Ch_None)
xmmreg,imm,imm \361\2\x0F\x78\200\375\21\375\22 SSE4,SB
xmmreg,imm,imm \361\2\x0F\x78\200\25\26 SSE4,SB
xmmreg,xmmreg \361\2\x0F\x79\110 SSE4
[LZCNT,lzcntX]

View File

@ -1,2 +1,2 @@
{ don't edit, this file is generated from x86ins.dat }
1203;
1199;

File diff suppressed because it is too large Load Diff

View File

@ -156,11 +156,39 @@ asm
psadbw (%r8), %xmm0
end;
procedure tmovd; assembler; nostackframe;
asm
movd 0x12345678(%rip), %xmm0
movd %xmm0, 0x12345678(%rip)
movd %eax, %xmm0
movd %xmm0, %eax
{ same for MMX registers }
movd 0x12345678(%rip), %mm0
movd %mm0, 0x12345678(%rip)
movd %eax, %mm0
movd %mm0, %eax
end;
procedure tmovq; assembler; nostackframe;
asm
movq 0x12345678(%rip), %xmm0
movq %xmm0, 0x12345678(%rip)
movq %xmm1, %xmm0
movq %rax, %xmm0
movq %xmm0, %rax
{ same for MMX registers }
movq 0x12345678(%rip), %mm0
movq %mm0, 0x12345678(%rip)
movq %mm1, %mm0
movq %rax, %mm0
movq %mm0, %rax
end;
// Here are some more tough nuts to crack...
procedure test2; assembler; nostackframe;
asm
// movq %xmm1,0x12345678(%rip) { converted to mov, invalid combination of opcode and operands }
// movq 0x12345678(%rip),%xmm1
// cmpsd $0x10,%xmm7,%xmm6 { unrecognized opcode }
// cmpsd $0x10,(%rax),%xmm7
// movsd (%rax),%xmm8 { unrecognized opcode }
@ -221,16 +249,46 @@ const
$58,$00,$F3,$41,$0F,$58,$00,$66,$41,$0F,$E4,$00,$66,$41,$0F,
$F6,$00,$C3);
tmovq_expected: array[0..54] of byte = (
$F3,$0F,$7E,$05,$78,$56,$34,$12,
$66,$0F,$D6,$05,$78,$56,$34,$12,
$F3,$0F,$7E,$C1,
$66,$48,$0F,$6E,$C0,
$66,$48,$0F,$7E,$C0,
$0F,$6F,$05,$78,$56,$34,$12,
$0F,$7F,$05,$78,$56,$34,$12,
$0F,$6F,$C1,
$48,$0F,$6E,$C0,
$48,$0F,$7E,$C0
);
tmovd_expected: array[0..43] of byte = (
$66,$0F,$6E,$05,$78,$56,$34,$12,
$66,$0F,$7E,$05,$78,$56,$34,$12,
$66,$0F,$6E,$C0,
$66,$0F,$7E,$C0,
$0F,$6E,$05,$78,$56,$34,$12,
$0F,$7E,$05,$78,$56,$34,$12,
$0F,$6E,$C0,
$0F,$7E,$C0
);
procedure check(const id: string; const expected: array of byte; p: pointer);
var
i : longint;
begin
for i:=0 to high(test_expected) do
if test_expected[i]<>pbyte(@test)[i] then
for i:=0 to high(expected) do
if expected[i]<>pbyte(p)[i] then
begin
writeln('mismatch at offset $',hexstr(i,4), ', expected=$',hexstr(test_expected[i],2),' actual=$',hexstr(pbyte(@test)[i],2));
writeln(id, ' mismatch at offset $',hexstr(i,4), ', expected=$',hexstr(expected[i],2),' actual=$',hexstr(pbyte(p)[i],2));
halt(1);
end;
end;
begin
check('generic', test_expected, @test);
check('movq', tmovq_expected, @tmovq);
check('movd', tmovd_expected, @tmovd);
writeln('ok');
end.