فهرست منبع

+ handle 32 bit references on x86-64 so lea can be used for 32 bit arithmetics

git-svn-id: trunk@25909 -
florian 11 سال پیش
والد
کامیت
f132a804d6
6فایلهای تغییر یافته به همراه61 افزوده شده و 9 حذف شده
  1. 1 1
      compiler/i386/i386tab.inc
  2. 1 1
      compiler/i8086/i8086tab.inc
  3. 56 5
      compiler/x86/aasmcpu.pas
  4. 1 0
      compiler/x86/cpubase.pas
  5. 1 1
      compiler/x86/x86ins.dat
  6. 1 1
      compiler/x86_64/x8664tab.inc

+ 1 - 1
compiler/i386/i386tab.inc

@@ -2650,7 +2650,7 @@
     opcode  : A_LEA;
     ops     : 2;
     optypes : (ot_reg16 or ot_bits32 or ot_bits64,ot_memory,ot_none,ot_none);
-    code    : #208#1#141#72;
+    code    : #193#208#1#141#72;
     flags   : if_8086
   ),
   (

+ 1 - 1
compiler/i8086/i8086tab.inc

@@ -2650,7 +2650,7 @@
     opcode  : A_LEA;
     ops     : 2;
     optypes : (ot_reg16 or ot_bits32 or ot_bits64,ot_memory,ot_none,ot_none);
-    code    : #208#1#141#72;
+    code    : #193#208#1#141#72;
     flags   : if_8086
   ),
   (

+ 56 - 5
compiler/x86/aasmcpu.pas

@@ -1667,10 +1667,11 @@ implementation
         else
         { it's an indirection }
          begin
-           { 16 bit or 32 bit address? }
-           if ((ir<>NR_NO) and (isub<>R_SUBADDR)) or
-              ((br<>NR_NO) and (bsub<>R_SUBADDR)) then
+           { 16 bit? }
+           if ((ir<>NR_NO) and (isub<>R_SUBADDR) and (isub<>R_SUBD)) or
+              ((br<>NR_NO) and (bsub<>R_SUBADDR) and (bsub<>R_SUBD)) then
              message(asmw_e_16bit_32bit_not_supported);
+
            { wrong, for various reasons }
            if (ir=NR_ESP) or ((s<>1) and (s<>2) and (s<>4) and (s<>8) and (ir<>NR_NO)) then
             exit;
@@ -1681,21 +1682,37 @@ implementation
 
            { base }
            case br of
+             NR_R8D,
+             NR_EAX,
              NR_R8,
              NR_RAX : base:=0;
+             NR_R9D,
+             NR_ECX,
              NR_R9,
              NR_RCX : base:=1;
+             NR_R10D,
+             NR_EDX,
              NR_R10,
              NR_RDX : base:=2;
+             NR_R11D,
+             NR_EBX,
              NR_R11,
              NR_RBX : base:=3;
+             NR_R12D,
+             NR_ESP,
              NR_R12,
              NR_RSP : base:=4;
+             NR_R13D,
+             NR_EBP,
              NR_R13,
              NR_NO,
              NR_RBP : base:=5;
+             NR_R14D,
+             NR_ESI,
              NR_R14,
              NR_RSI : base:=6;
+             NR_R15D,
+             NR_EDI,
              NR_R15,
              NR_RDI : base:=7;
            else
@@ -1703,20 +1720,36 @@ implementation
            end;
            { index }
            case ir of
+             NR_R8D,
+             NR_EAX,
              NR_R8,
              NR_RAX : index:=0;
+             NR_R9D,
+             NR_ECX,
              NR_R9,
              NR_RCX : index:=1;
+             NR_R10D,
+             NR_EDX,
              NR_R10,
              NR_RDX : index:=2;
+             NR_R11D,
+             NR_EBX,
              NR_R11,
              NR_RBX : index:=3;
+             NR_R12D,
+             NR_ESP,
              NR_R12,
              NR_NO  : index:=4;
+             NR_R13D,
+             NR_EBP,
              NR_R13,
              NR_RBP : index:=5;
+             NR_R14D,
+             NR_ESI,
              NR_R14,
              NR_RSI : index:=6;
+             NR_R15D,
+             NR_EDI,
              NR_R15,
              NR_RDI : index:=7;
            else
@@ -1733,7 +1766,7 @@ implementation
            end;
            { If rbp or r13 is used we must always include an offset }
            if (br=NR_NO) or
-              ((br<>NR_RBP) and (br<>NR_R13) and (o=0) and (sym=nil)) then
+              ((br<>NR_RBP) and (br<>NR_R13) and (br<>NR_EBP) and (br<>NR_R13D) and (o=0) and (sym=nil)) then
             md:=0
            else
             if ((o>=-128) and (o<=127) and (sym=nil)) then
@@ -1745,7 +1778,7 @@ implementation
            else
             output.bytes:=md;
            { SIB needed ? }
-           if (ir=NR_NO) and (br<>NR_RSP) and (br<>NR_R12) then
+           if (ir=NR_NO) and (br<>NR_RSP) and (br<>NR_R12) and (br<>NR_ESP) and (br<>NR_R12D)  then
             begin
               output.sib_present:=false;
               output.modrm:=(md shl 6) or (rfield shl 3) or base;
@@ -2100,6 +2133,13 @@ implementation
                   exists_vex_extention := true;
                 end;
               end;
+            192,193,194:
+              begin
+{$ifdef x86_64}
+                if (oper[c and 3]^.ot and OT_SIZE_MASK)=OT_BITS32 then
+                  inc(len);
+{$endif x86_64}
+              end;
             else
              InternalError(200603141);
           end;
@@ -2321,6 +2361,7 @@ implementation
         { safety check }
         if objdata.currobjsec.size<>longword(insoffset) then
            internalerror(200130121);
+
         { load data to write }
         codes:=insentry^.code;
 {$ifdef x86_64}
@@ -2656,6 +2697,16 @@ implementation
                 else
                   objdata.writebytes(currval,4);
               end;
+            192,193,194:
+              begin
+{$ifdef x86_64}
+                if (oper[c and 3]^.ot and OT_SIZE_MASK)=OT_BITS32 then
+                  begin
+                    bytes[0]:=$67;
+                    objdata.writebytes(bytes,1);
+                  end;
+{$endif x86_64}
+              end;
             200 :   { fixed 16-bit addr }
 {$ifndef x86_64}
               begin

+ 1 - 0
compiler/x86/cpubase.pas

@@ -68,6 +68,7 @@ uses
 
    const
       { Integer Super registers }
+      RS_NO         = $ffffffff;
       RS_RAX        = $00;      {EAX}
       RS_RCX        = $01;      {ECX}
       RS_RDX        = $02;      {EDX}

+ 1 - 1
compiler/x86/x86ins.dat

@@ -924,7 +924,7 @@ reg16|32,mem          \320\1\xC5\110                  8086,NOX86_64
 
 [LEA,leaX]
 (Ch_Wop2, Ch_Rop1, Ch_None)
-reg16|32|64,mem          \320\1\x8D\110                  8086
+reg16|32|64,mem       \301\320\1\x8D\110              8086
 
 [LEAVE]
 (Ch_RWESP, Ch_WEBP, Ch_None)

+ 1 - 1
compiler/x86_64/x8664tab.inc

@@ -2545,7 +2545,7 @@
     opcode  : A_LEA;
     ops     : 2;
     optypes : (ot_reg16 or ot_bits32 or ot_bits64,ot_memory,ot_none,ot_none);
-    code    : #208#1#141#72;
+    code    : #193#208#1#141#72;
     flags   : if_8086
   ),
   (