From 6f5a648516c85138b5b89938ff0ce34456b35bd4 Mon Sep 17 00:00:00 2001 From: svenbarth Date: Wed, 11 Sep 2013 17:07:32 +0000 Subject: [PATCH] Improve the cpu type handling for M68k just in case we should branch 2.8.0 before I can start working on M68k again. Therefor the cpu type (-Cp...) "coldfire" was split up into "isaa", "isaa+", "isab" and "isac". The Linux RTL can currently compiled for "68020", "isab" and "isac". For the other three Bcc.L must be handled differently (only Bcc.B/W supported) and for "68000" also EXT.L needs to be handled differently. fpcdefs.inc: + define CPUCAPABILITIES if capabilities can be set for a certain CPU type (currently ARM, AVR and M68k) options.pas: * check for CPUCAPABILITIES instead of specific CPUs assemble.pas: - the handling of the CPU type is already done in m68k/ag68kgas.pas, Tm68kGNUAssembler.MakeCmdLine (and thereby already using the gascputypestr array!) m68k/cpuinfo.pas: - tcputype: remove "cpu_coldfire" + tcputype: add "cpu_isa_a", "cpu_isa_a_p", "cpu_isa_b" and "cpu_isa_c" + add "cpu_coldfire" constant which contains all Coldfire specific cpu types * adjust "cputypestr" and "gascputypestr" + add tcpuflags and cpu_capabilities (DBRA restriction was checked with CPUCOLDFIRE, CAS/TAS will be needed for atomic operations and BRAL restriction was discovered during testing of new cpu types) m68k/cgcpu.pas: * adjust checks for "cpu_coldfire" m68k/n68kadd.pas: * don't use a BRA.L if it is not supported, but (at least for now) a BRA.W aggas.pas: * adjusted check for Coldfire git-svn-id: trunk@25457 - --- compiler/aggas.pas | 2 +- compiler/assemble.pas | 25 ------------------------- compiler/fpcdefs.inc | 3 +++ compiler/m68k/cgcpu.pas | 19 +++++++++++-------- compiler/m68k/cpuinfo.pas | 37 ++++++++++++++++++++++++++++++++++--- compiler/m68k/n68kadd.pas | 12 ++++++++++-- compiler/options.pas | 8 ++++---- 7 files changed, 63 insertions(+), 43 deletions(-) diff --git a/compiler/aggas.pas b/compiler/aggas.pas index 2e99604817..fb83bed99a 100644 --- a/compiler/aggas.pas +++ b/compiler/aggas.pas @@ -666,7 +666,7 @@ implementation { the Coldfire manual suggests the TBF instruction for alignments, but somehow QEMU does not interpret that correctly... } - {if current_settings.cputype=cpu_coldfire then + {if current_settings.cputype in cpu_coldfire then instr:='0x51fc' else} instr:='0x4e71'; diff --git a/compiler/assemble.pas b/compiler/assemble.pas index 0f51767c24..a2d87d52c0 100644 --- a/compiler/assemble.pas +++ b/compiler/assemble.pas @@ -579,31 +579,6 @@ Implementation function TExternalAssembler.MakeCmdLine: TCmdStr; begin result:=target_asm.asmcmd; -{$ifdef m68k} - { TODO: use a better approach for this } - if (target_info.system=system_m68k_amiga) then - begin - { m68k-amiga has old binutils, which doesn't support -march=* } - case current_settings.cputype of - cpu_MC68000: - result:='-m68000 '+result; - cpu_MC68020: - result:='-m68020 '+result; - { additionally, AmigaOS doesn't work on Coldfire } - end; - end - else - begin - case current_settings.cputype of - cpu_MC68000: - result:='-march=68000 '+result; - cpu_MC68020: - result:='-march=68020 '+result; - cpu_Coldfire: - result:='-march=cfv4e '+result; - end; - end; -{$endif} {$ifdef arm} if (target_info.system=system_arm_darwin) then Replace(result,'$ARCH',lower(cputypestr[current_settings.cputype])); diff --git a/compiler/fpcdefs.inc b/compiler/fpcdefs.inc index f883d380c5..6edf2ba97a 100644 --- a/compiler/fpcdefs.inc +++ b/compiler/fpcdefs.inc @@ -148,6 +148,7 @@ {$define cpurox} {$define cputargethasfixedstack} {$define cpurefshaveindexreg} + {$define cpucapabilities} {$define SUPPORT_SAFECALL} {$define SUPPORT_GET_FRAME} { default to armel } @@ -175,6 +176,7 @@ {$define cpuflags} {$define cpufpemu} {$define cpurefshaveindexreg} + {$define cpucapabilities} {$endif m68k} {$ifdef avr} @@ -187,6 +189,7 @@ {$define cpuneedsdiv32helper} {$define cpuneedsmulhelper} {$define cpurefshaveindexreg} + {$define cpucapabilities} {$endif avr} {$ifdef mipsel} diff --git a/compiler/m68k/cgcpu.pas b/compiler/m68k/cgcpu.pas index 7989464718..82abeb1111 100644 --- a/compiler/m68k/cgcpu.pas +++ b/compiler/m68k/cgcpu.pas @@ -517,7 +517,10 @@ unit cgcpu; fixref:=true; end; end; - cpu_Coldfire: + cpu_isa_a, + cpu_isa_a_p, + cpu_isa_b, + cpu_isa_c: begin if (ref.base<>NR_NO) then begin @@ -742,7 +745,7 @@ unit cgcpu; fixref(list,href); { for coldfire we need to go through a temporary register if we have a offset, index or symbol given } - if (current_settings.cputype=cpu_coldfire) and + if (current_settings.cputype in cpu_coldfire) and ( (href.offset<>0) or { TODO : check whether we really need this second condition } @@ -788,7 +791,7 @@ unit cgcpu; // writeln('a_load_ref_ref'); {$endif DEBUG_CHARLIE} { Coldfire dislikes certain move combinations } - if current_settings.cputype=cpu_coldfire then + if current_settings.cputype in cpu_coldfire then begin { TODO : move.b/w only allowed in newer coldfires... (ISA_B+) } @@ -1179,7 +1182,7 @@ unit cgcpu; case op of OP_ADD : begin - if current_settings.cputype = cpu_ColdFire then + if current_settings.cputype in cpu_ColdFire then begin { operation only allowed only a longword } sign_extend(list, size, reg1); @@ -1216,7 +1219,7 @@ unit cgcpu; else hreg2 := reg2; - if current_settings.cputype = cpu_ColdFire then + if current_settings.cputype in cpu_ColdFire then begin { operation only allowed only a longword } {!*************************************** @@ -1351,7 +1354,7 @@ unit cgcpu; hreg2 := reg2; { coldfire only supports long version } - if current_settings.cputype = cpu_ColdFire then + if current_settings.cputype in cpu_ColdFire then begin sign_extend(list, size,hreg2); list.concat(taicpu.op_reg(topcg2tasmop[op],S_L,hreg2)); @@ -1402,7 +1405,7 @@ unit cgcpu; end else begin - if (current_settings.cputype = cpu_ColdFire) then + if (current_settings.cputype in cpu_ColdFire) then begin { only longword comparison is supported, @@ -1622,7 +1625,7 @@ unit cgcpu; a_label(list,hl); list.concat(taicpu.op_ref_ref(A_MOVE,S_B,hp1,hp2)); a_label(list,hl2); - if current_settings.cputype=cpu_coldfire then + if current_settings.cputype in cpu_coldfire then begin { Coldfire does not support DBRA } list.concat(taicpu.op_const_reg(A_SUB,S_L,1,hregister)); diff --git a/compiler/m68k/cpuinfo.pas b/compiler/m68k/cpuinfo.pas index 68796b3590..8644124372 100644 --- a/compiler/m68k/cpuinfo.pas +++ b/compiler/m68k/cpuinfo.pas @@ -34,7 +34,10 @@ Type (cpu_none, cpu_MC68000, cpu_MC68020, - cpu_Coldfire + cpu_isa_a, + cpu_isa_a_p, + cpu_isa_b, + cpu_isa_c ); tfputype = @@ -60,13 +63,19 @@ Const cputypestr : array[tcputype] of string[8] = ('', '68000', '68020', - 'COLDFIRE' + 'ISAA', + 'ISAA+', + 'ISAB', + 'ISAC' ); gascputypestr : array[tcputype] of string[8] = ('', '68000', '68020', - 'cfv4e' + 'isaa', + 'isaaplus', + 'isab', + 'isac' ); fputypestr : array[tfputype] of string[6] = ('', @@ -90,6 +99,28 @@ Const level3optimizerswitches = genericlevel3optimizerswitches + level2optimizerswitches + [{,cs_opt_loopunroll}]; level4optimizerswitches = genericlevel4optimizerswitches + level3optimizerswitches + []; +type + tcpuflags = + (CPUM68K_HAS_DBRA, { CPU supports the DBRA instruction } + CPUM68K_HAS_CAS, { CPU supports the CAS instruction } + CPUM68K_HAS_TAS, { CPU supports the TAS instruction } + CPUM68K_HAS_BRAL { CPU supports the BRA.L/Bcc.L instructions } + ); + +const + cpu_capabilities : array[tcputype] of set of tcpuflags = + ( { cpu_none } [], + { cpu_68000 } [CPUM68K_HAS_DBRA,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL], + { cpu_68020 } [CPUM68K_HAS_DBRA,CPUM68K_HAS_CAS,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL], + { cpu_isaa } [], + { cpu_isaap } [CPUM68K_HAS_BRAL], + { cpu_isab } [CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL], + { cpu_isac } [CPUM68K_HAS_TAS] + ); + + { all CPUs commonly cold "coldfire" } + cpu_coldfire = [cpu_isa_a,cpu_isa_a_p,cpu_isa_b,cpu_isa_c]; + Implementation end. diff --git a/compiler/m68k/n68kadd.pas b/compiler/m68k/n68kadd.pas index 6802b9bb8d..7e316c1bf9 100644 --- a/compiler/m68k/n68kadd.pas +++ b/compiler/m68k/n68kadd.pas @@ -93,7 +93,11 @@ implementation current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,right_reg.reglo,left_reg.reglo)); current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_L,labelcmp64_2)); - current_asmdata.currasmlist.concat(Taicpu.op_sym(A_BRA,S_L,labelcmp64_1)); + if CPUM68K_HAS_BRAL in cpu_capabilities[current_settings.cputype] then + current_asmdata.currasmlist.concat(Taicpu.op_sym(A_BRA,S_L,labelcmp64_1)) + else + { better use JMP? } + current_asmdata.currasmlist.concat(Taicpu.op_sym(A_BRA,S_W,labelcmp64_1)); cg.a_label(current_asmdata.currasmlist,labelcmp64_2); @@ -213,7 +217,11 @@ implementation current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,right_reg.reglo,left_reg.reglo)); current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_L,labelcmp64_2)); - current_asmdata.currasmlist.concat(Taicpu.op_sym(A_BRA,S_L,labelcmp64_1)); + if CPUM68K_HAS_BRAL in cpu_capabilities[current_settings.cputype] then + current_asmdata.currasmlist.concat(Taicpu.op_sym(A_BRA,S_L,labelcmp64_1)) + else + { ToDo : use JMP? } + current_asmdata.currasmlist.concat(Taicpu.op_sym(A_BRA,S_W,labelcmp64_1)); cg.a_label(current_asmdata.currasmlist,labelcmp64_2); diff --git a/compiler/options.pas b/compiler/options.pas index 3ba1084307..f9e4dae80f 100644 --- a/compiler/options.pas +++ b/compiler/options.pas @@ -2778,10 +2778,10 @@ var env: ansistring; i : tfeature; abi : tabi; -{$if defined(arm) or defined(avr)} +{$if defined(cpucapabilities)} cpuflag : tcpuflags; hs : string; -{$endif defined(arm) or defined(avr)} +{$endif defined(cpucapabilities)} begin option:=coption.create; disable_configfile:=false; @@ -3363,7 +3363,7 @@ if (target_info.abi = abi_eabihf) then def_system_macro('FPU'+fputypestr[init_settings.fputype]); -{$if defined(arm) or defined(avr)} +{$if defined(cpucapabilities)} for cpuflag:=low(cpuflag) to high(cpuflag) do begin str(cpuflag,hs); @@ -3372,7 +3372,7 @@ if (target_info.abi = abi_eabihf) then else undef_system_macro(hs); end; -{$endif defined(arm) or defined(avr)} +{$endif defined(cpucapabilities)} if init_settings.fputype<>fpu_none then begin