Browse Source

* disallow pusha*/popa* for x86_64 (mantis #14862)
* disallow pushfd/popfd for x86_64 (mantis #14862)
* fixed assembling popfq with the internal assembler (it needs a rex.w
prefisx, while pushfq doesn't)
* changed the default opcode size of pushf/popf/pusha/popa in
{$asmmode intel} from "native size" to 16 bit (compatible with Intel
manuals and Kylix; in AT&T mode, the default size for those operations
remains the native one)
* changed pushf/popf in rtl/i386/* into pushfd/popfd because of the
previous change

git-svn-id: trunk@15546 -

Jonas Maebe 15 years ago
parent
commit
9273856e84

+ 9 - 0
.gitattributes

@@ -9797,6 +9797,14 @@ tests/webtbf/tw14777.pp svneol=native#text/plain
 tests/webtbf/tw14777a.pp svneol=native#text/plain
 tests/webtbf/tw1483.pp svneol=native#text/plain
 tests/webtbf/tw14849.pp svneol=native#text/plain
+tests/webtbf/tw14862a.pp svneol=native#text/plain
+tests/webtbf/tw14862b.pp svneol=native#text/plain
+tests/webtbf/tw14862c.pp svneol=native#text/plain
+tests/webtbf/tw14862d.pp svneol=native#text/plain
+tests/webtbf/tw14862e.pp svneol=native#text/plain
+tests/webtbf/tw14862f.pp svneol=native#text/plain
+tests/webtbf/tw14862h.pp svneol=native#text/plain
+tests/webtbf/tw14862i.pp svneol=native#text/plain
 tests/webtbf/tw14929a.pp svneol=native#text/plain
 tests/webtbf/tw14929b.pp svneol=native#text/plain
 tests/webtbf/tw14946.pp svneol=native#text/plain
@@ -10432,6 +10440,7 @@ tests/webtbs/tw14798.pp svneol=native#text/plain
 tests/webtbs/tw14812.pp svneol=native#text/plain
 tests/webtbs/tw14841.pp svneol=native#text/plain
 tests/webtbs/tw1485.pp svneol=native#text/plain
+tests/webtbs/tw14862g.pp svneol=native#text/plain
 tests/webtbs/tw1489.pp svneol=native#text/plain
 tests/webtbs/tw14941.pp svneol=native#text/plain
 tests/webtbs/tw14941a.pp svneol=native#text/plain

+ 2 - 0
compiler/i386/i386att.inc

@@ -271,6 +271,7 @@
 'popf',
 'popfl',
 'popfw',
+'popfq',
 'por',
 'prefetch',
 'prefetchw',
@@ -304,6 +305,7 @@
 'pushf',
 'pushfl',
 'pushfw',
+'pushfq',
 'pxor',
 'rcl',
 'rcr',

+ 2 - 0
compiler/i386/i386atts.inc

@@ -272,6 +272,7 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
 attsufINT,
 attsufINT,
 attsufNONE,
@@ -305,6 +306,7 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
 attsufINT,
 attsufINT,
 attsufNONE,

+ 2 - 0
compiler/i386/i386int.inc

@@ -271,6 +271,7 @@
 'popf',
 'popfd',
 'popfw',
+'popfq',
 'por',
 'prefetch',
 'prefetchw',
@@ -304,6 +305,7 @@
 'pushf',
 'pushfd',
 'pushfw',
+'pushfq',
 'pxor',
 'rcl',
 'rcr',

+ 2 - 0
compiler/i386/i386op.inc

@@ -271,6 +271,7 @@ A_POPAW,
 A_POPF,
 A_POPFD,
 A_POPFW,
+A_POPFQ,
 A_POR,
 A_PREFETCH,
 A_PREFETCHW,
@@ -304,6 +305,7 @@ A_PUSHAW,
 A_PUSHF,
 A_PUSHFD,
 A_PUSHFW,
+A_PUSHFQ,
 A_PXOR,
 A_RCL,
 A_RCR,

+ 2 - 0
compiler/i386/i386prop.inc

@@ -271,6 +271,7 @@
 (Ch: (Ch_RWESP, Ch_WFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_WFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_WFLAGS, Ch_None)),
+(Ch: (Ch_RWESP, Ch_WFlags, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -304,6 +305,7 @@
 (Ch: (Ch_RWESP, Ch_RFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_RFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_RFLAGS, Ch_None)),
+(Ch: (Ch_RWESP, Ch_RFlags, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_RWFlags)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_RWFlags)),

+ 10 - 10
compiler/i386/i386tab.inc

@@ -4527,42 +4527,42 @@
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
     code    : #215#1#97;
-    flags   : if_186
+    flags   : if_186 or if_nox86_64
   ),
   (
     opcode  : A_POPAD;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
     code    : #213#1#97;
-    flags   : if_386
+    flags   : if_386 or if_nox86_64
   ),
   (
     opcode  : A_POPAW;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
     code    : #212#1#97;
-    flags   : if_186
+    flags   : if_186 or if_nox86_64
   ),
   (
     opcode  : A_POPF;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
     code    : #215#1#157;
-    flags   : if_186
+    flags   : if_186 or if_nox86_64
   ),
   (
     opcode  : A_POPFD;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
     code    : #213#1#157;
-    flags   : if_386
+    flags   : if_386 or if_nox86_64
   ),
   (
     opcode  : A_POPFW;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
     code    : #212#1#157;
-    flags   : if_186
+    flags   : if_186 or if_nox86_64
   ),
   (
     opcode  : A_POR;
@@ -5381,21 +5381,21 @@
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
     code    : #215#1#96;
-    flags   : if_186
+    flags   : if_186 or if_nox86_64
   ),
   (
     opcode  : A_PUSHAD;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
     code    : #213#1#96;
-    flags   : if_386
+    flags   : if_386 or if_nox86_64
   ),
   (
     opcode  : A_PUSHAW;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
     code    : #212#1#96;
-    flags   : if_186
+    flags   : if_186 or if_nox86_64
   ),
   (
     opcode  : A_PUSHF;
@@ -5409,7 +5409,7 @@
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
     code    : #213#1#156;
-    flags   : if_386
+    flags   : if_386 or if_nox86_64
   ),
   (
     opcode  : A_PUSHFW;

+ 12 - 0
compiler/x86/rax86int.pas

@@ -1929,6 +1929,18 @@ Unit Rax86int;
             if (overrideop<>A_NONE) and (NOT CheckOverride(OverrideOp,ActOpcode)) then
               Message1(asmr_e_invalid_override_and_opcode,actasmpattern);
           end;
+        { pushf/popf/pusha/popa have to default to 16 bit in Intel mode
+          (Intel manual and Delphi-compatbile) -- setting the opsize for
+          these instructions doesn't change anything in the internal assember,
+          so change the opcode }
+        if (instr.opcode=A_POPF) then
+          instr.opcode:=A_POPFW
+        else if (instr.opcode=A_PUSHF) then
+          instr.opcode:=A_PUSHFW
+        else if (instr.opcode=A_PUSHA) then
+          instr.opcode:=A_PUSHAW
+        else if (instr.opcode=A_POPA) then
+          instr.opcode:=A_POPAW;
         { We are reading operands, so opcode will be an AS_ID }
         operandnum:=1;
         is_far_const:=false;

+ 20 - 10
compiler/x86/x86ins.dat

@@ -1468,27 +1468,33 @@ reg_fsgs              \1\x0F\5\335                    386
 
 [POPA,popaX]
 (Ch_All, Ch_None, Ch_None)
-void                  \327\1\x61                      186
+void                  \327\1\x61                      186,NOX86_64
 
 [POPAD,popal]
 (Ch_All, Ch_None, Ch_None)
-void                  \325\1\x61                      386
+void                  \325\1\x61                      386,NOX86_64
 
 [POPAW]
 (Ch_All, Ch_None, Ch_None)
-void                  \324\1\x61                      186
+void                  \324\1\x61                      186,NOX86_64
 
 [POPF]
 (Ch_RWESP, Ch_WFlags, Ch_None)
-void                  \327\1\x9D                      186
+void                  \327\1\x9D                      186,NOX86_64
+void                  \2\x48\x9D                      X86_64
 
 [POPFD,popfl]
 (Ch_RWESP, Ch_WFlags, Ch_None)
-void                  \325\1\x9D                      386
+void                  \325\1\x9D                      386,NOX86_64
 
 [POPFW]
 (Ch_RWESP, Ch_WFLAGS, Ch_None)
-void                  \324\1\x9D                      186
+void                  \324\1\x9D                      186,NOX86_64
+void                  \1\x9D                          X86_64
+
+[POPFQ]
+(Ch_RWESP, Ch_WFlags, Ch_None)
+void                  \2\x48\x9D                      X86_64
 
 [POR]
 (Ch_All, Ch_None, Ch_None)
@@ -1689,15 +1695,15 @@ reg_sreg              \6                              8086,NOX86_64
 
 [PUSHA,pushaX]
 (Ch_All, Ch_None, Ch_None)
-void                  \327\1\x60                      186
+void                  \327\1\x60                      186,NOX86_64
 
 [PUSHAD,pushal]
 (Ch_All, Ch_None, Ch_None)
-void                  \325\1\x60                      386
+void                  \325\1\x60                      386,NOX86_64
 
 [PUSHAW]
 (Ch_All, Ch_None, Ch_None)
-void                  \324\1\x60                      186
+void                  \324\1\x60                      186,NOX86_64
 
 [PUSHF]
 (Ch_RWESP, Ch_RFlags, Ch_None)
@@ -1705,12 +1711,16 @@ void                  \327\1\x9C                      186
 
 [PUSHFD,pushfl]
 (Ch_RWESP, Ch_RFlags, Ch_None)
-void                  \325\1\x9C                      386
+void                  \325\1\x9C                      386,NOX86_64
 
 [PUSHFW]
 (Ch_RWESP, Ch_RFLAGS, Ch_None)
 void                  \324\1\x9C                      186
 
+[PUSHFQ]
+(Ch_RWESP, Ch_RFlags, Ch_None)
+void                  \2\x48\x9C                      X86_64
+
 [PXOR]
 (Ch_Mop2, Ch_Rop1, Ch_None)
 mmxreg,mem            \301\2\x0F\xEF\110              PENT,MMX,SM

+ 2 - 0
compiler/x86_64/x8664ats.inc

@@ -272,6 +272,7 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
 attsufINT,
 attsufINT,
 attsufNONE,
@@ -305,6 +306,7 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
 attsufINT,
 attsufINT,
 attsufNONE,

+ 2 - 0
compiler/x86_64/x8664att.inc

@@ -271,6 +271,7 @@
 'popf',
 'popfl',
 'popfw',
+'popfq',
 'por',
 'prefetch',
 'prefetchw',
@@ -304,6 +305,7 @@
 'pushf',
 'pushfl',
 'pushfw',
+'pushfq',
 'pxor',
 'rcl',
 'rcr',

+ 2 - 0
compiler/x86_64/x8664int.inc

@@ -271,6 +271,7 @@
 'popf',
 'popfd',
 'popfw',
+'popfq',
 'por',
 'prefetch',
 'prefetchw',
@@ -304,6 +305,7 @@
 'pushf',
 'pushfd',
 'pushfw',
+'pushfq',
 'pxor',
 'rcl',
 'rcr',

+ 1 - 1
compiler/x86_64/x8664nop.inc

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

+ 2 - 0
compiler/x86_64/x8664op.inc

@@ -271,6 +271,7 @@ A_POPAW,
 A_POPF,
 A_POPFD,
 A_POPFW,
+A_POPFQ,
 A_POR,
 A_PREFETCH,
 A_PREFETCHW,
@@ -304,6 +305,7 @@ A_PUSHAW,
 A_PUSHF,
 A_PUSHFD,
 A_PUSHFW,
+A_PUSHFQ,
 A_PXOR,
 A_RCL,
 A_RCR,

+ 2 - 0
compiler/x86_64/x8664pro.inc

@@ -271,6 +271,7 @@
 (Ch: (Ch_RWESP, Ch_WFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_WFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_WFLAGS, Ch_None)),
+(Ch: (Ch_RWESP, Ch_WFlags, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -304,6 +305,7 @@
 (Ch: (Ch_RWESP, Ch_RFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_RFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_RFLAGS, Ch_None)),
+(Ch: (Ch_RWESP, Ch_RFlags, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_RWFlags)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_RWFlags)),

+ 14 - 56
compiler/x86_64/x8664tab.inc

@@ -4480,47 +4480,26 @@
     code    : #1#15#5#221;
     flags   : if_386
   ),
-  (
-    opcode  : A_POPA;
-    ops     : 0;
-    optypes : (ot_none,ot_none,ot_none);
-    code    : #215#1#97;
-    flags   : if_186
-  ),
-  (
-    opcode  : A_POPAD;
-    ops     : 0;
-    optypes : (ot_none,ot_none,ot_none);
-    code    : #213#1#97;
-    flags   : if_386
-  ),
-  (
-    opcode  : A_POPAW;
-    ops     : 0;
-    optypes : (ot_none,ot_none,ot_none);
-    code    : #212#1#97;
-    flags   : if_186
-  ),
   (
     opcode  : A_POPF;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
-    code    : #215#1#157;
-    flags   : if_186
+    code    : #2#72#157;
+    flags   : if_x86_64
   ),
   (
-    opcode  : A_POPFD;
+    opcode  : A_POPFW;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
-    code    : #213#1#157;
-    flags   : if_386
+    code    : #1#157;
+    flags   : if_x86_64
   ),
   (
-    opcode  : A_POPFW;
+    opcode  : A_POPFQ;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
-    code    : #212#1#157;
-    flags   : if_186
+    code    : #2#72#157;
+    flags   : if_x86_64
   ),
   (
     opcode  : A_POR;
@@ -5320,27 +5299,6 @@
     code    : #1#106#12#221;
     flags   : if_286
   ),
-  (
-    opcode  : A_PUSHA;
-    ops     : 0;
-    optypes : (ot_none,ot_none,ot_none);
-    code    : #215#1#96;
-    flags   : if_186
-  ),
-  (
-    opcode  : A_PUSHAD;
-    ops     : 0;
-    optypes : (ot_none,ot_none,ot_none);
-    code    : #213#1#96;
-    flags   : if_386
-  ),
-  (
-    opcode  : A_PUSHAW;
-    ops     : 0;
-    optypes : (ot_none,ot_none,ot_none);
-    code    : #212#1#96;
-    flags   : if_186
-  ),
   (
     opcode  : A_PUSHF;
     ops     : 0;
@@ -5349,18 +5307,18 @@
     flags   : if_186
   ),
   (
-    opcode  : A_PUSHFD;
+    opcode  : A_PUSHFW;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
-    code    : #213#1#156;
-    flags   : if_386
+    code    : #212#1#156;
+    flags   : if_186
   ),
   (
-    opcode  : A_PUSHFW;
+    opcode  : A_PUSHFQ;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none);
-    code    : #212#1#156;
-    flags   : if_186
+    code    : #2#72#156;
+    flags   : if_x86_64
   ),
   (
     opcode  : A_PXOR;

+ 5 - 5
rtl/i386/cpu.pp

@@ -38,16 +38,16 @@ unit cpu;
       }
       asm
          push    ebx
-         pushf
-         pushf
+         pushfd
+         pushfd
          pop     eax
          mov     ebx,eax
          xor     eax,200000h
          push    eax
-         popf
-         pushf
+         popfd
+         pushfd
          pop     eax
-         popf
+         popfd
          and     eax,200000h
          and     ebx,200000h
          cmp     eax,ebx

+ 5 - 5
rtl/i386/i386.inc

@@ -31,16 +31,16 @@ function cpuid_support : boolean;assembler;
   }
   asm
     push   ebx
-    pushf
-    pushf
+    pushfd
+    pushfd
     pop     eax
     mov     ebx,eax
     xor     eax,200000h
     push    eax
-    popf
-    pushf
+    popfd
+    pushfd
     pop     eax
-    popf
+    popfd
     and     eax,200000h
     and     ebx,200000h
     cmp     eax,ebx

+ 10 - 0
tests/webtbf/tw14862a.pp

@@ -0,0 +1,10 @@
+{ %cpu=x86_64 }
+{ %fail }
+
+{$asmmode intel}
+
+begin
+  asm
+    pusha
+  end;
+end.

+ 10 - 0
tests/webtbf/tw14862b.pp

@@ -0,0 +1,10 @@
+{ %cpu=x86_64 }
+{ %fail }
+
+{$asmmode intel}
+
+begin
+  asm
+    pushad
+  end;
+end.

+ 10 - 0
tests/webtbf/tw14862c.pp

@@ -0,0 +1,10 @@
+{ %cpu=x86_64 }
+{ %fail }
+
+{$asmmode intel}
+
+begin
+  asm
+    pushaq
+  end;
+end.

+ 10 - 0
tests/webtbf/tw14862d.pp

@@ -0,0 +1,10 @@
+{ %cpu=x86_64 }
+{ %fail }
+
+{$asmmode intel}
+
+begin
+  asm
+    popa
+  end;
+end.

+ 10 - 0
tests/webtbf/tw14862e.pp

@@ -0,0 +1,10 @@
+{ %cpu=x86_64 }
+{ %fail }
+
+{$asmmode intel}
+
+begin
+  asm
+    popad
+  end;
+end.

+ 10 - 0
tests/webtbf/tw14862f.pp

@@ -0,0 +1,10 @@
+{ %cpu=x86_64 }
+{ %fail }
+
+{$asmmode intel}
+
+begin
+  asm
+    popaq
+  end;
+end.

+ 10 - 0
tests/webtbf/tw14862h.pp

@@ -0,0 +1,10 @@
+{ %cpu=x86_64 }
+{ %fail }
+
+{$asmmode intel}
+
+begin
+  asm
+    pushfd
+  end;
+end.

+ 10 - 0
tests/webtbf/tw14862i.pp

@@ -0,0 +1,10 @@
+{ %cpu=x86_64 }
+{ %fail }
+
+{$asmmode intel}
+
+begin
+  asm
+    popfd
+  end;
+end.

+ 60 - 0
tests/webtbs/tw14862g.pp

@@ -0,0 +1,60 @@
+{ %cpu=x86_64 }
+{ %opt=-Cg- }
+
+
+var
+  f1, f2, f3: int64;
+begin
+{$asmmode att}
+  asm
+    // set alignment check flag so at least one flag in the upper 16 bits
+    // is set
+    pushfq
+    popq %rax
+    orq $(1 << 18), %rax
+    pushq %rax
+    popfq
+
+    // should be same as pushfq in AT&T mode
+    xorq %rax, %rax
+    pushfw
+    popw %ax
+    movq %rax, f1(%rip)
+    pushf
+    popq %rax
+    movq %rax, f2(%rip)
+    pushfq
+    popq %rax
+    movq %rax, f3(%rip)
+  end;
+  if (f1 > high(word)) then
+    halt(1);
+  if (f2 < high(word)) or
+     ((f2 and high(word))<>f1) then
+    halt(2);
+  if (f3 <> f2) then
+    halt(3);
+  f1:=0;
+  f2:=0;
+{$asmmode intel}
+  asm
+    // should be same as pushfw in Intel mode
+    xor rax, rax
+    pushf
+    pop ax
+    mov [f1 + rip], rax
+    pushfq
+    pop rax
+    mov [f2 + rip], rax
+
+    // clear alignment check flag again to be safe
+    and rax, not(1 shl 18)
+    push rax
+    popfq
+  end;
+  if (f1 > high(word)) then
+    halt(4);
+  if (f2 < high(word)) or
+     ((f2 and high(word))<>f1) then
+    halt(5);
+end.