瀏覽代碼

* 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:
               begin
                 if a>32 then
-                  internalerror(200308291);
+                  internalerror(200308294);
                 if a<>0 then
                   begin
                     shifterop_reset(so);
@@ -422,7 +422,7 @@ unit cgcpu;
             OP_SAR:
               begin
                 if a>32 then
-                  internalerror(200308291);
+                  internalerror(200308295);
                 if a<>0 then
                   begin
                     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
               begin
                 if l1>32 then{roozbeh does this ever happen?}
-                  internalerror(200308291);
+                  internalerror(200308296);
                 shifterop_reset(so);
                 so.shiftmode:=SM_LSL;
                 so.shiftimm:=l1;
@@ -844,7 +844,7 @@ unit cgcpu;
            OS_S32:
              oppostfix:=PF_None;
            else
-             InternalError(200308291);
+             InternalError(200308297);
          end;
          if Ref.alignment<>0 then
            begin
@@ -1020,7 +1020,15 @@ unit cgcpu;
               LOC_FPUREGISTER,LOC_CFPUREGISTER:
                 a_loadfpu_ref_reg(list,size,ref,hloc^.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 :
                 begin
                   reference_reset_base(href2,hloc^.reference.index,hloc^.reference.offset);
@@ -1046,8 +1054,10 @@ unit cgcpu;
          oppostfix:toppostfix;
        begin
          case size of
+           OS_32,
            OS_F32:
              oppostfix:=PF_S;
+           OS_64,
            OS_F64:
              oppostfix:=PF_D;
            OS_F80:

+ 1 - 1
compiler/arm/cpupara.pas

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

+ 16 - 16
compiler/cgobj.pas

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

+ 31 - 24
compiler/ncgcal.pas

@@ -76,6 +76,7 @@ implementation
     uses
       systems,
       cutils,verbose,globals,
+      cpuinfo,
       symconst,symtable,defutil,paramgr,
       cgbase,pass_2,
       aasmbase,aasmtai,aasmdata,
@@ -575,32 +576,38 @@ implementation
                           location_reset(location,LOC_REGISTER,cgsize);
 {$ifndef cpu64bit}
                           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
 {$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
                        else
                         begin

+ 3 - 3
compiler/ncgutil.pas

@@ -1578,7 +1578,7 @@ implementation
         paraloc  : pcgparalocation;
         href     : treference;
         sizeleft : aint;
-{$ifdef sparc}
+{$if defined(sparc) or defined(arm)}
         tempref  : treference;
 {$endif sparc}
       begin
@@ -1696,8 +1696,8 @@ implementation
                 end;
               LOC_CFPUREGISTER :
                 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 }
                   sizeleft := TCGSize2Size[currpara.initialloc.size];
                   tg.GetTemp(list,sizeleft,tt_normal,tempref);