Browse Source

+ added support for the retw, retnw, retfw, retd, retnd, retfd, retq, retnq and
retfq x86 instructions. These are variants of the ret instruction with the
return offset size set explicitly, e.g. retfw is a 16-bit far ret (i.e. pops
a 16-bit offset and a 16-bit segment), retfd is a 32-bit far ret (pops a
32-bit offset, followed by a 16-bit segment), etc.

git-svn-id: trunk@37571 -

nickysn 7 years ago
parent
commit
ae92973196

+ 2 - 0
.gitattributes

@@ -12434,6 +12434,8 @@ tests/test/tasm14c.pp svneol=native#text/plain
 tests/test/tasm14d.pp svneol=native#text/plain
 tests/test/tasm14e.pp svneol=native#text/plain
 tests/test/tasm14f.pp svneol=native#text/plain
+tests/test/tasm15.pp svneol=native#text/plain
+tests/test/tasm15a.pp svneol=native#text/plain
 tests/test/tasm2.inc svneol=native#text/plain
 tests/test/tasm2.pp svneol=native#text/plain
 tests/test/tasm2a.pp svneol=native#text/plain

+ 6 - 0
compiler/i386/i386att.inc

@@ -317,6 +317,12 @@
 'ret',
 'lret',
 'ret',
+'retw',
+'lretw',
+'retw',
+'ret',
+'lret',
+'ret',
 'rol',
 'ror',
 'rsdc',

+ 6 - 0
compiler/i386/i386atts.inc

@@ -317,6 +317,12 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
 attsufINT,
 attsufINT,
 attsufNONE,

+ 6 - 0
compiler/i386/i386int.inc

@@ -317,6 +317,12 @@
 'ret',
 'retf',
 'retn',
+'retw',
+'retfw',
+'retnw',
+'retd',
+'retfd',
+'retnd',
 'rol',
 'ror',
 'rsdc',

+ 1 - 1
compiler/i386/i386nop.inc

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

+ 6 - 0
compiler/i386/i386op.inc

@@ -317,6 +317,12 @@ A_REPZ,
 A_RET,
 A_RETF,
 A_RETN,
+A_RETW,
+A_RETFW,
+A_RETNW,
+A_RETD,
+A_RETFD,
+A_RETND,
 A_ROL,
 A_ROR,
 A_RSDC,

+ 6 - 0
compiler/i386/i386prop.inc

@@ -317,6 +317,12 @@
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WCarryFlag, Ch_WOverflowFlag]),
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WCarryFlag, Ch_WOverflowFlag]),
 (Ch: [Ch_All]),

+ 90 - 6
compiler/i386/i386tab.inc

@@ -4750,44 +4750,128 @@
     opcode  : A_RET;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none,ot_none);
-    code    : #1#195;
+    code    : #215#1#195;
     flags   : [if_8086]
   ),
   (
     opcode  : A_RET;
     ops     : 1;
     optypes : (ot_immediate,ot_none,ot_none,ot_none);
-    code    : #1#194#24;
+    code    : #215#1#194#24;
     flags   : [if_8086,if_sw]
   ),
   (
     opcode  : A_RETF;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none,ot_none);
-    code    : #1#203;
+    code    : #215#1#203;
     flags   : [if_8086]
   ),
   (
     opcode  : A_RETF;
     ops     : 1;
     optypes : (ot_immediate,ot_none,ot_none,ot_none);
-    code    : #1#202#24;
+    code    : #215#1#202#24;
     flags   : [if_8086,if_sw]
   ),
   (
     opcode  : A_RETN;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none,ot_none);
-    code    : #1#195;
+    code    : #215#1#195;
     flags   : [if_8086]
   ),
   (
     opcode  : A_RETN;
     ops     : 1;
     optypes : (ot_immediate,ot_none,ot_none,ot_none);
-    code    : #1#194#24;
+    code    : #215#1#194#24;
     flags   : [if_8086,if_sw]
   ),
+  (
+    opcode  : A_RETW;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #212#1#195;
+    flags   : [if_8086]
+  ),
+  (
+    opcode  : A_RETW;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #212#1#194#24;
+    flags   : [if_8086,if_sw]
+  ),
+  (
+    opcode  : A_RETFW;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #212#1#203;
+    flags   : [if_8086]
+  ),
+  (
+    opcode  : A_RETFW;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #212#1#202#24;
+    flags   : [if_8086,if_sw]
+  ),
+  (
+    opcode  : A_RETNW;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #212#1#195;
+    flags   : [if_8086]
+  ),
+  (
+    opcode  : A_RETNW;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #212#1#194#24;
+    flags   : [if_8086,if_sw]
+  ),
+  (
+    opcode  : A_RETD;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #213#1#195;
+    flags   : [if_386,if_nox86_64]
+  ),
+  (
+    opcode  : A_RETD;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #213#1#194#24;
+    flags   : [if_386,if_sw,if_nox86_64]
+  ),
+  (
+    opcode  : A_RETFD;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #213#1#203;
+    flags   : [if_386]
+  ),
+  (
+    opcode  : A_RETFD;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #213#1#202#24;
+    flags   : [if_386,if_sw]
+  ),
+  (
+    opcode  : A_RETND;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #213#1#195;
+    flags   : [if_386,if_nox86_64]
+  ),
+  (
+    opcode  : A_RETND;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #213#1#194#24;
+    flags   : [if_386,if_sw,if_nox86_64]
+  ),
   (
     opcode  : A_ROL;
     ops     : 2;

+ 6 - 0
compiler/i8086/i8086att.inc

@@ -317,6 +317,12 @@
 'ret',
 'lret',
 'ret',
+'retw',
+'lretw',
+'retw',
+'ret',
+'lret',
+'ret',
 'rol',
 'ror',
 'rsdc',

+ 6 - 0
compiler/i8086/i8086atts.inc

@@ -317,6 +317,12 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
 attsufINT,
 attsufINT,
 attsufNONE,

+ 6 - 0
compiler/i8086/i8086int.inc

@@ -317,6 +317,12 @@
 'ret',
 'retf',
 'retn',
+'retw',
+'retfw',
+'retnw',
+'retd',
+'retfd',
+'retnd',
 'rol',
 'ror',
 'rsdc',

+ 1 - 1
compiler/i8086/i8086nop.inc

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

+ 6 - 0
compiler/i8086/i8086op.inc

@@ -317,6 +317,12 @@ A_REPZ,
 A_RET,
 A_RETF,
 A_RETN,
+A_RETW,
+A_RETFW,
+A_RETNW,
+A_RETD,
+A_RETFD,
+A_RETND,
 A_ROL,
 A_ROR,
 A_RSDC,

+ 6 - 0
compiler/i8086/i8086prop.inc

@@ -317,6 +317,12 @@
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WCarryFlag, Ch_WOverflowFlag]),
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WCarryFlag, Ch_WOverflowFlag]),
 (Ch: [Ch_All]),

+ 90 - 6
compiler/i8086/i8086tab.inc

@@ -4764,44 +4764,128 @@
     opcode  : A_RET;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none,ot_none);
-    code    : #1#195;
+    code    : #215#1#195;
     flags   : [if_8086]
   ),
   (
     opcode  : A_RET;
     ops     : 1;
     optypes : (ot_immediate,ot_none,ot_none,ot_none);
-    code    : #1#194#24;
+    code    : #215#1#194#24;
     flags   : [if_8086,if_sw]
   ),
   (
     opcode  : A_RETF;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none,ot_none);
-    code    : #1#203;
+    code    : #215#1#203;
     flags   : [if_8086]
   ),
   (
     opcode  : A_RETF;
     ops     : 1;
     optypes : (ot_immediate,ot_none,ot_none,ot_none);
-    code    : #1#202#24;
+    code    : #215#1#202#24;
     flags   : [if_8086,if_sw]
   ),
   (
     opcode  : A_RETN;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none,ot_none);
-    code    : #1#195;
+    code    : #215#1#195;
     flags   : [if_8086]
   ),
   (
     opcode  : A_RETN;
     ops     : 1;
     optypes : (ot_immediate,ot_none,ot_none,ot_none);
-    code    : #1#194#24;
+    code    : #215#1#194#24;
     flags   : [if_8086,if_sw]
   ),
+  (
+    opcode  : A_RETW;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #212#1#195;
+    flags   : [if_8086]
+  ),
+  (
+    opcode  : A_RETW;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #212#1#194#24;
+    flags   : [if_8086,if_sw]
+  ),
+  (
+    opcode  : A_RETFW;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #212#1#203;
+    flags   : [if_8086]
+  ),
+  (
+    opcode  : A_RETFW;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #212#1#202#24;
+    flags   : [if_8086,if_sw]
+  ),
+  (
+    opcode  : A_RETNW;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #212#1#195;
+    flags   : [if_8086]
+  ),
+  (
+    opcode  : A_RETNW;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #212#1#194#24;
+    flags   : [if_8086,if_sw]
+  ),
+  (
+    opcode  : A_RETD;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #213#1#195;
+    flags   : [if_386,if_nox86_64]
+  ),
+  (
+    opcode  : A_RETD;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #213#1#194#24;
+    flags   : [if_386,if_sw,if_nox86_64]
+  ),
+  (
+    opcode  : A_RETFD;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #213#1#203;
+    flags   : [if_386]
+  ),
+  (
+    opcode  : A_RETFD;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #213#1#202#24;
+    flags   : [if_386,if_sw]
+  ),
+  (
+    opcode  : A_RETND;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #213#1#195;
+    flags   : [if_386,if_nox86_64]
+  ),
+  (
+    opcode  : A_RETND;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #213#1#194#24;
+    flags   : [if_386,if_sw,if_nox86_64]
+  ),
   (
     opcode  : A_ROL;
     ops     : 2;

+ 35 - 1
compiler/x86/agx86nsm.pas

@@ -1053,7 +1053,41 @@ interface
                       (is_segment_reg(taicpu(hp).oper[0]^.reg)) then
                     writer.AsmWriteln(#9#9'DB'#9'066h');
 {$endif not i8086}
-                  writer.AsmWrite(#9#9+prefix+std_op2str[fixed_opcode]+cond2str[taicpu(hp).condition]);
+                  if (fixed_opcode=A_RETW) or (fixed_opcode=A_RETNW) or (fixed_opcode=A_RETFW) or
+{$ifdef x86_64}
+                     (fixed_opcode=A_RETQ) or (fixed_opcode=A_RETNQ) or (fixed_opcode=A_RETFQ) or
+{$else x86_64}
+                     (fixed_opcode=A_RETD) or (fixed_opcode=A_RETND) or
+{$endif x86_64}
+                     (fixed_opcode=A_RETFD) then
+                   begin
+                     case fixed_opcode of
+                       A_RETW:
+                         writer.AsmWrite(#9#9'o16 ret');
+                       A_RETNW:
+                         writer.AsmWrite(#9#9'o16 retn');
+                       A_RETFW:
+                         writer.AsmWrite(#9#9'o16 retf');
+{$ifdef x86_64}
+                       A_RETQ,
+                       A_RETNQ:
+                         writer.AsmWrite(#9#9'ret');
+                       A_RETFQ:
+                         writer.AsmWrite(#9#9'o64 retf');
+{$else x86_64}
+                       A_RETD:
+                         writer.AsmWrite(#9#9'o32 ret');
+                       A_RETND:
+                         writer.AsmWrite(#9#9'o32 retn');
+{$endif x86_64}
+                       A_RETFD:
+                         writer.AsmWrite(#9#9'o32 retf');
+                       else
+                         internalerror(2017111001);
+                     end;
+                   end
+                  else
+                    writer.AsmWrite(#9#9+prefix+std_op2str[fixed_opcode]+cond2str[taicpu(hp).condition]);
                   if taicpu(hp).ops<>0 then
                    begin
                      if is_calljmp(fixed_opcode) then

+ 10 - 1
compiler/x86/rax86.pas

@@ -1112,7 +1112,16 @@ begin
       if (ops=1) and (opcode=A_BRKEM) then
         siz:=S_B;
 {$endif i8086}
-      if (ops=1) and (opcode=A_RET) or (opcode=A_RETN) or (opcode=A_RETF) then
+      if (ops=1) and (opcode=A_RET) or (opcode=A_RETN) or (opcode=A_RETF) or
+                     (opcode=A_RETW) or (opcode=A_RETNW) or (opcode=A_RETFW) or
+{$ifndef x86_64}
+                     (opcode=A_RETD) or (opcode=A_RETND) or
+{$endif x86_64}
+                     (opcode=A_RETFD)
+{$ifdef x86_64}
+                  or (opcode=A_RETQ) or (opcode=A_RETNQ) or (opcode=A_RETFQ)
+{$endif x86_64}
+          then
         siz:=S_W;
       if (ops=1) and (opcode=A_PUSH) then
         begin

+ 51 - 6
compiler/x86/x86ins.dat

@@ -1719,18 +1719,63 @@ void                  \1\xF3                          8086,PRE
 
 [RET]
 (Ch_All)
-void                  \1\xC3                          8086
-imm                   \1\xC2\30                       8086,SW
+void                  \327\1\xC3                      8086
+imm                   \327\1\xC2\30                   8086,SW
 
 [RETF,lret]
 (Ch_All)
-void                  \1\xCB                          8086
-imm                   \1\xCA\30                       8086,SW
+void                  \327\1\xCB                      8086
+imm                   \327\1\xCA\30                   8086,SW
 
 [RETN,ret]
 (Ch_All)
-void                  \1\xC3                          8086
-imm                   \1\xC2\30                       8086,SW
+void                  \327\1\xC3                      8086
+imm                   \327\1\xC2\30                   8086,SW
+
+[RETW]
+(Ch_All)
+void                  \324\1\xC3                      8086
+imm                   \324\1\xC2\30                   8086,SW
+
+[RETFW,lretw]
+(Ch_All)
+void                  \324\1\xCB                      8086
+imm                   \324\1\xCA\30                   8086,SW
+
+[RETNW,retw]
+(Ch_All)
+void                  \324\1\xC3                      8086
+imm                   \324\1\xC2\30                   8086,SW
+
+[RETD,ret]
+(Ch_All)
+void                  \325\1\xC3                      386,NOX86_64
+imm                   \325\1\xC2\30                   386,SW,NOX86_64
+
+[RETFD,lret]
+(Ch_All)
+void                  \325\1\xCB                      386
+imm                   \325\1\xCA\30                   386,SW
+
+[RETND,ret]
+(Ch_All)
+void                  \325\1\xC3                      386,NOX86_64
+imm                   \325\1\xC2\30                   386,SW,NOX86_64
+
+[RETQ,ret]
+(Ch_All)
+void                  \335\1\xC3                      X86_64
+imm                   \335\1\xC2\30                   X86_64,SW
+
+[RETFQ,lretq]
+(Ch_All)
+void                  \326\1\xCB                      X86_64
+imm                   \326\1\xCA\30                   X86_64,SW
+
+[RETNQ,ret]
+(Ch_All)
+void                  \335\1\xC3                      X86_64
+imm                   \335\1\xC2\30                   X86_64,SW
 
 [ROL,rolX]
 (Ch_Mop2, Ch_Rop1, Ch_WCarryFlag, Ch_WOverflowFlag)

+ 7 - 0
compiler/x86_64/x8664ats.inc

@@ -302,6 +302,13 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
 attsufINT,
 attsufINT,
 attsufNONE,

+ 7 - 0
compiler/x86_64/x8664att.inc

@@ -302,6 +302,13 @@
 'ret',
 'lret',
 'ret',
+'retw',
+'lretw',
+'retw',
+'lret',
+'ret',
+'lretq',
+'ret',
 'rol',
 'ror',
 'rsdc',

+ 7 - 0
compiler/x86_64/x8664int.inc

@@ -302,6 +302,13 @@
 'ret',
 'retf',
 'retn',
+'retw',
+'retfw',
+'retnw',
+'retfd',
+'retq',
+'retfq',
+'retnq',
 'rol',
 'ror',
 'rsdc',

+ 1 - 1
compiler/x86_64/x8664nop.inc

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

+ 7 - 0
compiler/x86_64/x8664op.inc

@@ -302,6 +302,13 @@ A_REPZ,
 A_RET,
 A_RETF,
 A_RETN,
+A_RETW,
+A_RETFW,
+A_RETNW,
+A_RETFD,
+A_RETQ,
+A_RETFQ,
+A_RETNQ,
 A_ROL,
 A_ROR,
 A_RSDC,

+ 7 - 0
compiler/x86_64/x8664pro.inc

@@ -302,6 +302,13 @@
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
+(Ch: [Ch_All]),
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WCarryFlag, Ch_WOverflowFlag]),
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WCarryFlag, Ch_WOverflowFlag]),
 (Ch: [Ch_All]),

+ 104 - 6
compiler/x86_64/x8664tab.inc

@@ -4701,44 +4701,142 @@
     opcode  : A_RET;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none,ot_none);
-    code    : #1#195;
+    code    : #215#1#195;
     flags   : [if_8086]
   ),
   (
     opcode  : A_RET;
     ops     : 1;
     optypes : (ot_immediate,ot_none,ot_none,ot_none);
-    code    : #1#194#24;
+    code    : #215#1#194#24;
     flags   : [if_8086,if_sw]
   ),
   (
     opcode  : A_RETF;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none,ot_none);
-    code    : #1#203;
+    code    : #215#1#203;
     flags   : [if_8086]
   ),
   (
     opcode  : A_RETF;
     ops     : 1;
     optypes : (ot_immediate,ot_none,ot_none,ot_none);
-    code    : #1#202#24;
+    code    : #215#1#202#24;
     flags   : [if_8086,if_sw]
   ),
   (
     opcode  : A_RETN;
     ops     : 0;
     optypes : (ot_none,ot_none,ot_none,ot_none);
-    code    : #1#195;
+    code    : #215#1#195;
     flags   : [if_8086]
   ),
   (
     opcode  : A_RETN;
     ops     : 1;
     optypes : (ot_immediate,ot_none,ot_none,ot_none);
-    code    : #1#194#24;
+    code    : #215#1#194#24;
     flags   : [if_8086,if_sw]
   ),
+  (
+    opcode  : A_RETW;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #212#1#195;
+    flags   : [if_8086]
+  ),
+  (
+    opcode  : A_RETW;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #212#1#194#24;
+    flags   : [if_8086,if_sw]
+  ),
+  (
+    opcode  : A_RETFW;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #212#1#203;
+    flags   : [if_8086]
+  ),
+  (
+    opcode  : A_RETFW;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #212#1#202#24;
+    flags   : [if_8086,if_sw]
+  ),
+  (
+    opcode  : A_RETNW;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #212#1#195;
+    flags   : [if_8086]
+  ),
+  (
+    opcode  : A_RETNW;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #212#1#194#24;
+    flags   : [if_8086,if_sw]
+  ),
+  (
+    opcode  : A_RETFD;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #213#1#203;
+    flags   : [if_386]
+  ),
+  (
+    opcode  : A_RETFD;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #213#1#202#24;
+    flags   : [if_386,if_sw]
+  ),
+  (
+    opcode  : A_RETQ;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #221#1#195;
+    flags   : [if_x86_64]
+  ),
+  (
+    opcode  : A_RETQ;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #221#1#194#24;
+    flags   : [if_x86_64,if_sw]
+  ),
+  (
+    opcode  : A_RETFQ;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #214#1#203;
+    flags   : [if_x86_64]
+  ),
+  (
+    opcode  : A_RETFQ;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #214#1#202#24;
+    flags   : [if_x86_64,if_sw]
+  ),
+  (
+    opcode  : A_RETNQ;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #221#1#195;
+    flags   : [if_x86_64]
+  ),
+  (
+    opcode  : A_RETNQ;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #221#1#194#24;
+    flags   : [if_x86_64,if_sw]
+  ),
   (
     opcode  : A_ROL;
     ops     : 2;

+ 83 - 0
tests/test/tasm15.pp

@@ -0,0 +1,83 @@
+{ %CPU=i386 }
+
+const
+  expect: array [0..41] of byte = (
+    $C3,              // ret
+    $C2,$05,$00,      // ret 5
+    $C3,              // retn
+    $C2,$05,$00,      // retn 5
+    $CB,              // retf
+    $CA,$05,$00,      // retf 5
+    $66,$C3,          // retw
+    $66,$C2,$05,$00,  // retw 5
+    $66,$C3,          // retnw
+    $66,$C2,$05,$00,  // retnw 5
+    $66,$CB,          // retfw
+    $66,$CA,$05,$00,  // retfw 5
+    $C3,              // retd
+    $C2,$05,$00,      // retd 5
+    $C3,              // retnd
+    $C2,$05,$00,      // retnd 5
+    $CB,              // retfd
+    $CA,$05,$00       // retfd 5
+  );
+
+{$asmmode intel}
+procedure test; assembler; nostackframe;
+asm
+  ret
+  ret 5
+  retn
+  retn 5
+  retf
+  retf 5
+  retw
+  retw 5
+  retnw
+  retnw 5
+  retfw
+  retfw 5
+  retd
+  retd 5
+  retnd
+  retnd 5
+  retfd
+  retfd 5
+end;
+
+{$asmmode att}
+procedure test2; assembler; nostackframe;
+asm
+  ret
+  ret $5
+  ret
+  ret $5
+  lret
+  lret $5
+  retw
+  retw $5
+  retw
+  retw $5
+  lretw
+  lretw $5
+  ret
+  ret $5
+  ret
+  ret $5
+  lret
+  lret $5
+end;
+
+procedure Error;
+begin
+  Writeln('Error!');
+  Halt(1);
+end;
+
+begin
+  if CompareByte(Pointer(@test)^, expect, SizeOf(expect)) <> 0 then
+    Error;
+  if CompareByte(Pointer(@test2)^, expect, SizeOf(expect)) <> 0 then
+    Error;
+  Writeln('Ok!')
+end.

+ 89 - 0
tests/test/tasm15a.pp

@@ -0,0 +1,89 @@
+{ %CPU=x86_64 }
+
+const
+  expect: array [0..47] of byte = (
+    $C3,              // ret
+    $C2,$05,$00,      // ret 5
+    $C3,              // retn
+    $C2,$05,$00,      // retn 5
+    $CB,              // retf
+    $CA,$05,$00,      // retf 5
+    $66,$C3,          // retw
+    $66,$C2,$05,$00,  // retw 5
+    $66,$C3,          // retnw
+    $66,$C2,$05,$00,  // retnw 5
+    $66,$CB,          // retfw
+    $66,$CA,$05,$00,  // retfw 5
+    $CB,              // retfd
+    $CA,$05,$00,      // retfd 5
+    $C3,              // retq
+    $C2,$05,$00,      // retq 5
+    $C3,              // retnq
+    $C2,$05,$00,      // retnq 5
+    $48,$CB,          // retfq
+    $48,$CA,$05,$00   // retfq 5
+  );
+
+{$asmmode intel}
+procedure test; assembler; nostackframe;
+asm
+  ret
+  ret 5
+  retn
+  retn 5
+  retf
+  retf 5
+  retw
+  retw 5
+  retnw
+  retnw 5
+  retfw
+  retfw 5
+  retfd
+  retfd 5
+  retq
+  retq 5
+  retnq
+  retnq 5
+  retfq
+  retfq 5
+end;
+
+{$asmmode att}
+procedure test2; assembler; nostackframe;
+asm
+  ret
+  ret $5
+  ret
+  ret $5
+  lret
+  lret $5
+  retw
+  retw $5
+  retw
+  retw $5
+  lretw
+  lretw $5
+  lret
+  lret $5
+  retq
+  retq $5
+  retq
+  retq $5
+  lretq
+  lretq $5
+end;
+
+procedure Error;
+begin
+  Writeln('Error!');
+  Halt(1);
+end;
+
+begin
+  if CompareByte(Pointer(@test)^, expect, SizeOf(expect)) <> 0 then
+    Error;
+  if CompareByte(Pointer(@test2)^, expect, SizeOf(expect)) <> 0 then
+    Error;
+  Writeln('Ok!')
+end.