mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-15 10:59:34 +01:00
m68k: support 32x32 to 64bit MUL generation when targeting CPUs which support this instruction
git-svn-id: trunk@36339 -
This commit is contained in:
parent
f5d17b2884
commit
87e8010f05
@ -65,8 +65,10 @@ type
|
|||||||
{ this is only allowed if _op1 is an int value (_op1^.isintvalue=true) }
|
{ this is only allowed if _op1 is an int value (_op1^.isintvalue=true) }
|
||||||
constructor op_ref_ref(op : tasmop;_size : topsize;_op1,_op2 : treference);
|
constructor op_ref_ref(op : tasmop;_size : topsize;_op1,_op2 : treference);
|
||||||
|
|
||||||
{ this is used for divx/remx regpair generation }
|
{ this is used for mulx/divx/remx regpair generation }
|
||||||
constructor op_reg_reg_reg(op : tasmop;_size : topsize;_op1,_op2,_op3 : tregister);
|
constructor op_reg_reg_reg(op : tasmop;_size : topsize;_op1,_op2,_op3 : tregister);
|
||||||
|
constructor op_const_reg_reg(op : tasmop;_size : topsize;_op1 : longint; _op2,_op3 : tregister);
|
||||||
|
constructor op_ref_reg_reg(op : tasmop;_size : topsize;_op1 : treference; _op2,_op3 : tregister);
|
||||||
|
|
||||||
constructor op_reg_regset(op: tasmop; _size : topsize; _op1: tregister;const _op2data,_op2addr,_op2fpu: tcpuregisterset);
|
constructor op_reg_regset(op: tasmop; _size : topsize; _op1: tregister;const _op2data,_op2addr,_op2fpu: tcpuregisterset);
|
||||||
constructor op_regset_reg(op: tasmop; _size : topsize;const _op1data,_op1addr,_op1fpu: tcpuregisterset; _op2: tregister);
|
constructor op_regset_reg(op: tasmop; _size : topsize;const _op1data,_op1addr,_op1fpu: tcpuregisterset; _op2: tregister);
|
||||||
@ -321,6 +323,26 @@ type
|
|||||||
loadreg(2,_op3);
|
loadreg(2,_op3);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
constructor taicpu.op_const_reg_reg(op : tasmop;_size : topsize;_op1 : longint; _op2,_op3 : tregister);
|
||||||
|
begin
|
||||||
|
inherited create(op);
|
||||||
|
init(_size);
|
||||||
|
ops:=3;
|
||||||
|
loadconst(0,aword(_op1));
|
||||||
|
loadreg(1,_op2);
|
||||||
|
loadreg(2,_op3);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor taicpu.op_ref_reg_reg(op : tasmop;_size : topsize;_op1 : treference; _op2,_op3 : tregister);
|
||||||
|
begin
|
||||||
|
inherited create(op);
|
||||||
|
init(_size);
|
||||||
|
ops:=3;
|
||||||
|
loadref(0,_op1);
|
||||||
|
loadreg(1,_op2);
|
||||||
|
loadreg(2,_op3);
|
||||||
|
end;
|
||||||
|
|
||||||
constructor taicpu.op_ref_regset(op: tasmop; _size : topsize; _op1: treference;const _op2data,_op2addr,_op2fpu: tcpuregisterset);
|
constructor taicpu.op_ref_regset(op: tasmop; _size : topsize; _op1: treference;const _op2data,_op2addr,_op2fpu: tcpuregisterset);
|
||||||
Begin
|
Begin
|
||||||
inherited create(op);
|
inherited create(op);
|
||||||
|
|||||||
@ -37,6 +37,7 @@ interface
|
|||||||
procedure second_mul64bit;
|
procedure second_mul64bit;
|
||||||
protected
|
protected
|
||||||
function use_generic_mul64bit: boolean; override;
|
function use_generic_mul64bit: boolean; override;
|
||||||
|
function use_generic_mul32to64: boolean; override;
|
||||||
procedure second_addfloat;override;
|
procedure second_addfloat;override;
|
||||||
procedure second_cmpfloat;override;
|
procedure second_cmpfloat;override;
|
||||||
procedure second_addordinal;override;
|
procedure second_addordinal;override;
|
||||||
@ -359,8 +360,13 @@ implementation
|
|||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
procedure t68kaddnode.second_addordinal;
|
procedure t68kaddnode.second_addordinal;
|
||||||
|
const
|
||||||
|
mul_op_signed: array[boolean] of tasmop = ( A_MULU, A_MULS );
|
||||||
var
|
var
|
||||||
cgop : topcg;
|
cgop : topcg;
|
||||||
|
asmop : tasmop;
|
||||||
|
list : tasmlist;
|
||||||
|
href : treference;
|
||||||
begin
|
begin
|
||||||
{ if we need to handle overflow checking, fall back to the generic cg }
|
{ if we need to handle overflow checking, fall back to the generic cg }
|
||||||
if (nodetype in [addn,subn,muln]) and
|
if (nodetype in [addn,subn,muln]) and
|
||||||
@ -372,6 +378,8 @@ implementation
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
list:=current_asmdata.CurrAsmList;
|
||||||
|
|
||||||
case nodetype of
|
case nodetype of
|
||||||
addn: cgop:=OP_ADD;
|
addn: cgop:=OP_ADD;
|
||||||
xorn: cgop:=OP_XOR;
|
xorn: cgop:=OP_XOR;
|
||||||
@ -398,6 +406,41 @@ implementation
|
|||||||
|
|
||||||
{ initialize the result }
|
{ initialize the result }
|
||||||
location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
|
location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
|
||||||
|
|
||||||
|
{ this is only true, if the CPU supports 32x32 -> 64 bit MUL, see the relevant method }
|
||||||
|
if (nodetype=muln) and is_64bit(resultdef) then
|
||||||
|
begin
|
||||||
|
list.concat(tai_comment.create(strpnew('second_addordinal: mul32to64bit')));
|
||||||
|
|
||||||
|
asmop:=mul_op_signed[cgop = OP_IMUL];
|
||||||
|
location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
|
||||||
|
location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
|
||||||
|
cg.a_load_reg_reg(list,left.location.size,OS_INT,left.location.register,location.register64.reglo);
|
||||||
|
|
||||||
|
if not (right.location.size in [OS_S32, OS_32]) or
|
||||||
|
not (right.location.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_CONSTANT,LOC_REFERENCE,LOC_CREFERENCE]) or
|
||||||
|
((right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) and needs_unaligned(right.location.reference.alignment,def_cgsize(resultdef))) then
|
||||||
|
hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true);
|
||||||
|
|
||||||
|
case right.location.loc of
|
||||||
|
LOC_REGISTER,
|
||||||
|
LOC_CREGISTER:
|
||||||
|
list.concat(taicpu.op_reg_reg_reg(asmop,S_L,right.location.register,location.register64.reghi,location.register64.reglo));
|
||||||
|
LOC_CONSTANT:
|
||||||
|
list.concat(taicpu.op_const_reg_reg(asmop,S_L,right.location.value,location.register64.reghi,location.register64.reglo));
|
||||||
|
LOC_REFERENCE,
|
||||||
|
LOC_CREFERENCE:
|
||||||
|
begin
|
||||||
|
href:=right.location.reference;
|
||||||
|
tcg68k(cg).fixref(list,href,false);
|
||||||
|
list.concat(taicpu.op_ref_reg_reg(asmop,S_L,href,location.register64.reghi,location.register64.reglo));
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
internalerror(2017052601);
|
||||||
|
end;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
location.register := cg.getintregister(current_asmdata.CurrAsmList,location.size);
|
location.register := cg.getintregister(current_asmdata.CurrAsmList,location.size);
|
||||||
cg.a_load_reg_reg(current_asmdata.CurrAsmlist,left.location.size,location.size,left.location.register,location.register);
|
cg.a_load_reg_reg(current_asmdata.CurrAsmlist,left.location.size,location.size,left.location.register,location.register);
|
||||||
|
|
||||||
@ -527,6 +570,11 @@ implementation
|
|||||||
64-bit
|
64-bit
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
|
function t68kaddnode.use_generic_mul32to64: boolean;
|
||||||
|
begin
|
||||||
|
result:=not (CPUM68K_HAS_64BITMUL in cpu_capabilities[current_settings.cputype]);
|
||||||
|
end;
|
||||||
|
|
||||||
function t68kaddnode.use_generic_mul64bit: boolean;
|
function t68kaddnode.use_generic_mul64bit: boolean;
|
||||||
begin
|
begin
|
||||||
result:=(cs_check_overflow in current_settings.localswitches) or
|
result:=(cs_check_overflow in current_settings.localswitches) or
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user