Bladeren bron

+ arm: tsettings.instructionset
* the selected instruction set is now independent from the cpu type: e.g. armv7-a can perfectly execute thumb(2) code

git-svn-id: trunk@25370 -

florian 12 jaren geleden
bovenliggende
commit
d4968e054b

+ 14 - 14
compiler/arm/aasmcpu.pas

@@ -892,7 +892,7 @@ implementation
         lastinspos:=-1;
         curinspos:=0;
         extradataoffset:=0;
-        if current_settings.cputype in cpu_thumb then
+        if GenerateThumbCode then
           begin
             multiplier:=2;
             limit:=504;
@@ -922,7 +922,7 @@ implementation
                             begin
                               { create a new copy of a data entry on arm thumb if the entry has been inserted already
                                 before because arm thumb does not allow pc relative negative offsets }
-                              if (current_settings.cputype in cpu_thumb) and
+                              if (GenerateThumbCode) and
                                 tai_label(curdatatai).inserted then
                                 begin
                                   current_asmdata.getjumplabel(l);
@@ -1039,10 +1039,10 @@ implementation
                   A_BX,
                   A_LDR:
                     { approximation if we hit a case jump table }
-                    if ((taicpu(hp).opcode=A_LDR) and not(current_settings.cputype in cpu_thumb+cpu_thumb2) and
+                    if ((taicpu(hp).opcode=A_LDR) and not(GenerateThumbCode or GenerateThumb2Code) and
                        (taicpu(hp).oper[0]^.typ=top_reg) and
                       (taicpu(hp).oper[0]^.reg=NR_PC)) or
-                      ((taicpu(hp).opcode=A_BX) and (current_settings.cputype in cpu_thumb) and
+                      ((taicpu(hp).opcode=A_BX) and (GenerateThumbCode) and
                        (taicpu(hp).oper[0]^.typ=top_reg))
                        then
                       begin
@@ -1059,17 +1059,17 @@ implementation
                           end;
                       end;
                   A_IT:
-                    if current_settings.cputype in cpu_thumb2 then
+                    if GenerateThumb2Code then
                       penalty:=multiplier;
                   A_ITE,
                   A_ITT:
-                    if current_settings.cputype in cpu_thumb2 then
+                    if GenerateThumb2Code then
                       penalty:=2*multiplier;
                   A_ITEE,
                   A_ITTE,
                   A_ITET,
                   A_ITTT:
-                    if current_settings.cputype in cpu_thumb2 then
+                    if GenerateThumb2Code then
                       penalty:=3*multiplier;
                   A_ITEEE,
                   A_ITTEE,
@@ -1079,7 +1079,7 @@ implementation
                   A_ITTET,
                   A_ITETT,
                   A_ITTTT:
-                    if current_settings.cputype in cpu_thumb2 then
+                    if GenerateThumb2Code then
                       penalty:=4*multiplier;
                   else
                     penalty:=0;
@@ -1115,7 +1115,7 @@ implementation
               ) and
               (
                 { do not insert data after a B instruction due to their limited range }
-                not((current_settings.cputype in cpu_thumb) and
+                not((GenerateThumbCode) and
                     (taicpu(curtai).opcode=A_B)
                    )
               ) then
@@ -1123,7 +1123,7 @@ implementation
                 lastinspos:=-1;
                 extradataoffset:=0;
 
-                if current_settings.cputype in cpu_thumb then
+                if GenerateThumbCode then
                   limit:=502
                 else
                   limit:=1016;
@@ -1131,7 +1131,7 @@ implementation
                 { on arm thumb, insert the data always after all labels etc. following an instruction so it
                   is prevent that a bxx yyy; bl xxx; yyyy: sequence gets separated ( we never insert on arm thumb after
                   bxx) and the distance of bxx gets too long }
-                if current_settings.cputype in cpu_thumb then
+                if GenerateThumbCode then
                   while assigned(tai(curtai.Next)) and (tai(curtai.Next).typ in SkipInstr+[ait_label]) do
                     curtai:=tai(curtai.next);
 
@@ -1139,7 +1139,7 @@ implementation
                 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
+                if not(curdata.empty) and (GenerateThumbCode) then
                   curdata.Insert(tai_align.Create(4));
                 curdata.insert(taicpu.op_sym(A_B,l));
                 curdata.concat(tai_label.create(l));
@@ -1167,7 +1167,7 @@ implementation
               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+cpu_thumb2) then
+        if not(curdata.empty) and (GenerateThumbCode or GenerateThumb2Code) then
           curdata.Insert(tai_align.Create(4));
         list.concatlist(curdata);
         curdata.free;
@@ -1329,7 +1329,7 @@ implementation
     procedure finalizearmcode(list, listtoinsert: TAsmList);
       begin
         { Do Thumb-2 16bit -> 32bit transformations }
-        if current_settings.cputype in cpu_thumb2 then
+        if GenerateThumb2Code then
           begin
             ensurethumb2encodings(list);
             foldITInstructions(list);

+ 4 - 4
compiler/arm/agarmgas.pas

@@ -110,9 +110,9 @@ unit agarmgas;
         if (current_settings.fputype = fpu_fpv4_s16) then
           result:='-mfpu=fpv4-sp-d16 '+result;
 
-        if current_settings.cputype in cpu_thumb2 then
+        if GenerateThumb2Code then
           result:='-march='+cputype_to_gas_march[current_settings.cputype]+' -mthumb -mthumb-interwork '+result
-        else if current_settings.cputype in cpu_thumb then
+        else if GenerateThumbCode then
           result:='-march='+cputype_to_gas_march[current_settings.cputype]+' -mthumb -mthumb-interwork '+result
         // EDSP instructions in RTL require armv5te at least to not generate error
         else if current_settings.cputype >= cpu_armv5te then
@@ -126,7 +126,7 @@ unit agarmgas;
     procedure TArmGNUAssembler.WriteExtraHeader;
       begin
         inherited WriteExtraHeader;
-        if current_settings.cputype in cpu_thumb2 then
+        if GenerateThumb2Code then
           AsmWriteLn(#9'.syntax unified');
       end;
 
@@ -289,7 +289,7 @@ unit agarmgas;
         sep: string[3];
     begin
       op:=taicpu(hp).opcode;
-      if current_settings.cputype in cpu_thumb2 then
+      if GenerateThumb2Code then
         begin
           postfix:='';
           if taicpu(hp).wideformat then

+ 10 - 10
compiler/arm/aoptcpu.pas

@@ -86,7 +86,7 @@ Implementation
   function CanBeCond(p : tai) : boolean;
     begin
       result:=
-        not(current_settings.cputype in cpu_thumb) and
+        not(GenerateThumbCode) and
         (p.typ=ait_instruction) and
         (taicpu(p).condition=C_None) and
         ((taicpu(p).opcode<A_IT) or (taicpu(p).opcode>A_ITTTT)) and
@@ -284,7 +284,7 @@ Implementation
 
   function isValidConstLoadStoreOffset(const aoffset: longint; const pf: TOpPostfix) : boolean;
     begin
-      if current_settings.cputype in cpu_thumb2 then
+      if GenerateThumb2Code then
         result := (aoffset<4096) and (aoffset>-256)
       else
         result := ((pf in [PF_None,PF_B]) and
@@ -419,7 +419,7 @@ Implementation
     var
       hp1: tai;
     begin
-      if (current_settings.cputype in cpu_arm) and
+      if GenerateARMCode and
         (p.ops=3) and
         MatchOperand(p.oper[0]^, p.oper[1]^.reg) and
         GetNextInstructionUsingReg(p, hp1, p.oper[0]^.reg) and
@@ -499,7 +499,7 @@ Implementation
         { don't apply the optimization if the (new) index register is loaded }
         (p.oper[0]^.reg<>taicpu(hp1).oper[2]^.reg) and
         not(RegModifiedBetween(taicpu(hp1).oper[2]^.reg,p,hp1)) and
-        (current_settings.cputype in cpu_arm) then
+        GenerateARMCode then
         begin
           DebugMsg('Peephole Str/LdrAdd/Sub2Str/Ldr Postindex done', p);
           p.oper[1]^.ref^.addressmode:=AM_POSTINDEXED;
@@ -735,7 +735,7 @@ Implementation
 
                         ldrb dst2, [ref]
                     }
-                    if not(current_settings.cputype in cpu_thumb) and
+                    if not(GenerateThumbCode) and
                        (taicpu(p).oppostfix=PF_B) and
                        GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
                        MatchInstruction(hp1, A_AND, [taicpu(p).condition], [PF_NONE]) and
@@ -1087,7 +1087,7 @@ Implementation
                           if (taicpu(hp1).ops > I) and
                              MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[I]^.reg) and
                              { prevent certain combinations on thumb(2), this is only a safe approximation }
-                             (not(current_settings.cputype in cpu_thumb+cpu_thumb2) or
+                             (not(GenerateThumbCode or GenerateThumb2Code) or
                               ((getsupreg(taicpu(p).oper[1]^.reg)<>RS_R13) and
                                (getsupreg(taicpu(p).oper[1]^.reg)<>RS_R15))
                              ) then
@@ -1121,7 +1121,7 @@ Implementation
                                               A_AND, A_BIC, A_EOR, A_ORR, A_TEQ, A_TST,
                                               A_CMP, A_CMN],
                                         [taicpu(p).condition], [PF_None]) and
-                       (not ((current_settings.cputype in cpu_thumb2) and
+                       (not ((GenerateThumb2Code) and
                              (taicpu(hp1).opcode in [A_SBC]) and
                              (((taicpu(hp1).ops=3) and 
                                MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[1]^.reg)) or
@@ -1222,7 +1222,7 @@ Implementation
                              add r1, r3, #imm
                              ldr r0, [r1, r2, lsl #2]
                     }
-                    if (not(current_settings.cputype in cpu_thumb)) and
+                    if (not(GenerateThumbCode)) and
                        (taicpu(p).opcode = A_MOV) and
                        (taicpu(p).ops = 3) and
                        (taicpu(p).oper[1]^.typ = top_reg) and
@@ -1232,7 +1232,7 @@ Implementation
                        (taicpu(p).oper[2]^.shifterop^.shiftmode <> SM_RRX) and
                        (taicpu(p).oper[2]^.shifterop^.shiftimm <> 0) and
                        { thumb2 allows only lsl #0..#3 }
-                       (not(current_settings.cputype in cpu_thumb2) or
+                       (not(GenerateThumb2Code) or
                         ((taicpu(p).oper[2]^.shifterop^.shiftimm in [0..3]) and
                          (taicpu(p).oper[2]^.shifterop^.shiftmode=SM_LSL)
                         )
@@ -1906,7 +1906,7 @@ Implementation
                 case taicpu(p).opcode Of
                   A_B:
                     if (taicpu(p).condition<>C_None) and
-                      not(current_settings.cputype in cpu_thumb) then
+                      not(GenerateThumbCode) then
                       begin
                          { check for
                                 Bxx   xxx

+ 19 - 19
compiler/arm/cgcpu.pas

@@ -1187,7 +1187,7 @@ unit cgcpu;
              ((abs(ref.offset) mod 4)<>0)
             )
            ) or
-           ((current_settings.cputype in cpu_thumb) and
+           ((GenerateThumbCode) and
             (((oppostfix in [PF_SB,PF_SH]) and (ref.offset<>0)) or
              ((oppostfix=PF_None) and ((ref.offset<0) or ((ref.base<>NR_STACK_POINTER_REG) and (ref.offset>124)) or
                ((ref.base=NR_STACK_POINTER_REG) and (ref.offset>1020)) or ((ref.offset mod 4)<>0))) or
@@ -1199,7 +1199,7 @@ unit cgcpu;
             fixref(list,ref);
           end;
 
-        if current_settings.cputype in cpu_thumb then
+        if GenerateThumbCode then
           begin
             { certain thumb load require base and index }
             if (oppostfix in [PF_SB,PF_SH]) and
@@ -1465,7 +1465,7 @@ unit cgcpu;
              else
                case fromsize of
                  OS_8:
-                   if current_settings.cputype in cpu_thumb then
+                   if GenerateThumbCode then
                      list.concat(taicpu.op_reg_reg(A_UXTB,reg2,reg1))
                    else
                      list.concat(taicpu.op_reg_reg_const(A_AND,reg2,reg1,$ff));
@@ -1600,12 +1600,12 @@ unit cgcpu;
         b : byte;
       begin
         a_reg_alloc(list,NR_DEFAULTFLAGS);
-        if (not(current_settings.cputype in cpu_thumb) and is_shifter_const(a,b)) or
-          ((current_settings.cputype in cpu_thumb) and is_thumb_imm(a)) then
+        if (not(GenerateThumbCode) and is_shifter_const(a,b)) or
+          ((GenerateThumbCode) and is_thumb_imm(a)) then
           list.concat(taicpu.op_reg_const(A_CMP,reg,a))
         { CMN reg,0 and CMN reg,$80000000 are different from CMP reg,$ffffffff
           and CMP reg,$7fffffff regarding the flags according to the ARM manual }
-        else if (a<>$7fffffff) and (a<>-1) and not(current_settings.cputype in cpu_thumb) and is_shifter_const(-a,b) then
+        else if (a<>$7fffffff) and (a<>-1) and not(GenerateThumbCode) and is_shifter_const(-a,b) then
           list.concat(taicpu.op_reg_const(A_CMN,reg,-a))
         else
           begin
@@ -1634,7 +1634,7 @@ unit cgcpu;
             list.Concat(taicpu.op_reg_reg(A_CLZ,dst,dst));
             a_reg_alloc(list,NR_DEFAULTFLAGS);
             list.Concat(taicpu.op_reg_const(A_CMP,dst,32));
-            if current_settings.cputype in cpu_thumb2 then
+            if GenerateThumb2Code then
               list.Concat(taicpu.op_cond(A_IT, C_EQ));
             list.Concat(setcondition(taicpu.op_reg_const(A_MOV,dst,$ff),C_EQ));
             a_reg_dealloc(list,NR_DEFAULTFLAGS);
@@ -1656,7 +1656,7 @@ unit cgcpu;
         ai : taicpu;
       begin
         { generate far jump, leave it to the optimizer to get rid of it }
-        if current_settings.cputype in cpu_thumb then
+        if GenerateThumbCode then
           ai:=taicpu.op_sym(A_BL,current_asmdata.RefAsmSymbol(s))
         else
           ai:=taicpu.op_sym(A_B,current_asmdata.RefAsmSymbol(s));
@@ -1670,7 +1670,7 @@ unit cgcpu;
         ai : taicpu;
       begin
         { generate far jump, leave it to the optimizer to get rid of it }
-        if current_settings.cputype in cpu_thumb then
+        if GenerateThumbCode then
           ai:=taicpu.op_sym(A_BL,l)
         else
           ai:=taicpu.op_sym(A_B,l);
@@ -1685,7 +1685,7 @@ unit cgcpu;
         inv_flags : TResFlags;
         hlabel : TAsmLabel;
       begin
-        if current_settings.cputype in cpu_thumb then
+        if GenerateThumbCode then
           begin
             inv_flags:=f;
             inverse_flags(inv_flags);
@@ -2519,7 +2519,7 @@ unit cgcpu;
       begin
         if len=0 then
           exit;
-        if current_settings.cputype in cpu_thumb then
+        if GenerateThumbCode then
           maxtmpreg:=maxtmpreg_thumb
         else
           maxtmpreg:=maxtmpreg_arm;
@@ -2652,7 +2652,7 @@ unit cgcpu;
                 {if aligned then
                 genloop(len,4)
                 else}
-                if current_settings.cputype in cpu_thumb then
+                if GenerateThumbCode then
                   genloop_thumb(len,1)
                 else
                   genloop(len,1);
@@ -2746,7 +2746,7 @@ unit cgcpu;
         ai : taicpu;
         hlabel : TAsmLabel;
       begin
-        if current_settings.cputype in cpu_thumb then
+        if GenerateThumbCode then
           begin
             { the optimizer has to fix this if jump range is sufficient short }
             current_asmdata.getjumplabel(hlabel);
@@ -3031,7 +3031,7 @@ unit cgcpu;
           l : TAsmLabel;
         begin
           reference_reset_base(href,NR_R0,0,sizeof(pint));
-          if current_settings.cputype in cpu_thumb then
+          if GenerateThumbCode then
             begin
               if (href.offset in [0..124]) and ((href.offset mod 4)=0) then
                 begin
@@ -3073,7 +3073,7 @@ unit cgcpu;
         begin
           if (procdef.extnumber=$ffff) then
             Internalerror(200006139);
-          if current_settings.cputype in cpu_thumb then
+          if GenerateThumbCode then
             begin
               reference_reset_base(href,NR_R0,tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber),sizeof(pint));
               if (href.offset in [0..124]) and ((href.offset mod 4)=0) then
@@ -3152,7 +3152,7 @@ unit cgcpu;
             op_onr12methodaddr;
           end
         { case 0 }
-        else if current_settings.cputype in cpu_thumb then
+        else if GenerateThumbCode then
           begin
             { bl cannot be used here because it destroys lr }
 
@@ -3200,7 +3200,7 @@ unit cgcpu;
         var
           tmpreg : TRegister;
         begin
-          if ((current_settings.cputype in cpu_thumb+cpu_thumb2) and (getsupreg(reg)=RS_R13)) or
+          if ((GenerateThumbCode or GenerateThumb2Code) and (getsupreg(reg)=RS_R13)) or
             (getsupreg(reg)=RS_R15) then
             begin
               tmpreg:=getintregister(list,OS_INT);
@@ -5237,14 +5237,14 @@ unit cgcpu;
 
     procedure create_codegen;
       begin
-        if current_settings.cputype in cpu_thumb2 then
+        if GenerateThumb2Code then
           begin
             cg:=tthumb2cgarm.create;
             cg64:=tthumb2cg64farm.create;
 
             casmoptimizer:=TCpuThumb2AsmOptimizer;
           end
-        else if current_settings.cputype in cpu_thumb then
+        else if GenerateThumbCode then
           begin
             cg:=tthumbcgarm.create;
             cg64:=tthumbcg64farm.create;

+ 26 - 2
compiler/arm/cpubase.pas

@@ -374,6 +374,10 @@ unit cpubase;
     function IsIT(op: TAsmOp) : boolean;
     function GetITLevels(op: TAsmOp) : longint;
 
+    function GenerateARMCode : boolean;
+    function GenerateThumbCode : boolean;
+    function GenerateThumb2Code : boolean;
+
   implementation
 
     uses
@@ -526,7 +530,7 @@ unit cpubase;
       var
          i : longint;
       begin
-        if current_settings.cputype in cpu_thumb2 then
+        if GenerateThumb2Code then
           begin
             for i:=0 to 24 do
               begin
@@ -616,7 +620,7 @@ unit cpubase;
       begin
         Result:=false;
         {Thumb2 is not supported (YET?)}
-        if current_settings.cputype in cpu_thumb2 then exit;
+        if GenerateThumb2Code then exit;
         d:=DWord(value);
         for i:=0 to 15 do
           begin
@@ -707,4 +711,24 @@ unit cpubase;
         end;
       end;
 
+
+    function GenerateARMCode : boolean;
+      begin
+        Result:=current_settings.instructionset=is_arm;
+      end;
+
+
+    function GenerateThumbCode : boolean;
+      begin
+        Result:=(current_settings.instructionset=is_thumb) and not(CPUARM_HAS_THUMB2 in cpu_capabilities[current_settings.cputype]);
+      end;
+
+
+    function GenerateThumb2Code : boolean;
+      begin
+        Result:=(current_settings.instructionset=is_thumb) and (CPUARM_HAS_THUMB2 in cpu_capabilities[current_settings.cputype]);
+      end;
+
+
 end.
+

+ 12 - 11
compiler/arm/cpuinfo.pas

@@ -51,10 +51,7 @@ Type
        cpu_armv7em
       );
 
-Const
-   cpu_arm = [cpu_none,cpu_armv3,cpu_armv4,cpu_armv4t,cpu_armv5];
-   cpu_thumb = [cpu_armv6m];
-   cpu_thumb2 = [cpu_armv7m,cpu_armv7em];
+   tinstructionset = (is_thumb,is_arm);
 
 Type
    tfputype =
@@ -665,7 +662,8 @@ Const
        CPUARM_HAS_RBIT,       { CPU supports the RBIT instruction                         }
        CPUARM_HAS_DMB,        { CPU has memory barrier instructions (DMB, DSB, ISB)       }
        CPUARM_HAS_LDREX,
-       CPUARM_HAS_IDIV
+       CPUARM_HAS_IDIV,
+       CPUARM_HAS_THUMB2
       );
 
  const
@@ -680,17 +678,20 @@ Const
        { cpu_armv5tej } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP],
        { cpu_armv6    } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX],
        { 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_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,CPUARM_HAS_THUMB2],
        { 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_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],
-       { cpu_armv7r   } [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_armv7m   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_IDIV,CPUARM_HAS_DMB],
-       { cpu_armv7em  } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_IDIV,CPUARM_HAS_DMB]
+       { 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,CPUARM_HAS_THUMB2],
+       { 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,CPUARM_HAS_THUMB2],
+       { cpu_armv7r   } [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,CPUARM_HAS_THUMB2],
+       { cpu_armv7m   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2],
+       { cpu_armv7em  } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2]
      );
 
+   { contains all CPU supporting any kind of thumb instruction set }
+   cpu_has_thumb = [cpu_armv4t,cpu_armv5t,cpu_armv5te,cpu_armv5tej,cpu_armv6t2,cpu_armv6z,cpu_armv6m,cpu_armv7a,cpu_armv7r,cpu_armv7m,cpu_armv7em];
+
 Implementation
 
 end.

+ 2 - 2
compiler/arm/cpupara.pas

@@ -298,7 +298,7 @@ unit cpupara;
         curfloatreg:=RS_F0;
         curmmreg:=RS_D0;
 
-        if (current_settings.cputype in cpu_thumb) and (side=calleeside) then
+        if GenerateThumbCode and (side=calleeside) then
           cur_stack_offset:=(p as tprocdef).total_stackframe_size
         else
           cur_stack_offset:=0;
@@ -581,7 +581,7 @@ unit cpupara;
                    begin
                      if paraloc^.loc=LOC_REFERENCE then
                        begin
-                         if current_settings.cputype in cpu_thumb then
+                         if GenerateThumbCode then
                            begin
                              paraloc^.reference.index:=NR_STACK_POINTER_REG;
                            end

+ 3 - 3
compiler/arm/cpupi.pas

@@ -98,7 +98,7 @@ unit cpupi;
           tg.setfirsttemp(maxpushedparasize);
 
         { estimate stack frame size }
-        if current_settings.cputype in cpu_thumb then
+        if GenerateThumbCode then
           begin
             stackframesize:=maxpushedparasize+32;
             localsize:=0;
@@ -140,7 +140,7 @@ unit cpupi;
          floatsavesize : aword;
          regs: tcpuregisterset;
       begin
-        if current_settings.cputype in cpu_thumb then
+        if GenerateThumbCode then
           result:=stackframesize
         else
           begin
@@ -194,7 +194,7 @@ unit cpupi;
 
     procedure tarmprocinfo.init_framepointer;
       begin
-        if (target_info.system in systems_darwin) or (current_settings.cputype in cpu_thumb) then
+        if (target_info.system in systems_darwin) or GenerateThumbCode then
           begin
             RS_FRAME_POINTER_REG:=RS_R7;
             NR_FRAME_POINTER_REG:=NR_R7;

+ 6 - 6
compiler/arm/narmadd.pas

@@ -332,7 +332,7 @@ interface
         (* Try to keep right as a constant *)
         if (right.location.loc <> LOC_CONSTANT) or
           not(is_shifter_const(right.location.value, b)) or
-          ((current_settings.cputype in cpu_thumb) and not(is_thumb_imm(right.location.value))) then
+          ((GenerateThumbCode) and not(is_thumb_imm(right.location.value))) then
           hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true);
         hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
 
@@ -402,7 +402,7 @@ interface
             dummyreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
             cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
 
-            if current_settings.cputype in cpu_thumb then
+            if GenerateThumbCode 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));
@@ -419,7 +419,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_thumb+cpu_thumb2) then
+                if GenerateThumbCode or GenerateThumb2Code then
                   begin
                     current_asmdata.getjumplabel(l);
                     cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,l);
@@ -515,7 +515,7 @@ interface
         if (not(cs_check_overflow in current_settings.localswitches)) and
            (nodetype in [muln]) and
            (is_64bitint(left.resultdef)) and
-           (not (current_settings.cputype in cpu_thumb)) then
+           (not (GenerateThumbCode)) then
           begin
             result := nil;
             firstpass(left);
@@ -630,8 +630,8 @@ interface
         cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
         if right.location.loc = LOC_CONSTANT then
           begin
-             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
+             if (not(GenerateThumbCode) and is_shifter_const(right.location.value,b)) or
+                ((GenerateThumbCode) 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

+ 3 - 3
compiler/arm/narmmat.pas

@@ -156,7 +156,7 @@ implementation
                       cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,numerator,helper1)
                     else
                       cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,31,numerator,helper1);
-                    if current_settings.cputype in cpu_thumb then
+                    if GenerateThumbCode 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));
@@ -437,7 +437,7 @@ implementation
 
     function tarmshlshrnode.first_shlshr64bitint: tnode;
       begin
-        if (current_settings.cputype in cpu_thumb+cpu_thumb2) then
+        if GenerateThumbCode or GenerateThumb2Code then
           result:=inherited
         else
           result := nil;
@@ -512,7 +512,7 @@ implementation
         end;
 
       begin
-        if (current_settings.cputype in cpu_thumb+cpu_thumb2) then
+        if GenerateThumbCode or GenerateThumb2Code then
         begin
           inherited;
           exit;

+ 2 - 2
compiler/arm/narmmem.pas

@@ -54,7 +54,7 @@ implementation
     procedure tarmloadparentfpnode.pass_generate_code;
       begin
         { normally, we cannot use the stack pointer as normal register on arm thumb }
-        if (current_settings.cputype in cpu_thumb) and
+        if (GenerateThumbCode) and
           (getsupreg(current_procinfo.framepointer) in [RS_R8..RS_R15]) and
           (current_procinfo.procdef.parast.symtablelevel=parentpd.parast.symtablelevel) then
           begin
@@ -76,7 +76,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
+            (GenerateThumbCode) 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)

+ 4 - 4
compiler/arm/narmset.pas

@@ -84,7 +84,7 @@ implementation
       begin
         location_reset(location,LOC_FLAGS,OS_NO);
         location.resflags:=F_NE;
-        if (left.location.loc=LOC_CONSTANT) and not(current_settings.cputype in cpu_thumb) then
+        if (left.location.loc=LOC_CONSTANT) and not(GenerateThumbCode) then
           begin
             hlcg.location_force_reg(current_asmdata.CurrAsmList, right.location,
               right.resultdef, right.resultdef, true);
@@ -104,7 +104,7 @@ implementation
             hregister:=cg.getintregister(current_asmdata.CurrAsmList, uopsize);
             current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_MOV,hregister,1));
 
-            if current_settings.cputype in cpu_thumb+cpu_thumb2 then
+            if GenerateThumbCode or GenerateThumb2Code then
               begin
                 current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_LSL,hregister,left.location.register));
                 cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
@@ -199,7 +199,7 @@ implementation
         indexreg:=cg.makeregsize(current_asmdata.CurrAsmList,hregister,OS_INT);
         cg.a_load_reg_reg(current_asmdata.CurrAsmList,opcgsize,OS_INT,hregister,indexreg);
 
-        if current_settings.cputype in cpu_thumb2 then
+        if GenerateThumb2Code then
           begin
             if cs_create_pic in current_settings.moduleswitches then
               internalerror(2013082101);
@@ -218,7 +218,7 @@ implementation
             last:=min_;
             genitem_thumb2(current_asmdata.CurrAsmList,hp);
           end
-        else if current_settings.cputype in cpu_thumb then
+        else if GenerateThumbCode then
           begin
             if cs_create_pic in current_settings.moduleswitches then
               internalerror(2013082102);

+ 2 - 2
compiler/arm/rgcpu.pas

@@ -186,7 +186,7 @@ unit rgcpu;
 
       { Lets remove the bits we can fold in later and check if the result can be easily with an add or sub }
       a:=abs(spilltemp.offset);
-      if current_settings.cputype in cpu_thumb then
+      if GenerateThumbCode then
         begin
           {$ifdef DEBUG_SPILLING}
           helplist.concat(tai_comment.create(strpnew('Spilling: Use a_load_const_reg to fix spill offset')));
@@ -243,7 +243,7 @@ unit rgcpu;
    function fix_spilling_offset(offset : ASizeInt) : boolean;
      begin
        result:=(abs(offset)>4095) or
-          ((current_settings.cputype in cpu_thumb) and ((offset<0) or (offset>1020)));
+          ((GenerateThumbCode) and ((offset<0) or (offset>1020)));
      end;
 
 

+ 38 - 3
compiler/globals.pas

@@ -156,7 +156,11 @@ interface
 
 {$if defined(i8086)}
          x86memorymodel  : tx86memorymodel;
-{$endif}
+{$endif defined(i8086)}
+
+{$if defined(ARM)}
+         instructionset : tinstructionset;
+{$endif defined(ARM)}
 
         { CPU targets with microcontroller support can add a controller specific unit }
 {$if defined(ARM) or defined(AVR)}
@@ -484,6 +488,9 @@ interface
 {$if defined(i8086)}
         x86memorymodel : mm_small;
 {$endif defined(i8086)}
+{$if defined(ARM)}
+        instructionset : is_arm;
+{$endif defined(ARM)}
 {$if defined(ARM) or defined(AVR)}
         controllertype : ct_none;
 {$endif defined(ARM) or defined(AVR)}
@@ -515,7 +522,8 @@ interface
 
     function SetAktProcCall(const s:string; var a:tproccalloption):boolean;
     function Setabitype(const s:string;var a:tabi):boolean;
-    function Setcputype(const s:string;var a:tcputype):boolean;
+    function Setoptimizecputype(const s:string;var a:tcputype):boolean;
+    function Setcputype(const s:string;var a:tsettings):boolean;
     function SetFpuType(const s:string;var a:tfputype):boolean;
 {$if defined(arm) or defined(avr)}
     function SetControllerType(const s:string;var a:tcontrollertype):boolean;
@@ -1111,7 +1119,7 @@ implementation
       end;
 
 
-    function Setcputype(const s:string;var a:tcputype):boolean;
+    function Setoptimizecputype(const s:string;var a:tcputype):boolean;
       var
         t  : tcputype;
         hs : string;
@@ -1128,6 +1136,33 @@ implementation
       end;
 
 
+    function Setcputype(const s:string;var a:tsettings):boolean;
+      var
+        t  : tcputype;
+        hs : string;
+      begin
+        result:=false;
+        hs:=Upper(s);
+        for t:=low(tcputype) to high(tcputype) do
+          if cputypestr[t]=hs then
+            begin
+              a.cputype:=t;
+              result:=true;
+              break;
+            end;
+{$ifdef arm}
+        { set default instruction set for arm }
+        if result then
+          begin
+            if a.cputype in [cpu_armv6t2,cpu_armv7m] then
+              a.instructionset:=is_thumb
+            else
+              a.instructionset:=is_arm;
+          end;
+{$endif arm}
+      end;
+
+
     function SetFpuType(const s:string;var a:tfputype):boolean;
       var
         t : tfputype;

+ 1 - 1
compiler/hlcgobj.pas

@@ -3888,7 +3888,7 @@ implementation
       while assigned(item) do
         begin
 {$ifdef arm}
-          if current_settings.cputype in cpu_thumb2+cpu_thumb then
+          if GenerateThumbCode or GenerateThumb2Code then
             list.concat(tai_thumb_func.create);
 {$endif arm}
           { "double link" all procedure entry symbols via .reference }

+ 1 - 0
compiler/msg/errore.msg

@@ -3412,6 +3412,7 @@ S*2Aas_Assemble using GNU AS
 **2Cg_Generate PIC code
 **2Ch<n>_<n> bytes heap (between 1023 and 67107840)
 **2Ci_IO-checking
+A*2CI<x>_Select instruction set on ARM: ARM or THUMB
 **2Cn_Omit linking stage
 P*2CN_Generate nil-pointer checks (AIX-only)
 **2Co_Check overflow of integer operations

+ 1 - 1
compiler/msgidx.inc

@@ -977,7 +977,7 @@ const
   option_info=11024;
   option_help_pages=11025;
 
-  MsgTxtSize = 69178;
+  MsgTxtSize = 69231;
 
   MsgIdxMax : array[1..20] of longint=(
     26,95,335,121,88,56,126,27,202,64,

+ 112 - 111
compiler/msgtxt.inc

@@ -1282,190 +1282,191 @@ const msgtxt : array[0..000288,1..240] of char=(
   '**2Cg_Generate PIC code'#010+
   '**2Ch<n>_<n> bytes heap (between 1023 and 67107840)'#010+
   '**2Ci_IO-checking'#010+
+  'A*2CI<x>_Select instruction set on ARM: ARM or',' THUMB'#010+
   '**2Cn_Omit linking stage'#010+
-  'P*2CN_Generate nil-po','inter checks (AIX-only)'#010+
+  'P*2CN_Generate nil-pointer checks (AIX-only)'#010+
   '**2Co_Check overflow of integer operations'#010+
   '**2CO_Check for possible overflow of integer operations'#010+
-  '**2Cp<x>_Select instruction set, see fpc -i for possible values'#010+
+  '**2Cp<x>_Select instruction set, see fpc -i for possible values'#010,
   '**2CP<x>=<y>_ packing settings'#010+
-  '**3CPPACKSET=<y>_ <y> ','set allocation: 0, 1 or DEFAULT or NORMAL, 2, '+
-  '4 and 8'#010+
+  '**3CPPACKSET=<y>_ <y> set allocation: 0, 1 or DEFAULT or NORMAL, 2, 4 '+
+  'and 8'#010+
   '**2Cr_Range checking'#010+
   '**2CR_Verify object method call validity'#010+
   '**2Cs<n>_Set stack checking size to <n>'#010+
-  '**2Ct_Stack checking (for testing only, see manual)'#010+
-  'p*2CT<x>_Target-specific code ge','neration options'#010+
+  '**2Ct_Stack checking (for testi','ng only, see manual)'#010+
+  'p*2CT<x>_Target-specific code generation options'#010+
   'P*2CT<x>_Target-specific code generation options'#010+
   'J*2CT<x>_Target-specific code generation options'#010+
   'A*2CT<x>_Target-specific code generation options'#010+
-  'p*3CTsmalltoc_ Generate smaller TOCs at the expense of execution speed'+
-  ' (AIX)',#010+
+  'p*3CTsmalltoc_ Generate',' smaller TOCs at the expense of execution spe'+
+  'ed (AIX)'#010+
   'P*3CTsmalltoc_ Generate smaller TOCs at the expense of execution speed'+
   ' (AIX)'#010+
   'J*3CTcompactintarrayinit_ Generate smaller (but potentially slower) co'+
-  'de for initializing integer array constants'#010+
-  'J*3CTenumfieldinit_ Initialize enumeration field','s in constructors to'+
-  ' enumtype(0), after calling inherited constructors'#010+
+  'de for initializing integer array const','ants'#010+
+  'J*3CTenumfieldinit_ Initialize enumeration fields in constructors to e'+
+  'numtype(0), after calling inherited constructors'#010+
   'J*3CTautogetterprefix=X_ Automatically create getters for properties w'+
   'ith prefix X (empty string disables)'#010+
-  'J*3CTautosetterprefix=X_ Automatically create setters for prop','erties'+
+  'J*3CTauto','setterprefix=X_ Automatically create setters for properties'+
   ' with prefix X (empty string disables)'#010+
   'A*3CTthumbinterworking_ Generate Thumb interworking-safe code if possi'+
   'ble'#010+
   'J*2Cv_Var/out parameter copy-out checking'#010+
-  '**2CX_Create also smartlinked library'#010+
+  '**2CX_Create also smartlin','ked library'#010+
   '**1d<x>_Defines the symbol <x>'#010+
-  '**1D_Gener','ate a DEF file'#010+
+  '**1D_Generate a DEF file'#010+
   '**2Dd<x>_Set description to <x>'#010+
   '**2Dv<x>_Set DLL version to <x>'#010+
   '*O2Dw_PM application'#010+
   '**1e<x>_Set path to executable'#010+
   '**1E_Same as -Cn'#010+
   '**1fPIC_Same as -Cg'#010+
-  '**1F<x>_Set file names and paths:'#010+
-  '**2Fa<x>[,y]_(for a program) load unit','s <x> and [y] before uses is p'+
-  'arsed'#010+
+  '**1F<x>_Set file na','mes and paths:'#010+
+  '**2Fa<x>[,y]_(for a program) load units <x> and [y] before uses is par'+
+  'sed'#010+
   '**2Fc<x>_Set input codepage to <x>'#010+
   '**2FC<x>_Set RC compiler binary name to <x>'#010+
   '**2Fd_Disable the compiler'#039's internal directory cache'#010+
-  '**2FD<x>_Set the directory where to search for compiler utilities'#010+
-  '**2Fe','<x>_Redirect error output to <x>'#010+
+  '**2FD<x>_Set the d','irectory where to search for compiler utilities'#010+
+  '**2Fe<x>_Redirect error output to <x>'#010+
   '**2Ff<x>_Add <x> to framework path (Darwin only)'#010+
   '**2FE<x>_Set exe/unit output path to <x>'#010+
   '**2Fi<x>_Add <x> to include path'#010+
-  '**2Fl<x>_Add <x> to library path'#010+
+  '**2Fl<x>_Add <x> to library pat','h'#010+
   '**2FL<x>_Use <x> as dynamic linker'#010+
-  '**2Fm<x>_Load un','icode conversion table from <x>.txt in the compiler '+
-  'dir'#010+
+  '**2Fm<x>_Load unicode conversion table from <x>.txt in the compiler di'+
+  'r'#010+
   '**2Fo<x>_Add <x> to object path'#010+
   '**2Fr<x>_Load error message file <x>'#010+
   '**2FR<x>_Set resource (.res) linker to <x>'#010+
-  '**2Fu<x>_Add <x> to unit path'#010+
-  '**2FU<x>_Set unit output path to <x>, over','rides -FE'#010+
+  '**2Fu<x>_Add <x> to',' unit path'#010+
+  '**2FU<x>_Set unit output path to <x>, overrides -FE'#010+
   '**2FW<x>_Store generated whole-program optimization feedback in <x>'#010+
   '**2Fw<x>_Load previously stored whole-program optimization feedback fr'+
   'om <x>'#010+
-  '*g1g_Generate debug information (default format for target)'#010+
-  '*g2gc_Generate checks for',' pointers'#010+
+  '*g1g_Generate debug information ','(default format for target)'#010+
+  '*g2gc_Generate checks for pointers'#010+
   '*g2gh_Use heaptrace unit (for memory leak/corruption debugging)'#010+
   '*g2gl_Use line info unit (show more info with backtraces)'#010+
   '*g2go<x>_Set debug information options'#010+
-  '*g3godwarfsets_ Enable DWARF '#039'set'#039' type debug information (bre'+
-  'aks gdb',' < 6.5)'#010+
+  '*g3godwarfsets_ ','Enable DWARF '#039'set'#039' type debug information (b'+
+  'reaks gdb < 6.5)'#010+
   '*g3gostabsabsincludes_ Store absolute/full include file paths in Stabs'+
   #010+
   '*g3godwarfmethodclassprefix_ Prefix method names in DWARF with class n'+
   'ame'#010+
-  '*g2gp_Preserve case in stabs symbol names'#010+
+  '*g2gp_Preserve case in stabs symbo','l names'#010+
   '*g2gs_Generate Stabs debug information'#010+
-  '*g2gt_','Trash local variables (to detect uninitialized uses)'#010+
+  '*g2gt_Trash local variables (to detect uninitialized uses)'#010+
   '*g2gv_Generates programs traceable with Valgrind'#010+
   '*g2gw_Generate DWARFv2 debug information (same as -gw2)'#010+
-  '*g2gw2_Generate DWARFv2 debug information'#010+
-  '*g2gw3_Generate DWARFv3 debug informatio','n'#010+
+  '*g2gw2_Generate DWARFv2 debug',' information'#010+
+  '*g2gw3_Generate DWARFv3 debug information'#010+
   '*g2gw4_Generate DWARFv4 debug information (experimental)'#010+
   '**1i_Information'#010+
   '**2iD_Return compiler date'#010+
   '**2iV_Return short compiler version'#010+
   '**2iW_Return full compiler version'#010+
-  '**2iSO_Return compiler OS'#010+
+  '**2iSO_Return',' compiler OS'#010+
   '**2iSP_Return compiler host processor'#010+
-  '**','2iTO_Return target OS'#010+
+  '**2iTO_Return target OS'#010+
   '**2iTP_Return target processor'#010+
   '**1I<x>_Add <x> to include path'#010+
   '**1k<x>_Pass <x> to the linker'#010+
   '**1l_Write logo'#010+
   '**1M<x>_Set language mode to <x>'#010+
-  '**2Mfpc_Free Pascal dialect (default)'#010+
-  '**2Mobjfpc_FPC mode with Object Pasca','l support'#010+
+  '**2Mfpc_Free Pascal di','alect (default)'#010+
+  '**2Mobjfpc_FPC mode with Object Pascal support'#010+
   '**2Mdelphi_Delphi 7 compatibility mode'#010+
   '**2Mtp_TP/BP 7.0 compatibility mode'#010+
   '**2Mmacpas_Macintosh Pascal dialects compatibility mode'#010+
   '**1n_Do not read the default config files'#010+
-  '**1o<x>_Change the name of the executable produced to <x>',#010+
+  '**1o','<x>_Change the name of the executable produced to <x>'#010+
   '**1O<x>_Optimizations:'#010+
   '**2O-_Disable optimizations'#010+
   '**2O1_Level 1 optimizations (quick and debugger friendly)'#010+
   '**2O2_Level 2 optimizations (-O1 + quick optimizations)'#010+
-  '**2O3_Level 3 optimizations (-O2 + slow optimizations)'#010+
-  '**2O4_Level 4 optim','izations (-O3 + optimizations which might have un'+
-  'expected side effects)'#010+
+  '**2O3_Level 3 optimiz','ations (-O2 + slow optimizations)'#010+
+  '**2O4_Level 4 optimizations (-O3 + optimizations which might have unex'+
+  'pected side effects)'#010+
   '**2Oa<x>=<y>_Set alignment'#010+
   '**2Oo[NO]<x>_Enable or disable optimizations, see fpc -i for possible '+
   'values'#010+
-  '**2Op<x>_Set target cpu for optimizing, see fpc -i for possible ','valu'+
+  '**2Op<x>_Se','t target cpu for optimizing, see fpc -i for possible valu'+
   'es'#010+
   '**2OW<x>_Generate whole-program optimization feedback for optimization'+
   ' <x>, see fpc -i for possible values'#010+
   '**2Ow<x>_Perform whole-program optimization <x>, see fpc -i for possib'+
-  'le values'#010+
+  'le ','values'#010+
   '**2Os_Optimize for size rather than speed'#010+
-  '**1p','g_Generate profile code for gprof (defines FPC_PROFILE)'#010+
+  '**1pg_Generate profile code for gprof (defines FPC_PROFILE)'#010+
   'F*1P<x>_Target CPU / compiler related options:'#010+
   'F*2PB_Show default compiler binary'#010+
   'F*2PP_Show default target cpu'#010+
-  'F*2P<x>_Set target CPU (arm,i386,m68k,mips,mipsel,powerpc,powerpc64,sp'+
-  'ar','c,x86_64'#010+
+  'F*2P<x>_Set target ','CPU (arm,i386,m68k,mips,mipsel,powerpc,powerpc64,'+
+  'sparc,x86_64'#010+
   '**1R<x>_Assembler reading style:'#010+
   '**2Rdefault_Use default assembler for target'#010+
   '3*2Ratt_Read AT&T style assembler'#010+
   '3*2Rintel_Read Intel style assembler'#010+
-  '6*2RMOT_Read motorola style assembler'#010+
+  '6*2RMOT_Read motorola style a','ssembler'#010+
   '**1S<x>_Syntax options:'#010+
-  '**2S2_Same as -Mobjf','pc'#010+
+  '**2S2_Same as -Mobjfpc'#010+
   '**2Sc_Support operators like C (*=,+=,/= and -=)'#010+
   '**2Sa_Turn on assertions'#010+
   '**2Sd_Same as -Mdelphi'#010+
   '**2Se<x>_Error options. <x> is a combination of the following:'#010+
-  '**3*_<n> : Compiler halts after the <n> errors (default is 1)'#010+
-  '**3*_w : Compil','er also halts after warnings'#010+
+  '**3*_<n> : Compiler halt','s after the <n> errors (default is 1)'#010+
+  '**3*_w : Compiler also halts after warnings'#010+
   '**3*_n : Compiler also halts after notes'#010+
   '**3*_h : Compiler also halts after hints'#010+
   '**2Sg_Enable LABEL and GOTO (default in -Mtp and -Mdelphi)'#010+
-  '**2Sh_Use reference counted strings (ansistring by default) instead of',
-  ' shortstrings'#010+
+  '**2Sh_Use referen','ce counted strings (ansistring by default) instead '+
+  'of shortstrings'#010+
   '**2Si_Turn on inlining of procedures/functions declared as "inline"'#010+
   '**2Sk_Load fpcylix unit'#010+
   '**2SI<x>_Set interface style to <x>'#010+
   '**3SIcom_COM compatible interface (default)'#010+
-  '**3SIcorba_CORBA compatible interface'#010+
-  '**2Sm_Support ma','cros like C (global)'#010+
+  '*','*3SIcorba_CORBA compatible interface'#010+
+  '**2Sm_Support macros like C (global)'#010+
   '**2So_Same as -Mtp'#010+
   '**2Ss_Constructor name must be init (destructor must be done)'#010+
   '**2Sx_Enable exception keywords (default in Delphi/ObjFPC modes)'#010+
-  '**2Sy_@<pointer> returns a typed pointer, same as $T+'#010+
-  '**1s_Do not call as','sembler and linker'#010+
+  '**2Sy_@<pointer> ret','urns a typed pointer, same as $T+'#010+
+  '**1s_Do not call assembler and linker'#010+
   '**2sh_Generate script to link on host'#010+
   '**2st_Generate script to link on target'#010+
   '**2sr_Skip register allocation phase (use with -alr)'#010+
   '**1T<x>_Target operating system:'#010+
-  '3*2Tdarwin_Darwin/Mac OS X'#010+
-  '3*2Temx_OS/2 via EMX (includin','g EMX/RSX extender)'#010+
+  '3*2T','darwin_Darwin/Mac OS X'#010+
+  '3*2Temx_OS/2 via EMX (including EMX/RSX extender)'#010+
   '3*2Tfreebsd_FreeBSD'#010+
   '3*2Tgo32v2_Version 2 of DJ Delorie DOS extender'#010+
   '3*2Tiphonesim_ iPhoneSimulator from iOS SDK 3.2+ (older versions: -Tda'+
   'rwin)'#010+
   '3*2Tlinux_Linux'#010+
-  '3*2Tnativent_Native NT API (experimental)'#010+
-  '3*2Tnetbsd_NetBSD'#010,
+  '3*2Tnat','ivent_Native NT API (experimental)'#010+
+  '3*2Tnetbsd_NetBSD'#010+
   '3*2Tnetware_Novell Netware Module (clib)'#010+
   '3*2Tnetwlibc_Novell Netware Module (libc)'#010+
   '3*2Topenbsd_OpenBSD'#010+
   '3*2Tos2_OS/2 / eComStation'#010+
   '3*2Tsunos_SunOS/Solaris'#010+
   '3*2Tsymbian_Symbian OS'#010+
-  '3*2Tsolaris_Solaris'#010+
+  '3*2Tsolari','s_Solaris'#010+
   '3*2Twatcom_Watcom compatible DOS extender'#010+
-  '3','*2Twdosx_WDOSX DOS extender'#010+
+  '3*2Twdosx_WDOSX DOS extender'#010+
   '3*2Twin32_Windows 32 Bit'#010+
   '3*2Twince_Windows CE'#010+
   '4*2Tdarwin_Darwin/Mac OS X'#010+
   '4*2Tlinux_Linux'#010+
   '4*2Twin64_Win64 (64 bit Windows systems)'#010+
   '6*2Tamiga_Commodore Amiga'#010+
-  '6*2Tatari_Atari ST/STe/TT'#010+
+  '6*2','Tatari_Atari ST/STe/TT'#010+
   '6*2Tlinux_Linux'#010+
-  '6*2Tpalmos_Pal','mOS'#010+
+  '6*2Tpalmos_PalmOS'#010+
   'A*2Tdarwin_Darwin/iPhoneOS/iOS'#010+
   'A*2Tlinux_Linux'#010+
   'A*2Twince_Windows CE'#010+
@@ -1474,119 +1475,119 @@ const msgtxt : array[0..000288,1..240] of char=(
   'P*2Tlinux_Linux'#010+
   'P*2Tmacos_Mac OS (classic)'#010+
   'P*2Tmorphos_MorphOS'#010+
-  'S*2Tsolaris_Solaris'#010+
+  'S*2Tsol','aris_Solaris'#010+
   'S*2Tlinux_Linux'#010+
-  '**1u<x>_Undefines the sy','mbol <x>'#010+
+  '**1u<x>_Undefines the symbol <x>'#010+
   '**1U_Unit options:'#010+
   '**2Un_Do not check where the unit name matches the file name'#010+
   '**2Ur_Generate release unit files (never automatically recompiled)'#010+
   '**2Us_Compile a system unit'#010+
-  '**1v<x>_Be verbose. <x> is a combination of the followin','g letters:'#010+
+  '**1','v<x>_Be verbose. <x> is a combination of the following letters:'#010+
   '**2*_e : Show errors (default)       0 : Show nothing (except errors)'#010+
   '**2*_w : Show warnings               u : Show unit info'#010+
-  '**2*_n : Show notes                  t : Show tried/used files'#010+
-  '**2*_h : Show hints                  c :',' Show conditionals'#010+
+  '**2*_n : Show notes                  t : Show trie','d/used files'#010+
+  '**2*_h : Show hints                  c : Show conditionals'#010+
   '**2*_i : Show general info           d : Show debug info'#010+
   '**2*_l : Show linenumbers            r : Rhide/GCC compatibility mode'#010+
-  '**2*_s : Show time stamps            q : Show message numbers'#010+
-  '**2*_a : Show everything        ','     x : Executable info (Win32 only'+
-  ')'#010+
+  '**2*_s : Show time stamps            q : ','Show message numbers'#010+
+  '**2*_a : Show everything             x : Executable info (Win32 only)'#010+
   '**2*_b : Write file names messages   p : Write tree.log with parse tre'+
   'e'#010+
   '**2*_    with full path              v : Write fpcdebug.txt with'#010+
-  '**2*_                                    lots of debugging info'#010+
-  '*','*2*_m<x>,<y> : Don'#039't show messages numbered <x> and <y>'#010+
+  '**2*_       ','                             lots of debugging info'#010+
+  '**2*_m<x>,<y> : Don'#039't show messages numbered <x> and <y>'#010+
   'F*1V<x>_Append '#039'-<x>'#039' to the used compiler binary name (e.g. f'+
   'or version)'#010+
   '**1W<x>_Target-specific options (targets)'#010+
-  '3*2WA_Specify native type application (Windows)'#010+
-  '4*2WA_Specify native',' type application (Windows)'#010+
+  '3*2WA_Specify n','ative type application (Windows)'#010+
+  '4*2WA_Specify native type application (Windows)'#010+
   'A*2WA_Specify native type application (Windows)'#010+
   '3*2Wb_Create a bundle instead of a library (Darwin)'#010+
   'P*2Wb_Create a bundle instead of a library (Darwin)'#010+
-  'p*2Wb_Create a bundle instead of a library (Darwin)'#010+
-  'A*2Wb_Cr','eate a bundle instead of a library (Darwin)'#010+
+  'p*2Wb_C','reate a bundle instead of a library (Darwin)'#010+
+  'A*2Wb_Create a bundle instead of a library (Darwin)'#010+
   '4*2Wb_Create a bundle instead of a library (Darwin)'#010+
   '3*2WB_Create a relocatable image (Windows, Symbian)'#010+
-  '3*2WBxxxx_Set image base to xxxx (Windows, Symbian)'#010+
-  '4*2WB_Create a relocatable image (Window','s)'#010+
+  '3*2WBxxxx_Set image base to xxxx (Windo','ws, Symbian)'#010+
+  '4*2WB_Create a relocatable image (Windows)'#010+
   '4*2WBxxxx_Set image base to xxxx (Windows)'#010+
   'A*2WB_Create a relocatable image (Windows, Symbian)'#010+
   'A*2WBxxxx_Set image base to xxxx (Windows, Symbian)'#010+
-  '3*2WC_Specify console type application (EMX, OS/2, Windows)'#010+
-  '4*2WC_Specify console type app','lication (EMX, OS/2, Windows)'#010+
+  '3*2WC_Specify console type applicatio','n (EMX, OS/2, Windows)'#010+
+  '4*2WC_Specify console type application (EMX, OS/2, Windows)'#010+
   'A*2WC_Specify console type application (Windows)'#010+
   'P*2WC_Specify console type application (Classic Mac OS)'#010+
-  '3*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
-  '4*2WD_Use DEFFILE to export functions of DL','L or EXE (Windows)'#010+
+  '3*2WD_Use DEFFILE to export functions of DLL or EXE ','(Windows)'#010+
+  '4*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
   'A*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
   '3*2We_Use external resources (Darwin)'#010+
   '4*2We_Use external resources (Darwin)'#010+
-  'A*2We_Use external resources (Darwin)'#010+
+  'A*2We_Use external resources (','Darwin)'#010+
   'P*2We_Use external resources (Darwin)'#010+
-  'p*2We_U','se external resources (Darwin)'#010+
+  'p*2We_Use external resources (Darwin)'#010+
   '3*2WF_Specify full-screen type application (EMX, OS/2)'#010+
   '3*2WG_Specify graphic type application (EMX, OS/2, Windows)'#010+
-  '4*2WG_Specify graphic type application (EMX, OS/2, Windows)'#010+
-  'A*2WG_Specify graphic type applica','tion (Windows)'#010+
+  '4*2WG_Specify graphic type application (E','MX, OS/2, Windows)'#010+
+  'A*2WG_Specify graphic type application (Windows)'#010+
   'P*2WG_Specify graphic type application (Classic Mac OS)'#010+
   '3*2Wi_Use internal resources (Darwin)'#010+
   '4*2Wi_Use internal resources (Darwin)'#010+
   'A*2Wi_Use internal resources (Darwin)'#010+
-  'P*2Wi_Use internal resources (Darwin)'#010+
-  'p*2Wi_Use interna','l resources (Darwin)'#010+
+  'P*','2Wi_Use internal resources (Darwin)'#010+
+  'p*2Wi_Use internal resources (Darwin)'#010+
   '3*2WI_Turn on/off the usage of import sections (Windows)'#010+
   '4*2WI_Turn on/off the usage of import sections (Windows)'#010+
-  'A*2WI_Turn on/off the usage of import sections (Windows)'#010+
+  'A*2WI_Turn on/off the usage of import sections (Wind','ows)'#010+
   '8*2Wm<x>_Set memory model'#010+
-  '8*3WmTiny_Tiny memory ','model'#010+
+  '8*3WmTiny_Tiny memory model'#010+
   '8*3WmSmall_Small memory model (default)'#010+
   '8*3WmMedium_Medium memory model'#010+
   '3*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
   'n)'#010+
-  '4*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
-  'n)'#010+
-  'p*2WM<x>_Minimum',' Mac OS X deployment version: 10.4, 10.5.1, ... (Dar'+
+  '4*2WM<x>_Minimum Mac OS X deployment',' version: 10.4, 10.5.1, ... (Dar'+
   'win)'#010+
+  'p*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
+  'n)'#010+
   'P*2WM<x>_Minimum Mac OS X deployment version: 10.4, 10.5.1, ... (Darwi'+
   'n)'#010+
-  '3*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
-  '4*2WN_Do not generate relocation code, n','eeded for debugging (Windows'+
+  '3*2WN_Do not generate relocation code, needed for debuggi','ng (Windows'+
   ')'#010+
+  '4*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
   'A*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
   'A*2Wpxxxx_Specify the controller type, see fpc -i for possible values'#010+
-  'V*2Wpxxxx_Specify the controller type, see fpc -i for possible values'#010,
+  'V*2Wpxxxx_Specify',' the controller type, see fpc -i for possible value'+
+  's'#010+
   '3*2WP<x>_Minimum iOS deployment version: 3.0, 5.0.1, ... (iphonesim)'#010+
   'A*2WP<x>_Minimum iOS deployment version: 3.0, 5.0.1, ... (Darwin)'#010+
   '3*2WR_Generate relocation code (Windows)'#010+
-  '4*2WR_Generate relocation code (Windows)'#010+
-  'A*2WR_Generate relocati','on code (Windows)'#010+
+  '4*2WR_Gener','ate relocation code (Windows)'#010+
+  'A*2WR_Generate relocation code (Windows)'#010+
   'P*2WT_Specify MPW tool type application (Classic Mac OS)'#010+
   '**2WX_Enable executable stack (Linux)'#010+
   '**1X_Executable options:'#010+
-  '**2Xc_Pass --shared/-dynamic to the linker (BeOS, Darwin, FreeBSD, Lin'+
-  'ux)'#010+
-  '**2Xd_Do not search default ','library path (sometimes required for cro'+
-  'ss-compiling when not using -XR)'#010+
+  '**2Xc_Pass --shared/-dynamic to the linker (BeOS,',' Darwin, FreeBSD, L'+
+  'inux)'#010+
+  '**2Xd_Do not search default library path (sometimes required for cross'+
+  '-compiling when not using -XR)'#010+
   '**2Xe_Use external linker'#010+
   '**2Xg_Create debuginfo in a separate file and add a debuglink section '+
   'to executable'#010+
-  '**2XD_Try to link units dynamically      (defines FPC_LIN','K_DYNAMIC)'#010+
+  '**2X','D_Try to link units dynamically      (defines FPC_LINK_DYNAMIC)'#010+
   '**2Xi_Use internal linker'#010+
   '**2Xm_Generate link map'#010+
   '**2XM<x>_Set the name of the '#039'main'#039' program routine (default i'+
   's '#039'main'#039')'#010+
-  'F*2Xp<x>_First search for the compiler binary in the directory <x>'#010+
-  '**2XP<x>_Prepend the binutils names with',' the prefix <x>'#010+
+  'F*2Xp<x>_First search for the compiler binary in the d','irectory <x>'#010+
+  '**2XP<x>_Prepend the binutils names with the prefix <x>'#010+
   '**2Xr<x>_Set the linker'#039's rlink-path to <x> (needed for cross comp'+
   'ile, see the ld manual for more information) (BeOS, Linux)'#010+
-  '**2XR<x>_Prepend <x> to all linker search paths (BeOS, Darwin, FreeBSD'+
-  ', Linux, Mac OS, Solaris)'#010+
-  '**2','Xs_Strip all symbols from executable'#010+
+  '**2XR<x>_Prepend <x> to all linker search path','s (BeOS, Darwin, FreeB'+
+  'SD, Linux, Mac OS, Solaris)'#010+
+  '**2Xs_Strip all symbols from executable'#010+
   '**2XS_Try to link units statically (default, defines FPC_LINK_STATIC)'#010+
   '**2Xt_Link with static libraries (-static is passed to linker)'#010+
-  '**2XX_Try to smartlink units             (defines FPC_LINK_SMART)'#010+
-  '**1*','_'#010+
+  '**2XX_Try to smar','tlink units             (defines FPC_LINK_SMART)'#010+
+  '**1*_'#010+
   '**1?_Show this help'#010+
   '**1h_Shows this help without waiting'
 );

+ 17 - 4
compiler/options.pas

@@ -892,6 +892,19 @@ begin
                         exclude(init_settings.localswitches,cs_check_io)
                       else
                         include(init_settings.localswitches,cs_check_io);
+{$ifdef arm}
+                    'I' :
+                      begin
+                        if (upper(copy(more,j+1,length(more)-j))='THUMB') and
+                          { does selected CPU really understand thumb? }
+                          (init_settings.cputype in cpu_has_thumb) then
+                          init_settings.instructionset:=is_thumb
+                        else if upper(copy(more,j+1,length(more)-j))='ARM' then
+                          init_settings.instructionset:=is_arm
+                        else
+                          IllegalPara(opt);
+                      end;
+{$endif arm}
                     'n' :
                       If UnsetBool(More, j, opt, false) then
                         exclude(init_settings.globalswitches,cs_link_nolink)
@@ -915,7 +928,7 @@ begin
                     'p' :
                       begin
                         s:=upper(copy(more,j+1,length(more)-j));
-                        if not(Setcputype(s,init_settings.cputype)) then
+                        if not(Setcputype(s,init_settings)) then
                           IllegalPara(opt);
                         CPUSetExplicitly:=true;
                         break;
@@ -1404,7 +1417,7 @@ begin
                       include(init_settings.optimizerswitches,cs_opt_size);
                     'p' :
                       begin
-                        if not Setcputype(copy(more,j+1,length(more)),init_settings.optimizecputype) then
+                        if not Setoptimizecputype(copy(more,j+1,length(more)),init_settings.optimizecputype) then
                           begin
                             OptCPUSetExplicitly:=true;
                             { Give warning for old i386 switches }
@@ -3324,14 +3337,14 @@ if (target_info.abi = abi_eabihf) then
 {$endif CPUARMV6}
   end;
 
-  if init_settings.cputype in cpu_thumb then
+  if (init_settings.instructionset=is_thumb) and not(CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype]) 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
+  if (init_settings.instructionset=is_thumb) and (CPUARM_HAS_THUMB2 in cpu_capabilities[init_settings.cputype]) then
     def_system_macro('CPUTHUMB2');
 {$endif arm}
 

+ 1 - 1
compiler/psub.pas

@@ -957,7 +957,7 @@ implementation
 {$if defined(arm)}
         { frame and stack pointer must be always the same on arm thumb so it makes no
           sense to fiddle with a frame pointer }
-        if current_settings.cputype in cpu_thumb then
+        if GenerateThumbCode then
           begin
             framepointer:=NR_STACK_POINTER_REG;
             tg.direction:=1;