Browse Source

* fixed several arm related problems

florian 21 years ago
parent
commit
a567970402

+ 8 - 3
compiler/arm/aasmcpu.pas

@@ -285,14 +285,16 @@ implementation
 
     function taicpu.is_nop: boolean;
       begin
-        { we don't insert any more nops than necessary }
-        is_nop := false;
+        { allow the register allocator to remove unnecessary moves }
+        result:=is_move and (oper[0]^.reg=oper[1]^.reg);
       end;
 
 
     function taicpu.is_move:boolean;
       begin
         result:=(opcode=A_MOV) and
+                (condition=C_None) and
+                (ops=2) and
                 (oper[0]^.typ=top_reg) and
                 (oper[1]^.typ=top_reg);
       end;
@@ -367,7 +369,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.15  2003-11-29 17:36:56  peter
+  Revision 1.16  2003-11-30 19:35:29  florian
+    * fixed several arm related problems
+
+  Revision 1.15  2003/11/29 17:36:56  peter
     * fixed is_move
 
   Revision 1.14  2003/11/24 15:17:37  florian

+ 16 - 6
compiler/arm/agarmgas.pas

@@ -208,11 +208,18 @@ unit agarmgas;
                { LDM and STM use references as first operand but they are written like a register }
                if (i=0) and (op in [A_LDM,A_STM]) then
                  begin
-                   if (taicpu(hp).oper[0]^.typ<>top_ref) then
-                     internalerror(200311292);
-                   s:=s+sep+gas_regname(taicpu(hp).oper[0]^.ref^.index);
-                   if taicpu(hp).oper[0]^.ref^.addressmode=AM_PREINDEXED then
-                     s:=s+'!';
+                   case taicpu(hp).oper[0]^.typ of
+                     top_ref:
+                       begin
+                         s:=s+sep+gas_regname(taicpu(hp).oper[0]^.ref^.index);
+                         if taicpu(hp).oper[0]^.ref^.addressmode=AM_PREINDEXED then
+                           s:=s+'!';
+                       end;
+                     top_reg:
+                       s:=s+sep+gas_regname(taicpu(hp).oper[0]^.reg);
+                     else
+                       internalerror(200311292);
+                   end;
                  end
                else
                   s:=s+sep+getopstr(taicpu(hp).oper[i]^);
@@ -229,7 +236,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.16  2003-11-29 17:36:56  peter
+  Revision 1.17  2003-11-30 19:35:29  florian
+    * fixed several arm related problems
+
+  Revision 1.16  2003/11/29 17:36:56  peter
     * fixed is_move
 
   Revision 1.15  2003/11/21 16:29:26  florian

+ 18 - 3
compiler/arm/cgcpu.pas

@@ -874,6 +874,7 @@ unit cgcpu;
     procedure tcgarm.g_stackframe_entry(list : taasmoutput;localsize : longint);
       var
          ref : treference;
+         shift : byte;
       begin
         LocalSize:=align(LocalSize,4);
 
@@ -889,10 +890,21 @@ unit cgcpu;
         list.concat(setoppostfix(taicpu.op_ref_regset(A_STM,ref,rgint.used_in_proc-[RS_R0..RS_R3]+[RS_R11,RS_R12,RS_R15]),PF_FD));
 
         list.concat(taicpu.op_reg_reg_const(A_SUB,NR_FRAME_POINTER_REG,NR_R12,4));
-        a_reg_dealloc(list,NR_R12);
 
         { allocate necessary stack size }
-        list.concat(taicpu.op_reg_reg_const(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,LocalSize));
+        { don't use  a_op_const_reg_reg here because we don't allow register allocations
+          in the entry/exit code }
+        if not(is_shifter_const(localsize,shift)) then
+          begin
+            a_load_const_reg(list,OS_ADDR,LocalSize,NR_R12);
+            list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
+            a_reg_dealloc(list,NR_R12);
+          end
+        else
+          begin
+            a_reg_dealloc(list,NR_R12);
+            list.concat(taicpu.op_reg_reg_const(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,LocalSize));
+          end;
       end;
 
 
@@ -1282,7 +1294,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.24  2003-11-24 15:17:37  florian
+  Revision 1.25  2003-11-30 19:35:29  florian
+    * fixed several arm related problems
+
+  Revision 1.24  2003/11/24 15:17:37  florian
     * changed some types to prevend range check errors
 
   Revision 1.23  2003/11/21 16:29:26  florian

+ 6 - 6
compiler/arm/cpupi.pas

@@ -119,11 +119,8 @@ unit cpupi;
 
     function tarmprocinfo.calc_stackframe_size:longint;
       begin
-        { more or less copied from cgcpu.pas/g_stackframe_entry }
-        if not (po_assembler in procdef.procoptions) then
-          result := align(align((31-13+1)*4+(31-14+1)*8,16)+tg.lasttemp*tg.direction,16)
-        else
-          result := align(tg.lasttemp*tg.direction,16);
+        { align to 4 bytes at least }
+        result:=Align(tg.direction*tg.lasttemp,max(aktalignment.localalignmin,4));
       end;
 
 
@@ -132,7 +129,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.3  2003-11-24 15:17:37  florian
+  Revision 1.4  2003-11-30 19:35:29  florian
+    * fixed several arm related problems
+
+  Revision 1.3  2003/11/24 15:17:37  florian
     * changed some types to prevend range check errors
 
   Revision 1.2  2003/11/02 14:30:03  florian

+ 94 - 2
compiler/arm/narmcnv.pas

@@ -119,16 +119,108 @@ implementation
 
 
     procedure tarmtypeconvnode.second_int_to_bool;
+      var
+        hregister : tregister;
+        href      : treference;
+        resflags  : tresflags;
+        hlabel,oldtruelabel,oldfalselabel : tasmlabel;
       begin
+         oldtruelabel:=truelabel;
+         oldfalselabel:=falselabel;
+         objectlibrary.getlabel(truelabel);
+         objectlibrary.getlabel(falselabel);
+         secondpass(left);
+         if codegenerror then
+          exit;
+         { byte(boolean) or word(wordbool) or longint(longbool) must
+           be accepted for var parameters                            }
+         if (nf_explicit in flags) and
+            (left.resulttype.def.size=resulttype.def.size) and
+            (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
+           begin
+              location_copy(location,left.location);
+              truelabel:=oldtruelabel;
+              falselabel:=oldfalselabel;
+              exit;
+           end;
+
+         { Load left node into flag F_NE/F_E }
+         resflags:=F_NE;
+         case left.location.loc of
+            LOC_CREFERENCE,
+            LOC_REFERENCE :
+              begin
+                if left.location.size in [OS_64,OS_S64] then
+                 begin
+                   location_release(exprasmlist,left.location);
+                   hregister:=cg.getintregister(exprasmlist,OS_INT);
+                   cg.a_load_ref_reg(exprasmlist,OS_32,OS_32,left.location.reference,hregister);
+                   href:=left.location.reference;
+                   inc(href.offset,4);
+                   cg.ungetregister(exprasmlist,hregister);
+                   cg.a_op_ref_reg(exprasmlist,OP_OR,OS_32,href,hregister);
+                 end
+                else
+                 begin
+                   location_force_reg(exprasmlist,left.location,left.location.size,true);
+                   location_release(exprasmlist,left.location);
+                   cg.a_op_reg_reg(exprasmlist,OP_OR,left.location.size,left.location.register,left.location.register);
+                 end;
+              end;
+            LOC_FLAGS :
+              begin
+                resflags:=left.location.resflags;
+              end;
+            LOC_REGISTER,LOC_CREGISTER :
+              begin
+                if left.location.size in [OS_64,OS_S64] then
+                 begin
+                   hregister:=cg.getintregister(exprasmlist,OS_32);
+                   cg.a_load_reg_reg(exprasmlist,OS_32,OS_32,left.location.registerlow,hregister);
+                   cg.ungetregister(exprasmlist,hregister);
+                   location_release(exprasmlist,left.location);
+                   cg.a_op_reg_reg(exprasmlist,OP_OR,OS_32,left.location.registerhigh,hregister);
+                 end
+                else
+                 begin
+                   location_release(exprasmlist,left.location);
+                   cg.a_op_reg_reg(exprasmlist,OP_OR,left.location.size,left.location.register,left.location.register);
+                 end;
+              end;
+            LOC_JUMP :
+              begin
+                hregister:=cg.getintregister(exprasmlist,OS_INT);
+                objectlibrary.getlabel(hlabel);
+                cg.a_label(exprasmlist,truelabel);
+                cg.a_load_const_reg(exprasmlist,OS_INT,1,hregister);
+                cg.a_jmp_always(exprasmlist,hlabel);
+                cg.a_label(exprasmlist,falselabel);
+                cg.a_load_const_reg(exprasmlist,OS_INT,0,hregister);
+                cg.a_label(exprasmlist,hlabel);
+                cg.ungetregister(exprasmlist,hregister);
+                cg.a_op_reg_reg(exprasmlist,OP_OR,OS_INT,hregister,hregister);
+              end;
+            else
+              internalerror(200311301);
+         end;
+         { load flags to register }
+         location_reset(location,LOC_REGISTER,def_cgsize(resulttype.def));
+         location.register:=cg.getintregister(exprasmlist,location.size);
+         cg.g_flags2reg(exprasmlist,location.size,resflags,location.register);
+         truelabel:=oldtruelabel;
+         falselabel:=oldfalselabel;
       end;
 
 
 begin
-   ctypeconvnode:=tarmtypeconvnode;
+  ctypeconvnode:=tarmtypeconvnode;
 end.
 {
   $Log$
-  Revision 1.6  2003-11-04 22:30:15  florian
+  Revision 1.7  2003-11-30 19:35:29  florian
+    * fixed several arm related problems
+
+  Revision 1.6  2003/11/04 22:30:15  florian
     + type cast variant<->enum
     * cnv. node second pass uses now as well helper wrappers
 

+ 5 - 3
compiler/globals.pas

@@ -1715,7 +1715,6 @@ implementation
         {$IFDEF testvarsets}
         initsetalloc:=0;
         {$ENDIF}
-        initasmmode:=asmmode_direct;
         initfputype:=fpu_fpa;
 {$endif arm}
 {$ifdef x86_64}
@@ -1745,7 +1744,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.115  2003-11-12 16:05:39  florian
+  Revision 1.116  2003-11-30 19:35:29  florian
+    * fixed several arm related problems
+
+  Revision 1.115  2003/11/12 16:05:39  florian
     * assembler readers OOPed
     + typed currency constants
     + typed 128 bit float constants if the CPU supports it
@@ -2023,4 +2025,4 @@ end.
    * implicit result variable generation for assembler routines
    * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
 
-}
+}

+ 8 - 2
compiler/ncgutil.pas

@@ -225,7 +225,10 @@ implementation
                        end;
 {$endif cpuflags}
                      else
-                       internalerror(200308241);
+                       begin
+                         printnode(output,p);
+                         internalerror(200308241);
+                       end;
                    end;
                 end;
            end
@@ -1979,7 +1982,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.170  2003-11-29 20:13:25  florian
+  Revision 1.171  2003-11-30 19:35:29  florian
+    * fixed several arm related problems
+
+  Revision 1.170  2003/11/29 20:13:25  florian
     * fixed several pi_do_call problems
 
   Revision 1.169  2003/11/23 17:05:15  peter