Browse Source

llvm: support for adding/subtracting constants to pointers in typed constants

Fixes webtbs/tw34027 for llvm
Jonas Maebe 3 years ago
parent
commit
70908b1449
3 changed files with 34 additions and 10 deletions
  1. 8 8
      compiler/aasmcnst.pas
  2. 24 0
      compiler/llvm/nllvmtcon.pas
  3. 2 2
      compiler/ngtcon.pas

+ 8 - 8
compiler/aasmcnst.pas

@@ -428,10 +428,10 @@ type
      function queue_subscriptn_multiple_by_name(def: tabstractrecorddef; const fields: array of TIDString): tdef;
      { queue a type conversion operation }
      procedure queue_typeconvn(fromdef, todef: tdef); virtual;
-     { queue a add operation }
-     procedure queue_addn(def: tdef; const index: tconstexprint); virtual;
-     { queue a sub operation }
-     procedure queue_subn(def: tdef; const index: tconstexprint); virtual;
+     { queue a pointer add operation }
+     procedure queue_pointeraddn(def: tpointerdef; const index: tconstexprint); virtual;
+     { queue a pointer sub operation }
+     procedure queue_pointersubn(def: tpointerdef; const index: tconstexprint); virtual;
      { finalise the queue (so a new one can be created) and flush the
         previously queued operations, applying them in reverse order on a...}
      { ... procdef }
@@ -2107,15 +2107,15 @@ implementation
      end;
 
 
-   procedure ttai_typedconstbuilder.queue_addn(def: tdef; const index: tconstexprint);
+   procedure ttai_typedconstbuilder.queue_pointeraddn(def: tpointerdef; const index: tconstexprint);
      begin
-       inc(fqueue_offset,def.size*int64(index));
+       inc(fqueue_offset,def.pointeddef.size*int64(index));
      end;
 
 
-   procedure ttai_typedconstbuilder.queue_subn(def: tdef; const index: tconstexprint);
+   procedure ttai_typedconstbuilder.queue_pointersubn(def: tpointerdef; const index: tconstexprint);
      begin
-       dec(fqueue_offset,def.size*int64(index));
+       dec(fqueue_offset,def.pointeddef.size*int64(index));
      end;
 
 

+ 24 - 0
compiler/llvm/nllvmtcon.pas

@@ -106,6 +106,8 @@ interface
       procedure emit_dynarray_offset(const ll: tasmlabofs; const arrlength: asizeint; const arrdef: tarraydef; const arrconstdatadef: trecorddef); override;
       procedure queue_init(todef: tdef); override;
       procedure queue_vecn(def: tdef; const index: tconstexprint); override;
+      procedure queue_pointeraddn(def: tpointerdef; const index: tconstexprint); override;
+      procedure queue_pointersubn(def: tpointerdef; const index: tconstexprint); override;
       procedure queue_subscriptn(def: tabstractrecorddef; vs: tfieldvarsym); override;
       procedure queue_typeconvn(fromdef, todef: tdef); override;
       procedure queue_emit_staticvar(vs: tstaticvarsym); override;
@@ -671,6 +673,28 @@ implementation
     end;
 
 
+  procedure tllvmtai_typedconstbuilder.queue_pointeraddn(def: tpointerdef; const index: tconstexprint);
+    begin
+      queue_pointersubn(def, -index);
+    end;
+
+
+  procedure tllvmtai_typedconstbuilder.queue_pointersubn(def: tpointerdef; const index: tconstexprint);
+    var
+      ai: taillvm;
+      aityped: tai;
+    begin
+      { update range checking info }
+      inherited;
+      if index.svalue<>low(int64) then
+        ai:=taillvm.getelementptr_reg_tai_size_const(NR_NO,nil,ptrsinttype,-index.svalue,false)
+      else
+        ai:=taillvm.getelementptr_reg_tai_size_const(NR_NO,nil,ptrsinttype,index.svalue,false);
+      aityped:=wrap_with_type(ai,def);
+      update_queued_tai(def,aityped,ai,1);
+    end;
+
+
   procedure tllvmtai_typedconstbuilder.queue_subscriptn(def: tabstractrecorddef; vs: tfieldvarsym);
     var
       getllvmfieldaddr,

+ 2 - 2
compiler/ngtcon.pas

@@ -952,7 +952,7 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
                                is_constcharnode(taddnode(hp).right) or
                                is_constboolnode(taddnode(hp).right)) and
                                is_pointer(taddnode(hp).left.resultdef) then
-                               ftcb.queue_addn(tpointerdef(taddnode(hp).left.resultdef).pointeddef,get_ordinal_value(taddnode(hp).right))
+                               ftcb.queue_pointeraddn(tpointerdef(taddnode(hp).left.resultdef),get_ordinal_value(taddnode(hp).right))
                              else
                                Message(parser_e_illegal_expression);
                            end;
@@ -963,7 +963,7 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
                                is_constcharnode(taddnode(hp).right) or
                                is_constboolnode(taddnode(hp).right)) and
                                is_pointer(taddnode(hp).left.resultdef) then
-                               ftcb.queue_subn(tpointerdef(taddnode(hp).left.resultdef).pointeddef,get_ordinal_value(taddnode(hp).right))
+                               ftcb.queue_pointersubn(tpointerdef(taddnode(hp).left.resultdef),get_ordinal_value(taddnode(hp).right))
                              else
                                Message(parser_e_illegal_expression);
                            end;