Browse Source

+ Xtensa: the boolean extension is used as flags

git-svn-id: trunk@44538 -
florian 5 years ago
parent
commit
ba3de67f3b
5 changed files with 63 additions and 5 deletions
  1. 1 0
      compiler/fpcdefs.inc
  2. 3 0
      compiler/ncgcnv.pas
  3. 4 0
      compiler/ncgutil.pas
  4. 28 0
      compiler/xtensa/cgcpu.pas
  5. 27 5
      compiler/xtensa/cpubase.pas

+ 1 - 0
compiler/fpcdefs.inc

@@ -313,6 +313,7 @@
   {$define cpu32bitaddr}
   {$define cpu32bitalu}
   {$define cpufpemu}
+  {$define cpuflags} { xtensa has a boolean extension }
   {$define cputargethasfixedstack}
   {$define cpuneedsmulhelper}
   {$define cpuneedsdivhelper}

+ 3 - 0
compiler/ncgcnv.pas

@@ -220,6 +220,9 @@ interface
 {$elseif defined(sparcgen)}
         { Load left node into flag F_NE/F_E }
         resflags.Init(NR_ICC,F_NE);
+{$elseif defined(xtensa)}
+        { Xtensa uses its own implementation }
+        Internalerror(2020032901);
 {$else}
         { Load left node into flag F_NE/F_E }
         resflags:=F_NE;

+ 4 - 0
compiler/ncgutil.pas

@@ -332,7 +332,11 @@ implementation
                      LOC_FLAGS :
                        begin
                          cg.a_jmp_flags(list,p.location.resflags,truelabel);
+
+                         { e.g. xtensa has no default flags but uses a boolean register }
+{$if defined(NR_DEFAULTFLAGS)}
                          cg.a_reg_dealloc(list,NR_DEFAULTFLAGS);
+{$endif defined(NR_DEFAULTFLAGS)}
                          cg.a_jmp_always(list,falselabel);
                        end;
 {$endif cpuflags}

+ 28 - 0
compiler/xtensa/cgcpu.pas

@@ -57,7 +57,9 @@ interface
 
         procedure a_call_name(list:TAsmList;const s:string; weak: boolean);override;
         procedure a_call_reg(list:TAsmList;Reg:tregister);override;
+
         procedure a_jmp_name(list: TAsmList; const s: string);override;
+        procedure a_jmp_flags(list: TAsmList; const f: TResFlags; l: tasmlabel);override;
 
         procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);override;
         procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);override;
@@ -67,6 +69,8 @@ interface
         procedure a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);override;
         procedure a_jmp_always(list: TAsmList; l: TAsmLabel);override;
 
+        procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: tresflags; reg: TRegister);override;
+
         procedure g_concatcopy(list : TAsmList; const source,dest : treference; len : tcgint);override;
 
         procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
@@ -546,6 +550,16 @@ implementation
       end;
 
 
+    procedure tcgcpu.a_jmp_flags(list: TAsmList; const f: TResFlags; l: tasmlabel);
+      var
+        instr: taicpu;
+      begin
+        instr:=taicpu.op_reg_sym(A_Bcc,f.register,l);
+        instr.condition:=flags_to_cond(f.flag);
+        list.concat(instr);
+      end;
+
+
     procedure tcgcpu.g_proc_entry(list : TAsmList; localsize : longint;
       nostackframe : boolean);
       var
@@ -773,6 +787,20 @@ implementation
       end;
 
 
+    procedure tcgcpu.g_flags2reg(list: TAsmList; size: TCgSize; const f: tresflags; reg: TRegister);
+      var
+        hregister: TRegister;
+        instr: taicpu;
+      begin
+        a_load_const_reg(list,size,0,reg);
+        hregister:=getintregister(list,size);
+        a_load_const_reg(list,size,1,hregister);
+        instr:=taicpu.op_reg_reg_reg(A_MOV,reg,hregister,f.register);
+        instr.condition:=flags_to_cond(f.flag);
+        list.concat(instr);
+      end;
+
+
     procedure tcgcpu.g_concatcopy_move(list: tasmlist; const Source, dest: treference; len: tcgint);
       var
         paraloc1, paraloc2, paraloc3: TCGPara;

+ 27 - 5
compiler/xtensa/cpubase.pas

@@ -78,7 +78,7 @@ unit cpubase;
 
       { Float Super register first and last }
       first_fpu_supreg    = RS_F0;
-      first_fpu_imreg     = $08;
+      first_fpu_imreg     = $10;
 
       { MM Super register first and last }
       first_mm_supreg    = RS_INVALID;
@@ -109,18 +109,27 @@ unit cpubase;
         C_GE,C_LT,C_GEU,C_LTU,
         C_ANY,C_BNONE,C_ALL,C_NALL,C_BC,C_BS,
         C_EQZ,C_NEZ,C_LTZ,C_GEZ,
-        C_EQI,C_NEI,C_LTI,C_GEI,C_LTUI,C_GEUI
+        C_EQI,C_NEI,C_LTI,C_GEI,C_LTUI,C_GEUI,
+        C_F,C_T
       );
 
       TAsmConds = set of TAsmCond;
 
+      TResFlagsEnum = (F_Z,F_NZ);
+
+      TResFlags = record
+        register: TRegister;
+        flag: TResFlagsEnum;
+      end;
+
     const
       cond2str : array[TAsmCond] of string[4]=('',
         'eq','ne',                         
         'ge','lt','geu','ltu',
         'any','none','all','nall','bc','bs',
         'eqz','nez','ltz','gez',
-        'eqi','nei','lti','gei','ltui','geui'
+        'eqi','nei','lti','gei','ltui','geui',
+        'f','t'
       );
 
       uppercond2str : array[TAsmCond] of string[4]=('',
@@ -128,7 +137,8 @@ unit cpubase;
         'GE','LT','GEU','LTU',
         'ANY','NONE','ALL','NALL','BC','BS',
         'EQZ','NEZ','LTZ','GEZ',
-        'EQI','NEI','LTI','GEI','LTUI','GEUI'
+        'EQI','NEI','LTI','GEI','LTUI','GEUI',
+        'F','T'
       );
 
 {*****************************************************************************
@@ -246,6 +256,8 @@ unit cpubase;
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
+    function flags_to_cond(const f: TResFlagsEnum) : TAsmCond;
+
     { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
     function condition_in(const Subset, c: TAsmCond): Boolean;
 
@@ -361,13 +373,23 @@ unit cpubase;
           C_BNONE,C_ANY,C_NALL,C_BNONE,C_BS,C_BC,
 
           C_NEZ,C_EQZ,C_GEZ,C_LTZ,
-          C_NEI,C_EQI,C_GEI,C_LTI,C_GEUI,C_LTUI
+          C_NEI,C_EQI,C_GEI,C_LTI,C_GEUI,C_LTUI,
+          C_T,C_F
         );
       begin
         result := inverse[c];
       end;
 
 
+    function flags_to_cond(const f: TResFlagsEnum) : TAsmCond;
+      const flags2cond: array[TResFlagsEnum] of tasmcond = (
+          C_F,
+          C_T);
+      begin
+        flags_to_cond := flags2cond[f];
+      end;
+
+
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
       begin
         result := c1 = c2;