Переглянути джерело

+ support segment overrides in inline asm references to local variables or parameters on x86

git-svn-id: trunk@38392 -
nickysn 7 роки тому
батько
коміт
2cee948b72
5 змінених файлів з 61 додано та 8 видалено
  1. 12 0
      compiler/aasmtai.pas
  2. 11 1
      compiler/ncgbas.pas
  3. 1 1
      compiler/ppu.pas
  4. 32 4
      compiler/rautils.pas
  5. 5 2
      compiler/x86/rax86.pas

+ 12 - 0
compiler/aasmtai.pas

@@ -270,6 +270,9 @@ interface
         localsym : pointer;
         localsym : pointer;
         localsymderef : tderef;
         localsymderef : tderef;
         localsymofs : longint;
         localsymofs : longint;
+{$ifdef x86}
+        localsegment,
+{$endif x86}
         localindexreg : tregister;
         localindexreg : tregister;
         localscale : byte;
         localscale : byte;
         localgetoffset,
         localgetoffset,
@@ -2634,6 +2637,9 @@ implementation
                localscale:=scale;
                localscale:=scale;
                localgetoffset:=getoffset;
                localgetoffset:=getoffset;
                localforceref:=forceref;
                localforceref:=forceref;
+{$ifdef x86}
+               localsegment:=NR_NO;
+{$endif x86}
              end;
              end;
            typ:=top_local;
            typ:=top_local;
          end;
          end;
@@ -2988,6 +2994,9 @@ implementation
                 begin
                 begin
                   ppufile.getderef(localsymderef);
                   ppufile.getderef(localsymderef);
                   localsymofs:=ppufile.getaint;
                   localsymofs:=ppufile.getaint;
+{$ifdef x86}
+                  localsegment:=tregister(ppufile.getlongint);
+{$endif x86}
                   localindexreg:=tregister(ppufile.getlongint);
                   localindexreg:=tregister(ppufile.getlongint);
                   localscale:=ppufile.getbyte;
                   localscale:=ppufile.getbyte;
                   localgetoffset:=(ppufile.getbyte<>0);
                   localgetoffset:=(ppufile.getbyte<>0);
@@ -3027,6 +3036,9 @@ implementation
                 begin
                 begin
                   ppufile.putderef(localsymderef);
                   ppufile.putderef(localsymderef);
                   ppufile.putaint(localsymofs);
                   ppufile.putaint(localsymofs);
+{$ifdef x86}
+                  ppufile.putlongint(longint(localsegment));
+{$endif x86}
                   ppufile.putlongint(longint(localindexreg));
                   ppufile.putlongint(longint(localindexreg));
                   ppufile.putbyte(localscale);
                   ppufile.putbyte(localscale);
                   ppufile.putbyte(byte(localgetoffset));
                   ppufile.putbyte(byte(localgetoffset));

+ 11 - 1
compiler/ncgbas.pas

@@ -127,6 +127,7 @@ interface
       var
       var
         sym : tabstractnormalvarsym;
         sym : tabstractnormalvarsym;
 {$ifdef x86}
 {$ifdef x86}
+        segment : tregister;
         scale : byte;
         scale : byte;
 {$endif x86}
 {$endif x86}
         forceref,
         forceref,
@@ -139,6 +140,7 @@ interface
             sofs:=op.localoper^.localsymofs;
             sofs:=op.localoper^.localsymofs;
             indexreg:=op.localoper^.localindexreg;
             indexreg:=op.localoper^.localindexreg;
 {$ifdef x86}
 {$ifdef x86}
+            segment:=op.localoper^.localsegment;
             scale:=op.localoper^.localscale;
             scale:=op.localoper^.localscale;
 {$endif x86}
 {$endif x86}
             getoffset:=op.localoper^.localgetoffset;
             getoffset:=op.localoper^.localgetoffset;
@@ -150,7 +152,11 @@ interface
                 begin
                 begin
                   if getoffset then
                   if getoffset then
                     begin
                     begin
-                      if indexreg=NR_NO then
+                      if (indexreg=NR_NO)
+{$ifdef x86}
+                         and (segment=NR_NO)
+{$endif x86}
+                         then
                         begin
                         begin
                           op.typ:=top_const;
                           op.typ:=top_const;
                           op.val:=sym.localloc.reference.offset+sofs;
                           op.val:=sym.localloc.reference.offset+sofs;
@@ -161,6 +167,9 @@ interface
                           new(op.ref);
                           new(op.ref);
                           reference_reset_base(op.ref^,indexreg,sym.localloc.reference.offset+sofs,
                           reference_reset_base(op.ref^,indexreg,sym.localloc.reference.offset+sofs,
                             newalignment(sym.localloc.reference.alignment,sofs),[]);
                             newalignment(sym.localloc.reference.alignment,sofs),[]);
+{$ifdef x86}
+                          op.ref^.segment:=segment;
+{$endif x86}
                         end;
                         end;
                     end
                     end
                   else
                   else
@@ -171,6 +180,7 @@ interface
                         newalignment(sym.localloc.reference.alignment,sofs),[]);
                         newalignment(sym.localloc.reference.alignment,sofs),[]);
                       op.ref^.index:=indexreg;
                       op.ref^.index:=indexreg;
 {$ifdef x86}
 {$ifdef x86}
+                      op.ref^.segment:=segment;
                       op.ref^.scalefactor:=scale;
                       op.ref^.scalefactor:=scale;
 {$endif x86}
 {$endif x86}
                     end;
                     end;

+ 1 - 1
compiler/ppu.pas

@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 {$endif Test_Double_checksum}
 
 
 const
 const
-  CurrentPPUVersion = 197;
+  CurrentPPUVersion = 198;
 
 
 { unit flags }
 { unit flags }
   uf_init                = $000001; { unit has initialization section }
   uf_init                = $000001; { unit has initialization section }

+ 32 - 4
compiler/rautils.pas

@@ -59,7 +59,7 @@ type
 {$endif}
 {$endif}
       OPR_SYMBOL    : (symbol:tasmsymbol;symofs:aint;symseg:boolean;sym_farproc_entry:boolean);
       OPR_SYMBOL    : (symbol:tasmsymbol;symofs:aint;symseg:boolean;sym_farproc_entry:boolean);
       OPR_REFERENCE : (varsize:asizeint; constoffset: asizeint;ref_farproc_entry:boolean;ref:treference);
       OPR_REFERENCE : (varsize:asizeint; constoffset: asizeint;ref_farproc_entry:boolean;ref:treference);
-      OPR_LOCAL     : (localvarsize, localconstoffset: asizeint;localsym:tabstractnormalvarsym;localsymofs:aint;localindexreg:tregister;localscale:byte;localgetoffset,localforceref:boolean);
+      OPR_LOCAL     : (localvarsize, localconstoffset: asizeint;localsym:tabstractnormalvarsym;localsymofs:aint;localsegment,localindexreg:tregister;localscale:byte;localgetoffset,localforceref:boolean);
       OPR_REGISTER  : (reg:tregister);
       OPR_REGISTER  : (reg:tregister);
 {$ifdef m68k}
 {$ifdef m68k}
       OPR_REGSET    : (regsetdata,regsetaddr,regsetfpu : tcpuregisterset);
       OPR_REGSET    : (regsetdata,regsetaddr,regsetfpu : tcpuregisterset);
@@ -810,6 +810,9 @@ Function TOperand.SetupVar(const s:string;GetOffset : boolean): Boolean;
 var
 var
   sym : tsym;
   sym : tsym;
   srsymtable : TSymtable;
   srsymtable : TSymtable;
+{$ifdef x86}
+  segreg,
+{$endif x86}
   indexreg : tregister;
   indexreg : tregister;
   plist : ppropaccesslistitem;
   plist : ppropaccesslistitem;
   size_set_from_absolute : boolean = false;
   size_set_from_absolute : boolean = false;
@@ -943,6 +946,9 @@ Begin
                 end;
                 end;
               if opr.typ=OPR_REFERENCE then
               if opr.typ=OPR_REFERENCE then
                 begin
                 begin
+{$ifdef x86}
+                  segreg:=opr.ref.segment;
+{$endif x86}
                   indexreg:=opr.ref.base;
                   indexreg:=opr.ref.base;
                   if opr.ref.index<>NR_NO then
                   if opr.ref.index<>NR_NO then
                     begin
                     begin
@@ -953,7 +959,12 @@ Begin
                     end;
                     end;
                 end
                 end
               else
               else
-                indexreg:=NR_NO;
+                begin
+{$ifdef x86}
+                  segreg:=NR_NO;
+{$endif x86}
+                  indexreg:=NR_NO;
+                end;
               opr.typ:=OPR_LOCAL;
               opr.typ:=OPR_LOCAL;
               if assigned(current_procinfo.parent) and
               if assigned(current_procinfo.parent) and
                  not(po_inline in current_procinfo.procdef.procoptions) and
                  not(po_inline in current_procinfo.procdef.procoptions) and
@@ -964,6 +975,9 @@ Begin
                 message1(asmr_e_local_para_unreachable,s);
                 message1(asmr_e_local_para_unreachable,s);
               opr.localsym:=tabstractnormalvarsym(sym);
               opr.localsym:=tabstractnormalvarsym(sym);
               opr.localsymofs:=absoffset;
               opr.localsymofs:=absoffset;
+{$ifdef x86}
+              opr.localsegment:=segreg;
+{$endif x86}
               opr.localindexreg:=indexreg;
               opr.localindexreg:=indexreg;
               opr.localscale:=0;
               opr.localscale:=0;
               opr.localgetoffset:=GetOffset;
               opr.localgetoffset:=GetOffset;
@@ -1128,6 +1142,9 @@ var
   localvarsize,localconstoffset: asizeint;
   localvarsize,localconstoffset: asizeint;
   localsym:tabstractnormalvarsym;
   localsym:tabstractnormalvarsym;
   localsymofs:aint;
   localsymofs:aint;
+{$ifdef x86}
+  localsegment,
+{$endif x86}
   localindexreg:tregister;
   localindexreg:tregister;
   localscale:byte;
   localscale:byte;
 begin
 begin
@@ -1140,6 +1157,9 @@ begin
           localconstoffset:=opr.localconstoffset;
           localconstoffset:=opr.localconstoffset;
           localsym:=opr.localsym;
           localsym:=opr.localsym;
           localsymofs:=opr.localsymofs;
           localsymofs:=opr.localsymofs;
+{$ifdef x86}
+          localsegment:=opr.localsegment;
+{$endif x86}
           localindexreg:=opr.localindexreg;
           localindexreg:=opr.localindexreg;
           localscale:=opr.localscale;;
           localscale:=opr.localscale;;
           opr.typ:=OPR_REFERENCE;
           opr.typ:=OPR_REFERENCE;
@@ -1150,6 +1170,9 @@ begin
           opr.ref_farproc_entry:=false;
           opr.ref_farproc_entry:=false;
           opr.ref.base:=tparavarsym(localsym).paraloc[calleeside].Location^.register;
           opr.ref.base:=tparavarsym(localsym).paraloc[calleeside].Location^.register;
           opr.ref.offset:=localsymofs;
           opr.ref.offset:=localsymofs;
+{$ifdef x86}
+          opr.ref.segment:=localsegment;
+{$endif x86}
           opr.ref.index:=localindexreg;
           opr.ref.index:=localindexreg;
           opr.ref.scalefactor:=localscale;
           opr.ref.scalefactor:=localscale;
         end
         end
@@ -1233,8 +1256,13 @@ end;
               OPR_SYMBOL:
               OPR_SYMBOL:
                 ai.loadsymbol(i-1,symbol,symofs);
                 ai.loadsymbol(i-1,symbol,symofs);
               OPR_LOCAL :
               OPR_LOCAL :
-                ai.loadlocal(i-1,localsym,localsymofs,localindexreg,
-                             localscale,localgetoffset,localforceref);
+                begin
+                  ai.loadlocal(i-1,localsym,localsymofs,localindexreg,
+                               localscale,localgetoffset,localforceref);
+{$ifdef x86}
+                  ai.oper[i-1]^.localoper^.localsegment:=localsegment;
+{$endif x86}
+                end;
               OPR_REFERENCE:
               OPR_REFERENCE:
                 ai.loadref(i-1,ref);
                 ai.loadref(i-1,ref);
 {$ifdef m68k}
 {$ifdef m68k}

+ 5 - 2
compiler/x86/rax86.pas

@@ -1240,8 +1240,11 @@ begin
           ai.loadsymbol(i-1,operands[i].opr.symbol,operands[i].opr.symofs);
           ai.loadsymbol(i-1,operands[i].opr.symbol,operands[i].opr.symofs);
        OPR_LOCAL :
        OPR_LOCAL :
          with operands[i].opr do
          with operands[i].opr do
-           ai.loadlocal(i-1,localsym,localsymofs,localindexreg,
-                        localscale,localgetoffset,localforceref);
+           begin
+             ai.loadlocal(i-1,localsym,localsymofs,localindexreg,
+                          localscale,localgetoffset,localforceref);
+             ai.oper[i-1]^.localoper^.localsegment:=localsegment;
+           end;
        OPR_REFERENCE:
        OPR_REFERENCE:
          begin
          begin
            if (opcode<>A_XLAT) and not is_x86_string_op(opcode) then
            if (opcode<>A_XLAT) and not is_x86_string_op(opcode) then