Bläddra i källkod

* fixed the resultdef of length() intrinsic: it's ossinttype rather than
sinttype (they're the same on most platforms, except on 8 bit ones where
ossinttype is still 16 bit)
* simplified and documented second_length(), and fixed some (harmless)
errors in the used tcgsize for the resultdef (it had to be OS_SINT
rather than OS_INT -- now it's just def_cgsize(resultdef) so it's
always correct)

git-svn-id: branches/hlcgllvm@28387 -

Jonas Maebe 11 år sedan
förälder
incheckning
e8026ad8d3
2 ändrade filer med 20 tillägg och 15 borttagningar
  1. 19 14
      compiler/ncginl.pas
  2. 1 1
      compiler/ninl.pas

+ 19 - 14
compiler/ncginl.pas

@@ -68,7 +68,7 @@ implementation
     uses
       globtype,systems,constexp,
       cutils,verbose,globals,
-      symconst,symdef,defutil,symsym,
+      symconst,symtype,symdef,defutil,symsym,
       aasmbase,aasmtai,aasmdata,aasmcpu,parabase,
       cgbase,pass_1,pass_2,
       cpuinfo,cpubase,paramgr,procinfo,
@@ -287,6 +287,7 @@ implementation
       var
         lengthlab : tasmlabel;
         hregister : tregister;
+        lendef : tdef;
         href : treference;
       begin
         secondpass(left);
@@ -301,24 +302,28 @@ implementation
            hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
            current_asmdata.getjumplabel(lengthlab);
            hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,left.resultdef,OC_EQ,0,left.location.register,lengthlab);
-           if is_widestring(left.resultdef) and (tf_winlikewidestring in target_info.flags) then
-             begin
-               hlcg.reference_reset_base(href,left.resultdef,left.location.register,-sizeof(dword),sizeof(dword));
-               hregister:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,OS_INT);
-               cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_INT,href,hregister);
-             end
+           { the length of a widestring is a 32 bit unsigned int. Since every
+             character occupies 2 bytes, on a 32 bit platform you can express
+             the maximum length using 31 bits. On a 64 bit platform, it may be
+             32 bits. This means that regardless of the platform, a location
+             with size OS_SINT/ossinttype can hold the length without
+             overflowing (this code returns an ossinttype value) }
+           if is_widestring(left.resultdef) then
+             lendef:=u32inttype
            else
-             begin
-               hlcg.reference_reset_base(href,left.resultdef,left.location.register,-sizeof(pint),sizeof(pint));
-               hregister:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,OS_INT);
-               cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,href,hregister);
-             end;
+             lendef:=ossinttype;
+           hlcg.reference_reset_base(href,left.resultdef,left.location.register,-lendef.size,lendef.alignment);
+           { if the string pointer is nil, the length is 0 -> reuse the register
+             that originally held the string pointer for the length, so that we
+             can keep the original nil/0 as length in that case }
+           hregister:=cg.makeregsize(current_asmdata.CurrAsmList,left.location.register,def_cgsize(resultdef));
+           hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,lendef,resultdef,href,hregister);
            if is_widestring(left.resultdef) then
-             cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_INT,1,hregister);
+             hlcg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,resultdef,1,hregister);
 
            { Dynamic arrays do not have their length attached but their maximum index }
            if is_dynamic_array(left.resultdef) then
-             cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_ADD,OS_INT,1,hregister);
+             hlcg.a_op_const_reg(current_asmdata.CurrAsmList,OP_ADD,resultdef,1,hregister);
 
            cg.a_label(current_asmdata.CurrAsmList,lengthlab);
            location_reset(location,LOC_REGISTER,def_cgsize(resultdef));

+ 1 - 1
compiler/ninl.pas

@@ -2797,7 +2797,7 @@ implementation
                   if is_shortstring(left.resultdef) then
                     resultdef:=u8inttype
                   else
-                    resultdef:=sinttype;
+                    resultdef:=ossinttype;
                 end;
 
               in_typeinfo_x: