Forráskód Böngészése

* almost all second pass typeconvnode helpers are now processor independent
* fixed converting boolean to int64/qword
* fixed register allocation bugs which could cause internalerror 10
* isnode and asnode are completely processor indepent now as well
* fpc_do_as now returns its class argument (necessary to be able to use it
properly with compilerproc)

Jonas Maebe 24 éve
szülő
commit
fc6d300a95
6 módosított fájl, 657 hozzáadás és 487 törlés
  1. 10 2
      compiler/i386/cpunode.pas
  2. 61 454
      compiler/i386/n386cnv.pas
  3. 436 0
      compiler/ncgcnv.pas
  4. 127 25
      compiler/ncnv.pas
  5. 11 3
      rtl/inc/compproc.inc
  6. 12 3
      rtl/inc/objpas.inc

+ 10 - 2
compiler/i386/cpunode.pas

@@ -29,7 +29,7 @@ unit cpunode;
   implementation
   implementation
 
 
     uses
     uses
-       ncgbas,ncgflw,
+       ncgbas,ncgflw,ncgcnv,
        n386ld,n386add,n386cal,n386con,n386flw,n386mat,n386mem,
        n386ld,n386add,n386cal,n386con,n386flw,n386mat,n386mem,
        n386set,n386inl,n386opt,
        n386set,n386inl,n386opt,
        { this not really a node }
        { this not really a node }
@@ -38,7 +38,15 @@ unit cpunode;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.5  2001-09-28 20:39:33  jonas
+  Revision 1.6  2001-09-29 21:32:47  jonas
+    * almost all second pass typeconvnode helpers are now processor independent
+    * fixed converting boolean to int64/qword
+    * fixed register allocation bugs which could cause internalerror 10
+    * isnode and asnode are completely processor indepent now as well
+    * fpc_do_as now returns its class argument (necessary to be able to use it
+      properly with compilerproc)
+
+  Revision 1.5  2001/09/28 20:39:33  jonas
     * changed all flow control structures (except for exception handling
     * changed all flow control structures (except for exception handling
       related things) to processor independent code (in new ncgflw unit)
       related things) to processor independent code (in new ncgflw unit)
     + generic cgobj unit which contains lots of code generator helpers with
     + generic cgobj unit which contains lots of code generator helpers with

+ 61 - 454
compiler/i386/n386cnv.pas

@@ -27,30 +27,30 @@ unit n386cnv;
 interface
 interface
 
 
     uses
     uses
-      node,ncnv,types;
+      node,ncnv,ncgcnv,types;
 
 
     type
     type
-       ti386typeconvnode = class(ttypeconvnode)
-          procedure second_int_to_int;virtual;
-         { procedure second_string_to_string;virtual; }
-          procedure second_cstring_to_pchar;virtual;
-          procedure second_string_to_chararray;virtual;
-          procedure second_array_to_pointer;virtual;
-          procedure second_pointer_to_array;virtual;
-         { procedure second_chararray_to_string;virtual; }
-          procedure second_char_to_string;virtual;
-          procedure second_int_to_real;virtual;
-          procedure second_real_to_real;virtual;
-          procedure second_cord_to_pointer;virtual;
-          procedure second_proc_to_procvar;virtual;
-          procedure second_bool_to_int;virtual;
-          procedure second_int_to_bool;virtual;
-          procedure second_load_smallset;virtual;
-          procedure second_ansistring_to_pchar;virtual;
-         { procedure second_pchar_to_string;virtual; }
-          procedure second_class_to_intf;virtual;
-          procedure second_char_to_char;virtual;
-          procedure second_nothing;virtual;
+       ti386typeconvnode = class(tcgtypeconvnode)
+         protected
+          procedure second_int_to_int;override;
+         { procedure second_string_to_string;override; }
+         { procedure second_cstring_to_pchar;override; }
+         { procedure second_string_to_chararray;override; }
+         { procedure second_array_to_pointer;override; }
+         { procedure second_pointer_to_array;override; }
+         { procedure second_chararray_to_string;override; }
+         { procedure second_char_to_string;override; }
+          procedure second_int_to_real;override;
+         { procedure second_real_to_real;override; }
+         { procedure second_cord_to_pointer;override; }
+         { procedure second_proc_to_procvar;override; }
+         { procedure second_bool_to_int;override; }
+          procedure second_int_to_bool;override;
+         { procedure second_load_smallset;override;  }
+         { procedure second_ansistring_to_pchar;override; }
+         { procedure second_pchar_to_string;override; }
+         { procedure second_class_to_intf;override;  }
+         { procedure second_char_to_char;override; }
           procedure pass_2;override;
           procedure pass_2;override;
           procedure second_call_helper(c : tconverttype);
           procedure second_call_helper(c : tconverttype);
        end;
        end;
@@ -201,141 +201,6 @@ implementation
       end;
       end;
 
 
 
 
-    procedure ti386typeconvnode.second_cstring_to_pchar;
-      var
-        hr : preference;
-      begin
-         clear_location(location);
-         location.loc:=LOC_REGISTER;
-         case tstringdef(left.resulttype.def).string_typ of
-           st_shortstring :
-             begin
-               inc(left.location.reference.offset);
-               del_reference(left.location.reference);
-               location.register:=getregister32;
-               emit_ref_reg(A_LEA,S_L,newreference(left.location.reference),
-                 location.register);
-             end;
-           st_ansistring :
-             begin
-               if (left.nodetype=stringconstn) and
-                  (str_length(left)=0) then
-                begin
-                  new(hr);
-                  reset_reference(hr^);
-                  hr^.symbol:=newasmsymbol('FPC_EMPTYCHAR');
-                  location.register:=getregister32;
-                  emit_ref_reg(A_LEA,S_L,hr,location.register);
-                end
-               else
-                begin
-                  del_reference(left.location.reference);
-                  location.register:=getregister32;
-                  emit_ref_reg(A_MOV,S_L,newreference(left.location.reference),
-                    location.register);
-                end;
-             end;
-           st_longstring:
-             begin
-               {!!!!!!!}
-               internalerror(8888);
-             end;
-           st_widestring:
-             begin
-               if (left.nodetype=stringconstn) and
-                  (str_length(left)=0) then
-                begin
-                  new(hr);
-                  reset_reference(hr^);
-                  hr^.symbol:=newasmsymbol('FPC_EMPTYCHAR');
-                  location.register:=getregister32;
-                  emit_ref_reg(A_LEA,S_L,hr,location.register);
-                end
-               else
-                begin
-                  del_reference(left.location.reference);
-                  location.register:=getregister32;
-                  emit_ref_reg(A_MOV,S_L,newreference(left.location.reference),
-                    location.register);
-                end;
-             end;
-         end;
-      end;
-
-
-    procedure ti386typeconvnode.second_string_to_chararray;
-      var
-        arrsize: longint;
-      begin
-         with tarraydef(resulttype.def) do
-           arrsize := highrange-lowrange+1;
-         if (left.nodetype = stringconstn) and
-            { left.length+1 since there's always a terminating #0 character (JM) }
-            (tstringconstnode(left).len+1 >= arrsize) and
-            (tstringdef(left.resulttype.def).string_typ=st_shortstring) then
-           begin
-             inc(location.reference.offset);
-             exit;
-           end
-         else
-           { should be handled already in resulttype pass (JM) }
-           internalerror(200108292);
-      end;
-
-
-    procedure ti386typeconvnode.second_array_to_pointer;
-      begin
-         del_reference(left.location.reference);
-         clear_location(location);
-         location.loc:=LOC_REGISTER;
-         location.register:=getregister32;
-         emit_ref_reg(A_LEA,S_L,newreference(left.location.reference),
-           location.register);
-      end;
-
-
-    procedure ti386typeconvnode.second_pointer_to_array;
-      begin
-        clear_location(location);
-        location.loc:=LOC_REFERENCE;
-        reset_reference(location.reference);
-        case left.location.loc of
-          LOC_REGISTER :
-            location.reference.base:=left.location.register;
-          LOC_CREGISTER :
-            begin
-              location.reference.base:=getregister32;
-              emit_reg_reg(A_MOV,S_L,left.location.register,location.reference.base);
-            end
-         else
-            begin
-              del_reference(left.location.reference);
-              location.reference.base:=getregister32;
-              emit_ref_reg(A_MOV,S_L,newreference(left.location.reference),
-                location.reference.base);
-            end;
-        end;
-      end;
-
-
-    procedure ti386typeconvnode.second_char_to_string;
-
-      begin
-         clear_location(location);
-         location.loc:=LOC_MEM;
-         case tstringdef(resulttype.def).string_typ of
-           st_shortstring :
-             begin
-               gettempofsizereference(256,location.reference);
-               loadshortstring(left,self);
-             end;
-           { the rest is removed in the resulttype pass and coverted to compilerprocs }
-           else
-            internalerror(4179);
-        end;
-      end;
-
-
     procedure ti386typeconvnode.second_int_to_real;
     procedure ti386typeconvnode.second_int_to_real;
 
 
       var
       var
@@ -454,175 +319,6 @@ implementation
       end;
       end;
 
 
 
 
-    procedure ti386typeconvnode.second_real_to_real;
-      begin
-         case left.location.loc of
-            LOC_FPU : ;
-            LOC_CFPUREGISTER:
-              begin
-                 location:=left.location;
-                 exit;
-              end;
-            LOC_MEM,
-            LOC_REFERENCE:
-              begin
-                 floatload(tfloatdef(left.resulttype.def).typ,
-                   left.location.reference);
-                 { we have to free the reference }
-                 del_reference(left.location.reference);
-              end;
-         end;
-         clear_location(location);
-         location.loc:=LOC_FPU;
-      end;
-
-
-    procedure ti386typeconvnode.second_cord_to_pointer;
-      begin
-        { this can't happend, because constants are already processed in
-          pass 1 }
-        internalerror(47423985);
-      end;
-
-
-    procedure ti386typeconvnode.second_proc_to_procvar;
-      begin
-        { method pointer ? }
-        if assigned(tcallnode(left).left) then
-          begin
-             set_location(location,left.location);
-          end
-        else
-          begin
-             clear_location(location);
-             location.loc:=LOC_REGISTER;
-             location.register:=getregister32;
-             del_reference(left.location.reference);
-             emit_ref_reg(A_LEA,S_L,
-               newreference(left.location.reference),location.register);
-          end;
-      end;
-
-
-    procedure ti386typeconvnode.second_bool_to_int;
-      var
-         oldtruelabel,oldfalselabel,hlabel : tasmlabel;
-         hregister : tregister;
-         newsize,
-         opsize : topsize;
-         op     : tasmop;
-      begin
-         oldtruelabel:=truelabel;
-         oldfalselabel:=falselabel;
-         getlabel(truelabel);
-         getlabel(falselabel);
-         secondpass(left);
-         { byte(boolean) or word(wordbool) or longint(longbool) must
-         be accepted for var parameters }
-         if (nf_explizit in flags) and
-            (left.resulttype.def.size=resulttype.def.size) and
-            (left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
-           begin
-              set_location(location,left.location);
-              truelabel:=oldtruelabel;
-              falselabel:=oldfalselabel;
-              exit;
-           end;
-         clear_location(location);
-         location.loc:=LOC_REGISTER;
-         del_reference(left.location.reference);
-         case left.resulttype.def.size of
-          1 : begin
-                case resulttype.def.size of
-                 1 : opsize:=S_B;
-                 2 : opsize:=S_BW;
-                 4 : opsize:=S_BL;
-                end;
-              end;
-          2 : begin
-                case resulttype.def.size of
-                 1 : begin
-                       if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
-                        left.location.register:=reg16toreg8(left.location.register);
-                       opsize:=S_B;
-                     end;
-                 2 : opsize:=S_W;
-                 4 : opsize:=S_WL;
-                end;
-              end;
-          4 : begin
-                case resulttype.def.size of
-                 1 : begin
-                       if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
-                        left.location.register:=reg32toreg8(left.location.register);
-                       opsize:=S_B;
-                     end;
-                 2 : begin
-                       if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
-                        left.location.register:=reg32toreg16(left.location.register);
-                       opsize:=S_W;
-                     end;
-                 4 : opsize:=S_L;
-                end;
-              end;
-         end;
-         if opsize in [S_B,S_W,S_L] then
-          op:=A_MOV
-         else
-          if is_signed(resulttype.def) then
-           op:=A_MOVSX
-          else
-           op:=A_MOVZX;
-         hregister:=getregister32;
-         case resulttype.def.size of
-          1 : begin
-                location.register:=reg32toreg8(hregister);
-                newsize:=S_B;
-              end;
-          2 : begin
-                location.register:=reg32toreg16(hregister);
-                newsize:=S_W;
-              end;
-          4 : begin
-                location.register:=hregister;
-                newsize:=S_L;
-              end;
-         else
-          internalerror(10060);
-         end;
-
-         case left.location.loc of
-            LOC_MEM,
-      LOC_REFERENCE : emit_ref_reg(op,opsize,
-                        newreference(left.location.reference),location.register);
-       LOC_REGISTER,
-      LOC_CREGISTER : begin
-                      { remove things like movb %al,%al }
-                        if left.location.register<>location.register then
-                          emit_reg_reg(op,opsize,
-                            left.location.register,location.register);
-                      end;
-          LOC_FLAGS : begin
-                        emit_flag2reg(left.location.resflags,location.register);
-                      end;
-           LOC_JUMP : begin
-                        getlabel(hlabel);
-                        emitlab(truelabel);
-                        emit_const_reg(A_MOV,newsize,1,location.register);
-                        emitjmp(C_None,hlabel);
-                        emitlab(falselabel);
-                        emit_reg_reg(A_XOR,newsize,location.register,
-                          location.register);
-                        emitlab(hlabel);
-                      end;
-         else
-           internalerror(10061);
-         end;
-         truelabel:=oldtruelabel;
-         falselabel:=oldfalselabel;
-      end;
-
-
     procedure ti386typeconvnode.second_int_to_bool;
     procedure ti386typeconvnode.second_int_to_bool;
       var
       var
         hregister : tregister;
         hregister : tregister;
@@ -630,8 +326,8 @@ implementation
         opsize    : topsize;
         opsize    : topsize;
       begin
       begin
          clear_location(location);
          clear_location(location);
-         { byte(boolean) or word(wordbool) or longint(longbool) must
-         be accepted for var parameters }
+         { byte(boolean) or word(wordbool) or longint(longbool) must }
+         { be accepted for var parameters                            }
          if (nf_explizit in flags) and
          if (nf_explizit in flags) and
             (left.resulttype.def.size=resulttype.def.size) and
             (left.resulttype.def.size=resulttype.def.size) and
             (left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
             (left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
@@ -640,7 +336,7 @@ implementation
               exit;
               exit;
            end;
            end;
          location.loc:=LOC_REGISTER;
          location.loc:=LOC_REGISTER;
-         del_reference(left.location.reference);
+         del_location(left.location);
          opsize:=def_opsize(left.resulttype.def);
          opsize:=def_opsize(left.resulttype.def);
          case left.location.loc of
          case left.location.loc of
             LOC_MEM,LOC_REFERENCE :
             LOC_MEM,LOC_REFERENCE :
@@ -676,103 +372,6 @@ implementation
       end;
       end;
 
 
 
 
-    procedure ti386typeconvnode.second_load_smallset;
-      var
-        href : treference;
-        pushedregs : tpushed;
-      begin
-        href.symbol:=nil;
-        pushusedregisters(pushedregs,$ff);
-        gettempofsizereference(32,href);
-        emit_push_mem_size(left.location.reference,4);
-        emitpushreferenceaddr(href);
-        saveregvars($ff);
-        emitcall('FPC_SET_LOAD_SMALL');
-        maybe_loadself;
-        popusedregisters(pushedregs);
-        clear_location(location);
-        location.loc:=LOC_MEM;
-        location.reference:=href;
-      end;
-
-
-    procedure ti386typeconvnode.second_ansistring_to_pchar;
-      var
-         l1 : tasmlabel;
-         hr : preference;
-      begin
-         clear_location(location);
-         location.loc:=LOC_REGISTER;
-         getlabel(l1);
-         case left.location.loc of
-            LOC_CREGISTER,LOC_REGISTER:
-              location.register:=left.location.register;
-            LOC_MEM,LOC_REFERENCE:
-              begin
-                location.register:=getregister32;
-                emit_ref_reg(A_MOV,S_L,newreference(left.location.reference),
-                  location.register);
-                del_reference(left.location.reference);
-              end;
-         end;
-         emit_const_reg(A_CMP,S_L,0,location.register);
-         emitjmp(C_NZ,l1);
-         new(hr);
-         reset_reference(hr^);
-         hr^.symbol:=newasmsymbol('FPC_EMPTYCHAR');
-         emit_ref_reg(A_LEA,S_L,hr,location.register);
-         emitlab(l1);
-      end;
-
-
-    procedure ti386typeconvnode.second_class_to_intf;
-      var
-         hreg : tregister;
-         l1 : tasmlabel;
-      begin
-         case left.location.loc of
-            LOC_MEM,
-            LOC_REFERENCE:
-              begin
-                 del_reference(left.location.reference);
-                 hreg:=getregister32;
-                 exprasmList.concat(Taicpu.Op_ref_reg(
-                   A_MOV,S_L,newreference(left.location.reference),hreg));
-              end;
-            LOC_CREGISTER:
-              begin
-                 hreg:=getregister32;
-                 exprasmList.concat(Taicpu.Op_reg_reg(
-                   A_MOV,S_L,left.location.register,hreg));
-              end;
-            LOC_REGISTER:
-              hreg:=left.location.register;
-            else internalerror(121120001);
-         end;
-         emit_reg_reg(A_TEST,S_L,hreg,hreg);
-         getlabel(l1);
-         emitjmp(C_Z,l1);
-         emit_const_reg(A_ADD,S_L,tobjectdef(left.resulttype.def).implementedinterfaces.ioffsets(
-           tobjectdef(left.resulttype.def).implementedinterfaces.searchintf(resulttype.def))^,hreg);
-         emitlab(l1);
-         location.loc:=LOC_REGISTER;
-         location.register:=hreg;
-      end;
-
-
-    procedure ti386typeconvnode.second_char_to_char;
-      begin
-        {$warning todo: add RTL routine for widechar-char conversion }
-        { Quick hack to atleast generate 'working' code (PFV) }
-        second_int_to_int;
-      end;
-
-
-    procedure ti386typeconvnode.second_nothing;
-      begin
-      end;
-
-
 {****************************************************************************
 {****************************************************************************
                            TI386TYPECONVNODE
                            TI386TYPECONVNODE
 ****************************************************************************}
 ****************************************************************************}
@@ -781,33 +380,33 @@ implementation
 
 
       const
       const
          secondconvert : array[tconverttype] of pointer = (
          secondconvert : array[tconverttype] of pointer = (
-           @ti386typeconvnode.second_nothing, {equal}
-           @ti386typeconvnode.second_nothing, {not_possible}
-           @ti386typeconvnode.second_nothing, {second_string_to_string, handled in resulttype pass }
-           @ti386typeconvnode.second_char_to_string,
-           @ti386typeconvnode.second_nothing, { pchar_to_string, handled in resulttype pass }
-           @ti386typeconvnode.second_nothing, {cchar_to_pchar}
-           @ti386typeconvnode.second_cstring_to_pchar,
-           @ti386typeconvnode.second_ansistring_to_pchar,
-           @ti386typeconvnode.second_string_to_chararray,
-           @ti386typeconvnode.second_nothing, { chararray_to_string, handled in resulttype pass }
-           @ti386typeconvnode.second_array_to_pointer,
-           @ti386typeconvnode.second_pointer_to_array,
-           @ti386typeconvnode.second_int_to_int,
-           @ti386typeconvnode.second_int_to_bool,
-           @ti386typeconvnode.second_bool_to_int, { bool_to_bool }
-           @ti386typeconvnode.second_bool_to_int,
-           @ti386typeconvnode.second_real_to_real,
-           @ti386typeconvnode.second_int_to_real,
-           @ti386typeconvnode.second_proc_to_procvar,
-           @ti386typeconvnode.second_nothing, {arrayconstructor_to_set}
-           @ti386typeconvnode.second_load_smallset,
-           @ti386typeconvnode.second_cord_to_pointer,
-           @ti386typeconvnode.second_nothing, { interface 2 string }
-           @ti386typeconvnode.second_nothing, { interface 2 guid   }
-           @ti386typeconvnode.second_class_to_intf,
-           @ti386typeconvnode.second_char_to_char,
-           @ti386typeconvnode.second_nothing  { normal_2_smallset }
+           @second_nothing, {equal}
+           @second_nothing, {not_possible}
+           @second_nothing, {second_string_to_string, handled in resulttype pass }
+           @second_char_to_string,
+           @second_nothing, { pchar_to_string, handled in resulttype pass }
+           @second_nothing, {cchar_to_pchar}
+           @second_cstring_to_pchar,
+           @second_ansistring_to_pchar,
+           @second_string_to_chararray,
+           @second_nothing, { chararray_to_string, handled in resulttype pass }
+           @second_array_to_pointer,
+           @second_pointer_to_array,
+           @second_int_to_int,
+           @second_int_to_bool,
+           @second_bool_to_int, { bool_to_bool }
+           @second_bool_to_int,
+           @second_real_to_real,
+           @second_int_to_real,
+           @second_proc_to_procvar,
+           @second_nothing, { arrayconstructor_to_set }
+           @second_nothing, { second_load_smallset, handled in first pass }
+           @second_cord_to_pointer,
+           @second_nothing, { interface 2 string }
+           @second_nothing, { interface 2 guid   }
+           @second_class_to_intf,
+           @second_char_to_char,
+           @second_nothing  { normal_2_smallset }
          );
          );
       type
       type
          tprocedureofobject = procedure of object;
          tprocedureofobject = procedure of object;
@@ -1001,7 +600,15 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.23  2001-09-03 13:27:42  jonas
+  Revision 1.24  2001-09-29 21:32:47  jonas
+    * almost all second pass typeconvnode helpers are now processor independent
+    * fixed converting boolean to int64/qword
+    * fixed register allocation bugs which could cause internalerror 10
+    * isnode and asnode are completely processor indepent now as well
+    * fpc_do_as now returns its class argument (necessary to be able to use it
+      properly with compilerproc)
+
+  Revision 1.23  2001/09/03 13:27:42  jonas
     * compilerproc implementation of set addition/substraction/...
     * compilerproc implementation of set addition/substraction/...
     * changed the declaration of some set helpers somewhat to accomodate the
     * changed the declaration of some set helpers somewhat to accomodate the
       above change
       above change

+ 436 - 0
compiler/ncgcnv.pas

@@ -0,0 +1,436 @@
+{
+    $Id$
+    Copyright (c) 2000 by Florian Klaempfl
+
+    Generate assembler for nodes that handle type conversions which are
+    the same for all (most) processors
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit ncgcnv;
+
+{$i defines.inc}
+
+interface
+
+    uses
+       node,ncnv;
+
+    type
+       tcgtypeconvnode = class(ttypeconvnode)
+         procedure second_cstring_to_pchar;override;
+         procedure second_string_to_chararray;override;
+         procedure second_array_to_pointer;override;
+         procedure second_pointer_to_array;override;
+         procedure second_char_to_string;override;
+         procedure second_real_to_real;override;
+         procedure second_cord_to_pointer;override;
+         procedure second_proc_to_procvar;override;
+         procedure second_bool_to_int;override;
+         procedure second_ansistring_to_pchar;override;
+         procedure second_class_to_intf;override;
+         procedure second_char_to_char;override;
+       end;
+
+  implementation
+
+    uses
+      globtype,
+      cutils,cclasses,globals,verbose,
+      aasm,symconst,symsym,symtable,symdef,symtype,types,
+      ncon,ncal,
+      htypechk,
+      cpubase,cpuasm,
+      pass_2,
+      cgbase,
+      cga,cgobj,cgcpu,
+{$ifdef i386}
+      n386util,
+{$endif i386}
+      tgcpu,temp_gen
+      ;
+
+
+    procedure tcgtypeconvnode.second_cstring_to_pchar;
+
+      var
+        hr : treference;
+
+      begin
+         clear_location(location);
+         location.loc:=LOC_REGISTER;
+         case tstringdef(left.resulttype.def).string_typ of
+           st_shortstring :
+             begin
+               inc(left.location.reference.offset);
+               del_reference(left.location.reference);
+               location.register:=getregister32;
+               cg.a_loadaddress_ref_reg(exprasmlist,left.location.reference,
+                 location.register);
+             end;
+           st_ansistring :
+             begin
+               if (left.nodetype=stringconstn) and
+                  (str_length(left)=0) then
+                begin
+                  reset_reference(hr);
+                  hr.symbol:=newasmsymbol('FPC_EMPTYCHAR');
+                  location.register:=getregister32;
+                  cg.a_loadaddress_ref_reg(exprasmlist,hr,location.register);
+                end
+               else
+                begin
+                  del_reference(left.location.reference);
+                  location.register:=getregister32;
+                  cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,
+                    location.register);
+                end;
+             end;
+           st_longstring:
+             begin
+               {!!!!!!!}
+               internalerror(8888);
+             end;
+           st_widestring:
+             begin
+               if (left.nodetype=stringconstn) and
+                  (str_length(left)=0) then
+                begin
+                  reset_reference(hr);
+                  hr.symbol:=newasmsymbol('FPC_EMPTYCHAR');
+                  location.register:=getregister32;
+                  cg.a_loadaddress_ref_reg(exprasmlist,hr,location.register);
+                end
+               else
+                begin
+                  del_reference(left.location.reference);
+                  location.register:=getregister32;
+{$warning Todo: convert widestrings to ascii when typecasting them to pchars}
+                  cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,
+                    location.register);
+                end;
+             end;
+         end;
+      end;
+
+
+    procedure tcgtypeconvnode.second_string_to_chararray;
+
+      var
+        arrsize: longint;
+
+      begin
+         with tarraydef(resulttype.def) do
+           arrsize := highrange-lowrange+1;
+         if (left.nodetype = stringconstn) and
+            { left.length+1 since there's always a terminating #0 character (JM) }
+            (tstringconstnode(left).len+1 >= arrsize) and
+            (tstringdef(left.resulttype.def).string_typ=st_shortstring) then
+           begin
+             inc(location.reference.offset);
+             exit;
+           end
+         else
+           { should be handled already in resulttype pass (JM) }
+           internalerror(200108292);
+      end;
+
+
+    procedure tcgtypeconvnode.second_array_to_pointer;
+
+      begin
+         del_reference(left.location.reference);
+         clear_location(location);
+         location.loc:=LOC_REGISTER;
+         location.register:=getregister32;
+         cg.a_loadaddress_ref_reg(exprasmlist,left.location.reference,
+           location.register);
+      end;
+
+
+    procedure tcgtypeconvnode.second_pointer_to_array;
+
+      begin
+        clear_location(location);
+        location.loc:=LOC_REFERENCE;
+        reset_reference(location.reference);
+        case left.location.loc of
+          LOC_REGISTER :
+            location.reference.base:=left.location.register;
+          LOC_CREGISTER :
+            begin
+              location.reference.base:=getregister32;
+              cg.a_load_reg_reg(exprasmlist,OS_32,left.location.register,
+                location.reference.base);
+            end
+         else
+            begin
+              del_reference(left.location.reference);
+              location.reference.base:=getregister32;
+              cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,
+                location.reference.base);
+            end;
+        end;
+      end;
+
+
+    procedure tcgtypeconvnode.second_char_to_string;
+
+      begin
+         clear_location(location);
+         location.loc:=LOC_MEM;
+         case tstringdef(resulttype.def).string_typ of
+           st_shortstring :
+             begin
+               gettempofsizereference(256,location.reference);
+               loadshortstring(left,self);
+             end;
+           { the rest is removed in the resulttype pass and converted to compilerprocs }
+           else
+            internalerror(4179);
+        end;
+      end;
+
+
+    procedure tcgtypeconvnode.second_real_to_real;
+      begin
+         case left.location.loc of
+            LOC_FPU : ;
+            LOC_CFPUREGISTER:
+              begin
+                 location:=left.location;
+                 exit;
+              end;
+            LOC_MEM,
+            LOC_REFERENCE:
+              begin
+                 floatload(tfloatdef(left.resulttype.def).typ,
+                   left.location.reference);
+                 { we have to free the reference }
+                 del_reference(left.location.reference);
+              end;
+         end;
+         clear_location(location);
+         location.loc:=LOC_FPU;
+      end;
+
+
+    procedure tcgtypeconvnode.second_cord_to_pointer;
+      begin
+        { this can't happen because constants are already processed in
+          pass 1 }
+        internalerror(47423985);
+      end;
+
+
+    procedure tcgtypeconvnode.second_proc_to_procvar;
+
+      begin
+        { method pointer ? }
+        if assigned(tcallnode(left).left) then
+          begin
+             set_location(location,left.location);
+          end
+        else
+          begin
+             clear_location(location);
+             location.loc:=LOC_REGISTER;
+             del_reference(left.location.reference);
+             location.register:=getregister32;
+             cg.a_loadaddress_ref_reg(exprasmlist,left.location.reference,
+               location.register);
+          end;
+      end;
+
+
+    procedure tcgtypeconvnode.second_bool_to_int;
+
+      var
+         oldtruelabel,oldfalselabel,hlabel : tasmlabel;
+         newsize,
+         opsize : tcgsize;
+
+      begin
+         oldtruelabel:=truelabel;
+         oldfalselabel:=falselabel;
+         getlabel(truelabel);
+         getlabel(falselabel);
+         secondpass(left);
+         { byte(boolean) or word(wordbool) or longint(longbool) must }
+         { be accepted for var parameters                            }
+         if (nf_explizit in flags) and
+            (left.resulttype.def.size=resulttype.def.size) and
+            (left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
+           begin
+              set_location(location,left.location);
+              truelabel:=oldtruelabel;
+              falselabel:=oldfalselabel;
+              exit;
+           end;
+         clear_location(location);
+         location.loc:=LOC_REGISTER;
+         del_location(left.location);
+         location.register:=getregister32;
+         { size of the boolean we're converting }
+         opsize := def_cgsize(left.resulttype.def);
+         { size of the destination }
+         newsize := def_cgsize(resulttype.def);
+         { the the source size is bigger than the destination, we can }
+         { simply decrease the sources size (since wordbool(true) =   }
+         { boolean(true) etc... (JM)                                  }
+         case newsize of
+           OS_8,OS_S8:
+             begin
+               opsize := OS_8;
+{$ifdef i386}
+               location.register := makereg8(location.register);
+               if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
+                 makereg8(left.location.register);
+{$endif i386}
+             end;
+           OS_16,OS_S16:
+             begin
+{$ifdef i386}
+               location.register := makereg16(location.register);
+{$endif i386}
+               if opsize in [OS_32,OS_S32] then
+                 begin
+                   opsize := OS_16;
+{$ifdef i386}
+                   if (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+                     makereg16(left.location.register);
+{$endif i386}
+                 end
+             end;
+         end;
+         case left.location.loc of
+            LOC_MEM,
+      LOC_REFERENCE :
+           cg.a_load_ref_reg(exprasmlist,opsize,left.location.reference,
+             location.register);
+       LOC_REGISTER,
+      LOC_CREGISTER :
+           if left.location.register<>location.register then
+             cg.a_load_reg_reg(exprasmlist,opsize,left.location.register,
+               location.register);
+          LOC_FLAGS :
+            cg.g_flags2reg(exprasmlist,left.location.resflags,location.register);
+           LOC_JUMP :
+             begin
+               getlabel(hlabel);
+               cg.a_label(exprasmlist,truelabel);
+               cg.a_load_const_reg(exprasmlist,newsize,1,location.register);
+               cg.a_jmp_cond(exprasmlist,OC_NONE,hlabel);
+               cg.a_label(exprasmlist,falselabel);
+               cg.a_load_const_reg(exprasmlist,newsize,0,location.register);
+               cg.a_label(exprasmlist,hlabel);
+             end;
+         else
+           internalerror(10061);
+         end;
+         truelabel:=oldtruelabel;
+         falselabel:=oldfalselabel;
+      end;
+
+
+    procedure tcgtypeconvnode.second_ansistring_to_pchar;
+      var
+         l1 : tasmlabel;
+         hr : treference;
+      begin
+         clear_location(location);
+         location.loc:=LOC_REGISTER;
+         getlabel(l1);
+         case left.location.loc of
+            LOC_CREGISTER,LOC_REGISTER:
+              location.register:=left.location.register;
+            LOC_MEM,LOC_REFERENCE:
+              begin
+                del_reference(left.location.reference);
+                location.register:=getregister32;
+                cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,
+                  location.register);
+              end;
+         end;
+         cg.a_cmp_const_reg_label(exprasmlist,OS_32,OC_NE,0,location.register,
+           l1);
+         reset_reference(hr);
+         hr.symbol:=newasmsymbol('FPC_EMPTYCHAR');
+         cg.a_loadaddress_ref_reg(exprasmlist,hr,location.register);
+         cg.a_label(exprasmlist,l1);
+      end;
+
+
+    procedure tcgtypeconvnode.second_class_to_intf;
+      var
+         hreg : tregister;
+         l1 : tasmlabel;
+      begin
+         case left.location.loc of
+            LOC_MEM,
+            LOC_REFERENCE:
+              begin
+                 del_reference(left.location.reference);
+                 hreg:=getregister32;
+                 cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,
+                   hreg);
+              end;
+            LOC_CREGISTER:
+              begin
+                 hreg:=getregister32;
+                 cg.a_load_reg_reg(exprasmlist,OS_32,left.location.register,
+                   hreg);
+              end;
+            LOC_REGISTER:
+              hreg:=left.location.register;
+            else internalerror(121120001);
+         end;
+         getlabel(l1);
+         cg.a_cmp_const_reg_label(exprasmlist,OS_32,OC_EQ,0,hreg,l1);
+         cg.a_op_const_reg(exprasmlist,OP_ADD,
+           tobjectdef(left.resulttype.def).implementedinterfaces.ioffsets(
+           tobjectdef(left.resulttype.def).implementedinterfaces.searchintf(
+           resulttype.def))^,hreg);
+         cg.a_label(exprasmlist,l1);
+         location.loc:=LOC_REGISTER;
+         location.register:=hreg;
+      end;
+
+
+    procedure tcgtypeconvnode.second_char_to_char;
+      begin
+        {$warning todo: add RTL routine for widechar-char conversion }
+        { Quick hack to atleast generate 'working' code (PFV) }
+        second_int_to_int;
+      end;
+
+begin
+  ctypeconvnode := tcgtypeconvnode;
+end.
+
+{
+  $Log$
+  Revision 1.1  2001-09-29 21:32:47  jonas
+    * almost all second pass typeconvnode helpers are now processor independent
+    * fixed converting boolean to int64/qword
+    * fixed register allocation bugs which could cause internalerror 10
+    * isnode and asnode are completely processor indepent now as well
+    * fpc_do_as now returns its class argument (necessary to be able to use it
+      properly with compilerproc)
+
+
+}

+ 127 - 25
compiler/ncnv.pas

@@ -76,6 +76,28 @@ interface
           function first_class_to_intf : tnode;virtual;
           function first_class_to_intf : tnode;virtual;
           function first_char_to_char : tnode;virtual;
           function first_char_to_char : tnode;virtual;
           function first_call_helper(c : tconverttype) : tnode;
           function first_call_helper(c : tconverttype) : tnode;
+
+          procedure second_int_to_int;virtual;abstract;
+          procedure second_string_to_string;virtual;abstract;
+          procedure second_cstring_to_pchar;virtual;abstract;
+          procedure second_string_to_chararray;virtual;abstract;
+          procedure second_array_to_pointer;virtual;abstract;
+          procedure second_pointer_to_array;virtual;abstract;
+          procedure second_chararray_to_string;virtual;abstract;
+          procedure second_char_to_string;virtual;abstract;
+          procedure second_int_to_real;virtual;abstract;
+          procedure second_real_to_real;virtual;abstract;
+          procedure second_cord_to_pointer;virtual;abstract;
+          procedure second_proc_to_procvar;virtual;abstract;
+          procedure second_bool_to_int;virtual;abstract;
+          procedure second_int_to_bool;virtual;abstract;
+          procedure second_load_smallset;virtual;abstract;
+          procedure second_ansistring_to_pchar;virtual;abstract;
+          procedure second_pchar_to_string;virtual;abstract;
+          procedure second_class_to_intf;virtual;abstract;
+          procedure second_char_to_char;virtual;abstract;
+          procedure second_nothing; virtual;
+
        end;
        end;
        ttypeconvnodeclass = class of ttypeconvnode;
        ttypeconvnodeclass = class of ttypeconvnode;
 
 
@@ -117,6 +139,7 @@ implementation
 *****************************************************************************}
 *****************************************************************************}
 
 
     procedure inserttypeconv(var p:tnode;const t:ttype);
     procedure inserttypeconv(var p:tnode;const t:ttype);
+
       begin
       begin
         if not assigned(p.resulttype.def) then
         if not assigned(p.resulttype.def) then
          begin
          begin
@@ -397,8 +420,10 @@ implementation
 
 
 
 
     function ttypeconvnode.resulttype_cord_to_pointer : tnode;
     function ttypeconvnode.resulttype_cord_to_pointer : tnode;
+
       var
       var
         t : tnode;
         t : tnode;
+
       begin
       begin
         result:=nil;
         result:=nil;
         if left.nodetype=ordconstn then
         if left.nodetype=ordconstn then
@@ -427,6 +452,7 @@ implementation
       end;
       end;
 
 
     function ttypeconvnode.resulttype_chararray_to_string : tnode;
     function ttypeconvnode.resulttype_chararray_to_string : tnode;
+
       begin
       begin
         result := ccallnode.createinternres(
         result := ccallnode.createinternres(
           'fpc_chararray_to_'+lower(tstringdef(resulttype.def).stringtypname),
           'fpc_chararray_to_'+lower(tstringdef(resulttype.def).stringtypname),
@@ -435,8 +461,10 @@ implementation
       end;
       end;
 
 
     function ttypeconvnode.resulttype_string_to_chararray : tnode;
     function ttypeconvnode.resulttype_string_to_chararray : tnode;
+
       var
       var
         arrsize: longint;
         arrsize: longint;
+
       begin
       begin
          with tarraydef(resulttype.def) do
          with tarraydef(resulttype.def) do
           begin
           begin
@@ -460,12 +488,15 @@ implementation
         left := nil;
         left := nil;
       end;
       end;
 
 
+
     function ttypeconvnode.resulttype_string_to_string : tnode;
     function ttypeconvnode.resulttype_string_to_string : tnode;
+
       var
       var
         procname: string[31];
         procname: string[31];
         stringpara : tcallparanode;
         stringpara : tcallparanode;
         pw : pcompilerwidestring;
         pw : pcompilerwidestring;
         pc : pchar;
         pc : pchar;
+
       begin
       begin
          result:=nil;
          result:=nil;
          if left.nodetype=stringconstn then
          if left.nodetype=stringconstn then
@@ -520,11 +551,13 @@ implementation
 
 
 
 
     function ttypeconvnode.resulttype_char_to_string : tnode;
     function ttypeconvnode.resulttype_char_to_string : tnode;
+
       var
       var
          procname: string[31];
          procname: string[31];
          para : tcallparanode;
          para : tcallparanode;
          hp : tstringconstnode;
          hp : tstringconstnode;
          ws : pcompilerwidestring;
          ws : pcompilerwidestring;
+
       begin
       begin
          result:=nil;
          result:=nil;
          if left.nodetype=ordconstn then
          if left.nodetype=ordconstn then
@@ -559,8 +592,10 @@ implementation
 
 
 
 
     function ttypeconvnode.resulttype_char_to_char : tnode;
     function ttypeconvnode.resulttype_char_to_char : tnode;
+
       var
       var
          hp : tordconstnode;
          hp : tordconstnode;
+
       begin
       begin
          result:=nil;
          result:=nil;
          if left.nodetype=ordconstn then
          if left.nodetype=ordconstn then
@@ -587,8 +622,10 @@ implementation
 
 
 
 
     function ttypeconvnode.resulttype_int_to_real : tnode;
     function ttypeconvnode.resulttype_int_to_real : tnode;
+
       var
       var
         t : trealconstnode;
         t : trealconstnode;
+
       begin
       begin
         result:=nil;
         result:=nil;
         if left.nodetype=ordconstn then
         if left.nodetype=ordconstn then
@@ -601,8 +638,10 @@ implementation
 
 
 
 
     function ttypeconvnode.resulttype_real_to_real : tnode;
     function ttypeconvnode.resulttype_real_to_real : tnode;
+
       var
       var
         t : tnode;
         t : tnode;
+
       begin
       begin
          result:=nil;
          result:=nil;
          if left.nodetype=realconstn then
          if left.nodetype=realconstn then
@@ -614,6 +653,7 @@ implementation
 
 
 
 
     function ttypeconvnode.resulttype_cchar_to_pchar : tnode;
     function ttypeconvnode.resulttype_cchar_to_pchar : tnode;
+
       begin
       begin
          result:=nil;
          result:=nil;
          if is_pwidechar(resulttype.def) then
          if is_pwidechar(resulttype.def) then
@@ -628,6 +668,7 @@ implementation
 
 
 
 
     function ttypeconvnode.resulttype_cstring_to_pchar : tnode;
     function ttypeconvnode.resulttype_cstring_to_pchar : tnode;
+
       begin
       begin
          result:=nil;
          result:=nil;
          if is_pwidechar(resulttype.def) then
          if is_pwidechar(resulttype.def) then
@@ -636,8 +677,10 @@ implementation
 
 
 
 
     function ttypeconvnode.resulttype_arrayconstructor_to_set : tnode;
     function ttypeconvnode.resulttype_arrayconstructor_to_set : tnode;
+
       var
       var
         hp : tnode;
         hp : tnode;
+
       begin
       begin
         result:=nil;
         result:=nil;
         if left.nodetype<>arrayconstructorn then
         if left.nodetype<>arrayconstructorn then
@@ -652,6 +695,7 @@ implementation
 
 
 
 
     function ttypeconvnode.resulttype_pchar_to_string : tnode;
     function ttypeconvnode.resulttype_pchar_to_string : tnode;
+
       begin
       begin
         result := ccallnode.createinternres(
         result := ccallnode.createinternres(
           'fpc_pchar_to_'+lower(tstringdef(resulttype.def).stringtypname),
           'fpc_pchar_to_'+lower(tstringdef(resulttype.def).stringtypname),
@@ -711,9 +755,11 @@ implementation
 
 
 
 
     function ttypeconvnode.det_resulttype:tnode;
     function ttypeconvnode.det_resulttype:tnode;
+
       var
       var
         hp : tnode;
         hp : tnode;
         aprocdef : tprocdef;
         aprocdef : tprocdef;
+
       begin
       begin
         result:=nil;
         result:=nil;
         resulttype:=totype;
         resulttype:=totype;
@@ -1048,6 +1094,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_cord_to_pointer : tnode;
     function ttypeconvnode.first_cord_to_pointer : tnode;
+
       begin
       begin
         result:=nil;
         result:=nil;
         internalerror(200104043);
         internalerror(200104043);
@@ -1055,6 +1102,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_int_to_int : tnode;
     function ttypeconvnode.first_int_to_int : tnode;
+
       begin
       begin
         first_int_to_int:=nil;
         first_int_to_int:=nil;
         if (left.location.loc<>LOC_REGISTER) and
         if (left.location.loc<>LOC_REGISTER) and
@@ -1068,6 +1116,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_cstring_to_pchar : tnode;
     function ttypeconvnode.first_cstring_to_pchar : tnode;
+
       begin
       begin
          first_cstring_to_pchar:=nil;
          first_cstring_to_pchar:=nil;
          registers32:=1;
          registers32:=1;
@@ -1076,6 +1125,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_string_to_chararray : tnode;
     function ttypeconvnode.first_string_to_chararray : tnode;
+
       begin
       begin
          first_string_to_chararray:=nil;
          first_string_to_chararray:=nil;
          registers32:=1;
          registers32:=1;
@@ -1084,6 +1134,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_char_to_string : tnode;
     function ttypeconvnode.first_char_to_string : tnode;
+
       begin
       begin
          first_char_to_string:=nil;
          first_char_to_string:=nil;
          location.loc:=LOC_MEM;
          location.loc:=LOC_MEM;
@@ -1098,6 +1149,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_array_to_pointer : tnode;
     function ttypeconvnode.first_array_to_pointer : tnode;
+
       begin
       begin
          first_array_to_pointer:=nil;
          first_array_to_pointer:=nil;
          if registers32<1 then
          if registers32<1 then
@@ -1107,6 +1159,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_int_to_real : tnode;
     function ttypeconvnode.first_int_to_real : tnode;
+
       begin
       begin
         first_int_to_real:=nil;
         first_int_to_real:=nil;
 {$ifdef m68k}
 {$ifdef m68k}
@@ -1144,6 +1197,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_pointer_to_array : tnode;
     function ttypeconvnode.first_pointer_to_array : tnode;
+
       begin
       begin
          first_pointer_to_array:=nil;
          first_pointer_to_array:=nil;
          if registers32<1 then
          if registers32<1 then
@@ -1153,6 +1207,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_cchar_to_pchar : tnode;
     function ttypeconvnode.first_cchar_to_pchar : tnode;
+
       begin
       begin
          first_cchar_to_pchar:=nil;
          first_cchar_to_pchar:=nil;
          internalerror(200104021);
          internalerror(200104021);
@@ -1160,6 +1215,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_bool_to_int : tnode;
     function ttypeconvnode.first_bool_to_int : tnode;
+
       begin
       begin
          first_bool_to_int:=nil;
          first_bool_to_int:=nil;
          { byte(boolean) or word(wordbool) or longint(longbool) must
          { byte(boolean) or word(wordbool) or longint(longbool) must
@@ -1168,6 +1224,17 @@ implementation
             (left.resulttype.def.size=resulttype.def.size) and
             (left.resulttype.def.size=resulttype.def.size) and
             (left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
             (left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
            exit;
            exit;
+         { when converting to 64bit, first convert to a 32bit int and then   }
+         { convert to a 64bit int (only necessary for 32bit processors) (JM) }
+         if resulttype.def.size > sizeof(aword) then
+           begin
+             result := ctypeconvnode.create(left,u32bittype);
+             result.toggleflag(nf_explizit);
+             result := ctypeconvnode.create(result,resulttype);
+             left := nil;
+             firstpass(result);
+             exit;
+           end;
          location.loc:=LOC_REGISTER;
          location.loc:=LOC_REGISTER;
          if registers32<1 then
          if registers32<1 then
            registers32:=1;
            registers32:=1;
@@ -1175,6 +1242,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_int_to_bool : tnode;
     function ttypeconvnode.first_int_to_bool : tnode;
+
       begin
       begin
          first_int_to_bool:=nil;
          first_int_to_bool:=nil;
          { byte(boolean) or word(wordbool) or longint(longbool) must
          { byte(boolean) or word(wordbool) or longint(longbool) must
@@ -1204,6 +1272,7 @@ implementation
 
 
 
 
     function ttypeconvnode.first_char_to_char : tnode;
     function ttypeconvnode.first_char_to_char : tnode;
+
       begin
       begin
          first_char_to_char:=nil;
          first_char_to_char:=nil;
          location.loc:=LOC_REGISTER;
          location.loc:=LOC_REGISTER;
@@ -1225,12 +1294,29 @@ implementation
 
 
 
 
     function ttypeconvnode.first_load_smallset : tnode;
     function ttypeconvnode.first_load_smallset : tnode;
+
+      var
+        srsym: ttypesym;
+        p: tcallparanode;
+
       begin
       begin
-         first_load_smallset:=nil;
+        if not searchsystype('FPC_SMALL_SET',srsym) then
+          internalerror(200108313);
+        p := ccallparanode.create(left,nil);
+        { reused }
+        left := nil;
+        { convert parameter explicitely to fpc_small_set }
+        p.left := ctypeconvnode.create(p.left,srsym.restype);
+        p.left.toggleflag(nf_explizit);
+        { create call, adjust resulttype }
+        result :=
+          ccallnode.createinternres('fpc_set_load_small',p,resulttype);
+        firstpass(result);
       end;
       end;
 
 
 
 
     function ttypeconvnode.first_ansistring_to_pchar : tnode;
     function ttypeconvnode.first_ansistring_to_pchar : tnode;
+
       begin
       begin
          first_ansistring_to_pchar:=nil;
          first_ansistring_to_pchar:=nil;
          location.loc:=LOC_REGISTER;
          location.loc:=LOC_REGISTER;
@@ -1254,6 +1340,7 @@ implementation
            registers32:=1;
            registers32:=1;
       end;
       end;
 
 
+
     function ttypeconvnode.first_call_helper(c : tconverttype) : tnode;
     function ttypeconvnode.first_call_helper(c : tconverttype) : tnode;
 
 
       const
       const
@@ -1345,6 +1432,19 @@ implementation
       end;
       end;
 
 
 
 
+    function ttypeconvnode.docompare(p: tnode) : boolean;
+      begin
+        docompare :=
+          inherited docompare(p) and
+          (convtype = ttypeconvnode(p).convtype);
+      end;
+
+
+    procedure ttypeconvnode.second_nothing;
+      begin
+      end;
+
+
 {*****************************************************************************
 {*****************************************************************************
                                 TISNODE
                                 TISNODE
 *****************************************************************************}
 *****************************************************************************}
@@ -1391,16 +1491,16 @@ implementation
 
 
 
 
     function tisnode.pass_1 : tnode;
     function tisnode.pass_1 : tnode;
-      begin
-         result:=nil;
-         firstpass(left);
-         firstpass(right);
-         if codegenerror then
-           exit;
 
 
-         left_right_max;
+      var
+        paras: tcallparanode;
 
 
-         location.loc:=LOC_FLAGS;
+      begin
+         paras := ccallparanode.create(left,ccallparanode.create(right,nil));
+         left := nil;
+         right := nil;
+         result := ccallnode.createintern('fpc_do_is',paras);
+         firstpass(result);
       end;
       end;
 
 
 
 
@@ -1449,26 +1549,20 @@ implementation
 
 
 
 
     function tasnode.pass_1 : tnode;
     function tasnode.pass_1 : tnode;
-      begin
-         result:=nil;
-         firstpass(right);
-         firstpass(left);
-         if codegenerror then
-           exit;
-
-         left_right_max;
-
-         set_location(location,left.location);
-      end;
 
 
+      var
+        paras: tcallparanode;
 
 
-    function ttypeconvnode.docompare(p: tnode) : boolean;
       begin
       begin
-        docompare :=
-          inherited docompare(p) and
-          (convtype = ttypeconvnode(p).convtype);
+         paras := ccallparanode.create(left,ccallparanode.create(right,nil));
+         left := nil;
+         right := nil;
+         result := ccallnode.createinternres('fpc_do_as',paras,
+           resulttype);
+         firstpass(result);
       end;
       end;
 
 
+
 begin
 begin
    ctypeconvnode:=ttypeconvnode;
    ctypeconvnode:=ttypeconvnode;
    casnode:=tasnode;
    casnode:=tasnode;
@@ -1476,7 +1570,15 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.37  2001-09-03 13:27:42  jonas
+  Revision 1.38  2001-09-29 21:32:46  jonas
+    * almost all second pass typeconvnode helpers are now processor independent
+    * fixed converting boolean to int64/qword
+    * fixed register allocation bugs which could cause internalerror 10
+    * isnode and asnode are completely processor indepent now as well
+    * fpc_do_as now returns its class argument (necessary to be able to use it
+      properly with compilerproc)
+
+  Revision 1.37  2001/09/03 13:27:42  jonas
     * compilerproc implementation of set addition/substraction/...
     * compilerproc implementation of set addition/substraction/...
     * changed the declaration of some set helpers somewhat to accomodate the
     * changed the declaration of some set helpers somewhat to accomodate the
       above change
       above change

+ 11 - 3
rtl/inc/compproc.inc

@@ -99,7 +99,7 @@ Procedure fpc_widestr_Unique(Var S : WideString); compilerproc;
 Function fpc_Val_Real_AnsiStr(Const S : AnsiString; Var Code : ValSInt): ValReal; compilerproc;
 Function fpc_Val_Real_AnsiStr(Const S : AnsiString; Var Code : ValSInt): ValReal; compilerproc;
 Function fpc_Val_UInt_AnsiStr (Const S : AnsiString; Var Code : ValSInt): ValUInt; compilerproc;
 Function fpc_Val_UInt_AnsiStr (Const S : AnsiString; Var Code : ValSInt): ValUInt; compilerproc;
 Function fpc_Val_SInt_AnsiStr (DestSize: longint; Const S : AnsiString; Var Code : ValSInt): ValSInt; compilerproc;
 Function fpc_Val_SInt_AnsiStr (DestSize: longint; Const S : AnsiString; Var Code : ValSInt): ValSInt; compilerproc;
-Function fpc_Val_qword_AnsiStr (Const S : AnsiString; Var Code : ValSInt): qword;compilerproc; 
+Function fpc_Val_qword_AnsiStr (Const S : AnsiString; Var Code : ValSInt): qword;compilerproc;
 Function fpc_Val_int64_AnsiStr (Const S : AnsiString; Var Code : ValSInt): Int64; compilerproc;
 Function fpc_Val_int64_AnsiStr (Const S : AnsiString; Var Code : ValSInt): Int64; compilerproc;
 procedure fpc_AnsiStr_Float(d : ValReal;len,fr,rt : longint;var s : ansistring); compilerproc;
 procedure fpc_AnsiStr_Float(d : ValReal;len,fr,rt : longint;var s : ansistring); compilerproc;
 Procedure fpc_AnsiStr_Cardinal(C : Cardinal;Len : Longint; Var S : AnsiString); compilerproc;
 Procedure fpc_AnsiStr_Cardinal(C : Cardinal;Len : Longint; Var S : AnsiString); compilerproc;
@@ -165,7 +165,7 @@ function fpc_mul_qword(f1,f2 : qword;checkoverflow : longbool) : qword; compiler
 function fpc_mul_int64(f1,f2 : int64;checkoverflow : longbool) : int64; compilerproc;
 function fpc_mul_int64(f1,f2 : int64;checkoverflow : longbool) : int64; compilerproc;
 
 
 function fpc_do_is(aclass : tclass;aobject : tobject) : boolean; compilerproc;
 function fpc_do_is(aclass : tclass;aobject : tobject) : boolean; compilerproc;
-procedure fpc_do_as(aclass : tclass;aobject : tobject); compilerproc;
+function fpc_do_as(aclass : tclass;aobject : tobject): tobject; compilerproc;
 procedure fpc_intf_decr_ref(var i: pointer); compilerproc;
 procedure fpc_intf_decr_ref(var i: pointer); compilerproc;
 procedure fpc_intf_incr_ref(const i: pointer); compilerproc;
 procedure fpc_intf_incr_ref(const i: pointer); compilerproc;
 procedure fpc_intf_assign(var D: pointer; const S: pointer); compilerproc;
 procedure fpc_intf_assign(var D: pointer; const S: pointer); compilerproc;
@@ -247,7 +247,15 @@ Procedure fpc_typed_read(TypeSize : Longint;var f : TypedFile;var Buf); compiler
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.10  2001-09-05 15:22:09  jonas
+  Revision 1.11  2001-09-29 21:32:47  jonas
+    * almost all second pass typeconvnode helpers are now processor independent
+    * fixed converting boolean to int64/qword
+    * fixed register allocation bugs which could cause internalerror 10
+    * isnode and asnode are completely processor indepent now as well
+    * fpc_do_as now returns its class argument (necessary to be able to use it
+      properly with compilerproc)
+
+  Revision 1.10  2001/09/05 15:22:09  jonas
     * made multiplying, dividing and mod'ing of int64 and qword processor
     * made multiplying, dividing and mod'ing of int64 and qword processor
       independent with compilerprocs (+ small optimizations by using shift/and
       independent with compilerprocs (+ small optimizations by using shift/and
       where possible)
       where possible)

+ 12 - 3
rtl/inc/objpas.inc

@@ -27,10 +27,11 @@
 
 
 
 
     { the reverse order of the parameters make code generation easier }
     { the reverse order of the parameters make code generation easier }
-    procedure fpc_do_as(aclass : tclass;aobject : tobject);[public,alias: 'FPC_DO_AS']; {$ifdef hascompilerproc} compilerproc; {$endif}
+    function fpc_do_as(aclass : tclass;aobject : tobject): tobject;[public,alias: 'FPC_DO_AS']; {$ifdef hascompilerproc} compilerproc; {$endif}
       begin
       begin
          if assigned(aobject) and not(aobject.inheritsfrom(aclass)) then
          if assigned(aobject) and not(aobject.inheritsfrom(aclass)) then
-           handleerror(219);
+           handleerrorframe(219,get_frame);
+         result := aobject;
       end;
       end;
 
 
 {$ifndef HASINTF}
 {$ifndef HASINTF}
@@ -692,7 +693,15 @@
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.16  2001-08-01 15:00:10  jonas
+  Revision 1.17  2001-09-29 21:32:47  jonas
+    * almost all second pass typeconvnode helpers are now processor independent
+    * fixed converting boolean to int64/qword
+    * fixed register allocation bugs which could cause internalerror 10
+    * isnode and asnode are completely processor indepent now as well
+    * fpc_do_as now returns its class argument (necessary to be able to use it
+      properly with compilerproc)
+
+  Revision 1.16  2001/08/01 15:00:10  jonas
     + "compproc" helpers
     + "compproc" helpers
     * renamed several helpers so that their name is the same as their
     * renamed several helpers so that their name is the same as their
       "public alias", which should facilitate the conversion of processor
       "public alias", which should facilitate the conversion of processor