mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 19:08:15 +02:00
+ support for assembler instructions with four operands
+ support for insertq, resolves #19910 git-svn-id: trunk@18206 -
This commit is contained in:
parent
4a34192510
commit
8308b46a94
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -11720,6 +11720,7 @@ tests/webtbs/tw19548.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw1964.pp svneol=native#text/plain
|
||||
tests/webtbs/tw19700.pp svneol=native#text/plain
|
||||
tests/webtbs/tw19864.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw19910.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw1996.pp svneol=native#text/plain
|
||||
tests/webtbs/tw19960.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw19974.pp svneol=native#text/pascal
|
||||
|
@ -1,2 +1,2 @@
|
||||
{ don't edit, this file is generated from x86ins.dat }
|
||||
1204;
|
||||
1205;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1018,19 +1018,32 @@ end;
|
||||
Var
|
||||
p : toperand;
|
||||
Begin
|
||||
case Ops of
|
||||
2 :
|
||||
begin
|
||||
p:=Operands[1];
|
||||
Operands[1]:=Operands[2];
|
||||
Operands[2]:=p;
|
||||
end;
|
||||
3 :
|
||||
begin
|
||||
p:=Operands[1];
|
||||
Operands[1]:=Operands[3];
|
||||
Operands[3]:=p;
|
||||
end;
|
||||
case ops of
|
||||
0,1:
|
||||
;
|
||||
2 : begin
|
||||
{ 0,1 -> 1,0 }
|
||||
p:=Operands[1];
|
||||
Operands[1]:=Operands[2];
|
||||
Operands[2]:=p;
|
||||
end;
|
||||
3 : begin
|
||||
{ 0,1,2 -> 2,1,0 }
|
||||
p:=Operands[1];
|
||||
Operands[1]:=Operands[3];
|
||||
Operands[3]:=p;
|
||||
end;
|
||||
4 : begin
|
||||
{ 0,1,2,3 -> 3,2,1,0 }
|
||||
p:=Operands[1];
|
||||
Operands[1]:=Operands[4];
|
||||
Operands[4]:=p;
|
||||
p:=Operands[2];
|
||||
Operands[2]:=Operands[3];
|
||||
Operands[3]:=p;
|
||||
end;
|
||||
else
|
||||
internalerror(201108142);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -15,8 +15,8 @@
|
||||
program mkx86ins;
|
||||
|
||||
const
|
||||
Version = '1.5.1';
|
||||
|
||||
Version = '1.6.0';
|
||||
max_operands = 4;
|
||||
var
|
||||
s : string;
|
||||
i : longint;
|
||||
@ -205,7 +205,7 @@ var
|
||||
opcode,
|
||||
codes,
|
||||
flags : string;
|
||||
optypes : array[1..3] of string;
|
||||
optypes : array[1..max_operands] of string;
|
||||
begin
|
||||
writeln('Nasm Instruction Table Converter Version ',Version);
|
||||
x86_64:=paramstr(1)='x86_64';
|
||||
@ -331,9 +331,8 @@ begin
|
||||
runerror(234);
|
||||
{ clear }
|
||||
ops:=0;
|
||||
optypes[1]:='';
|
||||
optypes[2]:='';
|
||||
optypes[3]:='';
|
||||
for i:=low(optypes) to high(optypes) do
|
||||
optypes[i]:='';
|
||||
codes:='';
|
||||
flags:='';
|
||||
skip:=false;
|
||||
@ -355,8 +354,8 @@ begin
|
||||
else
|
||||
break;
|
||||
until false;
|
||||
for j:=1 to 3-ops do
|
||||
optypes[3-j+1]:='ot_none';
|
||||
for j:=1 to max_operands-ops do
|
||||
optypes[max_operands-j+1]:='ot_none';
|
||||
{ codes }
|
||||
skipspace;
|
||||
j:=0;
|
||||
@ -429,7 +428,7 @@ begin
|
||||
writeln(insfile,' (');
|
||||
writeln(insfile,' opcode : ',opcode,';');
|
||||
writeln(insfile,' ops : ',ops,';');
|
||||
writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],');');
|
||||
writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],',',optypes[4],');');
|
||||
writeln(insfile,' code : ',codes,';');
|
||||
writeln(insfile,' flags : ',flags);
|
||||
write(insfile,' )');
|
||||
|
@ -222,7 +222,7 @@ interface
|
||||
tinsentry=packed record
|
||||
opcode : tasmop;
|
||||
ops : byte;
|
||||
optypes : array[0..2] of longint;
|
||||
optypes : array[0..max_operands-1] of longint;
|
||||
code : array[0..maxinfolen] of char;
|
||||
flags : cardinal;
|
||||
end;
|
||||
@ -861,6 +861,8 @@ implementation
|
||||
begin
|
||||
{ Fix the operands which are in AT&T style and we need them in Intel style }
|
||||
case ops of
|
||||
0,1:
|
||||
;
|
||||
2 : begin
|
||||
{ 0,1 -> 1,0 }
|
||||
p:=oper[0];
|
||||
@ -873,6 +875,17 @@ implementation
|
||||
oper[0]:=oper[2];
|
||||
oper[2]:=p;
|
||||
end;
|
||||
4 : begin
|
||||
{ 0,1,2,3 -> 3,2,1,0 }
|
||||
p:=oper[0];
|
||||
oper[0]:=oper[3];
|
||||
oper[3]:=p;
|
||||
p:=oper[1];
|
||||
oper[1]:=oper[2];
|
||||
oper[2]:=p;
|
||||
end;
|
||||
else
|
||||
internalerror(201108141);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1056,9 +1069,9 @@ implementation
|
||||
end;
|
||||
top_const :
|
||||
begin
|
||||
{ allow 2nd or 3rd operand being a constant and expect no size for shuf* etc. }
|
||||
{ allow 2nd, 3rd or 4th operand being a constant and expect no size for shuf* etc. }
|
||||
{ further, allow AAD and AAM with imm. operand }
|
||||
if (opsize=S_NO) and not((i in [1,2]) or ((i=0) and (opcode in [A_AAD,A_AAM]))) then
|
||||
if (opsize=S_NO) and not((i in [1,2,3]) or ((i=0) and (opcode in [A_AAD,A_AAM]))) then
|
||||
message(asmr_e_invalid_opcode_and_operand);
|
||||
if (opsize<>S_W) and (aint(val)>=-128) and (val<=127) then
|
||||
ot:=OT_IMM8 or OT_SIGNED
|
||||
@ -1112,7 +1125,7 @@ implementation
|
||||
currot,
|
||||
i,j,asize,oprs : longint;
|
||||
insflags:cardinal;
|
||||
siz : array[0..2] of longint;
|
||||
siz : array[0..max_operands-1] of longint;
|
||||
begin
|
||||
result:=false;
|
||||
|
||||
@ -1753,7 +1766,7 @@ implementation
|
||||
end;
|
||||
12,13,14,
|
||||
16,17,18,
|
||||
20,21,22,
|
||||
20,21,22,23,
|
||||
40,41,42 :
|
||||
inc(len);
|
||||
24,25,26,
|
||||
@ -1879,7 +1892,7 @@ implementation
|
||||
* to the condition code value of the instruction.
|
||||
* \14, \15, \16 - a signed byte immediate operand, from operand 0, 1 or 2
|
||||
* \20, \21, \22 - a byte immediate operand, from operand 0, 1 or 2
|
||||
* \24, \25, \26 - an unsigned byte immediate operand, from operand 0, 1 or 2
|
||||
* \24, \25, \26, \27 - an unsigned byte immediate operand, from operand 0, 1, 2 or 3
|
||||
* \30, \31, \32 - a word immediate operand, from operand 0, 1 or 2
|
||||
* \34, \35, \36 - select between \3[012] and \4[012] depending on 16/32 bit
|
||||
* assembly mode or the address-size override on the operand
|
||||
@ -2126,7 +2139,7 @@ implementation
|
||||
else
|
||||
objdata.writebytes(currval,1);
|
||||
end;
|
||||
20,21,22 :
|
||||
20,21,22,23 :
|
||||
begin
|
||||
getvalsym(c-20);
|
||||
if (currval<0) or (currval>255) then
|
||||
|
@ -3045,8 +3045,7 @@ mem,xmmreg \334\325\2\x0F\x2B\101 SSE4 ;,SQ
|
||||
[INSERTQ]
|
||||
(Ch_All, Ch_None, Ch_None)
|
||||
xmmreg,xmmreg \334\2\x0F\x79\110 SSE4
|
||||
; four operands are not possible yet
|
||||
; xmmreg,xmmreg,imm,imm \334\2\x0F\x78\110\26\27 SSE4,SB
|
||||
xmmreg,xmmreg,imm,imm \334\2\x0F\x78\110\26\27 SSE4,SB
|
||||
|
||||
[EXTRQ]
|
||||
(Ch_All, Ch_None, Ch_None)
|
||||
|
@ -1,2 +1,2 @@
|
||||
{ don't edit, this file is generated from x86ins.dat }
|
||||
1213;
|
||||
1214;
|
||||
|
File diff suppressed because it is too large
Load Diff
39
tests/webtbs/tw19910.pp
Normal file
39
tests/webtbs/tw19910.pp
Normal file
@ -0,0 +1,39 @@
|
||||
{ %cpu=i386 }
|
||||
procedure p1;assembler;
|
||||
asm
|
||||
INSERTQ $1,$3,%xmm0,%xmm1
|
||||
end;
|
||||
|
||||
{$asmmode intel}
|
||||
procedure p2;assembler;
|
||||
asm
|
||||
INSERTQ xmm1,xmm0,3,1
|
||||
end;
|
||||
|
||||
|
||||
const
|
||||
test_expected : array[0..5] of byte = (
|
||||
$F2,$0F,$78,$C8,$03,$01);
|
||||
|
||||
var
|
||||
i : longint;
|
||||
|
||||
|
||||
begin
|
||||
for i:=0 to high(test_expected) do
|
||||
if test_expected[i]<>pbyte(@p1)[i] then
|
||||
begin
|
||||
writeln('mismatch at offset $',hexstr(i,4), ', expected=$',
|
||||
hexstr(test_expected[i],2),' actual=$',hexstr(pbyte(@p1)[i],2));
|
||||
halt(1);
|
||||
end;
|
||||
for i:=0 to high(test_expected) do
|
||||
if test_expected[i]<>pbyte(@p2)[i] then
|
||||
begin
|
||||
writeln('mismatch at offset $',hexstr(i,4), ', expected=$',
|
||||
hexstr(test_expected[i],2),' actual=$',hexstr(pbyte(@p2)[i],2));
|
||||
halt(1);
|
||||
end;
|
||||
writeln('ok');
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user