mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 17:29:21 +02:00
* 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 -
This commit is contained in:
parent
ee6b4762b3
commit
dba5da67af
@ -75,6 +75,13 @@ type
|
|||||||
procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1,
|
procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1,
|
||||||
reg2: tregister); override;
|
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 }
|
{ fpu move instructions }
|
||||||
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2:
|
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2:
|
||||||
tregister); override;
|
tregister); override;
|
||||||
@ -206,6 +213,16 @@ begin
|
|||||||
result := cgsize_strings[size];
|
result := cgsize_strings[size];
|
||||||
end;
|
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;
|
function is_signed_cgsize(const size : TCgSize) : Boolean;
|
||||||
begin
|
begin
|
||||||
case size of
|
case size of
|
||||||
@ -736,7 +753,7 @@ var
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
{$IFDEF EXTDEBUG}
|
{$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)));
|
list.concat(tai_comment.create(strpnew(astring)));
|
||||||
{$ENDIF EXTDEBUG}
|
{$ENDIF EXTDEBUG}
|
||||||
if not (size in [OS_8, OS_S8, OS_16, OS_S16, OS_32, OS_S32, OS_64, OS_S64]) then
|
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;
|
instr: taicpu;
|
||||||
op : tasmop;
|
op : tasmop;
|
||||||
begin
|
begin
|
||||||
|
{$ifdef extdebug}
|
||||||
|
list.concat(tai_comment.create(strpnew('a_load_reg_reg from : ' + cgsize2string(fromsize) + ' to ' + cgsize2string(tosize))));
|
||||||
|
{$endif}
|
||||||
op := movemap[fromsize, tosize];
|
op := movemap[fromsize, tosize];
|
||||||
case op of
|
case op of
|
||||||
A_MR, A_EXTSB, A_EXTSH, A_EXTSW : instr := taicpu.op_reg_reg(op, reg2, reg1);
|
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);
|
rg[R_INTREGISTER].add_move_instruction(instr);
|
||||||
end;
|
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;
|
procedure tcgppc.a_loadfpu_reg_reg(list: TAsmList; size: tcgsize;
|
||||||
reg1, reg2: tregister);
|
reg1, reg2: tregister);
|
||||||
var
|
var
|
||||||
@ -1055,6 +1112,10 @@ begin
|
|||||||
a_op_const_reg_reg(list, OP_ADD, size, -a, src, dst);
|
a_op_const_reg_reg(list, OP_ADD, size, -a, src, dst);
|
||||||
exit;
|
exit;
|
||||||
end;
|
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,
|
{ This case includes some peephole optimizations for the various operations,
|
||||||
(e.g. AND, OR, XOR, ..) - can't this be done at some higher level,
|
(e.g. AND, OR, XOR, ..) - can't this be done at some higher level,
|
||||||
independent of architecture? }
|
independent of architecture? }
|
||||||
|
@ -102,7 +102,8 @@ type
|
|||||||
A_LVX, A_STVX,
|
A_LVX, A_STVX,
|
||||||
A_MULLDO, A_MULLDO_, A_MULHDU, A_MULHDU_,
|
A_MULLDO, A_MULLDO_, A_MULHDU, A_MULHDU_,
|
||||||
A_MFXER,
|
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 }
|
{# This should define the array of instructions as string }
|
||||||
op2strtable = array[tasmop] of string[8];
|
op2strtable = array[tasmop] of string[8];
|
||||||
|
@ -92,7 +92,8 @@ const
|
|||||||
'lvx', 'stvx',
|
'lvx', 'stvx',
|
||||||
'mulldo', 'mulldo.', 'mulhdu', 'mulhdu.',
|
'mulldo', 'mulldo.', 'mulhdu', 'mulhdu.',
|
||||||
'mfxer',
|
'mfxer',
|
||||||
'fctid', 'fctid.', 'fctidz', 'fctidz.');
|
'fctid', 'fctid.', 'fctidz', 'fctidz.',
|
||||||
|
'extrdi', 'extrdi.', 'insrdi', 'insrdi.');
|
||||||
|
|
||||||
function gas_regnum_search(const s: string): Tregister;
|
function gas_regnum_search(const s: string): Tregister;
|
||||||
function gas_regname(r: Tregister): string;
|
function gas_regname(r: Tregister): string;
|
||||||
|
@ -163,12 +163,18 @@ var
|
|||||||
op: tasmop;
|
op: tasmop;
|
||||||
tmpreg: tregister;
|
tmpreg: tregister;
|
||||||
useconst: boolean;
|
useconst: boolean;
|
||||||
|
|
||||||
|
{$IFDEF EXTDEBUG}
|
||||||
|
opsize : TCgSize;
|
||||||
|
{$ENDIF EXTDEBUG}
|
||||||
|
|
||||||
begin
|
begin
|
||||||
// get the constant on the right if there is one
|
// get the constant on the right if there is one
|
||||||
if (left.location.loc = LOC_CONSTANT) then
|
if (left.location.loc = LOC_CONSTANT) then
|
||||||
swapleftright;
|
swapleftright;
|
||||||
|
|
||||||
{$IFDEF EXTDEBUG}
|
{$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]))));
|
current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('tppcaddnode.emit_compare ' + inttostr(ord(opsize)) + ' ' + inttostr(tcgsize2size[opsize]))));
|
||||||
{$ENDIF EXTDEBUG}
|
{$ENDIF EXTDEBUG}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user