瀏覽代碼

* several arm fixes

git-svn-id: trunk@4742 -
florian 19 年之前
父節點
當前提交
67ba76f090
共有 5 個文件被更改,包括 66 次插入49 次删除
  1. 15 5
      compiler/arm/cgcpu.pas
  2. 1 1
      compiler/arm/cpupara.pas
  3. 16 16
      compiler/cgobj.pas
  4. 31 24
      compiler/ncgcal.pas
  5. 3 3
      compiler/ncgutil.pas

+ 15 - 5
compiler/arm/cgcpu.pas

@@ -394,7 +394,7 @@ unit cgcpu;
             OP_SHL:
             OP_SHL:
               begin
               begin
                 if a>32 then
                 if a>32 then
-                  internalerror(200308291);
+                  internalerror(200308294);
                 if a<>0 then
                 if a<>0 then
                   begin
                   begin
                     shifterop_reset(so);
                     shifterop_reset(so);
@@ -422,7 +422,7 @@ unit cgcpu;
             OP_SAR:
             OP_SAR:
               begin
               begin
                 if a>32 then
                 if a>32 then
-                  internalerror(200308291);
+                  internalerror(200308295);
                 if a<>0 then
                 if a<>0 then
                   begin
                   begin
                     shifterop_reset(so);
                     shifterop_reset(so);
@@ -465,7 +465,7 @@ unit cgcpu;
             else if (op in [OP_MUL,OP_IMUL]) and ispowerof2(a-1,l1) and not(cgsetflags or setflags) then
             else if (op in [OP_MUL,OP_IMUL]) and ispowerof2(a-1,l1) and not(cgsetflags or setflags) then
               begin
               begin
                 if l1>32 then{roozbeh does this ever happen?}
                 if l1>32 then{roozbeh does this ever happen?}
-                  internalerror(200308291);
+                  internalerror(200308296);
                 shifterop_reset(so);
                 shifterop_reset(so);
                 so.shiftmode:=SM_LSL;
                 so.shiftmode:=SM_LSL;
                 so.shiftimm:=l1;
                 so.shiftimm:=l1;
@@ -844,7 +844,7 @@ unit cgcpu;
            OS_S32:
            OS_S32:
              oppostfix:=PF_None;
              oppostfix:=PF_None;
            else
            else
-             InternalError(200308291);
+             InternalError(200308297);
          end;
          end;
          if Ref.alignment<>0 then
          if Ref.alignment<>0 then
            begin
            begin
@@ -1020,7 +1020,15 @@ unit cgcpu;
               LOC_FPUREGISTER,LOC_CFPUREGISTER:
               LOC_FPUREGISTER,LOC_CFPUREGISTER:
                 a_loadfpu_ref_reg(list,size,ref,hloc^.register);
                 a_loadfpu_ref_reg(list,size,ref,hloc^.register);
               LOC_REGISTER :
               LOC_REGISTER :
-                a_load_ref_reg(list,hloc^.size,hloc^.size,href,hloc^.register);
+                case hloc^.size of
+                  OS_F32:
+                    a_load_ref_reg(list,OS_32,OS_32,href,hloc^.register);
+                  OS_64,
+                  OS_F64:
+                    cg64.a_param64_ref(list,href,paraloc);
+                  else
+                    a_load_ref_reg(list,hloc^.size,hloc^.size,href,hloc^.register);
+                end;
               LOC_REFERENCE :
               LOC_REFERENCE :
                 begin
                 begin
                   reference_reset_base(href2,hloc^.reference.index,hloc^.reference.offset);
                   reference_reset_base(href2,hloc^.reference.index,hloc^.reference.offset);
@@ -1046,8 +1054,10 @@ unit cgcpu;
          oppostfix:toppostfix;
          oppostfix:toppostfix;
        begin
        begin
          case size of
          case size of
+           OS_32,
            OS_F32:
            OS_F32:
              oppostfix:=PF_S;
              oppostfix:=PF_S;
+           OS_64,
            OS_F64:
            OS_F64:
              oppostfix:=PF_D;
              oppostfix:=PF_D;
            OS_F80:
            OS_F80:

+ 1 - 1
compiler/arm/cpupara.pas

@@ -288,7 +288,7 @@ unit cpupara;
                      OS_F32:
                      OS_F32:
                        paraloc^.size:=OS_32;
                        paraloc^.size:=OS_32;
                      OS_F64:
                      OS_F64:
-                       paraloc^.size:=OS_64;
+                       paraloc^.size:=OS_32;
                      else
                      else
                        internalerror(2005082901);
                        internalerror(2005082901);
                    end
                    end

+ 16 - 16
compiler/cgobj.pas

@@ -1047,18 +1047,18 @@ implementation
   in memory. They are like a regular reference, but contain an extra bit
   in memory. They are like a regular reference, but contain an extra bit
   offset (either constant -startbit- or variable -bitindexreg, always OS_INT)
   offset (either constant -startbit- or variable -bitindexreg, always OS_INT)
   and a bit length (always constant).
   and a bit length (always constant).
-  
+
   Bit packed values are stored differently in memory depending on whether we
   Bit packed values are stored differently in memory depending on whether we
   are on a big or a little endian system (compatible with at least GPC). The
   are on a big or a little endian system (compatible with at least GPC). The
   size of the basic working unit is always the smallest power-of-2 byte size
   size of the basic working unit is always the smallest power-of-2 byte size
   which can contain the bit value (so 1..8 bits -> 1 byte, 9..16 bits -> 2
   which can contain the bit value (so 1..8 bits -> 1 byte, 9..16 bits -> 2
   bytes, 17..32 bits -> 4 bytes etc).
   bytes, 17..32 bits -> 4 bytes etc).
-  
+
   On a big endian, 5-bit: values are stored like this:
   On a big endian, 5-bit: values are stored like this:
     11111222 22333334 44445555 56666677 77788888
     11111222 22333334 44445555 56666677 77788888
   The leftmost bit of each 5-bit value corresponds to the most significant
   The leftmost bit of each 5-bit value corresponds to the most significant
   bit.
   bit.
-  
+
   On little endian, it goes like this:
   On little endian, it goes like this:
     22211111 43333322 55554444 77666665 88888777
     22211111 43333322 55554444 77666665 88888777
   In this case, per byte the left-most bit is more significant than those on
   In this case, per byte the left-most bit is more significant than those on
@@ -1066,10 +1066,10 @@ implementation
   those in the previous byte (e.g., the 222 in the first byte are the low
   those in the previous byte (e.g., the 222 in the first byte are the low
   three bits of that value, while the 22 in the second byte are the upper
   three bits of that value, while the 22 in the second byte are the upper
   three bits.
   three bits.
-  
+
   Big endian, 9 bit values:
   Big endian, 9 bit values:
     11111111 12222222 22333333 33344444 ...
     11111111 12222222 22333333 33344444 ...
-  
+
   Little endian, 9 bit values:
   Little endian, 9 bit values:
     11111111 22222221 33333322 44444333 ...
     11111111 22222221 33333322 44444333 ...
   This is memory representation and the 16 bit values are byteswapped.
   This is memory representation and the 16 bit values are byteswapped.
@@ -1080,7 +1080,7 @@ implementation
   alignment can be guaranteed), this becomes:
   alignment can be guaranteed), this becomes:
     22222221 11111111 44444333 33333322 ...
     22222221 11111111 44444333 33333322 ...
     (l)ow  u     l     l    u     l   u
     (l)ow  u     l     l    u     l   u
-  
+
   The startbit/bitindex in a subsetreference always refers to
   The startbit/bitindex in a subsetreference always refers to
   a) on big endian: the most significant bit of the value
   a) on big endian: the most significant bit of the value
      (bits counted from left to right, both memory an registers)
      (bits counted from left to right, both memory an registers)
@@ -1101,13 +1101,13 @@ implementation
         intloadsize: aint;
         intloadsize: aint;
       begin
       begin
         intloadsize := packedbitsloadsize(sref.bitlen);
         intloadsize := packedbitsloadsize(sref.bitlen);
-        
+
 {$ifdef cpurequiresproperalignment}
 {$ifdef cpurequiresproperalignment}
         { may need to be split into several smaller loads/stores }
         { may need to be split into several smaller loads/stores }
         if intloadsize <> sref.ref.alignment then
         if intloadsize <> sref.ref.alignment then
            internalerror(2006082011);
            internalerror(2006082011);
 {$endif cpurequiresproperalignment}
 {$endif cpurequiresproperalignment}
-        
+
         if (intloadsize = 0) then
         if (intloadsize = 0) then
           internalerror(2006081310);
           internalerror(2006081310);
 
 
@@ -1205,7 +1205,7 @@ implementation
                 a_op_const_reg(list,OP_SUB,OS_INT,1,tmpreg);
                 a_op_const_reg(list,OP_SUB,OS_INT,1,tmpreg);
                 { if (tmpreg = cpu_bit_size) then extra_value_reg := 0 }
                 { if (tmpreg = cpu_bit_size) then extra_value_reg := 0 }
                 a_op_reg_reg(list,OP_AND,OS_INT,tmpreg,extra_value_reg);
                 a_op_reg_reg(list,OP_AND,OS_INT,tmpreg,extra_value_reg);
-              end;  
+              end;
 {$endif x86}
 {$endif x86}
             { merge }
             { merge }
             a_op_reg_reg(list,OP_OR,OS_INT,extra_value_reg,valuereg);
             a_op_reg_reg(list,OP_OR,OS_INT,extra_value_reg,valuereg);
@@ -1301,7 +1301,7 @@ implementation
             destreg := makeregsize(list,destreg,tosize);
             destreg := makeregsize(list,destreg,tosize);
           end
           end
       end;
       end;
-          
+
 
 
     procedure tcg.a_load_reg_subsetref(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sref: tsubsetreference);
     procedure tcg.a_load_reg_subsetref(list : TAsmList; fromsize, subsetsize: tcgsize; fromreg: tregister; const sref: tsubsetreference);
       var
       var
@@ -1315,7 +1315,7 @@ implementation
         { the register must be able to contain the requested value }
         { the register must be able to contain the requested value }
         if (tcgsize2size[fromsize]*8 < sref.bitlen) then
         if (tcgsize2size[fromsize]*8 < sref.bitlen) then
           internalerror(2006081613);
           internalerror(2006081613);
-      
+
         get_subsetref_load_info(sref,loadsize,extra_load);
         get_subsetref_load_info(sref,loadsize,extra_load);
         loadbitsize := tcgsize2size[loadsize]*8;
         loadbitsize := tcgsize2size[loadsize]*8;
 
 
@@ -1418,7 +1418,7 @@ implementation
                 a_load_subsetreg_subsetreg(list,subsetsize,subsetsize,fromsreg,tosreg);
                 a_load_subsetreg_subsetreg(list,subsetsize,subsetsize,fromsreg,tosreg);
                 valuereg := makeregsize(list,valuereg,loadsize);
                 valuereg := makeregsize(list,valuereg,loadsize);
                 a_load_reg_ref(list,loadsize,loadsize,valuereg,sref.ref);
                 a_load_reg_ref(list,loadsize,loadsize,valuereg,sref.ref);
-                
+
                 { transfer second part }
                 { transfer second part }
                 if (target_info.endian = endian_big) then
                 if (target_info.endian = endian_big) then
                   begin
                   begin
@@ -1470,7 +1470,7 @@ implementation
 
 
                 a_op_reg_reg(list,OP_NOT,OS_INT,maskreg,maskreg);
                 a_op_reg_reg(list,OP_NOT,OS_INT,maskreg,maskreg);
                 a_op_reg_reg(list,OP_AND,OS_INT,maskreg,valuereg);
                 a_op_reg_reg(list,OP_AND,OS_INT,maskreg,valuereg);
-                
+
                 { insert the value }
                 { insert the value }
                 tmpreg := getintregister(list,OS_INT);
                 tmpreg := getintregister(list,OS_INT);
                 a_load_reg_reg(list,fromsize,OS_INT,fromreg,tmpreg);
                 a_load_reg_reg(list,fromsize,OS_INT,fromreg,tmpreg);
@@ -1527,13 +1527,13 @@ implementation
                         { if (tmpreg = cpu_bit_size) then tmpreg := maskreg := 0 }
                         { if (tmpreg = cpu_bit_size) then tmpreg := maskreg := 0 }
                         a_op_reg_reg(list,OP_AND,OS_INT,valuereg,tmpreg);
                         a_op_reg_reg(list,OP_AND,OS_INT,valuereg,tmpreg);
                         a_op_reg_reg(list,OP_AND,OS_INT,valuereg,maskreg);
                         a_op_reg_reg(list,OP_AND,OS_INT,valuereg,maskreg);
-                      end;  
+                      end;
 {$endif x86}
 {$endif x86}
                   end;
                   end;
 
 
                 a_op_reg_reg(list,OP_NOT,OS_INT,maskreg,maskreg);
                 a_op_reg_reg(list,OP_NOT,OS_INT,maskreg,maskreg);
                 a_op_reg_reg(list,OP_AND,OS_INT,maskreg,extra_value_reg);
                 a_op_reg_reg(list,OP_AND,OS_INT,maskreg,extra_value_reg);
-                
+
                 if (target_info.endian = endian_big) then
                 if (target_info.endian = endian_big) then
                   a_op_reg_reg(list,OP_SHL,OS_INT,tmpindexreg,tmpreg)
                   a_op_reg_reg(list,OP_SHL,OS_INT,tmpindexreg,tmpreg)
                 else
                 else
@@ -1614,7 +1614,7 @@ implementation
         a_load_subsetref_reg(list,fromsubsetsize,tosubsetsize,fromsref,tmpreg);
         a_load_subsetref_reg(list,fromsubsetsize,tosubsetsize,fromsref,tmpreg);
         a_load_reg_subsetreg(list,tosubsetsize,tosubsetsize,tmpreg,tosreg);
         a_load_reg_subsetreg(list,tosubsetsize,tosubsetsize,tmpreg,tosreg);
       end;
       end;
-      
+
 
 
     procedure tcg.a_load_subsetreg_subsetref(list: TAsmlist; fromsubsetsize, tosubsetsize : tcgsize; const fromsreg: tsubsetregister; const tosref: tsubsetreference);
     procedure tcg.a_load_subsetreg_subsetref(list: TAsmlist; fromsubsetsize, tosubsetsize : tcgsize; const fromsreg: tsubsetregister; const tosref: tsubsetreference);
       var
       var

+ 31 - 24
compiler/ncgcal.pas

@@ -76,6 +76,7 @@ implementation
     uses
     uses
       systems,
       systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
+      cpuinfo,
       symconst,symtable,defutil,paramgr,
       symconst,symtable,defutil,paramgr,
       cgbase,pass_2,
       cgbase,pass_2,
       aasmbase,aasmtai,aasmdata,
       aasmbase,aasmtai,aasmdata,
@@ -575,32 +576,38 @@ implementation
                           location_reset(location,LOC_REGISTER,cgsize);
                           location_reset(location,LOC_REGISTER,cgsize);
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
                           if cgsize in [OS_64,OS_S64] then
                           if cgsize in [OS_64,OS_S64] then
-                           begin
-                             retloc:=procdefinition.funcretloc[callerside];
-                             if retloc.loc<>LOC_REGISTER then
-                               internalerror(200409141);
-                             { the function result registers are already allocated }
-                             if getsupreg(retloc.register64.reglo)<first_int_imreg then
-                               cg.ungetcpuregister(current_asmdata.CurrAsmList,retloc.register64.reglo);
-                             location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-                             cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,retloc.register64.reglo,location.register64.reglo);
-                             if getsupreg(retloc.register64.reghi)<first_int_imreg then
-                               cg.ungetcpuregister(current_asmdata.CurrAsmList,retloc.register64.reghi);
-                             location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-                             cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,retloc.register64.reghi,location.register64.reghi);
-                           end
+                            begin
+                              retloc:=procdefinition.funcretloc[callerside];
+                              if retloc.loc<>LOC_REGISTER then
+                                internalerror(200409141);
+                              { the function result registers are already allocated }
+                              if getsupreg(retloc.register64.reglo)<first_int_imreg then
+                                cg.ungetcpuregister(current_asmdata.CurrAsmList,retloc.register64.reglo);
+                              location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+                              cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,retloc.register64.reglo,location.register64.reglo);
+                              if getsupreg(retloc.register64.reghi)<first_int_imreg then
+                                cg.ungetcpuregister(current_asmdata.CurrAsmList,retloc.register64.reghi);
+                              location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+                              cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,retloc.register64.reghi,location.register64.reghi);
+                            end
                           else
                           else
 {$endif cpu64bit}
 {$endif cpu64bit}
-                           begin
-                             { change register size after the unget because the
-                               getregister was done for the full register
-                               def_cgsize(resulttype.def) is used here because
-                               it could be a constructor call }
-                             if getsupreg(procdefinition.funcretloc[callerside].register)<first_int_imreg then
-                               cg.ungetcpuregister(current_asmdata.CurrAsmList,procdefinition.funcretloc[callerside].register);
-                             location.register:=cg.getintregister(current_asmdata.CurrAsmList,def_cgsize(resulttype.def));
-                             cg.a_load_reg_reg(current_asmdata.CurrAsmList,cgsize,def_cgsize(resulttype.def),procdefinition.funcretloc[callerside].register,location.register);
-                           end;
+                            begin
+                              { change register size after the unget because the
+                                getregister was done for the full register
+                                def_cgsize(resulttype.def) is used here because
+                                it could be a constructor call }
+                              if getsupreg(procdefinition.funcretloc[callerside].register)<first_int_imreg then
+                                cg.ungetcpuregister(current_asmdata.CurrAsmList,procdefinition.funcretloc[callerside].register);
+                              location.register:=cg.getintregister(current_asmdata.CurrAsmList,def_cgsize(resulttype.def));
+                              cg.a_load_reg_reg(current_asmdata.CurrAsmList,cgsize,def_cgsize(resulttype.def),procdefinition.funcretloc[callerside].register,location.register);
+                            end;
+{$ifdef arm}
+                          if (resulttype.def.deftype=floatdef) and (aktfputype in [fpu_fpa,fpu_fpa10,fpu_fpa11]) then
+                            begin
+                              location_force_mem(current_asmdata.CurrAsmList,location);
+                            end;
+{$endif arm}
                         end
                         end
                        else
                        else
                         begin
                         begin

+ 3 - 3
compiler/ncgutil.pas

@@ -1578,7 +1578,7 @@ implementation
         paraloc  : pcgparalocation;
         paraloc  : pcgparalocation;
         href     : treference;
         href     : treference;
         sizeleft : aint;
         sizeleft : aint;
-{$ifdef sparc}
+{$if defined(sparc) or defined(arm)}
         tempref  : treference;
         tempref  : treference;
 {$endif sparc}
 {$endif sparc}
       begin
       begin
@@ -1696,8 +1696,8 @@ implementation
                 end;
                 end;
               LOC_CFPUREGISTER :
               LOC_CFPUREGISTER :
                 begin
                 begin
-{$ifdef sparc}
-                  { Sparc passes floats in int registers, when loading to fpu register
+{$if defined(sparc) or defined(arm)}
+                  { Arm and Sparc passes floats in int registers, when loading to fpu register
                     we need a temp }
                     we need a temp }
                   sizeleft := TCGSize2Size[currpara.initialloc.size];
                   sizeleft := TCGSize2Size[currpara.initialloc.size];
                   tg.GetTemp(list,sizeleft,tt_normal,tempref);
                   tg.GetTemp(list,sizeleft,tt_normal,tempref);