Browse Source

* packrecords 4 works
* word aligning of parameters

peter 27 years ago
parent
commit
9330b0e700
2 changed files with 386 additions and 427 deletions
  1. 286 300
      compiler/cg386cal.pas
  2. 100 127
      compiler/symsym.inc

+ 286 - 300
compiler/cg386cal.pas

@@ -60,7 +60,7 @@ implementation
            { open array ? }
            { defcoll^.data can be nil for read/write }
            if assigned(defcoll^.data) and
-             is_open_array(defcoll^.data) then
+              is_open_array(defcoll^.data) then
              begin
                 inc(pushedparasize,4);
                 { push high }
@@ -77,16 +77,18 @@ implementation
                      exprasmlist^.concat(new(pai386,op_ref(A_PUSH,S_L,r)));
                   end
                 else
-                     if inlined then
-                       begin
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_const_ref(A_MOV,S_L,
-                            parraydef(p^.left^.resulttype)^.highrange-
-                            parraydef(p^.left^.resulttype)^.lowrange,r)));
-                       end
-                     else
-                  push_int(parraydef(p^.left^.resulttype)^.highrange-
+                  begin
+                    if inlined then
+                      begin
+                         r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                         exprasmlist^.concat(new(pai386,op_const_ref(A_MOV,S_L,
+                           parraydef(p^.left^.resulttype)^.highrange-
+                           parraydef(p^.left^.resulttype)^.lowrange,r)));
+                      end
+                    else
+                      push_int(parraydef(p^.left^.resulttype)^.highrange-
                            parraydef(p^.left^.resulttype)^.lowrange);
+                  end;
              end;
         end;
 
@@ -94,15 +96,12 @@ implementation
          size : longint;
          stackref : treference;
          otlabel,hlabel,oflabel : plabel;
-
-
          { temporary variables: }
          tempdeftype : tdeftype;
          tempreference : treference;
          r : preference;
          s : topsize;
          op : tasmop;
-
       begin
          { push from left to right if specified }
          if push_from_left_to_right and assigned(p^.right) then
@@ -120,33 +119,31 @@ implementation
               inc(pushedparasize,4);
               if p^.left^.treetype=addrn then
                 begin
-                   { always a register }
-                     if inlined then
-                       begin
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            p^.left^.location.register,r)));
-                       end
-                     else
-                   exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_L,p^.left^.location.register)));
-                   ungetregister32(p^.left^.location.register);
+                { always a register }
+                  if inlined then
+                    begin
+                       r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                       exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
+                         p^.left^.location.register,r)));
+                    end
+                  else
+                    exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_L,p^.left^.location.register)));
+                  ungetregister32(p^.left^.location.register);
                 end
               else
                 begin
-                   if (p^.left^.location.loc<>LOC_REFERENCE) and
-                      (p^.left^.location.loc<>LOC_MEM) then
+                   if not(p^.left^.location.loc in [LOC_MEM,LOC_REFERENCE]) then
                      Message(sym_e_type_mismatch)
                    else
                      begin
-                     if inlined then
-                       begin
-                          exprasmlist^.concat(new(pai386,op_ref_reg(A_LEA,S_L,
-                            newreference(p^.left^.location.reference),R_EDI)));
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            R_EDI,r)));
-                       end
-                     else
+                       if inlined then
+                         begin
+                           exprasmlist^.concat(new(pai386,op_ref_reg(A_LEA,S_L,
+                             newreference(p^.left^.location.reference),R_EDI)));
+                           r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                           exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,R_EDI,r)));
+                         end
+                      else
                         emitpushreferenceaddr(exprasmlist,p^.left^.location.reference);
                         del_reference(p^.left^.location.reference);
                      end;
@@ -159,16 +156,15 @@ implementation
                 Message(cg_e_var_must_be_reference);
               maybe_push_open_array_high;
               inc(pushedparasize,4);
-                     if inlined then
-                       begin
-                          exprasmlist^.concat(new(pai386,op_ref_reg(A_LEA,S_L,
-                            newreference(p^.left^.location.reference),R_EDI)));
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            R_EDI,r)));
-                       end
-                     else
-              emitpushreferenceaddr(exprasmlist,p^.left^.location.reference);
+              if inlined then
+                begin
+                   exprasmlist^.concat(new(pai386,op_ref_reg(A_LEA,S_L,
+                     newreference(p^.left^.location.reference),R_EDI)));
+                   r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                   exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,R_EDI,r)));
+                end
+              else
+                emitpushreferenceaddr(exprasmlist,p^.left^.location.reference);
               del_reference(p^.left^.location.reference);
            end
          else
@@ -181,15 +177,15 @@ implementation
                 begin
                    maybe_push_open_array_high;
                    inc(pushedparasize,4);
-                     if inlined then
-                       begin
-                          exprasmlist^.concat(new(pai386,op_ref_reg(A_LEA,S_L,
-                            newreference(p^.left^.location.reference),R_EDI)));
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            R_EDI,r)));
-                       end
-                     else
+                   if inlined then
+                     begin
+                        exprasmlist^.concat(new(pai386,op_ref_reg(A_LEA,S_L,
+                          newreference(p^.left^.location.reference),R_EDI)));
+                        r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                        exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
+                          R_EDI,r)));
+                     end
+                   else
                      emitpushreferenceaddr(exprasmlist,p^.left^.location.reference);
                    del_reference(p^.left^.location.reference);
                 end
@@ -203,42 +199,42 @@ implementation
                            R_EDI,R_ESP,R_EBP :
                              begin
                                 inc(pushedparasize,4);
-                     if inlined then
-                       begin
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            p^.left^.location.register,r)));
-                       end
-                     else
-                                exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_L,p^.left^.location.register)));
+                                if inlined then
+                                  begin
+                                     r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                     exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
+                                       p^.left^.location.register,r)));
+                                  end
+                                else
+                                  exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_L,p^.left^.location.register)));
                                 ungetregister32(p^.left^.location.register);
                              end;
                            R_AX,R_BX,R_CX,R_DX,R_SI,R_DI:
                              begin
                                  inc(pushedparasize,2);
-                     if inlined then
-                       begin
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_W,
-                            p^.left^.location.register,r)));
-                       end
-                     else
-                                 exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_W,p^.left^.location.register)));
+                                 if inlined then
+                                   begin
+                                      r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                      exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_W,
+                                        p^.left^.location.register,r)));
+                                   end
+                                 else
+                                   exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_W,p^.left^.location.register)));
                                  ungetregister32(reg16toreg32(p^.left^.location.register));
                               end;
                            R_AL,R_BL,R_CL,R_DL:
                              begin
                                 inc(pushedparasize,2);
                                 { we must push always 16 bit }
-                     if inlined then
-                       begin
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            reg8toreg16(p^.left^.location.register),r)));
-                       end
-                     else
-                                exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_W,
-                                  reg8toreg16(p^.left^.location.register))));
+                                if inlined then
+                                  begin
+                                     r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                     exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
+                                       reg8toreg16(p^.left^.location.register),r)));
+                                  end
+                                else
+                                  exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_W,
+                                    reg8toreg16(p^.left^.location.register))));
                                 ungetregister32(reg8toreg32(p^.left^.location.register));
                              end;
                         end;
@@ -264,45 +260,10 @@ implementation
                         tempreference:=p^.left^.location.reference;
                         del_reference(p^.left^.location.reference);
                         case p^.resulttype^.deftype of
-                           orddef :
-                             begin
-                                case porddef(p^.resulttype)^.typ of
-                                  s32bit,u32bit,bool32bit :
-                                    begin
-                                       inc(pushedparasize,4);
-                                       if inlined then
-                                         begin
-                                            exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
-                                              newreference(tempreference),R_EDI)));
-                                            r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                                            exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                                            R_EDI,r)));
-                                         end
-                                       else
-                                         emit_push_mem(tempreference);
-                                    end;
-                                  s8bit,u8bit,uchar,bool8bit,bool16bit,s16bit,u16bit :
-                                    begin
-                                      inc(pushedparasize,2);
-                                      if inlined then
-                                        begin
-                                           exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_W,
-                                             newreference(tempreference),R_DI)));
-                                           r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                                           exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_W,
-                                           R_DI,r)));
-                                        end
-                                      else
-                                        exprasmlist^.concat(new(pai386,op_ref(A_PUSH,S_W,
-                                          newreference(tempreference))));
-                                    end;
-                                end;
-                             end;
-                           floatdef :
-                           begin
-                             case pfloatdef(p^.resulttype)^.typ of
-                               f32bit,
-                               s32real :
+                        orddef :
+                          begin
+                             case porddef(p^.resulttype)^.typ of
+                               s32bit,u32bit,bool32bit :
                                  begin
                                     inc(pushedparasize,4);
                                     if inlined then
@@ -310,174 +271,197 @@ implementation
                                          exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
                                            newreference(tempreference),R_EDI)));
                                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                                         exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                                           R_EDI,r)));
+                                         exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,R_EDI,r)));
                                       end
                                     else
                                       emit_push_mem(tempreference);
-                                              end;
-                                            s64real,
-                                            s64bit : begin
-                                                         inc(pushedparasize,4);
-                                                         inc(tempreference.offset,4);
-                     if inlined then
-                       begin
-                          exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
-                            newreference(tempreference),R_EDI)));
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            R_EDI,r)));
-                       end
-                     else
-                                                         emit_push_mem(tempreference);
-                                                         inc(pushedparasize,4);
-                                                         dec(tempreference.offset,4);
-                     if inlined then
-                       begin
-                          exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
-                            newreference(tempreference),R_EDI)));
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            R_EDI,r)));
-                       end
-                     else
-                                                         emit_push_mem(tempreference);
-                                                      end;
-                                            s80real : begin
-                                                         inc(pushedparasize,4);
-                                                         inc(tempreference.offset,6);
-                     if inlined then
-                       begin
-                          exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
-                            newreference(tempreference),R_EDI)));
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            R_EDI,r)));
-                       end
-                     else
-                                                         emit_push_mem(tempreference);
-                                                         dec(tempreference.offset,4);
-                                                         inc(pushedparasize,4);
-                     if inlined then
-                       begin
-                          exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
-                            newreference(tempreference),R_EDI)));
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            R_EDI,r)));
-                       end
-                     else
-                                                         emit_push_mem(tempreference);
-                                                         dec(tempreference.offset,2);
-                                                         inc(pushedparasize,2);
-                     if inlined then
-                       begin
-                          exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_W,
-                            newreference(tempreference),R_DI)));
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_W,
-                            R_DI,r)));
-                       end
-                     else
-                                                         exprasmlist^.concat(new(pai386,op_ref(A_PUSH,S_W,
-                                                           newreference(tempreference))));
-                                                      end;
-                                         end;
-                                      end;
-                           pointerdef,procvardef,
-                           enumdef,classrefdef:
-                             begin
-                                inc(pushedparasize,4);
-                     if inlined then
-                       begin
-                          exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
-                            newreference(tempreference),R_EDI)));
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            R_EDI,r)));
-                       end
-                     else
-                                emit_push_mem(tempreference);
+                                 end;
+                               s8bit,u8bit,uchar,bool8bit,
+                               bool16bit,s16bit,u16bit :
+                                 begin
+                                   inc(pushedparasize,2);
+                                   if inlined then
+                                     begin
+                                        exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_W,
+                                          newreference(tempreference),R_DI)));
+                                        r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                        exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_W,R_DI,r)));
+                                     end
+                                   else
+                                     exprasmlist^.concat(new(pai386,op_ref(A_PUSH,S_W,
+                                       newreference(tempreference))));
+                                 end;
                              end;
-                           arraydef,recorddef,stringdef,setdef,objectdef :
-                             begin
-                                { small set ? }
-                                if ((p^.resulttype^.deftype=setdef) and
-                                  (psetdef(p^.resulttype)^.settype=smallset)) then
+                          end;
+                        floatdef :
+                          begin
+                            case pfloatdef(p^.resulttype)^.typ of
+                            f32bit,
+                            s32real :
+                              begin
+                                 inc(pushedparasize,4);
+                                 if inlined then
+                                   begin
+                                      exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
+                                        newreference(tempreference),R_EDI)));
+                                      r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                      exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,R_EDI,r)));
+                                   end
+                                 else
+                                   emit_push_mem(tempreference);
+                              end;
+                            s64real,
+                            s64bit :
+                              begin
+                                inc(pushedparasize,4);
+                                inc(tempreference.offset,4);
+                                if inlined then
                                   begin
-                                     inc(pushedparasize,4);
-                                     if inlined then
-                                       begin
-                                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                                          concatcopy(tempreference,r^,4,false);
-                                       end
-                                     else
-                                     emit_push_mem(tempreference);
+                                     exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
+                                       newreference(tempreference),R_EDI)));
+                                     r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                     exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,R_EDI,r)));
                                   end
-                                { call by value open array ? }
-                                else if (p^.resulttype^.deftype=arraydef) and
-                                  assigned(defcoll^.data) and
-                                  is_open_array(defcoll^.data) then
+                                else
+                                  emit_push_mem(tempreference);
+                                inc(pushedparasize,4);
+                                dec(tempreference.offset,4);
+                                if inlined then
                                   begin
-                                     { first, push high }
-                                     maybe_push_open_array_high;
-                                     inc(pushedparasize,4);
-                     if inlined then
-                       begin
-                          exprasmlist^.concat(new(pai386,op_ref_reg(A_LEA,S_L,
-                            newreference(p^.left^.location.reference),R_EDI)));
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
-                            R_EDI,r)));
-                       end
-                     else
-                                     emitpushreferenceaddr(exprasmlist,p^.left^.location.reference);
+                                     exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
+                                       newreference(tempreference),R_EDI)));
+                                     r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                     exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,R_EDI,r)));
                                   end
                                 else
+                                  emit_push_mem(tempreference);
+                              end;
+                            s80real :
+                              begin
+                                inc(pushedparasize,4);
+                                inc(tempreference.offset,6);
+                                if inlined then
                                   begin
-
-                                     size:=p^.resulttype^.size;
-
-                                     { Alignment }
-                                     {
-                                     if (size>=4) and ((size and 3)<>0) then
-                                       inc(size,4-(size and 3))
-                                     else if (size>=2) and ((size and 1)<>0) then
-                                       inc(size,2-(size and 1))
-                                     else
-                                     if size=1 then size:=2;
-                                     }
-                                     { create stack space }
-                                     if not inlined then
-                                       exprasmlist^.concat(new(pai386,op_const_reg(A_SUB,S_L,size,R_ESP)));
-                                     inc(pushedparasize,size);
-                                     { create stack reference }
-                                     stackref.symbol := nil;
-                                     if not inlined then
-                                       begin
-                                          clear_reference(stackref);
-                                          stackref.base:=R_ESP;
-                                       end
-                                     else
-                                       begin
-                                          clear_reference(stackref);
-                                          stackref.base:=procinfo.framepointer;
-                                          stackref.offset:=para_offset-pushedparasize;
-                                       end;
-                                     { produce copy }
-                                     if p^.resulttype^.deftype=stringdef then
-                                       begin
-                                          copystring(stackref,p^.left^.location.reference,
-                                            pstringdef(p^.resulttype)^.len);
-                                       end
-                                     else
-                                       begin
-                                          concatcopy(p^.left^.location.reference,
-                                          stackref,p^.resulttype^.size,true);
-                                       end;
-                                  end;
-                             end;
-                           else Message(cg_e_illegal_expression);
+                                     exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
+                                       newreference(tempreference),R_EDI)));
+                                     r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                     exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,R_EDI,r)));
+                                  end
+                                else
+                                  emit_push_mem(tempreference);
+                                dec(tempreference.offset,4);
+                                inc(pushedparasize,4);
+                                if inlined then
+                                  begin
+                                     exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
+                                       newreference(tempreference),R_EDI)));
+                                     r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                     exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,R_EDI,r)));
+                                  end
+                                else
+                                  emit_push_mem(tempreference);
+                                dec(tempreference.offset,2);
+                                inc(pushedparasize,2);
+                                if inlined then
+                                  begin
+                                     exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_W,
+                                       newreference(tempreference),R_DI)));
+                                     r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                     exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_W,R_DI,r)));
+                                  end
+                                else
+                                  exprasmlist^.concat(new(pai386,op_ref(A_PUSH,S_W,
+                                    newreference(tempreference))));
+                              end;
+                            end;
+                          end;
+                        pointerdef,procvardef,
+                        enumdef,classrefdef:
+                          begin
+                             inc(pushedparasize,4);
+                             if inlined then
+                               begin
+                                  exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,
+                                    newreference(tempreference),R_EDI)));
+                                  r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                  exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,R_EDI,r)));
+                               end
+                             else
+                               emit_push_mem(tempreference);
+                          end;
+                        arraydef,recorddef,stringdef,setdef,objectdef :
+                          begin
+                             { small set ? }
+                             if ((p^.resulttype^.deftype=setdef) and
+                                 (psetdef(p^.resulttype)^.settype=smallset)) then
+                               begin
+                                  inc(pushedparasize,4);
+                                  if inlined then
+                                    begin
+                                      r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                      concatcopy(tempreference,r^,4,false);
+                                    end
+                                  else
+                                    emit_push_mem(tempreference);
+                               end
+                             { call by value open array ? }
+                             else
+                              if (p^.resulttype^.deftype=arraydef) and
+                                 assigned(defcoll^.data) and
+                                 is_open_array(defcoll^.data) then
+                               begin
+                                  { first, push high }
+                                  maybe_push_open_array_high;
+                                  inc(pushedparasize,4);
+                                  if inlined then
+                                    begin
+                                       exprasmlist^.concat(new(pai386,op_ref_reg(A_LEA,S_L,
+                                         newreference(p^.left^.location.reference),R_EDI)));
+                                       r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                                       exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,
+                                         R_EDI,r)));
+                                    end
+                                  else
+                                    emitpushreferenceaddr(exprasmlist,p^.left^.location.reference);
+                                end
+                              else
+                               begin
+                                  size:=p^.resulttype^.size;
+                                  { Word Alignment }
+                                  if Odd(size) then
+                                   inc(size);
+                                  { create stack space }
+                                  if not inlined then
+                                    exprasmlist^.concat(new(pai386,op_const_reg(A_SUB,S_L,size,R_ESP)));
+                                  inc(pushedparasize,size);
+                                  { create stack reference }
+                                  stackref.symbol := nil;
+                                  if not inlined then
+                                    begin
+                                      clear_reference(stackref);
+                                      stackref.base:=R_ESP;
+                                    end
+                                  else
+                                    begin
+                                      clear_reference(stackref);
+                                      stackref.base:=procinfo.framepointer;
+                                      stackref.offset:=para_offset-pushedparasize;
+                                    end;
+                                  { produce copy }
+                                  if p^.resulttype^.deftype=stringdef then
+                                    begin
+                                       copystring(stackref,p^.left^.location.reference,
+                                         pstringdef(p^.resulttype)^.len);
+                                    end
+                                  else
+                                    begin
+                                       concatcopy(p^.left^.location.reference,
+                                       stackref,p^.resulttype^.size,true);
+                                    end;
+                               end;
+                          end;
+                        else
+                          Message(cg_e_illegal_expression);
                         end;
                      end;
                    LOC_JUMP:
@@ -485,24 +469,22 @@ implementation
                         getlabel(hlabel);
                         inc(pushedparasize,2);
                         emitl(A_LABEL,truelabel);
-                     if inlined then
-                       begin
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_const_ref(A_MOV,S_W,
-                            1,r)));
-                       end
-                     else
-                        exprasmlist^.concat(new(pai386,op_const(A_PUSH,S_W,1)));
+                        if inlined then
+                          begin
+                             r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                             exprasmlist^.concat(new(pai386,op_const_ref(A_MOV,S_W,1,r)));
+                          end
+                        else
+                          exprasmlist^.concat(new(pai386,op_const(A_PUSH,S_W,1)));
                         emitl(A_JMP,hlabel);
                         emitl(A_LABEL,falselabel);
-                     if inlined then
-                       begin
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_const_ref(A_MOV,S_W,
-                            0,r)));
-                       end
-                     else
-                        exprasmlist^.concat(new(pai386,op_const(A_PUSH,S_W,0)));
+                        if inlined then
+                          begin
+                             r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                             exprasmlist^.concat(new(pai386,op_const_ref(A_MOV,S_W,0,r)));
+                          end
+                        else
+                          exprasmlist^.concat(new(pai386,op_const(A_PUSH,S_W,0)));
                         emitl(A_LABEL,hlabel);
                      end;
                    LOC_FLAGS:
@@ -518,14 +500,14 @@ implementation
                         exprasmlist^.concat(new(pai386,op_reg_reg(A_MOVZX,S_BW,R_AL,R_AX)));
                         {exprasmlist^.concat(new(pai386,op_reg_reg(A_XOR,S_L,R_EAX,R_EAX)));}
                         inc(pushedparasize,2);
-                     if inlined then
-                       begin
-                          r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
-                          exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_W,
-                            R_AX,r)));
-                       end
-                     else
-                        exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_W,R_AX)));
+                        if inlined then
+                          begin
+                             r:=new_reference(procinfo.framepointer,para_offset-pushedparasize);
+                             exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_W,
+                               R_AX,r)));
+                          end
+                        else
+                          exprasmlist^.concat(new(pai386,op_reg(A_PUSH,S_W,R_AX)));
                         { this is also false !!!
                         if not(R_EAX in unused) then
                           exprasmlist^.concat(new(pai386,op_reg_reg(A_MOV,S_L,R_EAX,R_EDI)));}
@@ -2268,7 +2250,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.8  1998-07-06 15:51:15  michael
+  Revision 1.9  1998-07-07 17:40:37  peter
+    * packrecords 4 works
+    * word aligning of parameters
+
+  Revision 1.8  1998/07/06 15:51:15  michael
   Added length checking for string reading
 
   Revision 1.7  1998/07/06 14:19:51  michael

+ 100 - 127
compiler/symsym.inc

@@ -866,7 +866,7 @@
     constructor tvarsym.init_C(const n,mangled : string;p : pdef);
 
       begin
-      { The tarsym is necessary for 0.99.5 (PFV) }
+      { The tvarsym is necessary for 0.99.5 (PFV) }
          tvarsym.init(n,p);
          var_options:=var_options or vo_is_C_var;
          _mangledname:=strpnew(target_os.Cprefix+mangled);
@@ -949,7 +949,7 @@
            begin
               case varspez of
                  vs_value : getsize:=definition^.size;
-                 vs_var : getsize:=sizeof(pointer);
+                   vs_var : getsize:=sizeof(pointer);
                  vs_const : begin
                                if (definition^.deftype in [stringdef,arraydef,
                                      recorddef,objectdef,setdef]) then
@@ -967,142 +967,111 @@
       var
          l,modulo : longint;
       begin
-       if (var_options and vo_is_external)<>0 then
-         exit;
-       { handle static variables of objects especially }
-       if read_member and (owner^.symtabletype=objectsymtable) and
-          ((properties and sp_static)<>0) then
+        if (var_options and vo_is_external)<>0 then
+          exit;
+        { handle static variables of objects especially }
+        if read_member and (owner^.symtabletype=objectsymtable) and
+           ((properties and sp_static)<>0) then
          begin
             { the data filed is generated in parser.pas
               with a tobject_FIELDNAME variable }
             { this symbol can't be loaded to a register }
             var_options:=var_options and not vo_regable;
          end
-       else if not(read_member) then
-         begin
-            { made problems with parameters etc. ! (FK) }
-
-            {  check for instance of an abstract object or class }
-            {
-            if (pvarsym(sym)^.definition^.deftype=objectdef) and
-              ((pobjectdef(pvarsym(sym)^.definition)^.options and oois_abstract)<>0) then
-              Message(sym_e_no_instance_of_abstract_object);
-            }
-            { bei einer lokalen Symboltabelle erst! erh”hen, da der }
-            { Wert in codegen.secondload dann mit minus verwendet   }
-            { wird                                                  }
-            l:=getsize;
-            if owner^.symtabletype=localsymtable then
-              begin
-                 is_valid := 0;
-                 modulo:=owner^.datasize and 3;
+        else
+         if not(read_member) then
+          begin
+             { made problems with parameters etc. ! (FK) }
+             {  check for instance of an abstract object or class }
+             {
+             if (pvarsym(sym)^.definition^.deftype=objectdef) and
+               ((pobjectdef(pvarsym(sym)^.definition)^.options and oois_abstract)<>0) then
+               Message(sym_e_no_instance_of_abstract_object);
+             }
+
+             l:=getsize;
+             case owner^.symtabletype of
+          localsymtable : begin
+                            is_valid := 0;
+                            modulo:=owner^.datasize and 3;
 {$ifdef m68k}
-                 { word alignment required for motorola }
-                 if (l=1) then
-                  l:=2
-                 else
+                          { word alignment required for motorola }
+                            if (l=1) then
+                             l:=2
+                            else
 {$endif}
-
-                 if (l>=4) and (modulo<>0) then
-                   inc(l,4-modulo)
-                 else if (l>=2) and ((modulo and 1)<>0) then
-                   inc(l,2-(modulo and 1));
-                 inc(owner^.datasize,l);
-
-                 address:=owner^.datasize;
-              end
-            else if owner^.symtabletype=staticsymtable then
-              begin
-                if (cs_smartlink in aktswitches) then
-                  bsssegment^.concat(new(pai_cut,init));
+                            if (l>=4) and (modulo<>0) then
+                             inc(l,4-modulo)
+                            else
+                             if (l>=2) and ((modulo and 1)<>0) then
+                              inc(l,2-(modulo and 1));
+                            inc(owner^.datasize,l);
+                            address:=owner^.datasize;
+                          end;
+         staticsymtable : begin
+                            if (cs_smartlink in aktswitches) then
+                              bsssegment^.concat(new(pai_cut,init));
 {$ifdef GDB}
-                if cs_debuginfo in aktswitches then
-                   concatstabto(bsssegment);
+                            if cs_debuginfo in aktswitches then
+                               concatstabto(bsssegment);
 {$endif GDB}
-                if (cs_smartlink in aktswitches) or
-                   ((var_options and vo_is_c_var)<>0) then
-                  bsssegment^.concat(new(pai_datablock,init_global(mangledname,l)))
-                else
-                  bsssegment^.concat(new(pai_datablock,init(mangledname,l)));
-
-                inc(owner^.datasize,l);
-
-                { this symbol can't be loaded to a register }
-                var_options:=var_options and not vo_regable;
-              end
-            else if owner^.symtabletype=globalsymtable then
-              begin
-                 if (cs_smartlink in aktswitches) then
-                   bsssegment^.concat(new(pai_cut,init));
+                            if (cs_smartlink in aktswitches) or
+                               ((var_options and vo_is_c_var)<>0) then
+                              bsssegment^.concat(new(pai_datablock,init_global(mangledname,l)))
+                            else
+                              bsssegment^.concat(new(pai_datablock,init(mangledname,l)));
+                            { increase datasize }
+                            inc(owner^.datasize,l);
+                            { this symbol can't be loaded to a register }
+                            var_options:=var_options and not vo_regable;
+                          end;
+         globalsymtable : begin
+                            if (cs_smartlink in aktswitches) then
+                              bsssegment^.concat(new(pai_cut,init));
 {$ifdef GDB}
-                 if cs_debuginfo in aktswitches then
-                   begin
-                      concatstabto(bsssegment);
-                      { this has to be added so that the debugger knows where to find
-                        the global variable
-                        Doesn't work !!
-                      bsssegment^.concat(new(pai_symbol,init('_'+name))); }
-                   end;
+                            if cs_debuginfo in aktswitches then
+                              concatstabto(bsssegment);
 {$endif GDB}
-                 bsssegment^.concat(new(pai_datablock,init_global(mangledname,l)));
-                 inc(owner^.datasize,l);
-
-                 { this symbol can't be loaded to a register }
-                 var_options:=var_options and not vo_regable;
-              end
-            else if owner^.symtabletype in [recordsymtable,objectsymtable] then
-              begin
-                 { align record and object fields }
-                 if aktpackrecords=2 then
-                   begin
-                     { align to word }
-                     modulo:=owner^.datasize and 3;
-                     if (l>=2) and ((modulo and 1)<>0) then
-                       inc(owner^.datasize);
-                   end
-                 else if aktpackrecords=4 then
-                   begin
-                      { align to dword }
-                      if (l>=3) and (modulo<>0) then
-                        inc(owner^.datasize,4-modulo)
-                        { or word }
-                      else if (l=2) and ((modulo and 1)<>0) then
-                        inc(owner^.datasize)
-                   end;
-                 address:=owner^.datasize;
-                 inc(owner^.datasize,l);
-
-                 { this symbol can't be loaded to a register }
-                var_options:=var_options and not vo_regable;
-              end
-             else if owner^.symtabletype=parasymtable then
-              begin
-                 address:=owner^.datasize;
-
-                 { intel processors don't know a byte push, }
-                 { so is always a word pushed               }
-                 { so it must allways be even               }
-                 if (l and 1)<>0 then
-                   inc(l);
-                 inc(owner^.datasize,l);
-              end
-            else
-              begin
-                 modulo:=owner^.datasize and 3 ;
-                 if (l>=4) and (modulo<>0) then
-                   inc(owner^.datasize,4-modulo)
-                 else if (l>=2) and ((modulo and 1)<>0) then
-                   { nice piece of code !!
-                   inc(owner^.datasize,2-(datasize and 1));
-                   2 - (datasize and 1) is allways 1 in this case
-                   Florian when will your global stream analyser
-                   find this out ?? }
-                   inc(owner^.datasize);
-                 address:=owner^.datasize;
-                 inc(owner^.datasize,l);
-              end;
-            end
-        end;
+                            bsssegment^.concat(new(pai_datablock,init_global(mangledname,l)));
+                            inc(owner^.datasize,l);
+                            { this symbol can't be loaded to a register }
+                            var_options:=var_options and not vo_regable;
+                          end;
+         recordsymtable,
+         objectsymtable : begin
+                            address:=owner^.datasize;
+                          { align record and object fields }
+                            owner^.datasize:=(owner^.datasize+l+(aktpackrecords-1)) and (not (aktpackrecords-1));
+                          { this symbol can't be loaded to a register }
+                            var_options:=var_options and not vo_regable;
+                          end;
+           parasymtable : begin
+                            address:=owner^.datasize;
+                          { needs word alignment }
+                            if odd(l) then
+                             inc(owner^.datasize,l+1)
+                            else
+                             inc(owner^.datasize,l);
+                          end
+             else
+               begin
+                  modulo:=owner^.datasize and 3 ;
+                  if (l>=4) and (modulo<>0) then
+                    inc(owner^.datasize,4-modulo)
+                  else
+                    if (l>=2) and ((modulo and 1)<>0) then
+                    { nice piece of code !!
+                    inc(owner^.datasize,2-(datasize and 1));
+                    2 - (datasize and 1) is allways 1 in this case
+                    Florian when will your global stream analyser
+                    find this out ?? }
+                      inc(owner^.datasize);
+                  address:=owner^.datasize;
+                  inc(owner^.datasize,l);
+               end;
+             end;
+          end;
+      end;
 
 {$ifdef GDB}
     function tvarsym.stabstring : pchar;
@@ -1656,7 +1625,11 @@
 
 {
   $Log$
-  Revision 1.18  1998-07-07 11:20:15  peter
+  Revision 1.19  1998-07-07 17:40:39  peter
+    * packrecords 4 works
+    * word aligning of parameters
+
+  Revision 1.18  1998/07/07 11:20:15  peter
     + NEWINPUT for a better inputfile and scanner object
 
   Revision 1.17  1998/06/24 14:48:40  peter