+ support for assembler instructions with four operands

+ support for insertq, resolves #19910

git-svn-id: trunk@18206 -
This commit is contained in:
florian 2011-08-14 16:46:35 +00:00
parent 4a34192510
commit 8308b46a94
10 changed files with 2528 additions and 2450 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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,' )');

View File

@ -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

View File

@ -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)

View File

@ -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
View 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.