فهرست منبع

+ avr flag and condition handling

git-svn-id: trunk@17016 -
florian 14 سال پیش
والد
کامیت
ef699b1864
4فایلهای تغییر یافته به همراه73 افزوده شده و 47 حذف شده
  1. 1 1
      compiler/avr/aasmcpu.pas
  2. 44 22
      compiler/avr/cgcpu.pas
  3. 17 16
      compiler/avr/cpubase.pas
  4. 11 8
      compiler/avr/navradd.pas

+ 1 - 1
compiler/avr/aasmcpu.pas

@@ -138,7 +138,7 @@ implementation
          inherited create(op);
          ops:=2;
          loadreg(0,_op1);
-         loadconst(1,_op2);
+         loadconst(1,aint(_op2));
       end;
 
      constructor taicpu.op_const_reg(op:tasmop; _op1: LongInt; _op2: tregister);

+ 44 - 22
compiler/avr/cgcpu.pas

@@ -86,7 +86,6 @@ unit cgcpu;
         procedure g_concatcopy_internal(list : TAsmList;const source,dest : treference;len : aint;aligned : boolean);
 
         procedure g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef); override;
-        procedure g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);override;
 
 //        procedure g_save_registers(list : TAsmList);override;
 //        procedure g_restore_registers(list : TAsmList);override;
@@ -113,9 +112,6 @@ unit cgcpu;
     procedure create_codegen;
 
     const
-      OpCmp2AsmCond : Array[topcmp] of TAsmCond = (C_NONE,C_EQ,C_GT,
-                           C_LT,C_GE,C_LE,C_NE,C_LS,C_CC,C_CS,C_HI);
-
       TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_NONE,A_MOV,A_ADD,A_AND,A_NONE,
                             A_NONE,A_MUL,A_MULS,A_NEG,A_COM,A_OR,
                             A_ASR,A_LSL,A_LSR,A_SUB,A_EOR,A_ROL,A_ROR);
@@ -401,6 +397,7 @@ unit cgcpu;
                  end
                else
              end;
+
            OP_SUB:
              begin
                if src<>dst then
@@ -417,6 +414,7 @@ unit cgcpu;
                      end;
                  end;
              end;
+
            OP_NEG:
              begin
                if src<>dst then
@@ -441,6 +439,7 @@ unit cgcpu;
                else
                  list.concat(taicpu.op_reg(A_NEG,dst));
              end;
+
            OP_NOT:
              begin
                for i:=1 to tcgsize2size[size] do
@@ -452,6 +451,7 @@ unit cgcpu;
                    dst:=GetNextReg(dst);
                  end;
              end;
+
            OP_MUL,OP_IMUL:
              begin
                if size in [OS_8,OS_S8] then
@@ -459,20 +459,17 @@ unit cgcpu;
                else
                  internalerror(2011022002);
              end;
+
            OP_DIV,OP_IDIV:
              { special stuff, needs separate handling inside code }
              { generator                                          }
              internalerror(2011022001);
-{!!!!
+
            OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
              begin
-               { Use ecx to load the value, that allows better coalescing }
-               getcpuregister(list,NR_ECX);
-               a_load_reg_reg(list,size,OS_32,src,NR_ECX);
-               list.concat(taicpu.op_reg_reg(Topcg2asmop[op],tcgsize2opsize[size],NR_CL,dst));
-               ungetcpuregister(list,NR_ECX);
+               {!!!!!!!}
              end;
-}
+
            OP_AND,OP_OR,OP_XOR:
              begin
                if src<>dst then
@@ -501,7 +498,7 @@ unit cgcpu;
          shift:=0;
          for i:=1 to tcgsize2size[size] do
            begin
-             list.concat(taicpu.op_reg_const(A_LDI,reg,(a and mask) shr shift));
+             list.concat(taicpu.op_reg_const(A_LDI,reg,(qword(a) and mask) shr shift));
              mask:=mask shl 8;
              inc(shift,8);
              reg:=GetNextReg(reg);
@@ -1129,6 +1126,7 @@ unit cgcpu;
         current_asmdata.getjumplabel(l);
         if len>16 then
           begin
+            {!!!!!!! load refs!}
             copysize:=OS_8;
             if len<256 then
               countregsize:=OS_8
@@ -1177,16 +1175,26 @@ unit cgcpu;
 
     procedure tcgavr.g_overflowCheck(list : TAsmList;const l : tlocation;def : tdef);
       var
-        ovloc : tlocation;
+        hl : tasmlabel;
+        ai : taicpu;
+        cond : TAsmCond;
       begin
-        ovloc.loc:=LOC_VOID;
-        g_overflowCheck_loc(list,l,def,ovloc);
-      end;
-
+        if not(cs_check_overflow in current_settings.localswitches) then
+         exit;
+        current_asmdata.getjumplabel(hl);
+        if not ((def.typ=pointerdef) or
+               ((def.typ=orddef) and
+                (torddef(def).ordtype in [u64bit,u16bit,u32bit,u8bit,uchar,pasbool]))) then
+          cond:=C_VC
+        else
+          cond:=C_CC;
+        ai:=Taicpu.Op_Sym(A_BRxx,hl);
+        ai.SetCondition(cond);
+        ai.is_jmp:=true;
+        list.concat(ai);
 
-    procedure tcgavr.g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);
-      begin
-        internalerror(2011021322);
+        a_call_name(list,'FPC_OVERFLOW',false);
+        a_label(list,hl);
       end;
 
 
@@ -1194,10 +1202,24 @@ unit cgcpu;
       var
         ai : taicpu;
       begin
+      {!!!!!
         ai:=Taicpu.Op_sym(A_BRxx,l);
-        ai.SetCondition(OpCmp2AsmCond[cond]);
+        case cond of
+          OC_EQ:
+            ai.SetCondition(C_EQ);
+          OC_GT
+          OC_LT
+          OC_GTE
+          OC_LTE
+          OC_NE
+          OC_BE
+          OC_B
+          OC_AE
+          OC_A:
+
         ai.is_jmp:=true;
         list.concat(ai);
+        }
       end;
 
 
@@ -1211,7 +1233,7 @@ unit cgcpu;
       var
          instr: taicpu;
       begin
-       instr:=taicpu.op_reg_reg(A_MOV, reg2, reg1);
+       instr:=taicpu.op_reg_reg(A_MOV,reg2,reg1);
        list.Concat(instr);
        { Notify the register allocator that we have written a move instruction so
          it can try to eliminate it. }

+ 17 - 16
compiler/avr/cpubase.pas

@@ -133,19 +133,19 @@ unit cpubase;
 
     type
       TAsmCond=(C_None,
-        C_EQ,C_NE,C_CS,C_CC,C_MI,C_PL,C_VS,C_VC,C_HI,C_LS,
-        C_GE,C_LT,C_GT,C_LE,C_AL,C_NV
+        C_CC,C_CS,C_EQ,C_GE,C_HC,C_HS,C_ID,C_IE,C_LO,C_LT,
+        C_MI,C_NE,C_PL,C_SH,C_TC,C_TS,C_VC,C_VS
       );
 
     const
       cond2str : array[TAsmCond] of string[2]=('',
-        'eq','ne','cs','cc','mi','pl','vs','vc','hi','ls',
-        'ge','lt','gt','le','al','nv'
+        'cc','cs','eq','ge','hc','hs','id','ie','lo','lt',
+        'mi','ne','pl','sh','tc','ts','vc','vs'
       );
 
       uppercond2str : array[TAsmCond] of string[2]=('',
-        'EQ','NE','CS','CC','MI','PL','VS','VC','HI','LS',
-        'GE','LT','GT','LE','AL','NV'
+        'CC','CS','EQ','GE','HC','HS','ID','IE','LO','LT',
+        'MI','NE','PL','SH','TC','TS','VC','VS'
       );
 
 {*****************************************************************************
@@ -153,8 +153,8 @@ unit cpubase;
 *****************************************************************************}
 
     type
-      TResFlags = (F_EQ,F_NE,F_CS,F_CC,F_MI,F_PL,F_VS,F_VC,F_HI,F_LS,
-        F_GE,F_LT,F_GT,F_LE);
+      TResFlags = (F_NotPossible,F_CC,F_CS,F_EQ,F_GE,F_LO,F_LT,
+        F_NE,F_SH,F_VC,F_VS);
 
 {*****************************************************************************
                                 Operands
@@ -383,8 +383,8 @@ unit cpubase;
     procedure inverse_flags(var f: TResFlags);
       const
         inv_flags: array[TResFlags] of TResFlags =
-          (F_NE,F_EQ,F_CC,F_CS,F_PL,F_MI,F_VC,F_VS,F_LS,F_HI,
-          F_LT,F_GE,F_LE,F_GT);
+          (F_NotPossible,F_CS,F_CC,F_NE,F_LT,F_SH,F_GE,
+           F_NE,F_LO,F_VS,F_VC);
       begin
         f:=inv_flags[f];
       end;
@@ -392,10 +392,12 @@ unit cpubase;
 
     function flags_to_cond(const f: TResFlags) : TAsmCond;
       const
-        flag_2_cond: array[F_EQ..F_LE] of TAsmCond =
-          (C_EQ,C_NE,C_CS,C_CC,C_MI,C_PL,C_VS,C_VC,C_HI,C_LS,
-           C_GE,C_LT,C_GT,C_LE);
+        flag_2_cond: array[F_CC..F_VS] of TAsmCond =
+          (C_CC,C_CS,C_EQ,C_GE,C_LO,C_LT,
+           C_NE,C_SH,C_VC,C_VS);
       begin
+        if f=F_NotPossible then
+          internalerror(2011022101);
         if f>high(flag_2_cond) then
           internalerror(200112301);
         result:=flag_2_cond[f];
@@ -429,9 +431,8 @@ unit cpubase;
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
       const
         inverse: array[TAsmCond] of TAsmCond=(C_None,
-          C_NE,C_EQ,C_CC,C_CS,C_PL,C_MI,C_VC,C_VS,C_LS,C_HI,
-          C_LT,C_GE,C_LE,C_GT,C_None,C_None
-        );
+          C_CS,C_CC,C_NE,C_LT,C_HS,C_HC,C_IE,C_ID,C_SH,C_GE,
+          C_PL,C_EQ,C_MI,C_LO,C_TS,C_TC,C_VS,C_VC);
       begin
         result := inverse[c];
       end;

+ 11 - 8
compiler/avr/navradd.pas

@@ -70,22 +70,22 @@ interface
                 if nf_swapped in flags then
                   case NodeType of
                     ltn:
-                      GetResFlags:=F_GT;
+                      GetResFlags:=F_NotPossible;
                     lten:
                       GetResFlags:=F_GE;
                     gtn:
                       GetResFlags:=F_LT;
                     gten:
-                      GetResFlags:=F_LE;
+                      GetResFlags:=F_NotPossible;
                   end
                 else
                   case NodeType of
                     ltn:
                       GetResFlags:=F_LT;
                     lten:
-                      GetResFlags:=F_LE;
+                      GetResFlags:=F_NotPossible;
                     gtn:
-                      GetResFlags:=F_GT;
+                      GetResFlags:=F_NotPossible;
                     gten:
                       GetResFlags:=F_GE;
                   end;
@@ -95,22 +95,22 @@ interface
                 if nf_swapped in Flags then
                   case NodeType of
                     ltn:
-                      GetResFlags:=F_HI;
+                      GetResFlags:=F_NotPossible;
                     lten:
                       GetResFlags:=F_CS;
                     gtn:
                       GetResFlags:=F_CC;
                     gten:
-                      GetResFlags:=F_LS;
+                      GetResFlags:=F_NotPossible;
                   end
                 else
                   case NodeType of
                     ltn:
                       GetResFlags:=F_CC;
                     lten:
-                      GetResFlags:=F_LS;
+                      GetResFlags:=F_NotPossible;
                     gtn:
-                      GetResFlags:=F_HI;
+                      GetResFlags:=F_NotPossible;
                     gten:
                       GetResFlags:=F_CS;
                   end;
@@ -173,6 +173,9 @@ interface
         unsigned:=not(is_signed(left.resultdef)) or
                   not(is_signed(right.resultdef));
 
+        if getresflags(unsigned)=F_NotPossible then
+          swapleftright;
+
         current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,right.location.register));
         tmpreg1:=left.location.register;
         tmpreg2:=right.location.register;