* fix stack frame generation on mips(el)

git-svn-id: trunk@21121 -
This commit is contained in:
florian 2012-04-29 21:29:06 +00:00
parent 14cfe770a4
commit 25e82bb1af
7 changed files with 299 additions and 234 deletions

View File

@ -50,6 +50,7 @@ type
constructor op_reg_reg(op: tasmop; _op1, _op2: tregister); constructor op_reg_reg(op: tasmop; _op1, _op2: tregister);
constructor op_reg_ref(op: tasmop; _op1: tregister; const _op2: treference); constructor op_reg_ref(op: tasmop; _op1: tregister; const _op2: treference);
constructor op_reg_const(op: tasmop; _op1: tregister; _op2: longint); constructor op_reg_const(op: tasmop; _op1: tregister; _op2: longint);
constructor op_const_const(op: tasmop; _op1: aint; _op2: aint);
constructor op_reg_reg_reg(op: tasmop; _op1, _op2, _op3: tregister); constructor op_reg_reg_reg(op: tasmop; _op1, _op2, _op3: tregister);
@ -132,6 +133,14 @@ begin
loadconst(1, _op2); loadconst(1, _op2);
end; end;
constructor taicpu.op_const_const(op: tasmop; _op1: aint; _op2: aint);
begin
inherited Create(op);
ops := 2;
loadconst(0, _op1);
loadconst(1, _op2);
end;
constructor taicpu.op_reg_ref(op: tasmop; _op1: tregister; const _op2: treference); constructor taicpu.op_reg_ref(op: tasmop; _op1: tregister; const _op2: treference);
begin begin

View File

@ -1,7 +1,7 @@
{ {
Copyright (c) 1998-2009 by Florian Klaempfl and David Zhang Copyright (c) 1998-2012 by Florian Klaempfl and David Zhang
This unit implements the code generator for the MIPSEL This unit implements the code generator for MIPS
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -34,7 +34,7 @@ uses
rgcpu; rgcpu;
type type
TCgMPSel = class(tcg) TCGMIPS = class(tcg)
public public
procedure init_register_allocators; override; procedure init_register_allocators; override;
procedure done_register_allocators; override; procedure done_register_allocators; override;
@ -296,7 +296,7 @@ var
procedure TCgMPSel.make_simple_ref(list: tasmlist; var ref: treference); procedure TCGMIPS.make_simple_ref(list: tasmlist; var ref: treference);
var var
tmpreg, tmpreg1: tregister; tmpreg, tmpreg1: tregister;
tmpref: treference; tmpref: treference;
@ -392,7 +392,7 @@ begin
end; end;
end; end;
procedure TCgMPSel.make_simple_ref_fpu(list: tasmlist; var ref: treference); procedure TCGMIPS.make_simple_ref_fpu(list: tasmlist; var ref: treference);
var var
tmpreg, tmpreg1: tregister; tmpreg, tmpreg1: tregister;
tmpref: treference; tmpref: treference;
@ -464,20 +464,20 @@ begin
ref.offset := 0; ref.offset := 0;
end; end;
procedure TCgMPSel.handle_load_store(list: tasmlist; isstore: boolean; op: tasmop; reg: tregister; ref: treference); procedure TCGMIPS.handle_load_store(list: tasmlist; isstore: boolean; op: tasmop; reg: tregister; ref: treference);
begin begin
make_simple_ref(list, ref); make_simple_ref(list, ref);
list.concat(taicpu.op_reg_ref(op, reg, ref)); list.concat(taicpu.op_reg_ref(op, reg, ref));
end; end;
procedure TCgMPSel.handle_load_store_fpu(list: tasmlist; isstore: boolean; op: tasmop; reg: tregister; ref: treference); procedure TCGMIPS.handle_load_store_fpu(list: tasmlist; isstore: boolean; op: tasmop; reg: tregister; ref: treference);
begin begin
make_simple_ref_fpu(list, ref); make_simple_ref_fpu(list, ref);
list.concat(taicpu.op_reg_ref(op, reg, ref)); list.concat(taicpu.op_reg_ref(op, reg, ref));
end; end;
procedure TCgMPSel.handle_reg_const_reg(list: tasmlist; op: Tasmop; src: tregister; a: tcgint; dst: tregister); procedure TCGMIPS.handle_reg_const_reg(list: tasmlist; op: Tasmop; src: tregister; a: tcgint; dst: tregister);
var var
tmpreg: tregister; tmpreg: tregister;
begin begin
@ -497,7 +497,7 @@ end;
Assembler code Assembler code
****************************************************************************} ****************************************************************************}
procedure TCgMPSel.init_register_allocators; procedure TCGMIPS.init_register_allocators;
begin begin
inherited init_register_allocators; inherited init_register_allocators;
@ -532,7 +532,7 @@ end;
procedure TCgMPSel.done_register_allocators; procedure TCGMIPS.done_register_allocators;
begin begin
rg[R_INTREGISTER].Free; rg[R_INTREGISTER].Free;
rg[R_FPUREGISTER].Free; rg[R_FPUREGISTER].Free;
@ -541,7 +541,7 @@ begin
end; end;
function TCgMPSel.getfpuregister(list: tasmlist; size: Tcgsize): Tregister; function TCGMIPS.getfpuregister(list: tasmlist; size: Tcgsize): Tregister;
begin begin
if size = OS_F64 then if size = OS_F64 then
Result := rg[R_FPUREGISTER].getregister(list, R_SUBFS) Result := rg[R_FPUREGISTER].getregister(list, R_SUBFS)
@ -550,7 +550,7 @@ begin
end; end;
procedure TCgMPSel.a_load_const_cgpara(list: tasmlist; size: tcgsize; a: tcgint; const paraloc: TCGPara); procedure TCGMIPS.a_load_const_cgpara(list: tasmlist; size: tcgsize; a: tcgint; const paraloc: TCGPara);
var var
Ref: TReference; Ref: TReference;
begin begin
@ -575,7 +575,7 @@ begin
end; end;
procedure TCgMPSel.a_load_ref_cgpara(list: tasmlist; sz: TCgSize; const r: TReference; const paraloc: TCGPara); procedure TCGMIPS.a_load_ref_cgpara(list: tasmlist; sz: TCgSize; const r: TReference; const paraloc: TCGPara);
var var
ref: treference; ref: treference;
tmpreg: TRegister; tmpreg: TRegister;
@ -606,7 +606,7 @@ begin
end; end;
procedure TCgMPSel.a_loadaddr_ref_cgpara(list: tasmlist; const r: TReference; const paraloc: TCGPara); procedure TCGMIPS.a_loadaddr_ref_cgpara(list: tasmlist; const r: TReference; const paraloc: TCGPara);
var var
Ref: TReference; Ref: TReference;
TmpReg: TRegister; TmpReg: TRegister;
@ -634,7 +634,7 @@ begin
end; end;
procedure TCgMPSel.a_loadfpu_ref_cgpara(list: tasmlist; size: tcgsize; const ref: treference; const paraloc: TCGPara); procedure TCGMIPS.a_loadfpu_ref_cgpara(list: tasmlist; size: tcgsize; const ref: treference; const paraloc: TCGPara);
var var
href, href2: treference; href, href2: treference;
hloc: pcgparalocation; hloc: pcgparalocation;
@ -663,7 +663,7 @@ begin
end; end;
procedure TCgMPSel.a_loadfpu_reg_cgpara(list: tasmlist; size: tcgsize; const r: tregister; const paraloc: TCGPara); procedure TCGMIPS.a_loadfpu_reg_cgpara(list: tasmlist; size: tcgsize; const r: tregister; const paraloc: TCGPara);
var var
href: treference; href: treference;
begin begin
@ -674,7 +674,7 @@ begin
end; end;
procedure TCgMPSel.a_call_name(list: tasmlist; const s: string; weak: boolean); procedure TCGMIPS.a_call_name(list: tasmlist; const s: string; weak: boolean);
begin begin
list.concat(taicpu.op_sym(A_JAL,current_asmdata.RefAsmSymbol(s))); list.concat(taicpu.op_sym(A_JAL,current_asmdata.RefAsmSymbol(s)));
{ Delay slot } { Delay slot }
@ -682,7 +682,7 @@ begin
end; end;
procedure TCgMPSel.a_call_reg(list: tasmlist; Reg: TRegister); procedure TCGMIPS.a_call_reg(list: tasmlist; Reg: TRegister);
begin begin
list.concat(taicpu.op_reg(A_JALR, reg)); list.concat(taicpu.op_reg(A_JALR, reg));
{ Delay slot } { Delay slot }
@ -692,7 +692,7 @@ end;
{********************** load instructions ********************} {********************** load instructions ********************}
procedure TCgMPSel.a_load_const_reg(list: tasmlist; size: TCGSize; a: tcgint; reg: TRegister); procedure TCGMIPS.a_load_const_reg(list: tasmlist; size: TCGSize; a: tcgint; reg: TRegister);
begin begin
if (a = 0) then if (a = 0) then
list.concat(taicpu.op_reg_reg(A_MOVE, reg, NR_R0)) list.concat(taicpu.op_reg_reg(A_MOVE, reg, NR_R0))
@ -710,7 +710,7 @@ begin
end; end;
procedure TCgMPSel.a_load_const_ref(list: tasmlist; size: tcgsize; a: tcgint; const ref: TReference); procedure TCGMIPS.a_load_const_ref(list: tasmlist; size: tcgsize; a: tcgint; const ref: TReference);
begin begin
if a = 0 then if a = 0 then
a_load_reg_ref(list, size, size, NR_R0, ref) a_load_reg_ref(list, size, size, NR_R0, ref)
@ -719,7 +719,7 @@ begin
end; end;
procedure TCgMPSel.a_load_reg_ref(list: tasmlist; FromSize, ToSize: TCGSize; reg: tregister; const Ref: TReference); procedure TCGMIPS.a_load_reg_ref(list: tasmlist; FromSize, ToSize: TCGSize; reg: tregister; const Ref: TReference);
var var
op: tasmop; op: tasmop;
begin begin
@ -744,7 +744,7 @@ begin
end; end;
procedure TCgMPSel.a_load_ref_reg(list: tasmlist; FromSize, ToSize: TCgSize; const ref: TReference; reg: tregister); procedure TCGMIPS.a_load_ref_reg(list: tasmlist; FromSize, ToSize: TCgSize; const ref: TReference; reg: tregister);
var var
op: tasmop; op: tasmop;
begin begin
@ -773,7 +773,7 @@ begin
end; end;
procedure TCgMPSel.a_load_reg_reg(list: tasmlist; fromsize, tosize: tcgsize; reg1, reg2: tregister); procedure TCGMIPS.a_load_reg_reg(list: tasmlist; fromsize, tosize: tcgsize; reg1, reg2: tregister);
var var
instr: taicpu; instr: taicpu;
begin begin
@ -827,7 +827,7 @@ begin
end; end;
procedure TCgMPSel.a_loadaddr_ref_reg(list: tasmlist; const ref: TReference; r: tregister); procedure TCGMIPS.a_loadaddr_ref_reg(list: tasmlist; const ref: TReference; r: tregister);
var var
tmpref, href: treference; tmpref, href: treference;
hreg, tmpreg: tregister; hreg, tmpreg: tregister;
@ -926,7 +926,7 @@ begin
internalerror(200703111); internalerror(200703111);
end; end;
procedure TCgMPSel.a_loadfpu_reg_reg(list: tasmlist; fromsize, tosize: tcgsize; reg1, reg2: tregister); procedure TCGMIPS.a_loadfpu_reg_reg(list: tasmlist; fromsize, tosize: tcgsize; reg1, reg2: tregister);
const const
FpuMovInstr: array[OS_F32..OS_F64] of TAsmOp = FpuMovInstr: array[OS_F32..OS_F64] of TAsmOp =
(A_MOV_S, A_MOV_D); (A_MOV_S, A_MOV_D);
@ -944,7 +944,7 @@ begin
end; end;
procedure TCgMPSel.a_loadfpu_ref_reg(list: tasmlist; fromsize, tosize: tcgsize; const ref: TReference; reg: tregister); procedure TCGMIPS.a_loadfpu_ref_reg(list: tasmlist; fromsize, tosize: tcgsize; const ref: TReference; reg: tregister);
var var
tmpref: treference; tmpref: treference;
tmpreg: tregister; tmpreg: tregister;
@ -959,7 +959,7 @@ begin
end; end;
end; end;
procedure TCgMPSel.a_loadfpu_reg_ref(list: tasmlist; fromsize, tosize: tcgsize; reg: tregister; const ref: TReference); procedure TCGMIPS.a_loadfpu_reg_ref(list: tasmlist; fromsize, tosize: tcgsize; reg: tregister; const ref: TReference);
var var
tmpref: treference; tmpref: treference;
tmpreg: tregister; tmpreg: tregister;
@ -974,7 +974,7 @@ begin
end; end;
end; end;
procedure TCgMPSel.a_op_const_reg(list: tasmlist; Op: TOpCG; size: tcgsize; a: tcgint; reg: TRegister); procedure TCGMIPS.a_op_const_reg(list: tasmlist; Op: TOpCG; size: tcgsize; a: tcgint; reg: TRegister);
var var
power: longint; power: longint;
tmpreg1: tregister; tmpreg1: tregister;
@ -1028,7 +1028,7 @@ begin
end; end;
procedure TCgMPSel.a_op_reg_reg(list: tasmlist; Op: TOpCG; size: TCGSize; src, dst: TRegister); procedure TCGMIPS.a_op_reg_reg(list: tasmlist; Op: TOpCG; size: TCGSize; src, dst: TRegister);
var var
a: aint; a: aint;
begin begin
@ -1060,7 +1060,7 @@ begin
end; end;
procedure TCgMPSel.a_op_const_reg_reg(list: tasmlist; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister); procedure TCGMIPS.a_op_const_reg_reg(list: tasmlist; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister);
var var
power: longint; power: longint;
tmpreg1: tregister; tmpreg1: tregister;
@ -1108,14 +1108,14 @@ begin
end; end;
procedure TCgMPSel.a_op_reg_reg_reg(list: tasmlist; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); procedure TCGMIPS.a_op_reg_reg_reg(list: tasmlist; op: TOpCg; size: tcgsize; src1, src2, dst: tregister);
begin begin
list.concat(taicpu.op_reg_reg_reg(f_TOpCG2AsmOp(op, size), dst, src2, src1)); list.concat(taicpu.op_reg_reg_reg(f_TOpCG2AsmOp(op, size), dst, src2, src1));
end; end;
procedure TCgMPSel.a_op_const_reg_reg_checkoverflow(list: tasmlist; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister; setflags: boolean; var ovloc: tlocation); procedure TCGMIPS.a_op_const_reg_reg_checkoverflow(list: tasmlist; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister; setflags: boolean; var ovloc: tlocation);
var var
tmpreg1: tregister; tmpreg1: tregister;
begin begin
@ -1181,7 +1181,7 @@ begin
end; end;
procedure TCgMPSel.a_op_reg_reg_reg_checkoverflow(list: tasmlist; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation); procedure TCGMIPS.a_op_reg_reg_reg_checkoverflow(list: tasmlist; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation);
begin begin
ovloc.loc := LOC_VOID; ovloc.loc := LOC_VOID;
case op of case op of
@ -1232,7 +1232,7 @@ end;
{*************** compare instructructions ****************} {*************** compare instructructions ****************}
procedure TCgMPSel.a_cmp_const_reg_label(list: tasmlist; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel); procedure TCGMIPS.a_cmp_const_reg_label(list: tasmlist; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);
var var
tmpreg: tregister; tmpreg: tregister;
begin begin
@ -1271,7 +1271,7 @@ end;
end; end;
procedure TCgMPSel.a_cmp_reg_reg_label(list: tasmlist; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel); procedure TCGMIPS.a_cmp_reg_reg_label(list: tasmlist; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);
begin begin
case cmp_op of case cmp_op of
OC_EQ: { equality comparison } OC_EQ: { equality comparison }
@ -1301,7 +1301,7 @@ begin
end; end;
procedure TCgMPSel.a_jmp_always(List: tasmlist; l: TAsmLabel); procedure TCGMIPS.a_jmp_always(List: tasmlist; l: TAsmLabel);
begin begin
List.Concat(TAiCpu.op_sym(A_J,l)); List.Concat(TAiCpu.op_sym(A_J,l));
{ Delay slot } { Delay slot }
@ -1309,7 +1309,7 @@ begin
end; end;
procedure TCgMPSel.a_jmp_name(list: tasmlist; const s: string); procedure TCGMIPS.a_jmp_name(list: tasmlist; const s: string);
begin begin
List.Concat(TAiCpu.op_sym(A_J, current_asmdata.RefAsmSymbol(s))); List.Concat(TAiCpu.op_sym(A_J, current_asmdata.RefAsmSymbol(s)));
{ Delay slot } { Delay slot }
@ -1317,18 +1317,18 @@ begin
end; end;
procedure TCgMPSel.a_jmp_cond(list: tasmlist; cond: TOpCmp; l: TAsmLabel); procedure TCGMIPS.a_jmp_cond(list: tasmlist; cond: TOpCmp; l: TAsmLabel);
begin begin
internalerror(200701181); internalerror(200701181);
end; end;
procedure TCgMPSel.g_overflowCheck(List: tasmlist; const Loc: TLocation; def: TDef); procedure TCGMIPS.g_overflowCheck(List: tasmlist; const Loc: TLocation; def: TDef);
begin begin
// this is an empty procedure // this is an empty procedure
end; end;
procedure TCgMPSel.g_overflowCheck_loc(List: tasmlist; const Loc: TLocation; def: TDef; ovloc: tlocation); procedure TCGMIPS.g_overflowCheck_loc(List: tasmlist; const Loc: TLocation; def: TDef; ovloc: tlocation);
begin begin
// this is an empty procedure // this is an empty procedure
@ -1337,15 +1337,16 @@ end;
{ *********** entry/exit code and address loading ************ } { *********** entry/exit code and address loading ************ }
procedure TCgMPSel.g_proc_entry(list: tasmlist; localsize: longint; nostackframe: boolean); procedure TCGMIPS.g_proc_entry(list: tasmlist; localsize: longint; nostackframe: boolean);
var var
regcounter, firstregfpu, firstreggpr: TSuperRegister; lastintoffset,lastfpuoffset,
nextoffset : aint;
fmask,mask : dword;
saveregs : tcpuregisterset;
href: treference; href: treference;
usesfpr, usesgpr, gotgot : boolean; usesfpr, usesgpr, gotgot : boolean;
regcounter2, firstfpureg: Tsuperregister; reg : Tsuperregister;
cond: tasmcond; helplist : TAsmList;
instr: taicpu;
begin begin
{ {
if STK2_dummy <> 0 then if STK2_dummy <> 0 then
@ -1353,7 +1354,6 @@ begin
list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, -STK2_dummy)); list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, -STK2_dummy));
end; end;
} }
LocalSize := align(LocalSize, 8);
a_reg_alloc(list,NR_STACK_POINTER_REG); a_reg_alloc(list,NR_STACK_POINTER_REG);
if current_procinfo.framepointer<>NR_STACK_POINTER_REG then if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
a_reg_alloc(list,NR_FRAME_POINTER_REG); a_reg_alloc(list,NR_FRAME_POINTER_REG);
@ -1361,102 +1361,128 @@ begin
if nostackframe then if nostackframe then
exit; exit;
usesfpr := False; helplist:=TAsmList.Create;
for regcounter := RS_F20 to RS_F30 do
begin
if regcounter in rg[R_FPUREGISTER].used_in_proc then
begin
usesfpr := True;
firstregfpu := regcounter;
end;
end;
usesgpr := False;
if not (po_assembler in current_procinfo.procdef.procoptions) then
for regcounter2 := RS_R0 to RS_R31 do
begin
if regcounter2 in rg[R_INTREGISTER].used_in_proc then
begin
usesgpr := True;
firstreggpr := regcounter2;
end;
end;
cgcpu_calc_stackframe_size := LocalSize; cgcpu_calc_stackframe_size := LocalSize;
list.concat(Taicpu.Op_reg_const_reg(A_P_FRAME, NR_FRAME_POINTER_REG, LocalSize, NR_R31)); { if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
list.concat(Taicpu.Op_reg_const_reg(A_P_FRAME, NR_FRAME_POINTER_REG, LocalSize, NR_R31)); }
{ if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
list.concat(Taicpu.Op_reg_reg_const(A_P_SW, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG, -LocalSize));
}
{ if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
list.concat(Taicpu.op_reg_reg(A_MOVE, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG));
}
reference_reset(href,0);
href.base:=NR_STACK_POINTER_REG;
usesfpr:=false;
fmask:=0;
nextoffset:=TMIPSProcInfo(current_procinfo).floatregstart;
lastfpuoffset:=LocalSize;
for reg := RS_F0 to RS_F30 do
begin
if reg in (rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall)) then
begin
usesfpr:=true;
fmask:=fmask or (1 shl ord(reg));
href.offset:=nextoffset;
lastfpuoffset:=nextoffset;
helplist.concat(taicpu.op_reg_ref(A_SWC1,newreg(R_FPUREGISTER,reg,R_SUBFS),href));
inc(nextoffset,4);
end;
end;
usesgpr:=false;
mask:=0;
nextoffset:=TMIPSProcInfo(current_procinfo).intregstart;
saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
include(saveregs,RS_R31);
lastintoffset:=LocalSize;
for reg:=RS_R1 to RS_R31 do
begin
if reg in saveregs then
begin
usesgpr:=true;
mask:=mask or (1 shl ord(reg));
href.offset:=nextoffset;
lastintoffset:=nextoffset;
helplist.concat(taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
inc(nextoffset,4);
end;
end;
list.concat(Taicpu.op_none(A_P_SET_NOMIPS16));
list.concat(Taicpu.op_reg_const_reg(A_P_FRAME,current_procinfo.framepointer,LocalSize,NR_R31));
list.concat(Taicpu.op_const_const(A_P_MASK,mask,-(LocalSize-lastintoffset)));
list.concat(Taicpu.op_const_const(A_P_FMASK,Fmask,-(LocalSize-lastfpuoffset)));
list.concat(Taicpu.op_none(A_P_SET_NOREORDER)); list.concat(Taicpu.op_none(A_P_SET_NOREORDER));
list.concat(Taicpu.op_none(A_P_SET_NOMACRO)); list.concat(Taicpu.op_none(A_P_SET_NOMACRO));
// list.concat(taicpu.op_
list.concat(Taicpu.Op_reg_reg_const(A_P_SW, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG, -LocalSize));
list.concat(Taicpu.Op_reg_reg_const(A_P_SW, NR_R31, NR_STACK_POINTER_REG, -LocalSize + 4));
list.concat(Taicpu.op_reg_reg(A_MOVE, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG));
list.concat(Taicpu.Op_reg_reg_const(A_ADDIU,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-LocalSize)); list.concat(Taicpu.Op_reg_reg_const(A_ADDIU,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-LocalSize));
if (cs_create_pic in current_settings.moduleswitches) and if (cs_create_pic in current_settings.moduleswitches) and
(pi_needs_got in current_procinfo.flags) then (pi_needs_got in current_procinfo.flags) then
begin begin
current_procinfo.got := NR_GP; current_procinfo.got := NR_GP;
end; end;
list.concatList(helplist);
helplist.Free;
end; end;
procedure TCGMIPS.g_proc_exit(list: tasmlist; parasize: longint; nostackframe: boolean);
procedure TCgMPSel.g_proc_exit(list: tasmlist; parasize: longint; nostackframe: boolean);
var var
hr: treference; href : treference;
localsize: aint; stacksize : aint;
saveregs : tcpuregisterset;
nextoffset : aint;
reg : Tsuperregister;
begin begin
localsize := cgcpu_calc_stackframe_size; stacksize:=current_procinfo.calc_stackframe_size;
if paramanager.ret_in_param(current_procinfo.procdef.returndef, current_procinfo.procdef.proccalloption) then
begin
reference_reset(hr,sizeof(aint));
hr.offset := 12;
hr.refaddr := addr_full;
if nostackframe then if nostackframe then
begin begin
if STK2_dummy <> 0 then { if STK2_dummy <> 0 then
list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, STK2_dummy)); list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, STK2_dummy));
}
list.concat(taicpu.op_reg(A_J, NR_R31)); list.concat(taicpu.op_reg(A_J, NR_R31));
list.concat(Taicpu.op_none(A_NOP)); list.concat(Taicpu.op_none(A_NOP));
list.concat(Taicpu.op_none(A_P_SET_MACRO));
list.concat(Taicpu.op_none(A_P_SET_REORDER));
end end
else else
begin begin
reference_reset(href,0);
href.base:=NR_STACK_POINTER_REG;
list.concat(Taicpu.Op_reg_reg_const(A_P_LW, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG, 0)); nextoffset:=TMIPSProcInfo(current_procinfo).floatregstart;
list.concat(Taicpu.Op_reg_reg_const(A_P_LW, NR_R31, NR_STACK_POINTER_REG, 4)); for reg := RS_F0 to RS_F30 do
list.concat(Taicpu.Op_reg_reg_const(A_ADDIU, NR_STACK_POINTER_REG, NR_STACK_POINTER_REG, localsize)); begin
if STK2_dummy <> 0 then if reg in (rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall)) then
list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, STK2_dummy)); begin
list.concat(taicpu.op_reg(A_J, NR_R31)); href.offset:=nextoffset;
list.concat(Taicpu.op_none(A_NOP)); list.concat(taicpu.op_reg_ref(A_LWC1,newreg(R_FPUREGISTER,reg,R_SUBFS),href));
list.concat(Taicpu.op_none(A_P_SET_MACRO)); inc(nextoffset,4);
list.concat(Taicpu.op_none(A_P_SET_REORDER)); end;
end;
nextoffset:=TMIPSProcInfo(current_procinfo).intregstart;
saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
include(saveregs,RS_R31);
for reg:=RS_R1 to RS_R31 do
begin
if reg in saveregs then
begin
href.offset:=nextoffset;
list.concat(taicpu.op_reg_ref(A_LD,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
inc(nextoffset,sizeof(aint));
end; end;
end end;
else
begin
if nostackframe then
begin
if STK2_dummy <> 0 then
list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, STK2_dummy));
list.concat(taicpu.op_reg(A_J, NR_R31)); list.concat(taicpu.op_reg(A_J, NR_R31));
list.concat(Taicpu.op_none(A_NOP)); { correct stack pointer in the delay slot }
list.concat(Taicpu.Op_reg_reg_const(A_ADDIU, NR_STACK_POINTER_REG, NR_STACK_POINTER_REG, stacksize));
list.concat(Taicpu.op_none(A_P_SET_MACRO)); list.concat(Taicpu.op_none(A_P_SET_MACRO));
list.concat(Taicpu.op_none(A_P_SET_REORDER)); list.concat(Taicpu.op_none(A_P_SET_REORDER));
end
else
begin
list.concat(Taicpu.Op_reg_reg_const(A_P_LW, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG, 0));
list.concat(Taicpu.Op_reg_reg_const(A_P_LW, NR_R31, NR_STACK_POINTER_REG, 4));
list.concat(Taicpu.Op_reg_reg_const(A_ADDIU, NR_STACK_POINTER_REG, NR_STACK_POINTER_REG, localsize));
if STK2_dummy <> 0 then
list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, STK2_dummy));
list.concat(taicpu.op_reg(A_J, NR_R31));
list.concat(Taicpu.op_none(A_NOP));
list.concat(Taicpu.op_none(A_P_SET_MACRO));
list.concat(Taicpu.op_none(A_P_SET_REORDER));
end;
end; end;
end; end;
@ -1464,7 +1490,7 @@ end;
{ ************* concatcopy ************ } { ************* concatcopy ************ }
procedure TCgMPSel.g_concatcopy_move(list: tasmlist; const Source, dest: treference; len: tcgint); procedure TCGMIPS.g_concatcopy_move(list: tasmlist; const Source, dest: treference; len: tcgint);
var var
paraloc1, paraloc2, paraloc3: TCGPara; paraloc1, paraloc2, paraloc3: TCGPara;
begin begin
@ -1491,7 +1517,7 @@ begin
end; end;
procedure TCgMPSel.g_concatcopy(list: tasmlist; const Source, dest: treference; len: tcgint); procedure TCGMIPS.g_concatcopy(list: tasmlist; const Source, dest: treference; len: tcgint);
var var
tmpreg1, hreg, countreg: TRegister; tmpreg1, hreg, countreg: TRegister;
src, dst: TReference; src, dst: TReference;
@ -1578,7 +1604,7 @@ begin
end; end;
procedure TCgMPSel.g_concatcopy_unaligned(list: tasmlist; const Source, dest: treference; len: tcgint); procedure TCGMIPS.g_concatcopy_unaligned(list: tasmlist; const Source, dest: treference; len: tcgint);
var var
src, dst: TReference; src, dst: TReference;
tmpreg1, countreg: TRegister; tmpreg1, countreg: TRegister;
@ -1635,7 +1661,7 @@ begin
end; end;
procedure TCgMPSel.g_intf_wrapper(list: tasmlist; procdef: tprocdef; const labelname: string; ioffset: longint); procedure TCGMIPS.g_intf_wrapper(list: tasmlist; procdef: tprocdef; const labelname: string; ioffset: longint);
procedure loadvmttor24; procedure loadvmttor24;
var var
@ -1697,12 +1723,12 @@ begin
List.concat(Tai_symbol_end.Createname(labelname)); List.concat(Tai_symbol_end.Createname(labelname));
end; end;
procedure TCgMPSel.g_stackpointer_alloc(list : TAsmList;localsize : longint); procedure TCGMIPS.g_stackpointer_alloc(list : TAsmList;localsize : longint);
begin begin
Comment(V_Error,'TCgMPSel.g_stackpointer_alloc method not implemented'); Comment(V_Error,'TCgMPSel.g_stackpointer_alloc method not implemented');
end; end;
procedure TCgMPSel.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister); procedure TCGMIPS.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister);
begin begin
Comment(V_Error,'TCgMPSel.a_bit_scan_reg_reg method not implemented'); Comment(V_Error,'TCgMPSel.a_bit_scan_reg_reg method not implemented');
end; end;
@ -1974,7 +2000,7 @@ end;
procedure create_codegen; procedure create_codegen;
begin begin
cg:=TCgMPSel.Create; cg:=TCGMIPS.Create;
cg64:=TCg64MPSel.Create; cg64:=TCg64MPSel.Create;
end; end;

View File

@ -175,6 +175,17 @@ unit cpugas;
s := #9 + gas_op2str[A_ADDIU] + #9 + getopstr(taicpu(hp).oper[0]^)+ ',' + getopstr(taicpu(hp).oper[1]^) + ',' + s1; s := #9 + gas_op2str[A_ADDIU] + #9 + getopstr(taicpu(hp).oper[0]^)+ ',' + getopstr(taicpu(hp).oper[1]^) + ',' + s1;
owner.AsmWriteLn(s); owner.AsmWriteLn(s);
end; end;
A_P_SET_NOMIPS16:
begin
s := #9 + '.set' + #9 + 'nomips16';
owner.AsmWriteLn(s);
end;
A_P_MASK,
A_P_FMASK:
begin
s := #9 + gas_op2str[op] + #9'0x' + hexstr(taicpu(hp).oper[0]^.val,8)+ ',' + getopstr(taicpu(hp).oper[1]^) ;
owner.AsmWriteLn(s);
end;
A_P_SET_MACRO: A_P_SET_MACRO:
begin begin
s := #9 + '.set' + #9 + 'macro'; s := #9 + '.set' + #9 + 'macro';

View File

@ -27,47 +27,61 @@ interface
uses uses
cutils, cutils,
globtype,
procinfo,cpuinfo, procinfo,cpuinfo,
psub; psub;
type type
{ TMIPSProcInfo }
TMIPSProcInfo=class(tcgprocinfo) TMIPSProcInfo=class(tcgprocinfo)
public intregstart,
floatregstart : aint;
intregssave,
floatregssave : byte;
constructor create(aparent:tprocinfo);override; constructor create(aparent:tprocinfo);override;
function calc_stackframe_size:longint;override; function calc_stackframe_size:longint;override;
procedure set_first_temp_offset;override;
end; end;
implementation implementation
uses uses
systems,globals, systems,globals,
cpubase,cgbase,cgobj,
tgobj,paramgr,symconst; tgobj,paramgr,symconst;
constructor tmipsprocinfo.create(aparent:tprocinfo); constructor TMIPSProcInfo.create(aparent: tprocinfo);
begin begin
inherited create(aparent); inherited create(aparent);
maxpushedparasize:=0; floatregssave:=11;
intregssave:=10;
end;
procedure TMIPSProcInfo.set_first_temp_offset;
begin
{ We allocate enough space to save all registers because we can't determine
the necessary space because the used registers aren't known before
secondpass is run. }
if tg.direction = -1 then
tg.setfirsttemp(0)
else
tg.setfirsttemp(maxpushedparasize+floatregssave*sizeof(aint)+intregssave*sizeof(aint));
end; end;
function TMIPSProcInfo.calc_stackframe_size:longint; function TMIPSProcInfo.calc_stackframe_size:longint;
var
r : byte;
regs: tcpuregisterset;
begin begin
{ result:=maxpushedparasize;
Stackframe layout: floatregstart:=result;
%fp inc(result,floatregssave*4);
<locals> intregstart:=result;
<temp> result:=Align(tg.lasttemp,max(current_settings.alignment.localalignmin,8));
<arguments 6-n for calling>
%sp+92
<space for arguments 0-5> \
<return pointer for calling> | included in first_parm_offset
<register window save area for calling> /
%sp
Alignment must be the max available, as doubles require
8 byte alignment
}
result:=Align(tg.direction*tg.lasttemp+maxpushedparasize+target_info.first_parm_offset,current_settings.alignment.localalignmax);
end; end;

View File

@ -1,6 +1,7 @@
A_NONE, A_NONE,
A_P_STK2, A_P_STK2,
A_P_LW, A_P_LW,
A_P_SET_NOMIPS16,
A_P_SET_NOREORDER, A_P_SET_NOREORDER,
A_P_SET_NOMACRO, A_P_SET_NOMACRO,
A_P_SET_MACRO, A_P_SET_MACRO,

View File

@ -1,13 +1,14 @@
'none', 'none',
'p_stk2', 'p_stk2',
'p_lw', 'p_lw',
'p_set_nomips16',
'p_set_noreorder', 'p_set_noreorder',
'p_set_nomacro', 'p_set_nomacro',
'p_set_macro', 'p_set_macro',
'p_set_reorder', 'p_set_reorder',
'.frame', '.frame',
'p_mask', '.mask',
'p_fmask', '.fmask',
'p_sw', 'p_sw',
'sparc8unimp', 'sparc8unimp',
'nop', 'nop',

View File

@ -871,8 +871,11 @@ implementation
tg.direction:=1; tg.direction:=1;
end; end;
end; end;
{$endif} {$endif}
{$ifdef MIPS}
framepointer:=NR_STACK_POINTER_REG;
tg.direction:=1;
{$endif MIPS}
{ set the start offset to the start of the temp area in the stack } { set the start offset to the start of the temp area in the stack }
set_first_temp_offset; set_first_temp_offset;
end; end;