mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-01 14:10:57 +01:00
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:
parent
cf57b81561
commit
504e0c6816
@ -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
@ -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.
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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
@ -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.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user