فهرست منبع

Merged revisions 8283,8285,8311,8413,8643,8674 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/trunk

........
r8283 | jonas | 2007-08-14 16:17:09 +0200 (Tue, 14 Aug 2007) | 3 lines

* slightly optimized ppc jumptable code (one compare+jump replaced
by a subtraction)

........
r8285 | jonas | 2007-08-14 19:32:24 +0200 (Tue, 14 Aug 2007) | 2 lines

+ jumptable support for darwin/ppc64

........
r8311 | jonas | 2007-08-26 13:15:14 +0200 (Sun, 26 Aug 2007) | 5 lines

* fixed bug in ppc jumptable generation for case statements with
negative cases caused by wrong automatic type conversion from
longint to unsigned tconstexprint (+ test for such jump tables)
* fixed darwin/ppc64 jumptables in case of jmptablenorange

........
r8413 | jonas | 2007-09-09 00:52:12 +0200 (Sun, 09 Sep 2007) | 2 lines

* upped recordalignmax for darwin/ppc and darwin/ppc64 a bit

........
r8643 | jonas | 2007-09-25 19:56:23 +0200 (Tue, 25 Sep 2007) | 3 lines

* changed darwin/ppc32 jumptable code to be the same as the darwin/ppc64
code, because that's also what gcc does in all cases and it's pic-safe

........
r8674 | jonas | 2007-09-29 01:00:58 +0200 (Sat, 29 Sep 2007) | 3 lines

* use the gcc jumptable scheme for all ppc targets instead of only for
darwin

........

git-svn-id: branches/fixes_2_2@8895 -

Jonas Maebe 18 سال پیش
والد
کامیت
8941397c29
4فایلهای تغییر یافته به همراه78 افزوده شده و 26 حذف شده
  1. 1 0
      .gitattributes
  2. 33 24
      compiler/ppcgen/ngppcset.pas
  3. 2 2
      compiler/systems/i_bsd.pas
  4. 42 0
      tests/test/cg/tcase2.pp

+ 1 - 0
.gitattributes

@@ -6597,6 +6597,7 @@ tests/test/cg/tcalvar7.pp svneol=native#text/plain
 tests/test/cg/tcalvar8.pp svneol=native#text/plain
 tests/test/cg/tcalvar9.pp svneol=native#text/plain
 tests/test/cg/tcase.pp svneol=native#text/plain
+tests/test/cg/tcase2.pp svneol=native#text/plain
 tests/test/cg/tclacla1.pp svneol=native#text/plain
 tests/test/cg/tclasize.pp svneol=native#text/plain
 tests/test/cg/tclatype.pp svneol=native#text/plain

+ 33 - 24
compiler/ppcgen/ngppcset.pas

@@ -65,7 +65,7 @@ implementation
 
     function tgppccasenode.has_jumptable : boolean;
       begin
-        has_jumptable:=(target_info.system <> system_powerpc64_darwin);
+        has_jumptable:=true;
       end;
 
 
@@ -75,10 +75,11 @@ implementation
         last : TConstExprInt;
         indexreg : tregister;
         href : treference;
+        mulfactor: longint;
 
         procedure genitem(list:TAsmList;t : pcaselabel);
           var
-            i : aint;
+            i : TConstExprInt;
           begin
             if assigned(t^.less) then
               genitem(list,t^.less);
@@ -86,14 +87,14 @@ implementation
             i:=last+1;
             while i<=t^._low-1 do
               begin
-                list.concat(Tai_const.Create_sym(elselabel));
-                inc(i);
+                list.concat(Tai_const.Create_rel_sym(aitconst_32bit,table,elselabel));
+                i:=i+1;
               end;
             i:=t^._low;
             while i<=t^._high do
               begin
-                list.concat(Tai_const.Create_sym(blocklabel(t^.blockid)));
-                inc(i);
+                list.concat(Tai_const.Create_rel_sym(aitconst_32bit,table,blocklabel(t^.blockid)));
+                i:=i+1;
               end;
             last:=t^._high;
             if assigned(t^.greater) then
@@ -101,34 +102,42 @@ implementation
           end;
 
       begin
-        if not(jumptable_no_range) then
-          begin
-             { case expr less than min_ => goto elselabel }
-             cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,jmp_lt,aint(min_),hregister,elselabel);
-             { case expr greater than max_ => goto elselabel }
-             cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,jmp_gt,aint(max_),hregister,elselabel);
-          end;
-        current_asmdata.getjumplabel(table);
+        last:=min_;
         { make it a 32bit register }
         // allocate base and index registers register
         indexreg:= cg.makeregsize(current_asmdata.CurrAsmList, hregister, OS_INT);
         { indexreg := hregister; }
         cg.a_load_reg_reg(current_asmdata.CurrAsmList, opsize, OS_INT, hregister, indexreg);
-        { create reference, indexreg := indexreg * sizeof(OS_ADDR) }
-        cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_MUL, OS_INT, tcgsize2size[OS_ADDR], indexreg);
-        reference_reset_symbol(href, table, (-aint(min_)) * tcgsize2size[OS_ADDR]);
-        href.index := indexreg;
-
-        cg.a_load_ref_reg(current_asmdata.CurrAsmList, OS_INT, OS_INT, href, indexreg);
+        if not(jumptable_no_range) then
+          begin
+             { use aword(value-min)<aword(max-min) instead of two comparisons }
+             { case expr outside min_ .. max_ => goto elselabel               }
+             cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SUB,OS_INT,aint(min_),indexreg);
+             { this trick requires an unsigned comparison in all cases }
+             cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_A,aint(max_)-aint(min_),indexreg,elselabel);
+             { already taken into account now }
+             min_:=0;
+          end;
+        current_asmdata.getjumplabel(table);
+        { create reference, indexreg := indexreg * sizeof(jtentry) (= 4) }
+        mulfactor:=4;
+        cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_MUL, OS_INT, mulfactor, indexreg);
+        reference_reset_symbol(href, table, (-aint(min_)) * mulfactor);
+
+        hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
+        cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href,hregister);
+        reference_reset_base(href,hregister,0);
+        href.index:=indexreg;
+        indexreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
+        cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_S32,OS_ADDR,href,indexreg);
+        cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR,hregister,indexreg);
 
         current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_MTCTR, indexreg));
         current_asmdata.CurrAsmList.concat(taicpu.op_none(A_BCTR));
 
         { generate jump table }
-        new_section(current_procinfo.aktlocaldata,sec_rodata,current_procinfo.procdef.mangledname,sizeof(aint));
-        current_procinfo.aktlocaldata.concat(Tai_label.Create(table));
-        last:=min_;
-        genitem(current_procinfo.aktlocaldata,hp);
+        current_asmdata.CurrAsmList.concat(Tai_label.Create(table));
+        genitem(current_asmdata.CurrAsmList,hp);
       end;
 
 

+ 2 - 2
compiler/systems/i_bsd.pas

@@ -445,7 +445,7 @@ unit i_bsd;
                 localalignmin   : 0;
                 localalignmax   : 4;
                 recordalignmin  : 0;
-                recordalignmax  : 2;
+                recordalignmax  : 4;
                 maxCrecordalign : 4
               );
             first_parm_offset : 24;
@@ -566,7 +566,7 @@ unit i_bsd;
                 localalignmin   : 4;
                 localalignmax   : 8;
                 recordalignmin  : 0;
-                recordalignmax  : 2;
+                recordalignmax  : 8;
                 maxCrecordalign : 8
               );
             first_parm_offset : 48;

+ 42 - 0
tests/test/cg/tcase2.pp

@@ -0,0 +1,42 @@
+    const
+       maxsmallint = high(smallint);
+       { error codes }
+       grOk =  0;
+       grNoInitGraph = -1;
+       grNotDetected = -2;
+       grFileNotFound = -3;
+       grInvalidDriver = -4;
+       grNoLoadMem = -5;
+       grNoScanMem = -6;
+       grNoFloodMem = -7;
+       grFontNotFound = -8;
+       grNoFontMem = -9;
+       grInvalidMode = -10;
+       grError = -11;
+       grIOerror = -12;
+       grInvalidFont = -13;
+       grInvalidFontNum = -14;
+       grInvalidVersion = -18;
+
+function GraphErrorMsg(ErrorCode: smallint): string;
+Begin
+ GraphErrorMsg:='';
+ case ErrorCode of
+  grOk,grFileNotFound,grInvalidDriver: exit;
+  grNoInitGraph: GraphErrorMsg:='Graphics driver not installed';
+  grNotDetected: GraphErrorMsg:='Graphics hardware not detected';
+  grNoLoadMem,grNoScanMem,grNoFloodMem: GraphErrorMsg := 'Not enough memory for graphics';
+  grNoFontMem: GraphErrorMsg := 'Not enough memory to load font';
+  grFontNotFound: GraphErrorMsg:= 'Font file not found';
+  grInvalidMode: GraphErrorMsg := 'Invalid graphics mode';
+  grError: GraphErrorMsg:='Graphics error';
+  grIoError: GraphErrorMsg:='Graphics I/O error';
+  grInvalidFont,grInvalidFontNum: GraphErrorMsg := 'Invalid font';
+  grInvalidVersion: GraphErrorMsg:='Invalid driver version';
+ end;
+end;
+
+begin
+  if GraphErrorMsg(grNoInitGraph) <> 'Graphics driver not installed' then
+    halt(1);
+end.