瀏覽代碼

+ added x86 helper function get_default_segment_of_ref, which returns the
default segment base for the ref, in case there's no segment override
* in the internal assembler, use get_default_segment_of_ref to strip redundant
prefixes, instead of always assuming all refs are DS-based

git-svn-id: trunk@37486 -

nickysn 7 年之前
父節點
當前提交
67a0e9bdae
共有 2 個文件被更改,包括 25 次插入2 次删除
  1. 6 2
      compiler/aasmtai.pas
  2. 19 0
      compiler/x86/aasmcpu.pas

+ 6 - 2
compiler/aasmtai.pas

@@ -2632,7 +2632,9 @@ implementation
                 if (si_param=opidx) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
                   segprefix:=ref^.segment;
               end
-            else if (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
+            else if (opcode=A_XLAT) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
+              segprefix:=ref^.segment
+            else if (ref^.segment<>NR_NO) and (ref^.segment<>get_default_segment_of_ref(ref^)) then
               segprefix:=ref^.segment;
 {$endif}
 {$ifndef llvm}
@@ -2720,7 +2722,9 @@ implementation
                       if (si_param=opidx) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
                         segprefix:=ref^.segment;
                     end
-                  else if (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
+                  else if (opcode=A_XLAT) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
+                    segprefix:=ref^.segment
+                  else if (ref^.segment<>NR_NO) and (ref^.segment<>get_default_segment_of_ref(ref^)) then
                     segprefix:=ref^.segment;
 {$endif x86}
                   if assigned(add_reg_instruction_hook) then

+ 19 - 0
compiler/x86/aasmcpu.pas

@@ -495,6 +495,7 @@ interface
     function is_32_bit_ref(const ref:treference):boolean;
     function is_16_bit_ref(const ref:treference):boolean;
     function get_ref_address_size(const ref:treference):byte;
+    function get_default_segment_of_ref(const ref:treference):tregister;
 
     function spilling_create_load(const ref:treference;r:tregister):Taicpu;
     function spilling_create_store(r:tregister; const ref:treference):Taicpu;
@@ -1849,6 +1850,24 @@ implementation
       end;
 
 
+    function get_default_segment_of_ref(const ref:treference):tregister;
+      begin
+        { for 16-bit registers, we allow base and index to be swapped, that's
+        why we also we check whether ref.index=NR_BP. For 32-bit registers,
+        however, index=NR_EBP is encoded differently than base=NR_EBP and has
+        a different default segment. }
+        if (ref.base=NR_BP) or (ref.index=NR_BP) or
+           (ref.base=NR_EBP) or (ref.base=NR_ESP)
+{$ifdef x86_64}
+        or (ref.base=NR_RBP) or (ref.base=NR_RSP)
+{$endif x86_64}
+           then
+          result:=NR_SS
+        else
+          result:=NR_DS;
+      end;
+
+
     function taicpu.needaddrprefix(opidx:byte):boolean;
       begin
 {$if defined(x86_64)}