diff --git a/.gitattributes b/.gitattributes index e28869d650..0244088af6 100644 --- a/.gitattributes +++ b/.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 diff --git a/compiler/i386/i386att.inc b/compiler/i386/i386att.inc index 0f46d3bb3f..12a35b45e1 100644 --- a/compiler/i386/i386att.inc +++ b/compiler/i386/i386att.inc @@ -1025,5 +1025,13 @@ 'vfnmsub231sd', 'vfnmsub132ss', 'vfnmsub213ss', -'vfnmsub231ss' +'vfnmsub231ss', +'xacquire', +'xrelease', +'xbegin', +'xabort', +'xend', +'xtest', +'rdrand', +'rdseed' ); diff --git a/compiler/i386/i386atts.inc b/compiler/i386/i386atts.inc index e49fdb5316..69e2029915 100644 --- a/compiler/i386/i386atts.inc +++ b/compiler/i386/i386atts.inc @@ -1025,5 +1025,13 @@ attsufNONE, attsufNONE, attsufNONE, attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufINT, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, attsufNONE ); diff --git a/compiler/i386/i386int.inc b/compiler/i386/i386int.inc index 9fe67f5694..adc7db67b5 100644 --- a/compiler/i386/i386int.inc +++ b/compiler/i386/i386int.inc @@ -1025,5 +1025,13 @@ 'vfnmsub231sd', 'vfnmsub132ss', 'vfnmsub213ss', -'vfnmsub231ss' +'vfnmsub231ss', +'xacquire', +'xrelease', +'xbegin', +'xabort', +'xend', +'xtest', +'rdrand', +'rdseed' ); diff --git a/compiler/i386/i386nop.inc b/compiler/i386/i386nop.inc index d9b2daa0ad..c65555b17d 100644 --- a/compiler/i386/i386nop.inc +++ b/compiler/i386/i386nop.inc @@ -1,2 +1,2 @@ { don't edit, this file is generated from x86ins.dat } -1943; +1951; diff --git a/compiler/i386/i386op.inc b/compiler/i386/i386op.inc index d2c87141a5..e243021a76 100644 --- a/compiler/i386/i386op.inc +++ b/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 ); diff --git a/compiler/i386/i386prop.inc b/compiler/i386/i386prop.inc index e63108b238..ae1220dd11 100644 --- a/compiler/i386/i386prop.inc +++ b/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)) ); diff --git a/compiler/i386/i386tab.inc b/compiler/i386/i386tab.inc index d97fc4f06d..94b5a333e6 100644 --- a/compiler/i386/i386tab.inc +++ b/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 ) ); diff --git a/compiler/i8086/i8086att.inc b/compiler/i8086/i8086att.inc index cc4fdad7ec..733884ec89 100644 --- a/compiler/i8086/i8086att.inc +++ b/compiler/i8086/i8086att.inc @@ -1039,5 +1039,13 @@ 'vfnmsub231sd', 'vfnmsub132ss', 'vfnmsub213ss', -'vfnmsub231ss' +'vfnmsub231ss', +'xacquire', +'xrelease', +'xbegin', +'xabort', +'xend', +'xtest', +'rdrand', +'rdseed' ); diff --git a/compiler/i8086/i8086atts.inc b/compiler/i8086/i8086atts.inc index 058bde0884..674dec78b9 100644 --- a/compiler/i8086/i8086atts.inc +++ b/compiler/i8086/i8086atts.inc @@ -1039,5 +1039,13 @@ attsufNONE, attsufNONE, attsufNONE, attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufINT, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, attsufNONE ); diff --git a/compiler/i8086/i8086int.inc b/compiler/i8086/i8086int.inc index f1a62214e4..fa3b26c16d 100644 --- a/compiler/i8086/i8086int.inc +++ b/compiler/i8086/i8086int.inc @@ -1039,5 +1039,13 @@ 'vfnmsub231sd', 'vfnmsub132ss', 'vfnmsub213ss', -'vfnmsub231ss' +'vfnmsub231ss', +'xacquire', +'xrelease', +'xbegin', +'xabort', +'xend', +'xtest', +'rdrand', +'rdseed' ); diff --git a/compiler/i8086/i8086nop.inc b/compiler/i8086/i8086nop.inc index f36d11bb25..6d83251bac 100644 --- a/compiler/i8086/i8086nop.inc +++ b/compiler/i8086/i8086nop.inc @@ -1,2 +1,2 @@ { don't edit, this file is generated from x86ins.dat } -1975; +1983; diff --git a/compiler/i8086/i8086op.inc b/compiler/i8086/i8086op.inc index 82dfbc79ac..a85661a5e2 100644 --- a/compiler/i8086/i8086op.inc +++ b/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 ); diff --git a/compiler/i8086/i8086prop.inc b/compiler/i8086/i8086prop.inc index 4f9b9932fa..0f0d145cf6 100644 --- a/compiler/i8086/i8086prop.inc +++ b/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)) ); diff --git a/compiler/i8086/i8086tab.inc b/compiler/i8086/i8086tab.inc index f8f41b9b87..6a5c5ed480 100644 --- a/compiler/i8086/i8086tab.inc +++ b/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 ) ); diff --git a/compiler/x86/aasmcpu.pas b/compiler/x86/aasmcpu.pas index 638bd10c65..1df9a80fa4 100644 --- a/compiler/x86/aasmcpu.pas +++ b/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 } diff --git a/compiler/x86/rax86.pas b/compiler/x86/rax86.pas index c05ab6962a..5c018252bf 100644 --- a/compiler/x86/rax86.pas +++ b/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; diff --git a/compiler/x86/x86ins.dat b/compiler/x86/x86ins.dat index 92e0f84ec4..2d2a428ff5 100644 --- a/compiler/x86/x86ins.dat +++ b/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 diff --git a/compiler/x86_64/x8664ats.inc b/compiler/x86_64/x8664ats.inc index fc66dc6e9e..03faaa3bb5 100644 --- a/compiler/x86_64/x8664ats.inc +++ b/compiler/x86_64/x8664ats.inc @@ -1019,5 +1019,13 @@ attsufNONE, attsufNONE, attsufNONE, attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, +attsufINT, +attsufNONE, +attsufNONE, +attsufNONE, +attsufNONE, attsufNONE ); diff --git a/compiler/x86_64/x8664att.inc b/compiler/x86_64/x8664att.inc index cba099a823..b3dab1c8f1 100644 --- a/compiler/x86_64/x8664att.inc +++ b/compiler/x86_64/x8664att.inc @@ -1019,5 +1019,13 @@ 'vfnmsub231sd', 'vfnmsub132ss', 'vfnmsub213ss', -'vfnmsub231ss' +'vfnmsub231ss', +'xacquire', +'xrelease', +'xbegin', +'xabort', +'xend', +'xtest', +'rdrand', +'rdseed' ); diff --git a/compiler/x86_64/x8664int.inc b/compiler/x86_64/x8664int.inc index 67d2688e13..f30d908422 100644 --- a/compiler/x86_64/x8664int.inc +++ b/compiler/x86_64/x8664int.inc @@ -1019,5 +1019,13 @@ 'vfnmsub231sd', 'vfnmsub132ss', 'vfnmsub213ss', -'vfnmsub231ss' +'vfnmsub231ss', +'xacquire', +'xrelease', +'xbegin', +'xabort', +'xend', +'xtest', +'rdrand', +'rdseed' ); diff --git a/compiler/x86_64/x8664nop.inc b/compiler/x86_64/x8664nop.inc index a7c604bdc4..73f2e99cf1 100644 --- a/compiler/x86_64/x8664nop.inc +++ b/compiler/x86_64/x8664nop.inc @@ -1,2 +1,2 @@ { don't edit, this file is generated from x86ins.dat } -1964; +1972; diff --git a/compiler/x86_64/x8664op.inc b/compiler/x86_64/x8664op.inc index d6942517fa..b7709a8493 100644 --- a/compiler/x86_64/x8664op.inc +++ b/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 ); diff --git a/compiler/x86_64/x8664pro.inc b/compiler/x86_64/x8664pro.inc index 40205708e5..b79b572cbf 100644 --- a/compiler/x86_64/x8664pro.inc +++ b/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)) ); diff --git a/compiler/x86_64/x8664tab.inc b/compiler/x86_64/x8664tab.inc index 66d9da0282..a69c066168 100644 --- a/compiler/x86_64/x8664tab.inc +++ b/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 ) ); diff --git a/tests/webtbs/tw29893.pp b/tests/webtbs/tw29893.pp new file mode 100644 index 0000000000..ad5c717e46 --- /dev/null +++ b/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.