mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-19 20:13:33 +02: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) }
|
||||
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_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_regset_reg(op: tasmop; _size : topsize;const _op1data,_op1addr,_op1fpu: tcpuregisterset; _op2: tregister);
|
||||
@ -321,6 +323,26 @@ type
|
||||
loadreg(2,_op3);
|
||||
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);
|
||||
Begin
|
||||
inherited create(op);
|
||||
|
@ -37,6 +37,7 @@ interface
|
||||
procedure second_mul64bit;
|
||||
protected
|
||||
function use_generic_mul64bit: boolean; override;
|
||||
function use_generic_mul32to64: boolean; override;
|
||||
procedure second_addfloat;override;
|
||||
procedure second_cmpfloat;override;
|
||||
procedure second_addordinal;override;
|
||||
@ -359,8 +360,13 @@ implementation
|
||||
*****************************************************************************}
|
||||
|
||||
procedure t68kaddnode.second_addordinal;
|
||||
const
|
||||
mul_op_signed: array[boolean] of tasmop = ( A_MULU, A_MULS );
|
||||
var
|
||||
cgop : topcg;
|
||||
asmop : tasmop;
|
||||
list : tasmlist;
|
||||
href : treference;
|
||||
begin
|
||||
{ if we need to handle overflow checking, fall back to the generic cg }
|
||||
if (nodetype in [addn,subn,muln]) and
|
||||
@ -372,6 +378,8 @@ implementation
|
||||
exit;
|
||||
end;
|
||||
|
||||
list:=current_asmdata.CurrAsmList;
|
||||
|
||||
case nodetype of
|
||||
addn: cgop:=OP_ADD;
|
||||
xorn: cgop:=OP_XOR;
|
||||
@ -398,6 +406,41 @@ implementation
|
||||
|
||||
{ initialize the result }
|
||||
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);
|
||||
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
|
||||
*****************************************************************************}
|
||||
|
||||
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;
|
||||
begin
|
||||
result:=(cs_check_overflow in current_settings.localswitches) or
|
||||
|
Loading…
Reference in New Issue
Block a user