浏览代码

* initial support for subregister loading (ppc64 specific part only)
+ added EXTRDI and INSRDI opcode
* lots of additional debug code when EXTDEBUG enabled

git-svn-id: trunk@3724 -

tom_at_work 19 年之前
父节点
当前提交
dba5da67af
共有 4 个文件被更改,包括 72 次插入3 次删除
  1. 62 1
      compiler/powerpc64/cgcpu.pas
  2. 2 1
      compiler/powerpc64/cpubase.pas
  3. 2 1
      compiler/powerpc64/itcpugas.pas
  4. 6 0
      compiler/powerpc64/nppcadd.pas

+ 62 - 1
compiler/powerpc64/cgcpu.pas

@@ -75,6 +75,13 @@ type
     procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1,
       reg2: tregister); override;
 
+    procedure a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize;
+      startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister); override;
+    procedure a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize, 
+      subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister); override;
+    procedure a_load_const_subsetreg(list: TAsmlist; subsetregsize, subsetsize: tcgsize;
+      startbit: byte; a: aint; subsetreg: tregister); override;
+
     { fpu move instructions }
     procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2:
       tregister); override;
@@ -206,6 +213,16 @@ begin
   result := cgsize_strings[size];
 end;
 
+function cgop2string(const op : TOpCg) : String;
+const
+  opcg_strings : array[TOpCg] of string[6] = (
+    'None', 'Move', 'Add', 'And', 'Div', 'IDiv', 'IMul', 'Mul',
+    'Neg', 'Not', 'Or', 'Sar', 'Shl', 'Shr', 'Sub', 'Xor'
+  );
+begin
+  result := opcg_strings[op];
+end;
+
 function is_signed_cgsize(const size : TCgSize) : Boolean;
 begin
   case size of
@@ -736,7 +753,7 @@ var
 
 begin
   {$IFDEF EXTDEBUG}
-  astring := 'a_load_const_reg ' + inttostr(hi(a)) + ' ' + inttostr(lo(a)) + ' ' + inttostr(ord(size)) + ' ' + inttostr(tcgsize2size[size]);
+  astring := 'a_load_const_reg ' + inttostr(hi(a)) + ' ' + inttostr(lo(a)) + ' ' + inttostr(ord(size)) + ' ' + inttostr(tcgsize2size[size]) + ' ' + hexstr(a, 16);
   list.concat(tai_comment.create(strpnew(astring)));
   {$ENDIF EXTDEBUG}
   if not (size in [OS_8, OS_S8, OS_16, OS_S16, OS_32, OS_S32, OS_64, OS_S64]) then
@@ -852,6 +869,9 @@ var
   instr: taicpu;
   op : tasmop;
 begin
+  {$ifdef extdebug}
+  list.concat(tai_comment.create(strpnew('a_load_reg_reg from : ' + cgsize2string(fromsize) + ' to ' + cgsize2string(tosize))));
+  {$endif}
   op := movemap[fromsize, tosize];
   case op of
     A_MR, A_EXTSB, A_EXTSH, A_EXTSW : instr := taicpu.op_reg_reg(op, reg2, reg1);
@@ -863,6 +883,43 @@ begin
   rg[R_INTREGISTER].add_move_instruction(instr);
 end;
 
+procedure tcgppc.a_load_subsetreg_reg(list : TAsmList; subsetregsize, subsetsize: tcgsize;
+  startbit: byte; tosize: tcgsize; subsetreg, destreg: tregister);
+var
+  total : byte;
+begin
+  {$ifdef extdebug}
+  list.concat(tai_comment.create(strpnew('a_load_subsetreg_reg subsetregsize = ' + cgsize2string(subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + intToStr(startbit) + ' tosize = ' + cgsize2string(tosize))));
+  {$endif}
+  total := tcgsize2size[subsetsize]*8 + startbit and 63;
+  if (total <> 64) then begin
+    list.concat(taicpu.op_reg_reg_const_const(A_EXTRDI, destreg, subsetreg, tcgsize2size[subsetsize]*8, startbit and 63));
+  end else
+    a_load_reg_reg(list, subsetsize, tosize, subsetreg, destreg);
+
+  // extend sign (actually only required for signed subsets...) and if that subset isn't >= real size
+  a_load_reg_reg(list, subsetsize, tosize, destreg, destreg);
+end;
+
+procedure tcgppc.a_load_reg_subsetreg(list : TAsmList; fromsize: tcgsize; subsetregsize, 
+  subsetsize: tcgsize; startbit: byte; fromreg, subsetreg: tregister);
+begin
+  {$ifdef extdebug}
+  list.concat(tai_comment.create(strpnew('a_load_reg_subsetreg')));
+  {$endif}
+  list.concat(taicpu.op_reg_reg_const_const(A_INSRDI, subsetreg, fromreg, tcgsize2size[subsetsize]*8, startbit and 63));
+end;
+
+procedure tcgppc.a_load_const_subsetreg(list: TAsmlist; subsetregsize, subsetsize: tcgsize;
+  startbit: byte; a: aint; subsetreg: tregister);
+begin
+  {$ifdef extdebug}
+  list.concat(tai_comment.create(strpnew('a_load_const_subsetreg subsetregsize = ' + cgsize2string(subsetregsize) + ' subsetsize = ' + cgsize2string(subsetsize) + ' startbit = ' + intToStr(startbit) + ' a = ' + intToStr(a))));
+  {$endif}
+  // use the default method because it is optimal anyway
+  inherited;
+end;
+
 procedure tcgppc.a_loadfpu_reg_reg(list: TAsmList; size: tcgsize;
   reg1, reg2: tregister);
 var
@@ -1055,6 +1112,10 @@ begin
     a_op_const_reg_reg(list, OP_ADD, size, -a, src, dst);
     exit;
   end;
+  {$IFDEF EXTDEBUG}
+  list.concat(tai_comment.create(strpnew('a_op_const_reg_reg ' + cgop2string(op))));
+  {$ENDIF EXTDEBUG}
+
   { This case includes some peephole optimizations for the various operations,
    (e.g. AND, OR, XOR, ..) - can't this be done at some higher level,
    independent of architecture? }

+ 2 - 1
compiler/powerpc64/cpubase.pas

@@ -102,7 +102,8 @@ type
     A_LVX, A_STVX,
     A_MULLDO, A_MULLDO_, A_MULHDU, A_MULHDU_,
     A_MFXER,
-    A_FCTID, A_FCTID_, A_FCTIDZ, A_FCTIDZ_);
+    A_FCTID, A_FCTID_, A_FCTIDZ, A_FCTIDZ_,
+    A_EXTRDI, A_EXTRDI_, A_INSRDI, A_INSRDI_);
 
   {# This should define the array of instructions as string }
   op2strtable = array[tasmop] of string[8];

+ 2 - 1
compiler/powerpc64/itcpugas.pas

@@ -92,7 +92,8 @@ const
     'lvx', 'stvx',
     'mulldo', 'mulldo.', 'mulhdu', 'mulhdu.',
     'mfxer',
-    'fctid', 'fctid.', 'fctidz', 'fctidz.');
+    'fctid', 'fctid.', 'fctidz', 'fctidz.',
+    'extrdi', 'extrdi.', 'insrdi', 'insrdi.');
 
 function gas_regnum_search(const s: string): Tregister;
 function gas_regname(r: Tregister): string;

+ 6 - 0
compiler/powerpc64/nppcadd.pas

@@ -163,12 +163,18 @@ var
   op: tasmop;
   tmpreg: tregister;
   useconst: boolean;
+
+  {$IFDEF EXTDEBUG}
+  opsize : TCgSize;
+  {$ENDIF EXTDEBUG}
+
 begin
   // get the constant on the right if there is one
   if (left.location.loc = LOC_CONSTANT) then
     swapleftright;
 
   {$IFDEF EXTDEBUG}
+  opsize := def_cgsize(left.resulttype.def);
   current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('tppcaddnode.emit_compare ' + inttostr(ord(opsize)) + ' ' + inttostr(tcgsize2size[opsize]))));
   {$ENDIF EXTDEBUG}