Просмотр исходного кода

Add immediate/zero comparisons.

git-svn-id: trunk@44356 -
Jeppe Johansen 5 лет назад
Родитель
Сommit
222cad35a9
4 измененных файлов с 124 добавлено и 25 удалено
  1. 10 0
      compiler/xtensa/aasmcpu.pas
  2. 95 18
      compiler/xtensa/cgcpu.pas
  3. 10 5
      compiler/xtensa/cpubase.pas
  4. 9 2
      compiler/xtensa/ncpuadd.pas

+ 10 - 0
compiler/xtensa/aasmcpu.pas

@@ -78,6 +78,7 @@ uses
         constructor op_sym(op : tasmop;_op1 : tasmsymbol);
         constructor op_sym(op : tasmop;_op1 : tasmsymbol);
         constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:aint);
         constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:aint);
         constructor op_reg_sym(op : tasmop;_op1 : tregister;_op2:tasmsymbol);
         constructor op_reg_sym(op : tasmop;_op1 : tregister;_op2:tasmsymbol);
+        constructor op_reg_const_sym(op : tasmop;_op1 : tregister;_op2:aint;_op3:tasmsymbol);
         constructor op_reg_reg_sym(op : tasmop;_op1, _op2 : tregister;_op3:tasmsymbol);
         constructor op_reg_reg_sym(op : tasmop;_op1, _op2 : tregister;_op3:tasmsymbol);
         constructor op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : aint);
         constructor op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : aint);
         constructor op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:aint;const _op2 : treference);
         constructor op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:aint;const _op2 : treference);
@@ -368,6 +369,15 @@ uses cutils, cclasses;
          loadsymbol(1,_op2,0);
          loadsymbol(1,_op2,0);
       end;
       end;
 
 
+    constructor taicpu.op_reg_const_sym(op: tasmop; _op1: tregister; _op2: aint; _op3: tasmsymbol);
+      begin
+         inherited create(op);
+         ops:=3;
+         loadreg(0,_op1);
+         loadconst(1,_op2);
+         loadsymbol(2,_op3,0);
+      end;
+
      constructor taicpu.op_reg_reg_sym(op: tasmop; _op1, _op2: tregister; _op3: tasmsymbol);
      constructor taicpu.op_reg_reg_sym(op: tasmop; _op1, _op2: tregister; _op3: tasmsymbol);
        begin
        begin
          inherited create(op);
          inherited create(op);

+ 95 - 18
compiler/xtensa/cgcpu.pas

@@ -63,6 +63,7 @@ interface
         procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);override;
         procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);override;
 
 
         { comparison operations }
         { comparison operations }
+        procedure a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel); override;
         procedure a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);override;
         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 a_jmp_always(list: TAsmList; l: TAsmLabel);override;
 
 
@@ -156,6 +157,21 @@ implementation
     symtable,symsym,
     symtable,symsym,
     tgobj,
     tgobj,
     procinfo,cpupi;
     procinfo,cpupi;
+                  
+  const
+    TOpCmp2AsmCond: array[TOpCmp] of TAsmCond = (
+      C_None,
+      C_EQ,
+      C_None,
+      C_LT,
+      C_GE,
+      C_None,
+      C_NE,
+      C_None,
+      C_LTU,
+      C_GEU,
+      C_None
+    );
 
 
     procedure tcgcpu.init_register_allocators;
     procedure tcgcpu.init_register_allocators;
       begin
       begin
@@ -550,28 +566,91 @@ implementation
           list.Concat(taicpu.op_none(A_RET));
           list.Concat(taicpu.op_none(A_RET));
       end;
       end;
 
 
+    procedure tcgcpu.a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);
+
+      function is_b4const(v: tcgint): boolean;
+        begin
+          case v of
+            -1,1,2,3,4,5,6,7,8,
+            10,12,16,32,64,128,256:
+              result:=true;
+          else
+            result:=false;
+          end;
+        end;
+
+      function is_b4constu(v: tcgint): boolean;
+        begin
+          case v of
+            32768,65536,
+            2,3,4,5,6,7,8,
+            10,12,16,32,64,128,256:
+              result:=true;
+          else
+            result:=false;
+          end;
+        end;
+
+      var
+        op: TAsmCond;
+        instr: taicpu;
+      begin
+        if (a=0) and (cmp_op in [OC_EQ,OC_NE,OC_LT,OC_GTE]) then
+          begin
+            case cmp_op of
+              OC_EQ: op:=C_EQZ;
+              OC_NE: op:=C_NEZ;
+              OC_LT: op:=C_LTZ;
+              OC_GTE: op:=C_GEZ;
+            else
+              Internalerror(2020030801);
+            end;     
+            instr:=taicpu.op_reg_sym(A_Bcc,reg,l);
+            instr.condition:=op;
+            list.concat(instr);
+          end
+        else if is_b4const(a) and
+                (cmp_op in [OC_EQ,OC_NE,OC_LT,OC_GTE]) then
+          begin
+            case cmp_op of
+              OC_EQ: op:=C_EQI;
+              OC_NE: op:=C_NEI;
+              OC_LT: op:=C_LTI;
+              OC_GTE: op:=C_GEI;
+            else
+              Internalerror(2020030801);
+            end;
+
+            instr:=taicpu.op_reg_const_sym(A_Bcc,reg,a,l);
+            instr.condition:=op;
+            list.concat(instr);
+          end
+        else if is_b4constu(a) and
+                (cmp_op in [OC_B,OC_AE]) then
+          begin
+            case cmp_op of
+              OC_B: op:=C_LTUI;
+              OC_AE: op:=C_GEUI;
+            else
+              Internalerror(2020030801);
+            end;
+
+            instr:=taicpu.op_reg_const_sym(A_Bcc,reg,a,l);
+            instr.condition:=op;
+            list.concat(instr);
+          end
+        else
+          inherited a_cmp_const_reg_label(list, size, cmp_op, a, reg, l);
+      end;
+
 
 
     procedure tcgcpu.a_cmp_reg_reg_label(list : TAsmList; size : tcgsize;
     procedure tcgcpu.a_cmp_reg_reg_label(list : TAsmList; size : tcgsize;
         cmp_op : topcmp; reg1,reg2 : tregister; l : tasmlabel);
         cmp_op : topcmp; reg1,reg2 : tregister; l : tasmlabel);
-      const
-        cmp2cond: array[TOpCmp] of TAsmCond = (
-          C_None,
-          C_EQ,
-          C_None,
-          C_LT,
-          C_GE,
-          C_None,
-          C_NE,
-          C_None,
-          C_LTU,
-          C_GEU,
-          C_None
-        );
       var
       var
         tmpreg: TRegister;
         tmpreg: TRegister;
         instr: taicpu;
         instr: taicpu;
       begin
       begin
-        if cmp2cond[cmp_op]=C_None then
+        if TOpCmp2AsmCond[cmp_op]=C_None then
           begin
           begin
             cmp_op:=swap_opcmp(cmp_op);
             cmp_op:=swap_opcmp(cmp_op);
             tmpreg:=reg1;
             tmpreg:=reg1;
@@ -579,10 +658,8 @@ implementation
             reg2:=tmpreg;
             reg2:=tmpreg;
           end;
           end;
 
 
-        if cmp2cond[cmp_op]=C_None then
-          writeln('t');
         instr:=taicpu.op_reg_reg_sym(A_Bcc,reg1,reg2,l);
         instr:=taicpu.op_reg_reg_sym(A_Bcc,reg1,reg2,l);
-        instr.condition:=cmp2cond[cmp_op];
+        instr.condition:=TOpCmp2AsmCond[cmp_op];
         list.concat(instr);
         list.concat(instr);
       end;
       end;
 
 

+ 10 - 5
compiler/xtensa/cpubase.pas

@@ -108,7 +108,8 @@ unit cpubase;
         C_EQ,C_NE,
         C_EQ,C_NE,
         C_GE,C_LT,C_GEU,C_LTU,
         C_GE,C_LT,C_GEU,C_LTU,
         C_ANY,C_BNONE,C_ALL,C_NALL,C_BC,C_BS,
         C_ANY,C_BNONE,C_ALL,C_NALL,C_BC,C_BS,
-        C_EQZ,C_NEZ
+        C_EQZ,C_NEZ,C_LTZ,C_GEZ,
+        C_EQI,C_NEI,C_LTI,C_GEI,C_LTUI,C_GEUI
       );
       );
 
 
       TAsmConds = set of TAsmCond;
       TAsmConds = set of TAsmCond;
@@ -118,14 +119,16 @@ unit cpubase;
         'eq','ne',                         
         'eq','ne',                         
         'ge','lt','geu','ltu',
         'ge','lt','geu','ltu',
         'any','none','all','nall','bc','bs',
         'any','none','all','nall','bc','bs',
-        'eqz','nez'
+        'eqz','nez','ltz','gez',
+        'eqi','nei','lti','gei','ltui','geui'
       );
       );
 
 
       uppercond2str : array[TAsmCond] of string[4]=('',
       uppercond2str : array[TAsmCond] of string[4]=('',
         'EQ','NE',
         'EQ','NE',
         'GE','LT','GEU','LTU',
         'GE','LT','GEU','LTU',
         'ANY','NONE','ALL','NALL','BC','BS',
         'ANY','NONE','ALL','NALL','BC','BS',
-        'EQZ','NEZ'
+        'EQZ','NEZ','LTZ','GEZ',
+        'EQI','NEI','LTI','GEI','LTUI','GEUI'
       );
       );
 
 
 {*****************************************************************************
 {*****************************************************************************
@@ -355,8 +358,10 @@ unit cpubase;
         inverse: array[TAsmCond] of TAsmCond=(C_None,
         inverse: array[TAsmCond] of TAsmCond=(C_None,
           C_NE,C_EQ,
           C_NE,C_EQ,
           C_LT,C_GE,C_LTU,C_GEU,
           C_LT,C_GE,C_LTU,C_GEU,
-          C_BNONE,C_ANY,C_NALL,C_BNONE,C_BS,C_BC,C_NEZ,
-          C_EQZ
+          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
         );
         );
       begin
       begin
         result := inverse[c];
         result := inverse[c];

+ 9 - 2
compiler/xtensa/ncpuadd.pas

@@ -98,8 +98,9 @@ interface
         current_asmdata.getjumplabel(falselab);
         current_asmdata.getjumplabel(falselab);
 
 
         location_reset_jump(location,truelab,falselab);
         location_reset_jump(location,truelab,falselab);
-        force_reg_left_right(false,false);
 
 
+        hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
+                                            
         if is_signed(left.resultdef) then
         if is_signed(left.resultdef) then
           case nodetype of
           case nodetype of
             equaln:   cond:=OC_EQ;
             equaln:   cond:=OC_EQ;
@@ -123,7 +124,13 @@ interface
             internalerror(2020030801);
             internalerror(2020030801);
           end;
           end;
 
 
-        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cond,left.location.register,right.location.register,location.truelabel);
+        if right.nodetype=ordconstn then
+          cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,OS_INT,cond,right.location.value,left.location.register,location.truelabel)
+        else
+          begin
+            force_reg_left_right(false,false);
+            cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cond,left.location.register,right.location.register,location.truelabel);
+          end;                                                                                                                                
         current_asmdata.CurrAsmList.concat(taicpu.op_sym(A_J,location.falselabel));
         current_asmdata.CurrAsmList.concat(taicpu.op_sym(A_J,location.falselabel));
       end;
       end;