Browse Source

Merged revisions 606-608,611-612,614 via svnmerge from
/trunk

git-svn-id: branches/fixes_2_0@866 -

peter 20 years ago
parent
commit
5465d23c2c

+ 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

+ 2 - 2
compiler/i386/cgcpu.pas

@@ -285,7 +285,7 @@ unit cgcpu;
            { complex return values are removed from stack in C code PM }
            if paramanager.ret_in_param(current_procinfo.procdef.rettype.def,
                                        current_procinfo.procdef.proccalloption) then
-             list.concat(Taicpu.Op_const(A_RET,S_NO,sizeof(aint)))
+             list.concat(Taicpu.Op_const(A_RET,S_W,sizeof(aint)))
            else
              list.concat(Taicpu.Op_none(A_RET,S_NO));
          end
@@ -297,7 +297,7 @@ unit cgcpu;
            { parameters are limited to 65535 bytes because ret allows only imm16 }
            if (parasize>65535) then
              CGMessage(cg_e_parasize_too_big);
-           list.concat(Taicpu.Op_const(A_RET,S_NO,parasize));
+           list.concat(Taicpu.Op_const(A_RET,S_W,parasize));
          end;
       end;
 

+ 1 - 1
compiler/i386/i386nop.inc

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

+ 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,
@@ -1699,14 +1695,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);
@@ -1720,47 +1717,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;
@@ -1781,6 +1777,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
@@ -1791,7 +1788,6 @@ Unit Ra386int;
         { Read Operands }
         repeat
           case actasmtoken of
-
             { End of asm operands for this opcode }
             AS_END,
             AS_SEPARATOR :
@@ -1799,13 +1795,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,
@@ -1814,11 +1820,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;
@@ -1851,7 +1857,7 @@ Unit Ra386int;
             { Type specifier }
             AS_NEAR,
             AS_FAR :
-              Begin
+              begin
                 if actasmtoken = AS_NEAR then
                   begin
                     Message(asmr_w_near_ignored);
@@ -1874,7 +1880,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 - 0
compiler/x86/aasmcpu.pas

@@ -1046,6 +1046,8 @@ implementation
                 end;
               top_const :
                 begin
+                  if opsize=S_NO then
+                    message(asmr_e_invalid_opcode_and_operand);
                   if (opsize<>S_W) and (longint(val)>=-128) and (val<=127) then
                     ot:=OT_IMM8 or OT_SIGNED
                   else

+ 1 - 1
compiler/x86/nx86mat.pas

@@ -308,7 +308,7 @@ interface
       { lower 32 bit }
       emit_reg_reg(A_PXOR,S_NO,hreg,location.register);
       { shift mask }
-      emit_const_reg(A_PSLLQ,S_NO,32,hreg);
+      emit_const_reg(A_PSLLQ,S_B,32,hreg);
       { higher 32 bit }
       emit_reg_reg(A_PXOR,S_NO,hreg,location.register);
     end;

+ 28 - 5
compiler/x86/rax86.pas

@@ -559,6 +559,28 @@ begin
 {$endif ATTOP}
      end;
 
+  {It is valid to specify some instructions without operand size.}
+  if siz=S_NO then
+    begin
+      if (ops=1) and (opcode=A_INT) then
+        siz:=S_B;
+      if (ops=1) and (opcode=A_RET) or (opcode=A_RETN) or (opcode=A_RETF) then
+        siz:=S_W;
+      if (ops=1) and (opcode=A_PUSH) then
+        begin
+          {We are a 32 compiler, assume 32-bit by default. This is Delphi
+           compatible but bad coding practise.}
+          siz:=S_L;
+          message(asmr_w_unable_to_determine_reference_size_using_dword);
+        end;
+      if (opcode=A_JMP) or (opcode=A_JCC) or (opcode=A_CALL) then
+        if ops=1 then
+          siz:=S_NEAR
+        else
+          siz:=S_FAR;
+    end;
+
+
    { GNU AS interprets FDIV without operand differently
      for version 2.9.1 and 2.10
      we add explicit args to it !! }
@@ -667,8 +689,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,15 +731,17 @@ begin
                  ai.oper[i-1]^.ot:=(ai.oper[i-1]^.ot and not OT_SIZE_MASK) or asize;
              end;
          end;
-     end;
-   end;
+    end;
 
+ {This is dead code since opcode and opsize aren't used from here!
+  Commented out...
   if (opcode=A_CALL) and (opsize=S_FAR) then
     opcode:=A_LCALL;
   if (opcode=A_JMP) and (opsize=S_FAR) then
     opcode:=A_LJMP;
   if (opcode=A_LCALL) or (opcode=A_LJMP) then
-    opsize:=S_FAR;
+    opsize:=S_FAR;}
+
  { Condition ? }
   if condition<>C_None then
    ai.SetCondition(condition);

+ 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