Browse Source

* (extended and modified) patch by Emelyanov Roman to add suport of RDRAND, RDSEED and TSX instructions set, resolves issue #29893.
In comparison with the original patch, support for a i386 has been added as well as a test program.
Further, a small issue with xbegin has been fixed

git-svn-id: trunk@33375 -

florian 9 years ago
parent
commit
8d5cc3dfa4

+ 1 - 0
.gitattributes

@@ -14992,6 +14992,7 @@ tests/webtbs/tw2976.pp svneol=native#text/plain
 tests/webtbs/tw29792.pp svneol=native#text/pascal
 tests/webtbs/tw2983.pp svneol=native#text/plain
 tests/webtbs/tw2984.pp svneol=native#text/plain
+tests/webtbs/tw29893.pp svneol=native#text/pascal
 tests/webtbs/tw2998.pp svneol=native#text/plain
 tests/webtbs/tw2999.pp svneol=native#text/plain
 tests/webtbs/tw3004.pp svneol=native#text/plain

+ 9 - 1
compiler/i386/i386att.inc

@@ -1025,5 +1025,13 @@
 'vfnmsub231sd',
 'vfnmsub132ss',
 'vfnmsub213ss',
-'vfnmsub231ss'
+'vfnmsub231ss',
+'xacquire',
+'xrelease',
+'xbegin',
+'xabort',
+'xend',
+'xtest',
+'rdrand',
+'rdseed'
 );

+ 8 - 0
compiler/i386/i386atts.inc

@@ -1025,5 +1025,13 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufINT,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
 attsufNONE
 );

+ 9 - 1
compiler/i386/i386int.inc

@@ -1025,5 +1025,13 @@
 'vfnmsub231sd',
 'vfnmsub132ss',
 'vfnmsub213ss',
-'vfnmsub231ss'
+'vfnmsub231ss',
+'xacquire',
+'xrelease',
+'xbegin',
+'xabort',
+'xend',
+'xtest',
+'rdrand',
+'rdseed'
 );

+ 1 - 1
compiler/i386/i386nop.inc

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

+ 9 - 1
compiler/i386/i386op.inc

@@ -1025,5 +1025,13 @@ A_VFNMSUB213SD,
 A_VFNMSUB231SD,
 A_VFNMSUB132SS,
 A_VFNMSUB213SS,
-A_VFNMSUB231SS
+A_VFNMSUB231SS,
+A_XACQUIRE,
+A_XRELEASE,
+A_XBEGIN,
+A_XABORT,
+A_XEND,
+A_XTEST,
+A_RDRAND,
+A_RDSEED
 );

+ 9 - 1
compiler/i386/i386prop.inc

@@ -1025,5 +1025,13 @@
 (Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
-(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1))
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_WFlags, Ch_None, Ch_None)),
+(Ch: (Ch_Wop1, Ch_WFlags, CH_None)),
+(Ch: (Ch_Wop1, Ch_WFlags, CH_None))
 );

+ 56 - 0
compiler/i386/i386tab.inc

@@ -13600,5 +13600,61 @@
     optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
     code    : #241#242#249#1#191#61#80;
     flags   : if_fma
+  ),
+  (
+    opcode  : A_XACQUIRE;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #1#242;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XRELEASE;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #1#243;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XBEGIN;
+    ops     : 1;
+    optypes : (ot_memory,ot_none,ot_none,ot_none);
+    code    : #208#2#199#248#52;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XABORT;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #2#198#248#20;
+    flags   : if_tsx or if_sb
+  ),
+  (
+    opcode  : A_XEND;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #3#15#1#213;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XTEST;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #3#15#1#214;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_RDRAND;
+    ops     : 1;
+    optypes : (ot_reg16 or ot_bits32 or ot_bits64,ot_none,ot_none,ot_none);
+    code    : #208#2#15#199#134;
+    flags   : if_rand
+  ),
+  (
+    opcode  : A_RDSEED;
+    ops     : 1;
+    optypes : (ot_reg16 or ot_bits32 or ot_bits64,ot_none,ot_none,ot_none);
+    code    : #208#2#15#199#135;
+    flags   : if_rand
   )
 );

+ 9 - 1
compiler/i8086/i8086att.inc

@@ -1039,5 +1039,13 @@
 'vfnmsub231sd',
 'vfnmsub132ss',
 'vfnmsub213ss',
-'vfnmsub231ss'
+'vfnmsub231ss',
+'xacquire',
+'xrelease',
+'xbegin',
+'xabort',
+'xend',
+'xtest',
+'rdrand',
+'rdseed'
 );

+ 8 - 0
compiler/i8086/i8086atts.inc

@@ -1039,5 +1039,13 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufINT,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
 attsufNONE
 );

+ 9 - 1
compiler/i8086/i8086int.inc

@@ -1039,5 +1039,13 @@
 'vfnmsub231sd',
 'vfnmsub132ss',
 'vfnmsub213ss',
-'vfnmsub231ss'
+'vfnmsub231ss',
+'xacquire',
+'xrelease',
+'xbegin',
+'xabort',
+'xend',
+'xtest',
+'rdrand',
+'rdseed'
 );

+ 1 - 1
compiler/i8086/i8086nop.inc

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

+ 9 - 1
compiler/i8086/i8086op.inc

@@ -1039,5 +1039,13 @@ A_VFNMSUB213SD,
 A_VFNMSUB231SD,
 A_VFNMSUB132SS,
 A_VFNMSUB213SS,
-A_VFNMSUB231SS
+A_VFNMSUB231SS,
+A_XACQUIRE,
+A_XRELEASE,
+A_XBEGIN,
+A_XABORT,
+A_XEND,
+A_XTEST,
+A_RDRAND,
+A_RDSEED
 );

+ 9 - 1
compiler/i8086/i8086prop.inc

@@ -1039,5 +1039,13 @@
 (Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
-(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1))
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_WFlags, Ch_None, Ch_None)),
+(Ch: (Ch_Wop1, Ch_WFlags, CH_None)),
+(Ch: (Ch_Wop1, Ch_WFlags, CH_None))
 );

+ 56 - 0
compiler/i8086/i8086tab.inc

@@ -13824,5 +13824,61 @@
     optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
     code    : #241#242#249#1#191#61#80;
     flags   : if_fma
+  ),
+  (
+    opcode  : A_XACQUIRE;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #1#242;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XRELEASE;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #1#243;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XBEGIN;
+    ops     : 1;
+    optypes : (ot_memory,ot_none,ot_none,ot_none);
+    code    : #208#2#199#248#52;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XABORT;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #2#198#248#20;
+    flags   : if_tsx or if_sb
+  ),
+  (
+    opcode  : A_XEND;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #3#15#1#213;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XTEST;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #3#15#1#214;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_RDRAND;
+    ops     : 1;
+    optypes : (ot_reg16 or ot_bits32 or ot_bits64,ot_none,ot_none,ot_none);
+    code    : #208#2#15#199#134;
+    flags   : if_rand
+  ),
+  (
+    opcode  : A_RDSEED;
+    ops     : 1;
+    optypes : (ot_reg16 or ot_bits32 or ot_bits64,ot_none,ot_none,ot_none);
+    code    : #208#2#15#199#135;
+    flags   : if_rand
   )
 );

+ 2 - 0
compiler/x86/aasmcpu.pas

@@ -447,6 +447,8 @@ implementation
        IF_16BITONLY = $00200000;
        IF_FMA    = $00200000;
        IF_FMA4   = $00200000;
+       IF_TSX    = $00200000;
+       IF_RAND   = $00200000;
 
        IF_PLEVEL = $0F000000;  { mask for processor level }
        IF_8086   = $00000000;  { 8086 instruction  }

+ 4 - 2
compiler/x86/rax86.pas

@@ -68,9 +68,9 @@ type
   end;
 
 const
-  AsmPrefixes = 6{$ifdef i8086}+2{$endif i8086};
+  AsmPrefixes = 8{$ifdef i8086}+2{$endif i8086};
   AsmPrefix : array[0..AsmPrefixes-1] of TasmOP =(
-    A_LOCK,A_REP,A_REPE,A_REPNE,A_REPNZ,A_REPZ{$ifdef i8086},A_REPC,A_REPNC{$endif i8086}
+    A_LOCK,A_REP,A_REPE,A_REPNE,A_REPNZ,A_REPZ,A_XACQUIRE,A_XRELEASE{$ifdef i8086},A_REPC,A_REPNC{$endif i8086}
   );
 
   AsmOverrides = 6;
@@ -1092,6 +1092,8 @@ begin
     begin
       if (ops=1) and (opcode=A_INT) then
         siz:=S_B;
+      if (ops=1) and (opcode=A_XABORT) then
+        siz:=S_B;
 {$ifdef i8086}
       if (ops=1) and (opcode=A_BRKEM) then
         siz:=S_B;

+ 38 - 0
compiler/x86/x86ins.dat

@@ -5372,3 +5372,41 @@ xmmreg,xmmreg,xmmrm                  \361\362\371\1\xAF\75\120            FMA
 (Ch_Mop3, Ch_Rop2, Ch_Rop1)
 xmmreg,xmmreg,xmmrm                  \361\362\371\1\xBF\75\120            FMA
 
+;*******************************************************************************
+;********** TSX ****************************************************************
+;*******************************************************************************
+[XACQUIRE]
+(Ch_None, Ch_None, Ch_None)
+void                                 \1\xF2                               TSX
+
+[XRELEASE]
+(Ch_None, Ch_None, Ch_None)
+void                                 \1\xF3                               TSX
+
+[XBEGIN,xbeginX]
+(Ch_None, Ch_None, Ch_None)
+mem                                  \320\2\xC7\xF8\64                    TSX
+; mem|short                           \324\2\xC7\xF8\64                     TSX - Make correct xbeginW opcode and offset, but offset is 4 bytes long (need 2 bytes)
+
+[XABORT]
+(Ch_All, Ch_None, Ch_None)
+imm                                  \2\xC6\xF8\24                        TSX,SB
+
+[XEND]
+(Ch_None, Ch_None, Ch_None)
+void                                 \3\x0F\x01\xD5                       TSX
+
+[XTEST]
+(Ch_WFlags, Ch_None, Ch_None)
+void                                 \3\x0F\x01\xD6                       TSX
+
+;*******************************************************************************
+;********** RAND ***************************************************************
+;*******************************************************************************
+[RDRAND]
+(Ch_Wop1, Ch_WFlags, CH_None)
+reg16|32|64                          \320\2\x0F\xC7\206                   RAND
+
+[RDSEED]
+(Ch_Wop1, Ch_WFlags, CH_None)
+reg16|32|64                          \320\2\x0F\xC7\207                   RAND

+ 8 - 0
compiler/x86_64/x8664ats.inc

@@ -1019,5 +1019,13 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufINT,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
 attsufNONE
 );

+ 9 - 1
compiler/x86_64/x8664att.inc

@@ -1019,5 +1019,13 @@
 'vfnmsub231sd',
 'vfnmsub132ss',
 'vfnmsub213ss',
-'vfnmsub231ss'
+'vfnmsub231ss',
+'xacquire',
+'xrelease',
+'xbegin',
+'xabort',
+'xend',
+'xtest',
+'rdrand',
+'rdseed'
 );

+ 9 - 1
compiler/x86_64/x8664int.inc

@@ -1019,5 +1019,13 @@
 'vfnmsub231sd',
 'vfnmsub132ss',
 'vfnmsub213ss',
-'vfnmsub231ss'
+'vfnmsub231ss',
+'xacquire',
+'xrelease',
+'xbegin',
+'xabort',
+'xend',
+'xtest',
+'rdrand',
+'rdseed'
 );

+ 1 - 1
compiler/x86_64/x8664nop.inc

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

+ 9 - 1
compiler/x86_64/x8664op.inc

@@ -1019,5 +1019,13 @@ A_VFNMSUB213SD,
 A_VFNMSUB231SD,
 A_VFNMSUB132SS,
 A_VFNMSUB213SS,
-A_VFNMSUB231SS
+A_VFNMSUB231SS,
+A_XACQUIRE,
+A_XRELEASE,
+A_XBEGIN,
+A_XABORT,
+A_XEND,
+A_XTEST,
+A_RDRAND,
+A_RDSEED
 );

+ 9 - 1
compiler/x86_64/x8664pro.inc

@@ -1019,5 +1019,13 @@
 (Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
-(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1))
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_None, Ch_None, Ch_None)),
+(Ch: (Ch_WFlags, Ch_None, Ch_None)),
+(Ch: (Ch_Wop1, Ch_WFlags, CH_None)),
+(Ch: (Ch_Wop1, Ch_WFlags, CH_None))
 );

+ 56 - 0
compiler/x86_64/x8664tab.inc

@@ -13747,5 +13747,61 @@
     optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
     code    : #241#242#249#1#191#61#80;
     flags   : if_fma
+  ),
+  (
+    opcode  : A_XACQUIRE;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #1#242;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XRELEASE;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #1#243;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XBEGIN;
+    ops     : 1;
+    optypes : (ot_memory,ot_none,ot_none,ot_none);
+    code    : #208#2#199#248#52;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XABORT;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #2#198#248#20;
+    flags   : if_tsx or if_sb
+  ),
+  (
+    opcode  : A_XEND;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #3#15#1#213;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_XTEST;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #3#15#1#214;
+    flags   : if_tsx
+  ),
+  (
+    opcode  : A_RDRAND;
+    ops     : 1;
+    optypes : (ot_reg16 or ot_bits32 or ot_bits64,ot_none,ot_none,ot_none);
+    code    : #208#2#15#199#134;
+    flags   : if_rand
+  ),
+  (
+    opcode  : A_RDSEED;
+    ops     : 1;
+    optypes : (ot_reg16 or ot_bits32 or ot_bits64,ot_none,ot_none,ot_none);
+    code    : #208#2#15#199#135;
+    flags   : if_rand
   )
 );

+ 71 - 0
tests/webtbs/tw29893.pp

@@ -0,0 +1,71 @@
+{ %CPU=i386,x86_64 }
+{ %norun }
+
+const
+{$ifdef CPUX86_64}
+  expected_code : array[0..44] of byte = ($f2,$f0,$87,$00,
+                                          $f3,$f0,$87,$00,
+                                          $c7,$f8,$00,$00,$00,$00,
+                                          $c6,$f8,$01,
+                                          $0f,$01,$d5,
+                                          $0f,$01,$d6,
+                                          $66,$0f,$c7,$f0,
+                                          $0f,$c7,$f3,
+                                          $49,$0f,$c7,$f4,
+                                          $66,$0f,$c7,$f8,
+                                          $0f,$c7,$fb,
+                                          $49,$0f,$c7,$fc);
+{$else CPUX86_64}
+  expected_code : array[0..36] of byte = ($f2,$f0,$87,$00,
+                                          $f3,$f0,$87,$00,
+                                          $c7,$f8,$00,$00,$00,$00,
+                                          $c6,$f8,$01,
+                                          $0f,$01,$d5,
+                                          $0f,$01,$d6,
+                                          $66,$0f,$c7,$f0,
+                                          $0f,$c7,$f3,
+                                          $66,$0f,$c7,$f8,
+                                          $0f,$c7,$fb);
+
+{$endif CPUX86_64}
+
+procedure proc;assembler;nostackframe;
+  asm
+{$ifdef CPUX86_64}
+    xacquire lock xchgl (%rax),%eax
+    xrelease lock xchgl (%rax),%eax
+{$else CPUX86_64}
+    xacquire lock xchgl (%eax),%eax
+    xrelease lock xchgl (%eax),%eax
+{$endif CPUX86_64}
+    xbegin .L1
+.L1:
+    xabort $1
+    xend
+    xtest
+    rdrand  %ax
+    rdrand  %ebx
+{$ifdef CPUX86_64}
+    rdrand  %r12
+{$endif CPUX86_64}
+    rdseed  %ax
+    rdseed  %ebx
+{$ifdef CPUX86_64}
+    rdseed  %r12
+{$endif CPUX86_64}
+   end;
+
+
+var
+  P : pointer;
+  i : integer;
+
+begin
+  for i:=0 to high(expected_code) do
+    if (pbyte(@proc)+i)^<>expected_code[i] then
+      begin
+        writeln('Error at pos ',i,'. Expected $',hexstr(expected_code[i],2),' got $',hexstr((pbyte(@proc)+i)^,2));
+        halt(1);
+      end;
+  writeln('ok');
+end.