+ 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/tw1964.pp svneol=native#text/plain
tests/webtbs/tw19700.pp svneol=native#text/plain tests/webtbs/tw19700.pp svneol=native#text/plain
tests/webtbs/tw19864.pp svneol=native#text/pascal 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/tw1996.pp svneol=native#text/plain
tests/webtbs/tw19960.pp svneol=native#text/pascal tests/webtbs/tw19960.pp svneol=native#text/pascal
tests/webtbs/tw19974.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 } { 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 Var
p : toperand; p : toperand;
Begin Begin
case Ops of case ops of
2 : 0,1:
begin ;
p:=Operands[1]; 2 : begin
Operands[1]:=Operands[2]; { 0,1 -> 1,0 }
Operands[2]:=p; p:=Operands[1];
end; Operands[1]:=Operands[2];
3 : Operands[2]:=p;
begin end;
p:=Operands[1]; 3 : begin
Operands[1]:=Operands[3]; { 0,1,2 -> 2,1,0 }
Operands[3]:=p; p:=Operands[1];
end; 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;
end; end;

View File

@ -15,8 +15,8 @@
program mkx86ins; program mkx86ins;
const const
Version = '1.5.1'; Version = '1.6.0';
max_operands = 4;
var var
s : string; s : string;
i : longint; i : longint;
@ -205,7 +205,7 @@ var
opcode, opcode,
codes, codes,
flags : string; flags : string;
optypes : array[1..3] of string; optypes : array[1..max_operands] of string;
begin begin
writeln('Nasm Instruction Table Converter Version ',Version); writeln('Nasm Instruction Table Converter Version ',Version);
x86_64:=paramstr(1)='x86_64'; x86_64:=paramstr(1)='x86_64';
@ -331,9 +331,8 @@ begin
runerror(234); runerror(234);
{ clear } { clear }
ops:=0; ops:=0;
optypes[1]:=''; for i:=low(optypes) to high(optypes) do
optypes[2]:=''; optypes[i]:='';
optypes[3]:='';
codes:=''; codes:='';
flags:=''; flags:='';
skip:=false; skip:=false;
@ -355,8 +354,8 @@ begin
else else
break; break;
until false; until false;
for j:=1 to 3-ops do for j:=1 to max_operands-ops do
optypes[3-j+1]:='ot_none'; optypes[max_operands-j+1]:='ot_none';
{ codes } { codes }
skipspace; skipspace;
j:=0; j:=0;
@ -429,7 +428,7 @@ begin
writeln(insfile,' ('); writeln(insfile,' (');
writeln(insfile,' opcode : ',opcode,';'); writeln(insfile,' opcode : ',opcode,';');
writeln(insfile,' ops : ',ops,';'); 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,' code : ',codes,';');
writeln(insfile,' flags : ',flags); writeln(insfile,' flags : ',flags);
write(insfile,' )'); write(insfile,' )');

View File

@ -222,7 +222,7 @@ interface
tinsentry=packed record tinsentry=packed record
opcode : tasmop; opcode : tasmop;
ops : byte; ops : byte;
optypes : array[0..2] of longint; optypes : array[0..max_operands-1] of longint;
code : array[0..maxinfolen] of char; code : array[0..maxinfolen] of char;
flags : cardinal; flags : cardinal;
end; end;
@ -861,6 +861,8 @@ implementation
begin begin
{ Fix the operands which are in AT&T style and we need them in Intel style } { Fix the operands which are in AT&T style and we need them in Intel style }
case ops of case ops of
0,1:
;
2 : begin 2 : begin
{ 0,1 -> 1,0 } { 0,1 -> 1,0 }
p:=oper[0]; p:=oper[0];
@ -873,6 +875,17 @@ implementation
oper[0]:=oper[2]; oper[0]:=oper[2];
oper[2]:=p; oper[2]:=p;
end; 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;
end; end;
@ -1056,9 +1069,9 @@ implementation
end; end;
top_const : top_const :
begin 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 } { 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); message(asmr_e_invalid_opcode_and_operand);
if (opsize<>S_W) and (aint(val)>=-128) and (val<=127) then if (opsize<>S_W) and (aint(val)>=-128) and (val<=127) then
ot:=OT_IMM8 or OT_SIGNED ot:=OT_IMM8 or OT_SIGNED
@ -1112,7 +1125,7 @@ implementation
currot, currot,
i,j,asize,oprs : longint; i,j,asize,oprs : longint;
insflags:cardinal; insflags:cardinal;
siz : array[0..2] of longint; siz : array[0..max_operands-1] of longint;
begin begin
result:=false; result:=false;
@ -1753,7 +1766,7 @@ implementation
end; end;
12,13,14, 12,13,14,
16,17,18, 16,17,18,
20,21,22, 20,21,22,23,
40,41,42 : 40,41,42 :
inc(len); inc(len);
24,25,26, 24,25,26,
@ -1879,7 +1892,7 @@ implementation
* to the condition code value of the instruction. * to the condition code value of the instruction.
* \14, \15, \16 - a signed byte immediate operand, from operand 0, 1 or 2 * \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 * \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 * \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 * \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 * assembly mode or the address-size override on the operand
@ -2126,7 +2139,7 @@ implementation
else else
objdata.writebytes(currval,1); objdata.writebytes(currval,1);
end; end;
20,21,22 : 20,21,22,23 :
begin begin
getvalsym(c-20); getvalsym(c-20);
if (currval<0) or (currval>255) then if (currval<0) or (currval>255) then

View File

@ -3045,8 +3045,7 @@ mem,xmmreg \334\325\2\x0F\x2B\101 SSE4 ;,SQ
[INSERTQ] [INSERTQ]
(Ch_All, Ch_None, Ch_None) (Ch_All, Ch_None, Ch_None)
xmmreg,xmmreg \334\2\x0F\x79\110 SSE4 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] [EXTRQ]
(Ch_All, Ch_None, Ch_None) (Ch_All, Ch_None, Ch_None)

View File

@ -1,2 +1,2 @@
{ don't edit, this file is generated from x86ins.dat } { 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.