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:
svenbarth 2012-10-31 20:58:16 +00:00
parent e190f76dd9
commit 49d953aea2

View File

@ -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