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

+ added generic inline nodes

carl 23 éve
szülő
commit
ebbd8e9e04
2 módosított fájl, 305 hozzáadás és 406 törlés
  1. 5 2
      compiler/i386/cpunode.pas
  2. 300 404
      compiler/i386/n386inl.pas

+ 5 - 2
compiler/i386/cpunode.pas

@@ -29,7 +29,7 @@ unit cpunode;
   implementation
 
     uses
-       ncgbas,ncgflw,ncgcnv,ncgld,ncgmem,ncgcon,ncgset,
+       ncgbas,ncgflw,ncgcnv,ncgld,ncgmem,ncgcon,ncgset,ncginl,
        n386add,n386cal,n386con,n386cnv,n386flw,n386mat,n386mem,
        n386set,n386inl,n386opt,
        { this not really a node }
@@ -38,7 +38,10 @@ unit cpunode;
 end.
 {
   $Log$
-  Revision 1.14  2002-07-06 20:27:26  carl
+  Revision 1.15  2002-07-25 18:01:58  carl
+   + added generic inline nodes
+
+  Revision 1.14  2002/07/06 20:27:26  carl
   + generic set handling
 
   Revision 1.13  2002/05/18 13:34:22  peter

+ 300 - 404
compiler/i386/n386inl.pas

@@ -27,11 +27,36 @@ unit n386inl;
 interface
 
     uses
-       node,ninl;
+       node,ninl,ncginl;
 
     type
-       ti386inlinenode = class(tinlinenode)
-          procedure pass_2;override;
+       ti386inlinenode = class(tcginlinenode)
+          { first pass override 
+            so that the code generator will actually generate
+            these nodes.
+          }
+          function first_assigned: tnode;override;
+          function first_pi: tnode ; override;
+          function first_arctan_real: tnode; override;
+          function first_abs_real: tnode; override;
+          function first_sqr_real: tnode; override;
+          function first_sqrt_real: tnode; override;
+          function first_ln_real: tnode; override;
+          function first_cos_real: tnode; override;
+          function first_sin_real: tnode; override;
+          { second pass override to generate these nodes }
+          procedure second_assigned;override;
+          procedure second_IncludeExclude;override;
+          procedure second_pi; override;
+          procedure second_arctan_real; override;
+          procedure second_abs_real; override;
+          procedure second_sqr_real; override;
+          procedure second_sqrt_real; override;
+          procedure second_ln_real; override;
+          procedure second_cos_real; override;
+          procedure second_sin_real; override;
+       private
+          procedure load_fpu_location;
        end;
 
 implementation
@@ -51,417 +76,288 @@ implementation
                               TI386INLINENODE
 *****************************************************************************}
 
+    function ti386inlinenode.first_assigned: tnode;
+     begin
+       location.loc:=LOC_FLAGS;
+       first_assigned := nil;
+     end;
 
-    procedure ti386inlinenode.pass_2;
-       const
-         {tfloattype = (s32real,s64real,s80real,s64bit,f16bit,f32bit);}
-{        float_name: array[tfloattype] of string[8]=
-           ('S32REAL','S64REAL','S80REAL','S64BIT','F16BIT','F32BIT'); }
-         addsubop:array[in_inc_x..in_dec_x] of TOpCG=(OP_ADD,OP_SUB);
-       var
-         asmop : tasmop;
-         {inc/dec}
-         addconstant : boolean;
-         addvalue : longint;
-         href : treference;
-         hp2 : tstringconstnode;
-         l : longint;
-         pushedregs : tmaybesave;
-         hregisterhi,
-         hregister : tregister;
-         lengthlab,
-         otlabel,oflabel{,l1}   : tasmlabel;
-         oldpushedparasize : longint;
-         cgop : TOpCG;
-         cgsize : TCGSize;
+     function ti386inlinenode.first_pi : tnode;
       begin
-      { save & reset pushedparasize }
-         oldpushedparasize:=pushedparasize;
-         pushedparasize:=0;
-         case inlinenumber of
-            in_assert_x_y:
-              begin
-                 { the node should be removed in the firstpass }
-                 if not (cs_do_assertion in aktlocalswitches) then
-                  internalerror(7123458);
-                 otlabel:=truelabel;
-                 oflabel:=falselabel;
-                 getlabel(truelabel);
-                 getlabel(falselabel);
-                 secondpass(tcallparanode(left).left);
-                 maketojumpbool(exprasmlist,tcallparanode(left).left,lr_load_regvars);
-                 cg.a_label(exprasmlist,falselabel);
-                 { erroraddr }
-                 cg.a_param_reg(exprasmlist,OS_ADDR,R_EBP,paramanager.getintparaloc(4));
-                 { lineno }
-                 cg.a_param_const(exprasmlist,OS_INT,aktfilepos.line,paramanager.getintparaloc(3));
-                 { filename string }
-                 hp2:=cstringconstnode.createstr(current_module.sourcefiles.get_file_name(aktfilepos.fileindex),st_shortstring);
-                 firstpass(hp2);
-                 secondpass(hp2);
-                 if codegenerror then
-                  exit;
-                 cg.a_paramaddr_ref(exprasmlist,hp2.location.reference,paramanager.getintparaloc(2));
-                 hp2.free;
-                 { push msg }
-                 secondpass(tcallparanode(tcallparanode(left).right).left);
-                 cg.a_paramaddr_ref(exprasmlist,tcallparanode(tcallparanode(left).right).left.location.reference,paramanager.getintparaloc(1));
-                 { call }
-                 cg.a_call_name(exprasmlist,'FPC_ASSERT');
-                 cg.a_label(exprasmlist,truelabel);
-                 truelabel:=otlabel;
-                 falselabel:=oflabel;
-              end;
-            in_sizeof_x,
-            in_typeof_x :
-              begin
-                 location_reset(location,LOC_REGISTER,OS_ADDR);
-                 { for both cases load vmt }
-                 if left.nodetype=typen then
-                   begin
-                      hregister:=rg.getaddressregister(exprasmlist);
-                      reference_reset_symbol(href,newasmsymbol(tobjectdef(left.resulttype.def).vmt_mangledname),0);
-                      cg.a_loadaddr_ref_reg(exprasmlist,href,hregister);
-                   end
-                 else
-                   begin
-                      secondpass(left);
-                      location_release(exprasmlist,left.location);
-                      hregister:=rg.getaddressregister(exprasmlist);
-                      { load VMT pointer }
-                      inc(left.location.reference.offset,tobjectdef(left.resulttype.def).vmt_offset);
-                      cg.a_load_ref_reg(exprasmlist,OS_ADDR,left.location.reference,hregister);
-                   end;
-                 { in sizeof load size }
-                 if inlinenumber=in_sizeof_x then
-                   begin
-                      reference_reset_base(href,hregister,0);
-                      rg.ungetaddressregister(exprasmlist,hregister);
-                      hregister:=rg.getregisterint(exprasmlist);
-                      cg.a_load_ref_reg(exprasmlist,OS_INT,href,hregister);
-                   end;
-                 location.register:=hregister;
-              end;
-            in_length_x :
-              begin
-                 secondpass(left);
-                 { length in ansi strings is at offset -8 }
-                 if is_ansistring(left.resulttype.def) or
-                    is_widestring(left.resulttype.def) then
-                  begin
-                    location_force_reg(exprasmlist,left.location,OS_ADDR,false);
-                    hregister:=left.location.register;
-                    getlabel(lengthlab);
-                    cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,hregister,lengthlab);
-                    reference_reset_base(href,hregister,-8);
-                    cg.a_load_ref_reg(exprasmlist,OS_INT,href,hregister);
-                    cg.a_label(exprasmlist,lengthlab);
-                    location_reset(location,LOC_REGISTER,OS_INT);
-                    location.register:=hregister;
-                  end
-                 else
-                  begin
-                    location_copy(location,left.location);
-                    location.size:=OS_8;
-                  end;
-              end;
-            in_pred_x,
-            in_succ_x:
-              begin
-                 secondpass(left);
-                 if inlinenumber=in_pred_x then
-                  cgop:=OP_SUB
-                 else
-                  cgop:=OP_ADD;
-                 cgsize:=def_cgsize(resulttype.def);
-
-                 { we need a value in a register }
-                 location_copy(location,left.location);
-                 location_force_reg(exprasmlist,location,cgsize,false);
-
-                 if cgsize in [OS_64,OS_S64] then
-                  cg64.a_op64_const_reg(exprasmlist,cgop,1,
-                      location.register64)
-                 else
-                  cg.a_op_const_reg(exprasmlist,cgop,1,location.register);
-
-                 cg.g_overflowcheck(exprasmlist,self);
-                 cg.g_rangecheck(exprasmlist,self,resulttype.def);
-              end;
-            in_dec_x,
-            in_inc_x :
-              begin
-                { set defaults }
-                addconstant:=true;
-                { load first parameter, must be a reference }
-                secondpass(tcallparanode(left).left);
-                cgsize:=def_cgsize(tcallparanode(left).left.resulttype.def);
-                { get addvalue }
-                case tcallparanode(left).left.resulttype.def.deftype of
-                  orddef,
-                  enumdef :
-                    addvalue:=1;
-                  pointerdef :
-                    begin
-                      if is_void(tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def) then
-                       addvalue:=1
-                      else
-                       addvalue:=tpointerdef(tcallparanode(left).left.resulttype.def).pointertype.def.size;
-                    end;
-                  else
-                    internalerror(10081);
-                end;
-                { second argument specified?, must be a s32bit in register }
-                if assigned(tcallparanode(left).right) then
-                 begin
-                   maybe_save(exprasmlist,tcallparanode(tcallparanode(left).right).left.registers32,
-                     tcallparanode(left).left.location,pushedregs);
-                   secondpass(tcallparanode(tcallparanode(left).right).left);
-                   maybe_restore(exprasmlist,tcallparanode(left).left.location,pushedregs);
-                   { when constant, just multiply the addvalue }
-                   if is_constintnode(tcallparanode(tcallparanode(left).right).left) then
-                    addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)
-                   else
-                    begin
-                      location_force_reg(exprasmlist,tcallparanode(tcallparanode(left).right).left.location,cgsize,false);
-                      hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
-                      hregisterhi:=tcallparanode(tcallparanode(left).right).left.location.registerhigh;
-                      { insert multiply with addvalue if its >1 }
-                      if addvalue>1 then
-                        cg.a_op_const_reg(exprasmlist,OP_IMUL,addvalue,hregister);
-                      addconstant:=false;
-                    end;
-                 end;
-              { write the add instruction }
-                if addconstant then
-                 begin
-                   if cgsize in [OS_64,OS_S64] then
-                    cg64.a_op64_const_loc(exprasmlist,addsubop[inlinenumber],
-                       addvalue,tcallparanode(left).left.location)
-                   else
-                    cg.a_op_const_loc(exprasmlist,addsubop[inlinenumber],
-                       addvalue,tcallparanode(left).left.location);
-                 end
-                else
-                 begin
-                   if cgsize in [OS_64,OS_S64] then
-                     cg64.a_op64_reg_loc(exprasmlist,addsubop[inlinenumber],
-                       joinreg64(hregister,hregisterhi),tcallparanode(left).left.location)
-                   else
-                    cg.a_op_reg_loc(exprasmlist,addsubop[inlinenumber],
-                       hregister,tcallparanode(left).left.location);
-                   location_release(exprasmlist,tcallparanode(tcallparanode(left).right).left.location);
-                 end;
-                cg.g_overflowcheck(exprasmlist,tcallparanode(left).left);
-                cg.g_rangecheck(exprasmlist,tcallparanode(left).left,tcallparanode(left).left.resulttype.def);
-              end;
-
-            in_typeinfo_x:
-               begin
-                  location_reset(location,LOC_REGISTER,OS_ADDR);
-                  location.register:=rg.getregisterint(exprasmlist);
-                  reference_reset_symbol(href,tstoreddef(ttypenode(tcallparanode(left).left).resulttype.def).get_rtti_label(fullrtti),0);
-                  emit_ref_reg(A_LEA,S_L,href,location.register);
-               end;
-
-            in_assigned_x :
-              begin
-                 secondpass(tcallparanode(left).left);
-                 location_release(exprasmlist,tcallparanode(left).left.location);
-                 if (tcallparanode(left).left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
-                   begin
-                      emit_reg_reg(A_OR,S_L,
-                        tcallparanode(left).left.location.register,
-                        tcallparanode(left).left.location.register);
-                   end
-                 else
-                   begin
-                      emit_const_ref(A_CMP,S_L,0,tcallparanode(left).left.location.reference);
-                   end;
-                 location_reset(location,LOC_FLAGS,OS_NO);
-                 location.resflags:=F_NE;
-              end;
-            in_include_x_y,
-            in_exclude_x_y:
-              begin
-                 location_copy(location,left.location);
-                 secondpass(tcallparanode(left).left);
-                 if tcallparanode(tcallparanode(left).right).left.nodetype=ordconstn then
-                   begin
-                      { calculate bit position }
-                      l:=1 shl (tordconstnode(tcallparanode(tcallparanode(left).right).left).value mod 32);
-
-                      { determine operator }
-                      if inlinenumber=in_include_x_y then
-                        asmop:=A_OR
-                      else
-                        begin
-                           asmop:=A_AND;
-                           l:=not(l);
-                        end;
-                      if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
-                        begin
-                           inc(tcallparanode(left).left.location.reference.offset,
-                             (tordconstnode(tcallparanode(tcallparanode(left).right).left).value div 32)*4);
-                           emit_const_ref(asmop,S_L,l,tcallparanode(left).left.location.reference);
-                           location_release(exprasmlist,tcallparanode(left).left.location);
-                        end
-                      else
-                        { LOC_CREGISTER }
-                        begin
-                          secondpass(tcallparanode(left).left);
-                          emit_const_reg(asmop,S_L,
-                            l,tcallparanode(left).left.location.register);
-                        end;
-                   end
-                 else
-                   begin
-                      { generate code for the element to set }
-                      maybe_save(exprasmlist,tcallparanode(tcallparanode(left).right).left.registers32,
-                        tcallparanode(left).left.location,pushedregs);
-                      secondpass(tcallparanode(tcallparanode(left).right).left);
-                      maybe_restore(exprasmlist,tcallparanode(left).left.location,pushedregs);
-                      { determine asm operator }
-                      if inlinenumber=in_include_x_y then
-                        asmop:=A_BTS
-                      else
-                        asmop:=A_BTR;
-
-                      if tcallparanode(tcallparanode(left).right).left.location.loc in [LOC_CREGISTER,LOC_REGISTER] then
-                        { we don't need a mod 32 because this is done automatically  }
-                        { by the bts instruction. For proper checking we would       }
-
-                        { note: bts doesn't do any mod'ing, that's why we can also use }
-                        { it for normalsets! (JM)                                      }
-
-                        { need a cmp and jmp, but this should be done by the         }
-                        { type cast code which does range checking if necessary (FK) }
-                        begin
-                          hregister := rg.makeregsize(tcallparanode(tcallparanode(left).right).left.location.register,OS_INT);
-                        end
-                      else
-                        begin
-                          rg.getexplicitregisterint(exprasmlist,R_EDI);
-                          hregister:=R_EDI;
-                        end;
-                      cg.a_load_loc_reg(exprasmlist,tcallparanode(tcallparanode(left).right).left.location,hregister);
-                      if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
-                        emit_reg_ref(asmop,S_L,hregister,tcallparanode(left).left.location.reference)
-                      else
-                        emit_reg_reg(asmop,S_L,hregister,tcallparanode(left).left.location.register);
-                      if hregister = R_EDI then
-                        rg.ungetregisterint(exprasmlist,R_EDI);
-                   end;
-              end;
-            in_pi:
-              begin
-                location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
-                emit_none(A_FLDPI,S_NO);
-                inc(trgcpu(rg).fpuvaroffset);
-                location.register:=R_ST;
-              end;
-            in_sin_extended,
-            in_arctan_extended,
-            in_abs_extended,
-            in_sqr_extended,
-            in_sqrt_extended,
-            in_ln_extended,
-            in_cos_extended:
-              begin
-                 location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
-                 location.register:=R_ST;
-                 secondpass(left);
-                 case left.location.loc of
-                    LOC_FPUREGISTER:
-                      ;
-                    LOC_CFPUREGISTER:
-                      begin
-                         cg.a_loadfpu_reg_reg(exprasmlist,
-                           left.location.register,location.register);
-                      end;
-                    LOC_REFERENCE,LOC_CREFERENCE:
-                      begin
-                         cg.a_loadfpu_ref_reg(exprasmlist,
-                           def_cgsize(left.resulttype.def),
-                           left.location.reference,location.register);
-                         location_release(exprasmlist,left.location);
-                      end
-                    else
-                      internalerror(309991);
-                 end;
-                 case inlinenumber of
-                    in_sin_extended,
-                    in_cos_extended:
-                      begin
-                         if inlinenumber=in_sin_extended then
-                           emit_none(A_FSIN,S_NO)
-                         else
-                           emit_none(A_FCOS,S_NO);
-                         {
-                         getlabel(l1);
-                         emit_reg(A_FNSTSW,S_NO,R_AX);
-                         emit_none(A_SAHF,S_NO);
-                         emitjmp(C_NP,l1);
-                         emit_reg(A_FSTP,S_NO,R_ST0);
-                         emit_none(A_FLDZ,S_NO);
-                         cg.a_label(exprasmlist,l1);
-                         }
-                      end;
-                    in_arctan_extended:
-                      begin
-                         emit_none(A_FLD1,S_NO);
-                         emit_none(A_FPATAN,S_NO);
-                      end;
-                    in_abs_extended:
-                      emit_none(A_FABS,S_NO);
-                    in_sqr_extended:
-                      begin
-                         (* emit_reg(A_FLD,S_NO,R_ST0);
-                         { emit_none(A_FMULP,S_NO); nasm does not accept this PM }
-                         emit_reg_reg(A_FMULP,S_NO,R_ST0,R_ST1);
-                           can be shorten to *)
-                         emit_reg_reg(A_FMUL,S_NO,R_ST0,R_ST0);
-                      end;
-                    in_sqrt_extended:
-                      emit_none(A_FSQRT,S_NO);
-                    in_ln_extended:
-                      begin
-                         emit_none(A_FLDLN2,S_NO);
-                         emit_none(A_FXCH,S_NO);
-                         emit_none(A_FYL2X,S_NO);
-                      end;
-                 end;
-              end;
+        location.loc:=LOC_FPUREGISTER;
+        registersfpu:=1;
+        first_pi := nil;
+      end;
+      
+      
+     function ti386inlinenode.first_arctan_real : tnode;
+      begin
+        location.loc:=LOC_FPUREGISTER;
+        registers32:=left.registers32;
+        registersfpu:=max(left.registersfpu,2);
+{$ifdef SUPPORT_MMX}
+        registersmmx:=left.registersmmx;
+{$endif SUPPORT_MMX}
+        first_arctan_real := nil;
+      end;
+      
+     function ti386inlinenode.first_abs_real : tnode;
+      begin
+        location.loc:=LOC_FPUREGISTER;
+        registers32:=left.registers32;
+        registersfpu:=max(left.registersfpu,1);
+{$ifdef SUPPORT_MMX}
+        registersmmx:=left.registersmmx;
+{$endif SUPPORT_MMX}
+        first_abs_real := nil;
+      end;
+      
+     function ti386inlinenode.first_sqr_real : tnode;
+      begin
+        location.loc:=LOC_FPUREGISTER;
+        registers32:=left.registers32;
+        registersfpu:=max(left.registersfpu,1);
+{$ifdef SUPPORT_MMX}
+        registersmmx:=left.registersmmx;
+{$endif SUPPORT_MMX}
+        first_sqr_real := nil;
+      end;
+      
+     function ti386inlinenode.first_sqrt_real : tnode;
+      begin
+        location.loc:=LOC_FPUREGISTER;
+        registers32:=left.registers32;
+        registersfpu:=max(left.registersfpu,1);
+{$ifdef SUPPORT_MMX}
+        registersmmx:=left.registersmmx;
+{$endif SUPPORT_MMX}
+        first_sqrt_real := nil;
+      end;
+      
+     function ti386inlinenode.first_ln_real : tnode;
+      begin
+        location.loc:=LOC_FPUREGISTER;
+        registers32:=left.registers32;
+        registersfpu:=max(left.registersfpu,2);
+{$ifdef SUPPORT_MMX}
+        registersmmx:=left.registersmmx;
+{$endif SUPPORT_MMX}
+        first_ln_real := nil;
+      end;
+      
+     function ti386inlinenode.first_cos_real : tnode;
+      begin
+        location.loc:=LOC_FPUREGISTER;
+        registers32:=left.registers32;
+        registersfpu:=max(left.registersfpu,1);
 {$ifdef SUPPORT_MMX}
-            in_mmx_pcmpeqb..in_mmx_pcmpgtw:
-              begin
-                 location_reset(location,LOC_MMXREGISTER,OS_NO);
-                 if left.location.loc=LOC_REGISTER then
-                   begin
-                      {!!!!!!!}
-                   end
-                 else if tcallparanode(left).left.location.loc=LOC_REGISTER then
-                   begin
-                      {!!!!!!!}
-                   end
-                 else
-                   begin
-                      {!!!!!!!}
-                   end;
-              end;
+        registersmmx:=left.registersmmx;
 {$endif SUPPORT_MMX}
-            else internalerror(9);
+        first_cos_real := nil;
+      end;
+      
+     function ti386inlinenode.first_sin_real : tnode;
+      begin
+        location.loc:=LOC_FPUREGISTER;
+        registers32:=left.registers32;
+        registersfpu:=max(left.registersfpu,1);
+{$ifdef SUPPORT_MMX}
+        registersmmx:=left.registersmmx;
+{$endif SUPPORT_MMX}
+        first_sin_real := nil;
+      end;
+
+ 
+     procedure ti386inlinenode.second_Pi;
+       begin
+         location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
+         emit_none(A_FLDPI,S_NO);
+         inc(trgcpu(rg).fpuvaroffset);
+         location.register:=FPU_RESULT_REG;
+         
+       end;
+     
+       { load the FPU into the an fpu register }
+       procedure ti386inlinenode.load_fpu_location;
+         begin
+           location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
+           location.register:=FPU_RESULT_REG;
+           secondpass(left);
+           case left.location.loc of
+             LOC_FPUREGISTER:
+                      ;
+             LOC_CFPUREGISTER:
+               begin
+                 cg.a_loadfpu_reg_reg(exprasmlist,
+                   left.location.register,location.register);
+               end;
+             LOC_REFERENCE,LOC_CREFERENCE:
+               begin
+                 cg.a_loadfpu_ref_reg(exprasmlist,
+                    def_cgsize(left.resulttype.def),
+                    left.location.reference,location.register);
+                 location_release(exprasmlist,left.location);
+               end
+           else
+              internalerror(309991);
+           end;
          end;
-         { reset pushedparasize }
-         pushedparasize:=oldpushedparasize;
+       
+     procedure ti386inlinenode.second_arctan_real;
+       begin
+         load_fpu_location;
+         emit_none(A_FLD1,S_NO);
+         emit_none(A_FPATAN,S_NO);
+       end;
+       
+     procedure ti386inlinenode.second_abs_real;
+       begin
+         load_fpu_location;
+         emit_none(A_FABS,S_NO);
+       end;
+       
+     procedure ti386inlinenode.second_sqr_real;
+       begin
+         load_fpu_location;
+         emit_reg_reg(A_FMUL,S_NO,R_ST0,R_ST0);
+       end;
+       
+     procedure ti386inlinenode.second_sqrt_real;
+       begin
+         load_fpu_location;
+         emit_none(A_FSQRT,S_NO);
+       end;
+       
+     procedure ti386inlinenode.second_ln_real;
+       begin
+         load_fpu_location;
+         emit_none(A_FLDLN2,S_NO);
+         emit_none(A_FXCH,S_NO);
+         emit_none(A_FYL2X,S_NO);
+       end;
+       
+     procedure ti386inlinenode.second_cos_real;
+       begin
+         load_fpu_location;
+         emit_none(A_FCOS,S_NO);
+       end;
+       
+     procedure ti386inlinenode.second_sin_real;
+       begin
+         load_fpu_location;
+         emit_none(A_FSIN,S_NO)
+       end;
+
+     procedure ti386inlinenode.second_assigned;
+      begin
+        secondpass(tcallparanode(left).left);
+        location_release(exprasmlist,tcallparanode(left).left.location);
+        if (tcallparanode(left).left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+           begin
+             emit_reg_reg(A_OR,S_L,
+                tcallparanode(left).left.location.register,
+                tcallparanode(left).left.location.register);
+           end
+         else
+           begin
+             emit_const_ref(A_CMP,S_L,0,tcallparanode(left).left.location.reference);
+           end;
+        location_reset(location,LOC_FLAGS,OS_NO);
+        location.resflags:=F_NE;
       end;
+       
+{*****************************************************************************
+                     INCLUDE/EXCLUDE GENERIC HANDLING
+*****************************************************************************}
 
+      procedure ti386inlinenode.second_IncludeExclude;
+        var
+         scratch_reg : boolean;
+         hregister : tregister;
+         asmop : tasmop;
+         L : longint;
+         pushedregs : TMaybesave;         
+         cgop : topcg;
+        begin
+          location_copy(location,left.location);
+          secondpass(tcallparanode(left).left);
+          if tcallparanode(tcallparanode(left).right).left.nodetype=ordconstn then
+            begin
+              { calculate bit position }
+              l:=1 shl (tordconstnode(tcallparanode(tcallparanode(left).right).left).value mod 32);
+
+              { determine operator }
+              if inlinenumber=in_include_x_y then
+                cgop:=OP_OR
+              else
+                begin
+                  cgop:=OP_AND;
+                  l:=not(l);
+                end;
+              if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
+                begin
+                  inc(tcallparanode(left).left.location.reference.offset,
+                    (tordconstnode(tcallparanode(tcallparanode(left).right).left).value div 32)*4);
+                  cg.a_op_const_ref(exprasmlist,cgop,OS_INT,l,tcallparanode(left).left.location.reference);
+                  location_release(exprasmlist,tcallparanode(left).left.location);
+                end
+              else
+                { LOC_CREGISTER }
+                begin
+                  cg.a_op_const_reg(exprasmlist,cgop,l,tcallparanode(left).left.location.register);
+                end;
+            end
+          else
+            begin
+              { generate code for the element to set }
+              maybe_save(exprasmlist,tcallparanode(tcallparanode(left).right).left.registers32,
+                        tcallparanode(left).left.location,pushedregs);
+              secondpass(tcallparanode(tcallparanode(left).right).left);
+              maybe_restore(exprasmlist,tcallparanode(left).left.location,pushedregs);
+              { determine asm operator }
+              if inlinenumber=in_include_x_y then
+                 asmop:=A_BTS
+              else
+                 asmop:=A_BTR;
+
+              if tcallparanode(tcallparanode(left).right).left.location.loc in [LOC_CREGISTER,LOC_REGISTER] then
+                { we don't need a mod 32 because this is done automatically  }
+                { by the bts instruction. For proper checking we would       }
+
+                { note: bts doesn't do any mod'ing, that's why we can also use }
+                { it for normalsets! (JM)                                      }
+
+                { need a cmp and jmp, but this should be done by the         }
+                { type cast code which does range checking if necessary (FK) }
+                begin
+                  scratch_reg := FALSE;
+                  hregister := rg.makeregsize(tcallparanode(tcallparanode(left).right).left.location.register,OS_INT);
+                end
+              else
+                begin
+                  scratch_reg := TRUE;
+                  hregister:=cg.get_scratch_reg_int(exprasmlist);
+                end;
+              cg.a_load_loc_reg(exprasmlist,tcallparanode(tcallparanode(left).right).left.location,hregister);
+              if (tcallparanode(left).left.location.loc=LOC_REFERENCE) then
+                emit_reg_ref(asmop,S_L,hregister,tcallparanode(left).left.location.reference)
+              else
+                emit_reg_reg(asmop,S_L,hregister,tcallparanode(left).left.location.register);
+              if scratch_reg then
+                cg.free_scratch_reg(exprasmlist,hregister);
+            end;
+        end;           
+     
+       
 begin
    cinlinenode:=ti386inlinenode;
 end.
 {
   $Log$
-  Revision 1.49  2002-07-20 11:58:02  florian
+  Revision 1.50  2002-07-25 18:02:33  carl
+   + added generic inline nodes
+
+  Revision 1.49  2002/07/20 11:58:02  florian
     * types.pas renamed to defbase.pas because D6 contains a types
       unit so this would conflicts if D6 programms are compiled
     + Willamette/SSE2 instructions to assembler added
@@ -550,9 +446,9 @@ end.
 
   Revision 1.33  2002/03/31 20:26:39  jonas
     + a_loadfpu_* and a_loadmm_* methods in tcg
-    * register allocation is now handled by a class and is mostly processor
+    * register allocation is now second_d by a class and is mostly processor
       independent (+rgobj.pas and i386/rgcpu.pas)
-    * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
+    * temp allocation is now second_d by a class (+tgobj.pas, -i386\tgcpu.pas)
     * some small improvements and fixes to the optimizer
     * some register allocation fixes
     * some fpuvaroffset fixes in the unary minus node