mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-19 21:19:31 +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
|
||||
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
|
||||
{ # Sign or zero extend the register to a full 32-bit value.
|
||||
The new value is left in the same register.
|
||||
@ -584,6 +587,59 @@ unit cgcpu;
|
||||
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);
|
||||
var
|
||||
@ -890,6 +946,7 @@ unit cgcpu;
|
||||
opcode : tasmop;
|
||||
r,r2 : Tregister;
|
||||
instr : taicpu;
|
||||
paraloc1,paraloc2,paraloc3 : tcgpara;
|
||||
begin
|
||||
optimize_op_const(op, a);
|
||||
opcode := topcg2tasmop[op];
|
||||
@ -942,23 +999,7 @@ unit cgcpu;
|
||||
OP_IMUL :
|
||||
begin
|
||||
if current_settings.cputype<>cpu_MC68020 then
|
||||
begin
|
||||
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
|
||||
call_rtl_mul_const_reg(list,size,a,reg,'FPC_MUL_LONGINT')
|
||||
else
|
||||
begin
|
||||
if (isaddressregister(reg)) then
|
||||
@ -979,22 +1020,7 @@ unit cgcpu;
|
||||
OP_MUL :
|
||||
begin
|
||||
if current_settings.cputype<>cpu_MC68020 then
|
||||
begin
|
||||
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
|
||||
call_rtl_mul_const_reg(list,size,a,reg,'FPC_MUL_DWORD')
|
||||
else
|
||||
begin
|
||||
if (isaddressregister(reg)) then
|
||||
@ -1104,6 +1130,7 @@ unit cgcpu;
|
||||
var
|
||||
hreg1,hreg2,r,r2: tregister;
|
||||
instr : taicpu;
|
||||
paraloc1,paraloc2,paraloc3 : tcgpara;
|
||||
begin
|
||||
case op of
|
||||
OP_ADD :
|
||||
@ -1186,25 +1213,8 @@ unit cgcpu;
|
||||
begin
|
||||
sign_extend(list, size,reg1);
|
||||
sign_extend(list, size,reg2);
|
||||
if current_settings.cputype = cpu_MC68000 then
|
||||
begin
|
||||
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
|
||||
if current_settings.cputype<>cpu_MC68020 then
|
||||
call_rtl_mul_reg_reg(list,reg1,reg2,'FPC_MUL_LONGINT')
|
||||
else
|
||||
begin
|
||||
// writeln('doing 68020');
|
||||
@ -1242,24 +1252,7 @@ unit cgcpu;
|
||||
sign_extend(list, size,reg1);
|
||||
sign_extend(list, size,reg2);
|
||||
if current_settings.cputype <> cpu_MC68020 then
|
||||
begin
|
||||
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
|
||||
call_rtl_mul_reg_reg(list,reg1,reg2,'FPC_MUL_DWORD')
|
||||
else
|
||||
begin
|
||||
if (isaddressregister(reg1)) then
|
||||
|
Loading…
Reference in New Issue
Block a user