Browse Source

+ implemented huge pointer subtraction
* the result of far pointer subtraction changed to word (for TP7 compatibility)

git-svn-id: trunk@28218 -

nickysn 11 năm trước cách đây
mục cha
commit
99c555cea8
3 tập tin đã thay đổi với 36 bổ sung13 xóa
  1. 17 0
      compiler/defutil.pas
  2. 16 11
      compiler/i8086/n8086add.pas
  3. 3 2
      compiler/nadd.pas

+ 17 - 0
compiler/defutil.pas

@@ -338,6 +338,11 @@ interface
        special i8086 pointer types (near, far, huge). }
     function get_int_type_for_pointer_arithmetic(p : tdef) : tdef;
 
+    {# returns the int type produced when subtracting two pointers of the given type p.
+       Normally, this is sinttype, except on i8086, where it takes into account the
+       special i8086 pointer types (near, far, huge). }
+    function get_int_result_type_from_pointer_subtraction(p : tdef) : tdef;
+
 {$ifdef i8086}
     {# Returns true if p is a far pointer def }
     function is_farpointer(p : tdef) : boolean;
@@ -1451,6 +1456,18 @@ implementation
           result:=sinttype;
       end;
 
+    function get_int_result_type_from_pointer_subtraction(p : tdef) : tdef;
+      begin
+{$ifdef i8086}
+        if is_hugepointer(p) then
+          result:=s32inttype
+        else if is_farpointer(p) then
+          result:=u16inttype
+        else
+{$endif i8086}
+          result:=sinttype;
+      end;
+
 {$ifdef i8086}
     { true if p is a far pointer def }
     function is_farpointer(p : tdef) : boolean;

+ 16 - 11
compiler/i8086/n8086add.pas

@@ -316,7 +316,7 @@ interface
 
     function ti8086addnode.first_addpointer: tnode;
       begin
-        if is_hugepointer(left.resultdef) xor is_hugepointer(right.resultdef) then
+        if is_hugepointer(left.resultdef) or is_hugepointer(right.resultdef) then
           result:=first_addhugepointer
         else
           result:=inherited;
@@ -329,17 +329,22 @@ interface
       begin
         result:=nil;
 
-        case nodetype of
-          addn:
-            procname:='fpc_hugeptr_add_longint';
-          subn:
-            procname:='fpc_hugeptr_sub_longint';
-          else
-            internalerror(2014070301);
-        end;
+        if (nodetype=subn) and is_hugepointer(left.resultdef) and is_hugepointer(right.resultdef) then
+          procname:='fpc_hugeptr_sub_hugeptr'
+        else
+          begin
+            case nodetype of
+              addn:
+                procname:='fpc_hugeptr_add_longint';
+              subn:
+                procname:='fpc_hugeptr_sub_longint';
+              else
+                internalerror(2014070301);
+            end;
 
-        if cs_hugeptr_arithmetic_normalization in current_settings.localswitches then
-          procname:=procname+'_normalized';
+            if cs_hugeptr_arithmetic_normalization in current_settings.localswitches then
+              procname:=procname+'_normalized';
+          end;
 
         if is_hugepointer(left.resultdef) then
           result := ccallnode.createintern(procname,

+ 3 - 2
compiler/nadd.pas

@@ -1697,9 +1697,10 @@ implementation
                       begin
                         hp:=getcopy;
                         include(hp.flags,nf_has_pointerdiv);
-                        result:=cmoddivnode.create(divn,hp,cordconstnode.create(tpointerdef(rd).pointeddef.size,sinttype,false));
+                        result:=cmoddivnode.create(divn,hp,
+                          cordconstnode.create(tpointerdef(rd).pointeddef.size,get_int_result_type_from_pointer_subtraction(rd),false));
                       end;
-                    resultdef:=sinttype;
+                    resultdef:=get_int_result_type_from_pointer_subtraction(rd);
                     exit;
                  end;
                else