浏览代码

* Add support for jmp $0011:$22334455 to Intel asm reader, request from
a user that is writing an operating system.
* Fix mkx86ins bug to interpret imm16:imm32 as a single operand

git-svn-id: trunk@606 -

daniel 20 年之前
父节点
当前提交
45bcc5b07a

+ 3 - 2
compiler/aasmtai.pas

@@ -163,7 +163,8 @@ interface
        top_regset,
        top_shifterop,
        { m68k only }
-       top_reglist);
+       top_reglist
+       { i386 only});
 
       { kinds of operations that an instruction can perform on an operand }
       topertype = (operand_read,operand_write,operand_readwrite);
@@ -1874,6 +1875,7 @@ implementation
       end;
 
 
+
     procedure tai_cpu_abstract.loadref(opidx:longint;const r:treference);
       begin
         allocate_oper(opidx+1);
@@ -1971,7 +1973,6 @@ implementation
           end;
       end;
 
-
     procedure tai_cpu_abstract.clearop(opidx:longint);
       begin
         with oper[opidx]^ do

+ 1 - 1
compiler/i386/i386int.inc

@@ -565,5 +565,5 @@
 'movsldup',
 'movabs',
 'movsxd',
-'cdo'
+'cqo'
 );

+ 1 - 1
compiler/i386/i386nop.inc

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

+ 1 - 1
compiler/i386/i386op.inc

@@ -565,5 +565,5 @@ A_MOVSHDUP,
 A_MOVSLDUP,
 A_MOVABS,
 A_MOVSXD,
-A_CDO
+A_CQO
 );

+ 16 - 30
compiler/i386/i386tab.inc

@@ -856,36 +856,36 @@
   ),
   (
     opcode  : A_CALL;
-    ops     : 1;
-    optypes : (ot_immediate or ot_immediate,ot_none,ot_none);
+    ops     : 2;
+    optypes : (ot_immediate,ot_immediate,ot_none);
     code    : #211#1#154#29#24;
     flags   : if_8086
   ),
   (
     opcode  : A_CALL;
-    ops     : 1;
-    optypes : (ot_immediate or ot_bits16 or ot_immediate,ot_none,ot_none);
+    ops     : 2;
+    optypes : (ot_immediate or ot_bits16,ot_immediate,ot_none);
     code    : #208#1#154#25#24;
     flags   : if_8086
   ),
   (
     opcode  : A_CALL;
-    ops     : 1;
-    optypes : (ot_immediate or ot_immediate or ot_bits16,ot_none,ot_none);
+    ops     : 2;
+    optypes : (ot_immediate,ot_immediate or ot_bits16,ot_none);
     code    : #208#1#154#25#24;
     flags   : if_8086
   ),
   (
     opcode  : A_CALL;
-    ops     : 1;
-    optypes : (ot_immediate or ot_bits32 or ot_immediate,ot_none,ot_none);
+    ops     : 2;
+    optypes : (ot_immediate or ot_bits32,ot_immediate,ot_none);
     code    : #209#1#154#33#24;
     flags   : if_386
   ),
   (
     opcode  : A_CALL;
-    ops     : 1;
-    optypes : (ot_immediate or ot_immediate or ot_bits32,ot_none,ot_none);
+    ops     : 2;
+    optypes : (ot_immediate,ot_immediate or ot_bits32,ot_none);
     code    : #209#1#154#33#24;
     flags   : if_386
   ),
@@ -3362,36 +3362,22 @@
   ),
   (
     opcode  : A_JMP;
-    ops     : 1;
-    optypes : (ot_immediate or ot_immediate,ot_none,ot_none);
+    ops     : 2;
+    optypes : (ot_immediate,ot_immediate,ot_none);
     code    : #211#1#234#29#24;
     flags   : if_8086
   ),
   (
     opcode  : A_JMP;
-    ops     : 1;
-    optypes : (ot_immediate or ot_bits16 or ot_immediate,ot_none,ot_none);
-    code    : #208#1#234#25#24;
-    flags   : if_8086
-  ),
-  (
-    opcode  : A_JMP;
-    ops     : 1;
-    optypes : (ot_immediate or ot_immediate or ot_bits16,ot_none,ot_none);
+    ops     : 2;
+    optypes : (ot_immediate,ot_immediate or ot_bits16,ot_none);
     code    : #208#1#234#25#24;
     flags   : if_8086
   ),
   (
     opcode  : A_JMP;
-    ops     : 1;
-    optypes : (ot_immediate or ot_bits32 or ot_immediate,ot_none,ot_none);
-    code    : #209#1#234#33#24;
-    flags   : if_386
-  ),
-  (
-    opcode  : A_JMP;
-    ops     : 1;
-    optypes : (ot_immediate or ot_immediate or ot_bits32,ot_none,ot_none);
+    ops     : 2;
+    optypes : (ot_immediate,ot_immediate or ot_bits32,ot_none);
     code    : #209#1#234#33#24;
     flags   : if_386
   ),

+ 64 - 54
compiler/i386/ra386int.pas

@@ -887,7 +887,7 @@ Unit Ra386int;
                   Consume(AS_RPAREN);
               end;
             AS_STRING:
-              Begin
+              begin
                 l:=0;
                 case Length(actasmpattern) of
                  1 :
@@ -908,7 +908,7 @@ Unit Ra386int;
                 Consume(AS_STRING);
               end;
             AS_ID:
-              Begin
+              begin
                 hs:='';
                 hssymtyp:=AT_DATA;
                 def:=nil;
@@ -1035,12 +1035,11 @@ Unit Ra386int;
             AS_END,
             AS_RBRACKET,
             AS_SEPARATOR,
-            AS_COMMA:
-              Begin
-                break;
-              end;
+            AS_COMMA,
+            AS_COLON:
+              break;
           else
-            Begin
+            begin
               { write error only once. }
               if not errorflag then
                 Message(asmr_e_invalid_constant_expression);
@@ -1441,21 +1440,19 @@ Unit Ra386int;
           Message(asmr_e_invalid_operand_type);
         BuildConstSymbolExpression(true,false,l,tempstr,tempsymtyp);
         if tempstr<>'' then
-         begin
-           oper.opr.typ:=OPR_SYMBOL;
-           oper.opr.symofs:=l;
-           oper.opr.symbol:=objectlibrary.newasmsymbol(tempstr,AB_EXTERNAL,tempsymtyp);
-         end
+          begin
+            oper.opr.typ:=OPR_SYMBOL;
+            oper.opr.symofs:=l;
+            oper.opr.symbol:=objectlibrary.newasmsymbol(tempstr,AB_EXTERNAL,tempsymtyp);
+          end
         else
-         begin
-           if oper.opr.typ=OPR_NONE then
-             begin
-               oper.opr.typ:=OPR_CONSTANT;
-               oper.opr.val:=l;
-             end
-           else
-             inc(oper.opr.val,l);
-         end;
+          if oper.opr.typ=OPR_NONE then
+            begin
+              oper.opr.typ:=OPR_CONSTANT;
+              oper.opr.val:=l;
+            end
+          else
+            inc(oper.opr.val,l);
       end;
 
 
@@ -1484,7 +1481,7 @@ Unit Ra386int;
         hl      : tasmlabel;
         toffset,
         tsize   : aint;
-      Begin
+      begin
         expr:='';
         repeat
           if actasmtoken=AS_DOT then
@@ -1536,7 +1533,6 @@ Unit Ra386int;
           end;
 
           case actasmtoken of
-
             AS_OFFSET,
             AS_SIZEOF,
             AS_TYPE,
@@ -1687,14 +1683,15 @@ Unit Ra386int;
 
             AS_SEPARATOR,
             AS_END,
-            AS_COMMA:
+            AS_COMMA,
+            AS_COLON:
               break;
 
             else
               Message(asmr_e_syn_operand);
           end;
         until not(actasmtoken in [AS_DOT,AS_PLUS,AS_LBRACKET]);
-        if not((actasmtoken in [AS_END,AS_SEPARATOR,AS_COMMA]) or
+        if not((actasmtoken in [AS_END,AS_SEPARATOR,AS_COMMA,AS_COLON]) or
                (oper.hastype and (actasmtoken=AS_RPAREN))) then
          begin
            Message(asmr_e_syntax_error);
@@ -1708,47 +1705,46 @@ Unit Ra386int;
         PrefixOp,OverrideOp: tasmop;
         size,
         operandnum : longint;
-      Begin
+        is_far_const:boolean;
+        i:byte;
+      begin
         PrefixOp:=A_None;
         OverrideOp:=A_None;
+        is_far_const:=false;
         { prefix seg opcode / prefix opcode }
         repeat
           if is_prefix(actopcode) then
-           begin
+            with instr do
+              begin
+                OpOrder:=op_intel;
+                PrefixOp:=ActOpcode;
+                opcode:=ActOpcode;
+                condition:=ActCondition;
+                opsize:=ActOpsize;
+                ConcatInstruction(curlist);
+                consume(AS_OPCODE);
+              end
+          else
+           if is_override(actopcode) then
              with instr do
                begin
                  OpOrder:=op_intel;
-                 PrefixOp:=ActOpcode;
+                 OverrideOp:=ActOpcode;
                  opcode:=ActOpcode;
                  condition:=ActCondition;
                  opsize:=ActOpsize;
                  ConcatInstruction(curlist);
-               end;
-             Consume(AS_OPCODE);
-           end
-          else
-           if is_override(actopcode) then
-            begin
-              with instr do
-                begin
-                  OpOrder:=op_intel;
-                  OverrideOp:=ActOpcode;
-                  opcode:=ActOpcode;
-                  condition:=ActCondition;
-                  opsize:=ActOpsize;
-                  ConcatInstruction(curlist);
-                end;
-              Consume(AS_OPCODE);
-            end
+                 consume(AS_OPCODE);
+               end
           else
-           break;
+            break;
           { allow for newline after prefix or override }
           while actasmtoken=AS_SEPARATOR do
-            Consume(AS_SEPARATOR);
+            consume(AS_SEPARATOR);
         until (actasmtoken<>AS_OPCODE);
         { opcode }
         if (actasmtoken <> AS_OPCODE) then
-         Begin
+         begin
            Message(asmr_e_invalid_or_missing_opcode);
            RecoverConsume(false);
            exit;
@@ -1769,6 +1765,7 @@ Unit Ra386int;
           end;
         { We are reading operands, so opcode will be an AS_ID }
         operandnum:=1;
+        is_far_const:=false;
         Consume(AS_OPCODE);
         { Zero operand opcode ?  }
         if actasmtoken in [AS_SEPARATOR,AS_END] then
@@ -1779,7 +1776,6 @@ Unit Ra386int;
         { Read Operands }
         repeat
           case actasmtoken of
-
             { End of asm operands for this opcode }
             AS_END,
             AS_SEPARATOR :
@@ -1787,13 +1783,23 @@ Unit Ra386int;
 
             { Operand delimiter }
             AS_COMMA :
-              Begin
+              begin
                 if operandnum > Max_Operands then
                   Message(asmr_e_too_many_operands)
                 else
                   Inc(operandnum);
                 Consume(AS_COMMA);
               end;
+            {Far constant, i.e. jmp $0000:$11111111.}
+            AS_COLON:
+              begin
+                is_far_const:=true;
+                if operandnum>1 then
+                  message(asmr_e_too_many_operands)
+                else
+                  inc(operandnum);
+                consume(AS_COLON);
+              end;
 
             { Typecast, Constant Expression, Type Specifier }
             AS_DWORD,
@@ -1802,11 +1808,11 @@ Unit Ra386int;
             AS_TBYTE,
             AS_DQWORD,
             AS_QWORD :
-              Begin
+              begin
                 { load the size in a temp variable, so it can be set when the
                   operand is read }
                 size:=0;
-                Case actasmtoken of
+                case actasmtoken of
                   AS_DWORD : size:=4;
                   AS_WORD  : size:=2;
                   AS_BYTE  : size:=1;
@@ -1839,7 +1845,7 @@ Unit Ra386int;
             { Type specifier }
             AS_NEAR,
             AS_FAR :
-              Begin
+              begin
                 if actasmtoken = AS_NEAR then
                   begin
                     Message(asmr_w_near_ignored);
@@ -1862,7 +1868,11 @@ Unit Ra386int;
               BuildOperand(instr.Operands[operandnum] as tx86operand);
           end; { end case }
         until false;
-        instr.Ops:=operandnum;
+        instr.ops:=operandnum;
+        if is_far_const then
+          for i:=1 to operandnum do
+            if instr.operands[i].opr.typ<>OPR_CONSTANT then
+              message(asmr_e_expr_illegal);
       end;
 
 

+ 1 - 1
compiler/i386/rropt386.pas

@@ -163,7 +163,7 @@ begin
             if (p.oper[0]^.ref^.refaddr=addr_full) then
               tmpref.symbol := p.oper[0]^.ref^.symbol
             else
-              internalerror(200402261);
+              internalerror(200402263);
           top_reg:
             begin
               tmpref.index := p.oper[0]^.reg;

+ 3 - 3
compiler/utils/mkx86ins.pp

@@ -350,17 +350,17 @@ begin
             break;
           inc(ops);
           optypes[ops]:=optypes[ops]+'ot_'+formatop(hs);
-          if s[i]=':' then
+{          if s[i]=':' then
             begin
                inc(i);
                optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
-            end;
+            end;}
           while s[i]='|' do
             begin
                inc(i);
                optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
             end;
-          if s[i]=',' then
+          if s[i] in [',',':'] then
             inc(i)
           else
             break;

+ 2 - 4
compiler/x86/rax86.pas

@@ -667,8 +667,7 @@ begin
   ai.Ops:=Ops;
   ai.Allocate_oper(Ops);
   for i:=1 to Ops do
-   begin
-     case operands[i].opr.typ of
+    case operands[i].opr.typ of
        OPR_CONSTANT :
          ai.loadconst(i-1,operands[i].opr.val);
        OPR_REGISTER:
@@ -710,8 +709,7 @@ begin
                  ai.oper[i-1]^.ot:=(ai.oper[i-1]^.ot and not OT_SIZE_MASK) or asize;
              end;
          end;
-     end;
-   end;
+    end;
 
   if (opcode=A_CALL) and (opsize=S_FAR) then
     opcode:=A_LCALL;

+ 2 - 2
compiler/x86/x86ins.dat

@@ -983,9 +983,9 @@ imm32                 \321\1\xE9\64                   8086,PASS2
 imm32|near            \321\1\xE9\64                   8086,ND,PASS2
 imm32|far             \321\1\xEA\34\37                8086,ND,PASS2
 imm:imm               \323\1\xEA\35\30                8086
-imm16:imm             \320\1\xEA\31\30                8086
+;???? imm16:imm             \320\1\xEA\31\30                8086
 imm:imm16             \320\1\xEA\31\30                8086
-imm32:imm             \321\1\xEA\41\30                386
+;???? imm32:imm             \321\1\xEA\41\30                386
 imm:imm32             \321\1\xEA\41\30                386
 mem|far               \323\300\1\xFF\205              8086
 mem16|far             \320\300\1\xFF\205              8086