mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 10:29:24 +02:00
m68k/cgcpu.pas:
+ add methods "call_rtl_mul_const_reg" and "call_rtl_mul_reg_reg" which can call the RTL helpers "fpc_mul_longint" and "fpc_mul_longword" (based on AVR code) * use the new call methods for the RTL to correctly pass the parameters (on the stack, not in registers...) git-svn-id: trunk@22892 -
This commit is contained in:
parent
e190f76dd9
commit
49d953aea2
@ -100,6 +100,9 @@ unit cgcpu;
|
|||||||
|
|
||||||
protected
|
protected
|
||||||
function fixref(list: TAsmList; var ref: treference): boolean;
|
function fixref(list: TAsmList; var ref: treference): boolean;
|
||||||
|
|
||||||
|
procedure call_rtl_mul_const_reg(list:tasmlist;size:tcgsize;a:tcgint;reg:tregister;const name:string);
|
||||||
|
procedure call_rtl_mul_reg_reg(list:tasmlist;reg1,reg2:tregister;const name:string);
|
||||||
private
|
private
|
||||||
{ # Sign or zero extend the register to a full 32-bit value.
|
{ # Sign or zero extend the register to a full 32-bit value.
|
||||||
The new value is left in the same register.
|
The new value is left in the same register.
|
||||||
@ -584,6 +587,59 @@ unit cgcpu;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg68k.call_rtl_mul_const_reg(list:tasmlist;size:tcgsize;a:tcgint;reg:tregister;const name:string);
|
||||||
|
var
|
||||||
|
paraloc1,paraloc2,paraloc3 : tcgpara;
|
||||||
|
begin
|
||||||
|
paraloc1.init;
|
||||||
|
paraloc2.init;
|
||||||
|
paraloc3.init;
|
||||||
|
paramanager.getintparaloc(pocall_default,1,u32inttype,paraloc1);
|
||||||
|
paramanager.getintparaloc(pocall_default,2,u32inttype,paraloc2);
|
||||||
|
paramanager.getintparaloc(pocall_default,3,pasbool8type,paraloc3);
|
||||||
|
a_load_const_cgpara(list,OS_8,0,paraloc3);
|
||||||
|
a_load_const_cgpara(list,size,a,paraloc2);
|
||||||
|
a_load_reg_cgpara(list,OS_32,reg,paraloc1);
|
||||||
|
paramanager.freecgpara(list,paraloc3);
|
||||||
|
paramanager.freecgpara(list,paraloc2);
|
||||||
|
paramanager.freecgpara(list,paraloc1);
|
||||||
|
alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
|
||||||
|
a_call_name(list,name,false);
|
||||||
|
dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
|
||||||
|
cg.a_reg_alloc(list,NR_FUNCTION_RESULT_REG);
|
||||||
|
cg.a_load_reg_reg(list,OS_32,OS_32,NR_FUNCTION_RESULT_REG,reg);
|
||||||
|
paraloc3.done;
|
||||||
|
paraloc2.done;
|
||||||
|
paraloc1.done;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg68k.call_rtl_mul_reg_reg(list:tasmlist;reg1,reg2:tregister;const name:string);
|
||||||
|
var
|
||||||
|
paraloc1,paraloc2,paraloc3 : tcgpara;
|
||||||
|
begin
|
||||||
|
paraloc1.init;
|
||||||
|
paraloc2.init;
|
||||||
|
paraloc3.init;
|
||||||
|
paramanager.getintparaloc(pocall_default,1,u32inttype,paraloc1);
|
||||||
|
paramanager.getintparaloc(pocall_default,2,u32inttype,paraloc2);
|
||||||
|
paramanager.getintparaloc(pocall_default,3,pasbool8type,paraloc3);
|
||||||
|
a_load_const_cgpara(list,OS_8,0,paraloc3);
|
||||||
|
a_load_reg_cgpara(list,OS_32,reg1,paraloc2);
|
||||||
|
a_load_reg_cgpara(list,OS_32,reg2,paraloc1);
|
||||||
|
paramanager.freecgpara(list,paraloc3);
|
||||||
|
paramanager.freecgpara(list,paraloc2);
|
||||||
|
paramanager.freecgpara(list,paraloc1);
|
||||||
|
alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
|
||||||
|
a_call_name(list,name,false);
|
||||||
|
dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
|
||||||
|
cg.a_reg_alloc(list,NR_FUNCTION_RESULT_REG);
|
||||||
|
cg.a_load_reg_reg(list,OS_32,OS_32,NR_FUNCTION_RESULT_REG,reg2);
|
||||||
|
paraloc3.done;
|
||||||
|
paraloc2.done;
|
||||||
|
paraloc1.done;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcg68k.a_call_name(list : TAsmList;const s : string; weak: boolean);
|
procedure tcg68k.a_call_name(list : TAsmList;const s : string; weak: boolean);
|
||||||
var
|
var
|
||||||
@ -890,6 +946,7 @@ unit cgcpu;
|
|||||||
opcode : tasmop;
|
opcode : tasmop;
|
||||||
r,r2 : Tregister;
|
r,r2 : Tregister;
|
||||||
instr : taicpu;
|
instr : taicpu;
|
||||||
|
paraloc1,paraloc2,paraloc3 : tcgpara;
|
||||||
begin
|
begin
|
||||||
optimize_op_const(op, a);
|
optimize_op_const(op, a);
|
||||||
opcode := topcg2tasmop[op];
|
opcode := topcg2tasmop[op];
|
||||||
@ -942,23 +999,7 @@ unit cgcpu;
|
|||||||
OP_IMUL :
|
OP_IMUL :
|
||||||
begin
|
begin
|
||||||
if current_settings.cputype<>cpu_MC68020 then
|
if current_settings.cputype<>cpu_MC68020 then
|
||||||
begin
|
call_rtl_mul_const_reg(list,size,a,reg,'FPC_MUL_LONGINT')
|
||||||
r:=NR_D0;
|
|
||||||
r2:=NR_D1;
|
|
||||||
cg.getcpuregister(list,NR_D0);
|
|
||||||
cg.getcpuregister(list,NR_D1);
|
|
||||||
list.concat(taicpu.op_const_reg(A_MOVE,S_L,a, r));
|
|
||||||
instr:=taicpu.op_reg_reg(A_MOVE,S_L,reg, r2);
|
|
||||||
add_move_instruction(instr);
|
|
||||||
list.concat(instr);
|
|
||||||
cg.a_call_name(list,'FPC_MUL_LONGINT',false);
|
|
||||||
instr:=taicpu.op_reg_reg(A_MOVE,S_L,r, reg);
|
|
||||||
add_move_instruction(instr);
|
|
||||||
list.concat(instr);
|
|
||||||
cg.ungetcpuregister(list,r);
|
|
||||||
cg.ungetcpuregister(list,r2);
|
|
||||||
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if (isaddressregister(reg)) then
|
if (isaddressregister(reg)) then
|
||||||
@ -979,22 +1020,7 @@ unit cgcpu;
|
|||||||
OP_MUL :
|
OP_MUL :
|
||||||
begin
|
begin
|
||||||
if current_settings.cputype<>cpu_MC68020 then
|
if current_settings.cputype<>cpu_MC68020 then
|
||||||
begin
|
call_rtl_mul_const_reg(list,size,a,reg,'FPC_MUL_DWORD')
|
||||||
r:=NR_D0;
|
|
||||||
r2:=NR_D1;
|
|
||||||
cg.getcpuregister(list,NR_D0);
|
|
||||||
cg.getcpuregister(list,NR_D1);
|
|
||||||
list.concat(taicpu.op_const_reg(A_MOVE,S_L,a, r));
|
|
||||||
instr:=taicpu.op_reg_reg(A_MOVE,S_L,reg, r2);
|
|
||||||
add_move_instruction(instr);
|
|
||||||
list.concat(instr);
|
|
||||||
cg.a_call_name(list,'FPC_MUL_DWORD',false);
|
|
||||||
instr:=taicpu.op_reg_reg(A_MOVE,S_L,r, reg);
|
|
||||||
add_move_instruction(instr);
|
|
||||||
list.concat(instr);
|
|
||||||
cg.ungetcpuregister(list,r);
|
|
||||||
cg.ungetcpuregister(list,r2);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if (isaddressregister(reg)) then
|
if (isaddressregister(reg)) then
|
||||||
@ -1104,6 +1130,7 @@ unit cgcpu;
|
|||||||
var
|
var
|
||||||
hreg1,hreg2,r,r2: tregister;
|
hreg1,hreg2,r,r2: tregister;
|
||||||
instr : taicpu;
|
instr : taicpu;
|
||||||
|
paraloc1,paraloc2,paraloc3 : tcgpara;
|
||||||
begin
|
begin
|
||||||
case op of
|
case op of
|
||||||
OP_ADD :
|
OP_ADD :
|
||||||
@ -1186,25 +1213,8 @@ unit cgcpu;
|
|||||||
begin
|
begin
|
||||||
sign_extend(list, size,reg1);
|
sign_extend(list, size,reg1);
|
||||||
sign_extend(list, size,reg2);
|
sign_extend(list, size,reg2);
|
||||||
if current_settings.cputype = cpu_MC68000 then
|
if current_settings.cputype<>cpu_MC68020 then
|
||||||
begin
|
call_rtl_mul_reg_reg(list,reg1,reg2,'FPC_MUL_LONGINT')
|
||||||
r:=NR_D0;
|
|
||||||
r2:=NR_D1;
|
|
||||||
cg.getcpuregister(list,NR_D0);
|
|
||||||
cg.getcpuregister(list,NR_D1);
|
|
||||||
instr:=taicpu.op_reg_reg(A_MOVE,S_L,reg1, r);
|
|
||||||
add_move_instruction(instr);
|
|
||||||
list.concat(instr);
|
|
||||||
instr:=taicpu.op_reg_reg(A_MOVE,S_L,reg2, r2);
|
|
||||||
add_move_instruction(instr);
|
|
||||||
list.concat(instr);
|
|
||||||
cg.a_call_name(list,'FPC_MUL_LONGINT',false);
|
|
||||||
instr:=taicpu.op_reg_reg(A_MOVE,S_L,r, reg2);
|
|
||||||
add_move_instruction(instr);
|
|
||||||
list.concat(instr);
|
|
||||||
cg.ungetcpuregister(list,r);
|
|
||||||
cg.ungetcpuregister(list,r2);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
// writeln('doing 68020');
|
// writeln('doing 68020');
|
||||||
@ -1242,24 +1252,7 @@ unit cgcpu;
|
|||||||
sign_extend(list, size,reg1);
|
sign_extend(list, size,reg1);
|
||||||
sign_extend(list, size,reg2);
|
sign_extend(list, size,reg2);
|
||||||
if current_settings.cputype <> cpu_MC68020 then
|
if current_settings.cputype <> cpu_MC68020 then
|
||||||
begin
|
call_rtl_mul_reg_reg(list,reg1,reg2,'FPC_MUL_DWORD')
|
||||||
r:=NR_D0;
|
|
||||||
r2:=NR_D1;
|
|
||||||
cg.getcpuregister(list,NR_D0);
|
|
||||||
cg.getcpuregister(list,NR_D1);
|
|
||||||
instr:=taicpu.op_reg_reg(A_MOVE,S_L,reg1, r);
|
|
||||||
add_move_instruction(instr);
|
|
||||||
list.concat(instr);
|
|
||||||
instr:=taicpu.op_reg_reg(A_MOVE,S_L,reg2, r2);
|
|
||||||
add_move_instruction(instr);
|
|
||||||
list.concat(instr);
|
|
||||||
cg.a_call_name(list,'FPC_MUL_DWORD',false);
|
|
||||||
instr:=taicpu.op_reg_reg(A_MOVE,S_L,r, reg2);
|
|
||||||
add_move_instruction(instr);
|
|
||||||
list.concat(instr);
|
|
||||||
cg.ungetcpuregister(list,r);
|
|
||||||
cg.ungetcpuregister(list,r2);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if (isaddressregister(reg1)) then
|
if (isaddressregister(reg1)) then
|
||||||
|
Loading…
Reference in New Issue
Block a user