瀏覽代碼

* intial armv6m support, it is not working yet, constant pool insertation and conditional branch fixup is not working yet

git-svn-id: trunk@23682 -
florian 12 年之前
父節點
當前提交
1eeeb309c7

+ 1 - 0
.gitattributes

@@ -7436,6 +7436,7 @@ rtl/arm/setjump.inc svneol=native#text/plain
 rtl/arm/setjumph.inc svneol=native#text/plain
 rtl/arm/strings.inc svneol=native#text/plain
 rtl/arm/stringss.inc svneol=native#text/plain
+rtl/arm/thumb.inc svneol=native#text/plain
 rtl/arm/thumb2.inc svneol=native#text/plain
 rtl/atari/os.inc svneol=native#text/plain
 rtl/atari/prt0.as svneol=native#text/plain

+ 36 - 14
compiler/arm/aasmcpu.pas

@@ -861,12 +861,22 @@ implementation
         l : tasmlabel;
         doinsert,
         removeref : boolean;
+        multiplier : byte;
       begin
         curdata:=TAsmList.create;
         lastinspos:=-1;
         curinspos:=0;
         extradataoffset:=0;
-        limit:=1016;
+        if current_settings.cputype in cpu_thumb then
+          begin
+            multiplier:=2;
+            limit:=504;
+          end
+        else
+          begin
+            limit:=1016;
+            multiplier:=1;
+          end;
         curtai:=tai(list.first);
         doinsert:=false;
         while assigned(curtai) do
@@ -898,16 +908,16 @@ implementation
                                     ait_const:
                                       begin
                                         if (tai_const(hp).consttype=aitconst_64bit) then
-                                          inc(extradataoffset);
+                                          inc(extradataoffset,multiplier);
                                       end;
                                     ait_comp_64bit,
                                     ait_real_64bit:
                                       begin
-                                        inc(extradataoffset);
+                                        inc(extradataoffset,multiplier);
                                       end;
                                     ait_real_80bit:
                                       begin
-                                        inc(extradataoffset,2);
+                                        inc(extradataoffset,2*multiplier);
                                       end;
                                   end;
                                   if (hp.typ=ait_const) then
@@ -947,32 +957,32 @@ implementation
                             end;
                         end;
                     end;
-                  inc(curinspos);
+                  inc(curinspos,multiplier);
                 end;
               ait_align:
                 begin
                   { code is always 4 byte aligned, so we don't have to take care of .align 2 which would
                     requires also incrementing curinspos by 1 }
-                  inc(curinspos,(tai_align(curtai).aligntype div 4));
+                  inc(curinspos,(tai_align(curtai).aligntype div 4)*multiplier);
                 end;
               ait_const:
                 begin
-                  inc(curinspos);
+                  inc(curinspos,multiplier);
                   if (tai_const(curtai).consttype=aitconst_64bit) then
-                    inc(curinspos);
+                    inc(curinspos,multiplier);
                 end;
               ait_real_32bit:
                 begin
-                  inc(curinspos);
+                  inc(curinspos,multiplier);
                 end;
               ait_comp_64bit,
               ait_real_64bit:
                 begin
-                  inc(curinspos,2);
+                  inc(curinspos,2*multiplier);
                 end;
               ait_real_80bit:
                 begin
-                  inc(curinspos,3);
+                  inc(curinspos,3*multiplier);
                 end;
             end;
             { special case for case jump tables }
@@ -982,14 +992,14 @@ implementation
               (taicpu(hp).oper[0]^.typ=top_reg) and
               (taicpu(hp).oper[0]^.reg=NR_PC) then
               begin
-                penalty:=1;
+                penalty:=1*multiplier;
                 hp:=tai(hp.next);
                 { skip register allocations and comments inserted by the optimizer }
                 while assigned(hp) and (hp.typ in [ait_comment,ait_regalloc]) do
                   hp:=tai(hp.next);
                 while assigned(hp) and (hp.typ=ait_const) do
                   begin
-                    inc(penalty);
+                    inc(penalty,multiplier);
                     hp:=tai(hp.next);
                   end;
               end
@@ -1023,10 +1033,19 @@ implementation
               begin
                 lastinspos:=-1;
                 extradataoffset:=0;
-                limit:=1016;
+
+                if current_settings.cputype in cpu_thumb then
+                  limit:=508
+                else
+                  limit:=1016;
+
                 doinsert:=false;
                 hp:=tai(curtai.next);
                 current_asmdata.getjumplabel(l);
+
+                { align thumb in thumb .text section to 4 bytes }
+                if not(curdata.empty) and (current_settings.cputype in cpu_thumb) then
+                  curdata.Insert(tai_align.Create(4));
                 curdata.insert(taicpu.op_sym(A_B,l));
                 curdata.concat(tai_label.create(l));
                 list.insertlistafter(curtai,curdata);
@@ -1035,6 +1054,9 @@ implementation
             else
               curtai:=tai(curtai.next);
           end;
+        { align thumb in thumb .text section to 4 bytes }
+        if not(curdata.empty) and (current_settings.cputype in cpu_thumb) then
+          curdata.Insert(tai_align.Create(4));
         list.concatlist(curdata);
         curdata.free;
       end;

+ 1 - 0
compiler/arm/agarmgas.pas

@@ -68,6 +68,7 @@ unit agarmgas;
         'armv6k',
         'armv6t2',
         'armv6z',
+        'armv6-m',
         'armv7',
         'armv7-a',
         'armv7-r',

+ 3 - 1
compiler/arm/aoptcpu.pas

@@ -85,6 +85,7 @@ Implementation
   function CanBeCond(p : tai) : boolean;
     begin
       result:=
+        not(current_settings.cputype in cpu_thumb) and
         (p.typ=ait_instruction) and
         (taicpu(p).condition=C_None) and
         ((taicpu(p).opcode<A_IT) or (taicpu(p).opcode>A_ITTTT)) and
@@ -1666,7 +1667,8 @@ Implementation
               begin
                 case taicpu(p).opcode Of
                   A_B:
-                    if taicpu(p).condition<>C_None then
+                    if (taicpu(p).condition<>C_None) and
+                      not(current_settings.cputype in cpu_thumb) then
                       begin
                          { check for
                                 Bxx   xxx

+ 2 - 1
compiler/arm/armatt.inc

@@ -327,5 +327,6 @@
 'vsqrt',
 'vstm',
 'vstr',
-'vsub'
+'vsub',
+'neg'
 );

+ 1 - 0
compiler/arm/armatts.inc

@@ -327,5 +327,6 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
 attsufNONE
 );

+ 6 - 1
compiler/arm/armins.dat

@@ -786,4 +786,9 @@ reg32,reg32,reg32,reg32  \x16\x00\x80\x90		 ARM7
 [VSQRT]
 [VSTM]
 [VSTR]
-[VSUB]
+[VSUB]
+
+; Thumb armv6-m (gcc)
+[NEG]
+
+

+ 2 - 1
compiler/arm/armop.inc

@@ -327,5 +327,6 @@ A_VPUSH,
 A_VSQRT,
 A_VSTM,
 A_VSTR,
-A_VSUB
+A_VSUB,
+A_NEG
 );

File diff suppressed because it is too large
+ 847 - 169
compiler/arm/cgcpu.pas


+ 12 - 1
compiler/arm/cpubase.pas

@@ -363,7 +363,10 @@ unit cpubase;
     function is_pc(const r : tregister) : boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
     function is_shifter_const(d : aint;var imm_shift : byte) : boolean;
-    function is_thumb_imm(d : aint) : boolean; { Doesn't handle ROR_C detection }
+    function is_thumb_imm(d: aint): boolean;
+    { Returns true if d is a valid constant for thumb 32 bit,
+      doesn't handle ROR_C detection }
+    function is_thumb32_imm(d : aint) : boolean;
     function split_into_shifter_const(value : aint;var imm1: dword; var imm2: dword):boolean;
     function dwarf_reg(r:tregister):shortint;
 
@@ -549,7 +552,14 @@ unit cpubase;
         result:=false;
       end;
 
+
     function is_thumb_imm(d: aint): boolean;
+      begin
+        result:=(d and $FF) = d;
+      end;
+
+
+    function is_thumb32_imm(d: aint): boolean;
       var
         t : aint;
         i : longint;
@@ -586,6 +596,7 @@ unit cpubase;
           end;
       end;
 
+
     function split_into_shifter_const(value : aint;var imm1: dword; var imm2: dword) : boolean;
       var
         d, i, i2: Dword;

+ 4 - 1
compiler/arm/cpuinfo.pas

@@ -43,6 +43,7 @@ Type
        cpu_armv6k,
        cpu_armv6t2,
        cpu_armv6z,
+       cpu_armv6m,
        cpu_armv7,
        cpu_armv7a,
        cpu_armv7r,
@@ -52,7 +53,7 @@ Type
 
 Const
    cpu_arm = [cpu_none,cpu_armv3,cpu_armv4,cpu_armv4t,cpu_armv5];
-   cpu_thumb = [];
+   cpu_thumb = [cpu_armv6m];
    cpu_thumb2 = [cpu_armv7m];
 
 Type
@@ -243,6 +244,7 @@ Const
      'ARMV6K',
      'ARMV6T2',
      'ARMV6Z',
+     'ARMV6M',
      'ARMV7',
      'ARMV7A',
      'ARMV7R',
@@ -1096,6 +1098,7 @@ Const
        { cpu_armv6k   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX],
        { cpu_armv6t2  } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX],
        { cpu_armv6z   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX],
+       { cpu_armv6m   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_REV],
        { the identifier armv7 is should not be used, it is considered being equal to armv7a }
        { cpu_armv7    } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB],
        { cpu_armv7a   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB],

+ 5 - 5
compiler/arm/cpupi.pas

@@ -143,15 +143,15 @@ unit cpupi;
 
     procedure tarmprocinfo.init_framepointer;
       begin
-        if not(target_info.system in systems_darwin) then
+        if (target_info.system in systems_darwin) or (current_settings.cputype in cpu_thumb) then
           begin
-            RS_FRAME_POINTER_REG:=RS_R11;
-            NR_FRAME_POINTER_REG:=NR_R11;
+            RS_FRAME_POINTER_REG:=RS_R7;
+            NR_FRAME_POINTER_REG:=NR_R7;
           end
         else
           begin
-            RS_FRAME_POINTER_REG:=RS_R7;
-            NR_FRAME_POINTER_REG:=NR_R7;
+            RS_FRAME_POINTER_REG:=RS_R11;
+            NR_FRAME_POINTER_REG:=NR_R11;
           end;
       end;
 

+ 13 - 4
compiler/arm/narmadd.pas

@@ -406,7 +406,11 @@ interface
               hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true);
             dummyreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
             cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
-            current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,right.location.register64.reglo,right.location.register64.reghi),PF_S));
+
+            if current_settings.cputype in cpu_thumb then
+              cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,right.location.register64.reglo,right.location.register64.reghi,dummyreg)
+            else
+              current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,right.location.register64.reglo,right.location.register64.reghi),PF_S));
           end
         else if (nodetype in [equaln,unequaln]) and
           (right.nodetype=ordconstn) and (tordconstnode(right).value=0) then
@@ -417,7 +421,11 @@ interface
               hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
             dummyreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
             cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
-            current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,left.location.register64.reglo,left.location.register64.reghi),PF_S));
+
+            if current_settings.cputype in cpu_thumb then
+              cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reglo,left.location.register64.reghi,dummyreg)
+            else
+              current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,left.location.register64.reglo,left.location.register64.reghi),PF_S));
           end
         else
           begin
@@ -431,7 +439,7 @@ interface
                 location.resflags:=getresflags(unsigned);
                 cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
                 current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,left.location.register64.reghi,right.location.register64.reghi));
-                if current_settings.cputype in cpu_thumb2 then
+                if current_settings.cputype in (cpu_thumb+cpu_thumb2) then
                   begin
                     current_asmdata.getjumplabel(l);
                     cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,l);
@@ -599,7 +607,8 @@ interface
         cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
         if right.location.loc = LOC_CONSTANT then
           begin
-             if is_shifter_const(right.location.value,b) then
+             if (not(current_settings.cputype in cpu_thumb) and is_shifter_const(right.location.value,b)) or
+                ((current_settings.cputype in cpu_thumb) and is_thumb_imm(right.location.value)) then
                current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CMP,left.location.register,right.location.value))
              else
                begin

+ 10 - 10
compiler/arm/narmcnv.pas

@@ -323,16 +323,16 @@ implementation
                    cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,hregister);
                    href:=left.location.reference;
                    inc(href.offset,4);
-                   tcgarm(cg).cgsetflags:=true;
+                   tbasecgarm(cg).cgsetflags:=true;
                    cg.a_op_ref_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,href,hregister);
-                   tcgarm(cg).cgsetflags:=false;
+                   tbasecgarm(cg).cgsetflags:=false;
                  end
                 else
                  begin
                    hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
-                   tcgarm(cg).cgsetflags:=true;
+                   tbasecgarm(cg).cgsetflags:=true;
                    cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
-                   tcgarm(cg).cgsetflags:=false;
+                   tbasecgarm(cg).cgsetflags:=false;
                  end;
               end;
             LOC_FLAGS :
@@ -345,15 +345,15 @@ implementation
                  begin
                    hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
                    cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.register64.reglo,hregister);
-                   tcgarm(cg).cgsetflags:=true;
+                   tbasecgarm(cg).cgsetflags:=true;
                    cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,hregister);
-                   tcgarm(cg).cgsetflags:=false;
+                   tbasecgarm(cg).cgsetflags:=false;
                  end
                 else
                  begin
-                   tcgarm(cg).cgsetflags:=true;
+                   tbasecgarm(cg).cgsetflags:=true;
                    cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
-                   tcgarm(cg).cgsetflags:=false;
+                   tbasecgarm(cg).cgsetflags:=false;
                  end;
               end;
             LOC_JUMP :
@@ -366,9 +366,9 @@ implementation
                 cg.a_label(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
                 cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,0,hregister);
                 cg.a_label(current_asmdata.CurrAsmList,hlabel);
-                tcgarm(cg).cgsetflags:=true;
+                tbasecgarm(cg).cgsetflags:=true;
                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_INT,hregister,hregister);
-                tcgarm(cg).cgsetflags:=false;
+                tbasecgarm(cg).cgsetflags:=false;
               end;
             else
               internalerror(200311301);

+ 16 - 14
compiler/arm/narmmat.pas

@@ -135,18 +135,20 @@ implementation
                  begin
                     helper1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
                     helper2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                    shifterop_reset(so);
-                    so.shiftmode:=SM_ASR;
-                    so.shiftimm:=31;
-                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_shifterop(A_MOV,helper1,numerator,so));
-                    shifterop_reset(so);
-                    so.shiftmode:=SM_LSR;
-                    so.shiftimm:=32-power;
-                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,helper2,numerator,helper1,so));
-                    shifterop_reset(so);
-                    so.shiftmode:=SM_ASR;
-                    so.shiftimm:=power;
-                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_shifterop(A_MOV,resultreg,helper2,so));
+                    cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,31,numerator,helper1);
+                    if current_settings.cputype in cpu_thumb then
+                      begin
+                        cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,32-power,helper1);
+                        current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_ADD,helper2,numerator,helper1));
+                      end
+                    else
+                      begin
+                        shifterop_reset(so);
+                        so.shiftmode:=SM_LSR;
+                        so.shiftimm:=32-power;
+                        current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,helper2,numerator,helper1,so));
+                      end;
+                    cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,power,helper2,resultreg);
                   end
                else
                  cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,OS_INT,power,numerator,resultreg)
@@ -415,7 +417,7 @@ implementation
 
     function tarmshlshrnode.first_shlshr64bitint: tnode;
       begin
-        if (current_settings.cputype in cpu_thumb2) then
+        if (current_settings.cputype in cpu_thumb+cpu_thumb2) then
           result:=inherited
         else
           result := nil;
@@ -490,7 +492,7 @@ implementation
         end;
 
       begin
-        if (current_settings.cputype in cpu_thumb2) then
+        if (current_settings.cputype in cpu_thumb+cpu_thumb2) then
         begin
           inherited;
           exit;

+ 3 - 1
compiler/arm/narmmem.pas

@@ -37,7 +37,8 @@ interface
 implementation
 
     uses
-      cutils,verbose,aasmdata,aasmcpu,cgobj;
+      cutils,verbose,globals,aasmdata,aasmcpu,cgobj,
+      cpuinfo;
 
 {*****************************************************************************
                              TARMVECNODE
@@ -49,6 +50,7 @@ implementation
          hl : longint;
        begin
          if ((location.reference.base=NR_NO) and (location.reference.index=NR_NO)) or
+            (current_settings.cputype in cpu_thumb) or
             { simple constant? }
             (l=1) or ispowerof2(l,hl) or ispowerof2(l+1,hl) or ispowerof2(l-1,hl) then
            inherited update_reference_reg_mul(maybe_const_reg,l)

+ 8 - 8
compiler/arm/narmset.pas

@@ -240,11 +240,11 @@ implementation
                     cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, opcgsize, OC_EQ,0,hregister,blocklabel(t^.blockid))
                   else
                     begin
-                      tcgarm(cg).cgsetflags:=true;
+                      tbasecgarm(cg).cgsetflags:=true;
                       { use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
                         then genlinearlist wouldn't be used }
                       cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_SUB, OS_32, aint(int64(t^._low-last)), hregister);
-                      tcgarm(cg).cgsetflags:=false;
+                      tbasecgarm(cg).cgsetflags:=false;
                       cg.a_jmp_flags(current_asmdata.CurrAsmList,F_EQ,blocklabel(t^.blockid));
                     end;
                   last:=t^._low;
@@ -260,11 +260,11 @@ implementation
                        { have we to ajust the first value ? }
                        if (t^._low>get_min_value(left.resultdef)) or (get_min_value(left.resultdef)<>0) then
                          begin
-                           tcgarm(cg).cgsetflags:=true;
+                           tbasecgarm(cg).cgsetflags:=true;
                            { use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
                              then genlinearlist wouldn't be use }
                            cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_SUB, OS_32, aint(int64(t^._low)), hregister);
-                           tcgarm(cg).cgsetflags:=false;
+                           tbasecgarm(cg).cgsetflags:=false;
                          end;
                     end
                   else
@@ -273,22 +273,22 @@ implementation
                       { present label then the lower limit can be checked    }
                       { immediately. else check the range in between:       }
 
-                      tcgarm(cg).cgsetflags:=true;
+                      tbasecgarm(cg).cgsetflags:=true;
                       { use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
                         then genlinearlist wouldn't be use }
                       cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_SUB, OS_32, aint(int64(t^._low-last)), hregister);
-                      tcgarm(cg).cgsetflags:=false;
+                      tbasecgarm(cg).cgsetflags:=false;
                       { no jump necessary here if the new range starts at }
                       { at the value following the previous one           }
                       if ((t^._low-last) <> 1) or
                          (not lastrange) then
                         cg.a_jmp_flags(current_asmdata.CurrAsmList,cond_lt,elselabel);
                     end;
-                  tcgarm(cg).cgsetflags:=true;
+                  tbasecgarm(cg).cgsetflags:=true;
                   { use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
                     then genlinearlist wouldn't be use }
                   cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SUB,OS_32,aint(int64(t^._high-t^._low)),hregister);
-                  tcgarm(cg).cgsetflags:=false;
+                  tbasecgarm(cg).cgsetflags:=false;
                   cg.a_jmp_flags(current_asmdata.CurrAsmList,cond_le,blocklabel(t^.blockid));
 
                   last:=t^._high;

+ 0 - 1
compiler/cgobj.pas

@@ -1702,7 +1702,6 @@ implementation
 
     procedure Tcg.a_op_const_reg_reg(list:TAsmList;op:Topcg;size:Tcgsize;
                                      a:tcgint;src,dst:Tregister);
-
     begin
       a_load_reg_reg(list,size,size,src,dst);
       a_op_const_reg(list,op,size,a,dst);

+ 1 - 1
compiler/ncgcon.pas

@@ -156,7 +156,7 @@ implementation
             lab_real := TAsmLabel(entry^.Data);  // is it needed anymore?
 
              { :-(, we must generate a new entry }
-             if not assigned(lab_real) then
+             if not(assigned(lab_real)) then
                begin
                   current_asmdata.getdatalabel(lastlabel);
                   entry^.Data:=lastlabel;

+ 7 - 0
compiler/options.pas

@@ -3250,6 +3250,13 @@ if (target_info.abi = abi_eabihf) then
 {$endif CPUARMV6}
   end;
 
+  if init_settings.cputype in cpu_thumb then
+    begin
+      def_system_macro('CPUTHUMB');
+      if not option.FPUSetExplicitly then
+        init_settings.fputype:=fpu_soft;
+    end;
+
   if init_settings.cputype in cpu_thumb2 then
     def_system_macro('CPUTHUMB2');
 {$endif arm}

+ 2 - 1
rtl/arm/int64p.inc

@@ -13,6 +13,7 @@
 
  **********************************************************************}
 
+{$ifndef CPUTHUMB}
 {$define FPC_SYSTEM_HAS_MUL_QWORD}
 function fpc_mul_qword(f1,f2 : qword;checkoverflow : longbool) : qword;assembler;nostackframe;[public,alias: 'FPC_MUL_QWORD']; compilerproc;
 asm
@@ -61,5 +62,5 @@ asm
 .Lexit:
   ldmfd sp!,{r4,r5,r6,r15}
 end;
-
+{$endif CPUTHUMB}
 

+ 40 - 3
rtl/arm/setjump.inc

@@ -27,13 +27,29 @@ function fpc_setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_S
     {$endif}
     {$endif}
 
-    {$if defined(CPUCORTEXM3) or defined(CPUARMV7M)}
+    {$if defined(CPUTHUMB2)}
     stmia	r0!, {v1-v6, sl, fp}
-    mov	   r2, sp
+    mov	        r2, sp
     stmia	r0!, {r2, lr}
 
     mov     r0,#0
     mov     pc,lr
+    {$elseif defined(CPUTHUMB)}
+    stmia	r0!,{v1-v4}
+    mov         r1,v5
+    str         r1,[r0]
+    mov         r1,v6
+    str         r1,[r0,#4]
+    mov         r1,sl
+    str         r1,[r0,#8]
+    mov         r1,fp
+    str         r1,[r0,#12]
+    mov         r1,sp
+    str         r1,[r0,#16]
+    mov         r1,lr
+    str         r1,[r0,#20]
+    mov         r0,#0
+    bx          lr
     {$else}
     stmia   r0,{v1-v6, sl, fp, sp, lr}
     mov     r0,#0
@@ -44,7 +60,7 @@ function fpc_setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_S
 
 procedure fpc_longjmp(var S : jmp_buf;value : longint);assembler;[Public, alias : 'FPC_LONGJMP']; compilerproc;
   asm
-    {$if defined(CPUCORTEXM3) or defined(CPUARMV7M)}
+    {$if defined(CPUTHUMB2)}
     mov     ip, r0
     movs    r0, r1
     it eq
@@ -56,6 +72,27 @@ procedure fpc_longjmp(var S : jmp_buf;value : longint);assembler;[Public, alias
     ldr     sp, [ip]
     add     ip, ip, #4
     ldr     pc, [ip]
+
+    {$elseif defined(CPUTHUMB)}
+    mov     r3, r0
+    movs    r0, r1
+    bne     .L1
+    mov     r0, #1
+.L1:
+    ldmia   r3!,{v1-v4}
+    ldr     r2,[r3]
+    mov     v5,r2
+    ldr     r2,[r3,#4]
+    mov     v6,r2
+    ldr     r2,[r3,#8]
+    mov     sl,r2
+    ldr     r2,[r3,#12]
+    mov     fp,r2
+    ldr     r2,[r3,#16]
+    mov     sp,r2
+    ldr     r2,[r3,#20]
+    mov     pc,r2
+
     {$else}
     mov     ip, r0
     movs    r0, r1

+ 96 - 0
rtl/arm/thumb.inc

@@ -0,0 +1,96 @@
+{
+
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2013 by the Free Pascal development team.
+
+    Processor dependent implementation for the system unit for
+    ARM Thumb
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+{$define FPC_SYSTEM_HAS_SYSINITFPU}
+Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
+begin
+  softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal;
+end;
+
+
+procedure fpc_cpuinit;
+begin
+  SysInitFPU;
+end;
+
+{$define FPC_SYSTEM_HAS_SYSRESETFPU}
+Procedure SysResetFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
+begin
+  softfloat_exception_flags:=0;
+end;
+
+
+{$IFNDEF INTERNAL_BACKTRACE}
+{$define FPC_SYSTEM_HAS_GET_FRAME}
+function get_frame:pointer;assembler;nostackframe;
+  asm
+  end;
+{$ENDIF not INTERNAL_BACKTRACE}
+
+
+{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
+function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;
+  asm
+  end;
+
+
+{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
+function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;
+  asm
+  end;
+
+
+{$define FPC_SYSTEM_HAS_SPTR}
+Function Sptr : pointer;assembler;
+  asm
+  end;
+
+
+function InterLockedDecrement (var Target: longint) : longint;
+  begin
+    dec(Target);
+    Result:=Target;
+  end;
+
+
+function InterLockedIncrement (var Target: longint) : longint;
+  begin
+    inc(Target);
+    Result:=Target;
+  end;
+
+
+function InterLockedExchange (var Target: longint;Source : longint) : longint;
+  begin
+    Result:=Target;
+    Target:=Source;
+  end;
+
+
+function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;
+  begin
+    Result:=Target;
+    if Target=Comperand then
+      Target:=NewValue;
+  end;
+
+
+function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;
+  begin
+    Result:=Target;
+    inc(Target,Source);
+  end;

+ 18 - 2
rtl/embedded/Makefile

@@ -1,5 +1,5 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2013/01/16]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2013/02/22]
 #
 default: all
 MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux jvm-java jvm-android
@@ -269,6 +269,19 @@ ifdef CROSSCOMPILE
 ifndef DARWIN2DARWIN
 ifneq ($(CPU_TARGET),jvm)
 BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+ifeq ($(OS_TARGET),android)
+ifeq ($(CPU_TARGET),arm)
+BINUTILSPREFIX=arm-linux-androideabi-
+else
+ifeq ($(CPU_TARGET),i386)
+BINUTILSPREFIX=i686-linux-android-
+else
+ifeq ($(CPU_TARGET),mips)
+BINUTILSPREFIX=mipsel-linux-android-
+endif
+endif
+endif
+endif
 endif
 endif
 endif
@@ -321,7 +334,7 @@ CPU_SPECIFIC_COMMON_UNITS=
 ifeq ($(ARCH),arm)
 CPU_SPECIFIC_COMMON_UNITS=sysutils sysconst
 ifeq ($(SUBARCH),armv7m)
-CPU_UNITS=lm3fury lm3tempest stm32f10x_ld stm32f10x_md stm32f10x_hd stm32f10x_xl stm32f10x_conn lpc1768 lpc1343 # thumb2_bare
+CPU_UNITS=lm3fury lm3tempest stm32f10x_ld stm32f10x_md stm32f10x_hd stm32f10x_xl stm32f10x_conn lpc1343 lpc1768 # thumb2_bare
 endif
 ifeq ($(SUBARCH),armv4t)
 CPU_UNITS=lpc21x4 at91sam7x256 sc32442b
@@ -329,6 +342,9 @@ endif
 ifeq ($(SUBARCH),armv4)
 CPU_UNITS=lpc21x4 at91sam7x256 sc32442b
 endif
+ifeq ($(SUBARCH),armv6m)
+CPU_UNITS=
+endif
 endif
 ifeq ($(ARCH),avr)
 CPU_UNITS=atmega128

+ 3 - 0
rtl/embedded/Makefile.fpc

@@ -62,6 +62,9 @@ endif
 ifeq ($(SUBARCH),armv4)
 CPU_UNITS=lpc21x4 at91sam7x256 sc32442b
 endif
+ifeq ($(SUBARCH),armv6m)
+CPU_UNITS=
+endif
 endif
 
 ifeq ($(ARCH),avr)

+ 5 - 1
rtl/inc/system.inc

@@ -221,7 +221,11 @@ function do_isdevice(handle:thandle):boolean;forward;
   {$if defined(CPUCORTEXM3) or defined(CPUARMV7M)}
     {$i thumb2.inc}  { Case dependent, don't change }
   {$else}
-    {$i arm.inc}  { Case dependent, don't change }
+    {$if defined(CPUARMV6M)}
+      {$i thumb.inc}  { Case dependent, don't change }
+    {$else}
+      {$i arm.inc}  { Case dependent, don't change }
+    {$endif}
   {$endif}
   {$define SYSPROCDEFINED}
 {$endif cpuarm}

Some files were not shown because too many files changed in this diff