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

+ tarmcasenode.genjmptreeentry

git-svn-id: trunk@35649 -
florian 8 лет назад
Родитель
Сommit
971280f082
1 измененных файлов с 69 добавлено и 5 удалено
  1. 69 5
      compiler/arm/narmset.pas

+ 69 - 5
compiler/arm/narmset.pas

@@ -26,7 +26,7 @@ unit narmset;
 interface
 
     uses
-      globtype,
+      globtype,constexp,
       symtype,
       cgbase,
       node,nset,pass_1,ncgset;
@@ -45,13 +45,14 @@ interface
          function  has_jumptable : boolean;override;
          procedure genjumptable(hp : pcaselabel;min_,max_ : aint);override;
          procedure genlinearlist(hp : pcaselabel);override;
+         procedure genjmptreeentry(p : pcaselabel;parentvalue : TConstExprInt);override;
       end;
 
 
 implementation
 
     uses
-      verbose,globals,constexp,defutil,systems,
+      verbose,globals,defutil,systems,
       aasmbase,aasmtai,aasmdata,aasmcpu,
       cpubase,cpuinfo,
       cgutils,cgobj,ncgutil,
@@ -244,14 +245,14 @@ implementation
             reference_reset(href,0,[]);
             href.base:=basereg;
             href.index:=indexreg;
-            
+
             tmpreg:=cg.getintregister(current_asmdata.CurrAsmList, OS_ADDR);
             cg.a_load_ref_reg(current_asmdata.CurrAsmList, OS_ADDR, OS_ADDR, href, tmpreg);
-            
+
             { do not use BX here to avoid switching into arm mode }
             current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_MOV, NR_PC, tmpreg));
 
-            current_asmdata.CurrAsmList.Concat(tai_align.Create(4));                
+            current_asmdata.CurrAsmList.Concat(tai_align.Create(4));
             cg.a_label(current_asmdata.CurrAsmList,tablelabel);
             { generate jump table }
             last:=min_;
@@ -394,6 +395,69 @@ implementation
              end;
         end;
 
+
+      procedure tarmcasenode.genjmptreeentry(p : pcaselabel;parentvalue : TConstExprInt);
+        var
+          lesslabel,greaterlabel : tasmlabel;
+          less,greater : pcaselabel;
+          cond_gt: TResFlags;
+          cmplow : Boolean;
+        begin
+           if with_sign then
+             cond_gt:=F_GT
+           else
+             cond_gt:=F_HI;
+          current_asmdata.CurrAsmList.concat(cai_align.Create(current_settings.alignment.jumpalign));
+          cg.a_label(current_asmdata.CurrAsmList,p^.labellabel);
+
+          { calculate labels for left and right }
+          if p^.less=nil then
+            lesslabel:=elselabel
+          else
+            lesslabel:=p^.less^.labellabel;
+          if p^.greater=nil then
+            greaterlabel:=elselabel
+          else
+            greaterlabel:=p^.greater^.labellabel;
+
+          { calculate labels for left and right }
+          { no range label: }
+          if p^._low=p^._high then
+            begin
+               if greaterlabel=lesslabel then
+                 begin
+                   if p^._low-1<>parentvalue then
+                     hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,OC_NE,p^._low,hregister,lesslabel);
+                 end
+               else
+                 begin
+                   cmplow:=p^._low-1<>parentvalue;
+                   if cmplow then
+                     hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,jmp_lt,p^._low,hregister,lesslabel);
+                   if p^._high+1<>parentvalue then
+                     begin
+                       if cmplow then
+                         hlcg.a_jmp_flags(current_asmdata.CurrAsmList,cond_gt,greaterlabel)
+                       else
+                         hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,jmp_gt,p^._low,hregister,greaterlabel);
+                     end;
+                 end;
+               hlcg.a_jmp_always(current_asmdata.CurrAsmList,blocklabel(p^.blockid));
+            end
+          else
+            begin
+              if p^._low-1<>parentvalue then
+                hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,jmp_lt,p^._low,hregister,lesslabel);
+              if p^._high+1<>parentvalue then
+                hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,jmp_gt,p^._high,hregister,greaterlabel);
+              hlcg.a_jmp_always(current_asmdata.CurrAsmList,blocklabel(p^.blockid));
+            end;
+           if assigned(p^.less) then
+             genjmptreeentry(p^.less,p^._low);
+           if assigned(p^.greater) then
+             genjmptreeentry(p^.greater,p^._high);
+        end;
+
 begin
   cinnode:=tarminnode;
   ccasenode:=tarmcasenode;