mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-25 00:29:25 +02:00
* fixed procedure entry/exit code
* started to fix reference handling
This commit is contained in:
parent
04501b6fff
commit
301df6dab9
@ -42,6 +42,7 @@ uses
|
|||||||
oppostfix : TOpPostfix;
|
oppostfix : TOpPostfix;
|
||||||
roundingmode : troundingmode;
|
roundingmode : troundingmode;
|
||||||
procedure loadshifterop(opidx:longint;const so:tshifterop);
|
procedure loadshifterop(opidx:longint;const so:tshifterop);
|
||||||
|
procedure loadregset(opidx:longint;const s:tsupregset);
|
||||||
constructor op_none(op : tasmop);
|
constructor op_none(op : tasmop);
|
||||||
|
|
||||||
constructor op_reg(op : tasmop;_op1 : tregister);
|
constructor op_reg(op : tasmop;_op1 : tregister);
|
||||||
@ -50,6 +51,7 @@ uses
|
|||||||
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_reg_regset(op:tasmop; _op1: tregister; _op2: tsupregset);
|
||||||
|
|
||||||
constructor op_const_const(op : tasmop;_op1,_op2 : longint);
|
constructor op_const_const(op : tasmop;_op1,_op2 : longint);
|
||||||
|
|
||||||
@ -108,13 +110,30 @@ implementation
|
|||||||
with oper[opidx] do
|
with oper[opidx] do
|
||||||
begin
|
begin
|
||||||
if typ<>top_shifterop then
|
if typ<>top_shifterop then
|
||||||
new(shifterop);
|
begin
|
||||||
|
clearop(opidx);
|
||||||
|
new(shifterop);
|
||||||
|
end;
|
||||||
shifterop^:=so;
|
shifterop^:=so;
|
||||||
typ:=top_shifterop;
|
typ:=top_shifterop;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure taicpu.loadregset(opidx:longint;const s:tsupregset);
|
||||||
|
begin
|
||||||
|
if opidx>=ops then
|
||||||
|
ops:=opidx+1;
|
||||||
|
with oper[opidx] do
|
||||||
|
begin
|
||||||
|
if typ<>top_regset then
|
||||||
|
clearop(opidx);
|
||||||
|
regset:=s;
|
||||||
|
typ:=top_regset;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
taicpu Constructors
|
taicpu Constructors
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -167,6 +186,17 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
constructor taicpu.op_reg_regset(op:tasmop; _op1: tregister; _op2: tsupregset);
|
||||||
|
begin
|
||||||
|
inherited create(op);
|
||||||
|
if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then
|
||||||
|
internalerror(2003031208);
|
||||||
|
ops:=2;
|
||||||
|
loadreg(0,_op1);
|
||||||
|
loadregset(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
|
||||||
inherited create(op);
|
inherited create(op);
|
||||||
@ -693,7 +723,11 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.6 2003-08-28 00:05:29 florian
|
Revision 1.7 2003-08-29 21:36:28 florian
|
||||||
|
* fixed procedure entry/exit code
|
||||||
|
* started to fix reference handling
|
||||||
|
|
||||||
|
Revision 1.6 2003/08/28 00:05:29 florian
|
||||||
* today's arm patches
|
* today's arm patches
|
||||||
|
|
||||||
Revision 1.5 2003/08/27 00:27:56 florian
|
Revision 1.5 2003/08/27 00:27:56 florian
|
||||||
|
@ -43,6 +43,10 @@ unit agarmgas;
|
|||||||
var
|
var
|
||||||
gas_reg2str : reg2strtable;
|
gas_reg2str : reg2strtable;
|
||||||
|
|
||||||
|
const
|
||||||
|
gas_shiftmode2str : array[tshiftmode] of string[3] = (
|
||||||
|
'','lsl','lsr','asr','ror','rrx');
|
||||||
|
|
||||||
function gas_regnum_search(const s:string):Tnewregister;
|
function gas_regnum_search(const s:string):Tnewregister;
|
||||||
function gas_regname(const r:Tnewregister):string;
|
function gas_regname(const r:Tnewregister):string;
|
||||||
|
|
||||||
@ -77,50 +81,62 @@ unit agarmgas;
|
|||||||
);
|
);
|
||||||
|
|
||||||
function getreferencestring(var ref : treference) : string;
|
function getreferencestring(var ref : treference) : string;
|
||||||
var
|
var
|
||||||
s : string;
|
s : string;
|
||||||
begin
|
nobase,noindex : boolean;
|
||||||
with ref do
|
begin
|
||||||
begin
|
with ref do
|
||||||
inc(offset,offsetfixup);
|
begin
|
||||||
|
inc(offset,offsetfixup);
|
||||||
|
|
||||||
if not assigned(symbol) then
|
noindex:=(index.enum=R_NO) or ((index.enum=R_INTREGISTER) and (index.number=NR_NO));
|
||||||
s := '['
|
{$ifdef extdebug}
|
||||||
else
|
nobase:=(base.enum=R_NO) or ((base.enum=R_INTREGISTER) and (base.number=NR_NO));
|
||||||
s:='['+symbol.name;
|
//!!!! if nobase then
|
||||||
|
//!!!! internalerror(200308292);
|
||||||
|
|
||||||
if offset<0 then
|
// !!! if (not(noindex) or (shiftmode<>SM_None)) and ((offset<>0) or (symbol<>nil)) then
|
||||||
s:=s+tostr(offset)
|
// !!! internalerror(200308293);
|
||||||
else
|
{$endif extdebug}
|
||||||
if (offset>0) then
|
if base.enum=R_INTREGISTER then
|
||||||
begin
|
s:='['+gas_regname(base.number)
|
||||||
if assigned(symbol) then
|
else
|
||||||
s:=s+'+'+tostr(offset)
|
s:='['+gas_reg2str[base.enum];
|
||||||
else
|
if addressmode=AM_POSTINDEXED then
|
||||||
s:=s+tostr(offset);
|
s:=s+']';
|
||||||
end;
|
|
||||||
|
|
||||||
if (index.enum=R_NO) and (base.enum<>R_NO) then
|
if not(noindex) then
|
||||||
begin
|
begin
|
||||||
if offset=0 then
|
if signindex<0 then
|
||||||
begin
|
s:=s+', -'
|
||||||
if assigned(symbol) then
|
else
|
||||||
s:=s+'+0'
|
s:=s+', ';
|
||||||
else
|
|
||||||
s:=s+'0';
|
if index.enum=R_INTREGISTER then
|
||||||
end;
|
s:=s+gas_regname(index.number)
|
||||||
if base.enum=R_INTREGISTER then
|
else
|
||||||
s:=s+'('+gas_regname(base.number)+')'
|
s:=s+gas_reg2str[index.enum];
|
||||||
else
|
|
||||||
s:=s+'('+gas_reg2str[base.enum]+')';
|
if shiftmode<>SM_None then
|
||||||
end
|
s:=s+' ,'+gas_shiftmode2str[shiftmode]+' #'+tostr(shiftimm);
|
||||||
else if (index.enum<>R_NO) and (base.enum<>R_NO) and (offset=0) then
|
end
|
||||||
s:=s+std_reg2str[base.enum]+','+std_reg2str[index.enum]
|
else
|
||||||
else if ((index.enum<>R_NO) or (base.enum<>R_NO)) then
|
begin
|
||||||
internalerror(19992);
|
{ handle symbol and index }
|
||||||
end;
|
if offset<>0 then
|
||||||
getreferencestring:=s;
|
s:=s+', #'+tostr(offset);
|
||||||
end;
|
{ !!!!!}
|
||||||
|
end;
|
||||||
|
|
||||||
|
case addressmode of
|
||||||
|
AM_OFFSET:
|
||||||
|
s:=s+']';
|
||||||
|
AM_PREINDEXED:
|
||||||
|
s:=s+']!';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
getreferencestring:=s;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function getopstr_jmp(const o:toper) : string;
|
function getopstr_jmp(const o:toper) : string;
|
||||||
@ -170,6 +186,8 @@ unit agarmgas;
|
|||||||
function getopstr(const o:toper) : string;
|
function getopstr(const o:toper) : string;
|
||||||
var
|
var
|
||||||
hs : string;
|
hs : string;
|
||||||
|
first : boolean;
|
||||||
|
r : tnewregister;
|
||||||
begin
|
begin
|
||||||
case o.typ of
|
case o.typ of
|
||||||
top_reg:
|
top_reg:
|
||||||
@ -194,6 +212,20 @@ unit agarmgas;
|
|||||||
end;
|
end;
|
||||||
top_const:
|
top_const:
|
||||||
getopstr:='#'+tostr(longint(o.val));
|
getopstr:='#'+tostr(longint(o.val));
|
||||||
|
top_regset:
|
||||||
|
begin
|
||||||
|
getopstr:='{';
|
||||||
|
first:=true;
|
||||||
|
for r:=RS_R0 to RS_R15 do
|
||||||
|
if r in o.regset then
|
||||||
|
begin
|
||||||
|
if not(first) then
|
||||||
|
getopstr:=getopstr+',';
|
||||||
|
getopstr:=getopstr+'r'+tostr(r-RS_R0);
|
||||||
|
first:=false;
|
||||||
|
end;
|
||||||
|
getopstr:=getopstr+'}';
|
||||||
|
end;
|
||||||
top_ref:
|
top_ref:
|
||||||
getopstr:=getreferencestring(o.ref^);
|
getopstr:=getreferencestring(o.ref^);
|
||||||
top_symbol:
|
top_symbol:
|
||||||
@ -225,9 +257,9 @@ unit agarmgas;
|
|||||||
sep: string[3];
|
sep: string[3];
|
||||||
begin
|
begin
|
||||||
op:=taicpu(hp).opcode;
|
op:=taicpu(hp).opcode;
|
||||||
|
{
|
||||||
if is_calljmp(op) then
|
if is_calljmp(op) then
|
||||||
begin
|
begin
|
||||||
{
|
|
||||||
{ direct BO/BI in op[0] and op[1] not supported, put them in condition! }
|
{ direct BO/BI in op[0] and op[1] not supported, put them in condition! }
|
||||||
case op of
|
case op of
|
||||||
A_B,A_BA,A_BL,A_BLA:
|
A_B,A_BA,A_BL,A_BLA:
|
||||||
@ -240,12 +272,12 @@ unit agarmgas;
|
|||||||
|
|
||||||
if (taicpu(hp).oper[0].typ <> top_none) then
|
if (taicpu(hp).oper[0].typ <> top_none) then
|
||||||
s:=s+getopstr_jmp(taicpu(hp).oper[0]);
|
s:=s+getopstr_jmp(taicpu(hp).oper[0]);
|
||||||
}
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
}
|
||||||
{ process operands }
|
{ process operands }
|
||||||
begin
|
begin
|
||||||
s:=#9+std_op2str[op];
|
s:=#9+std_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix];
|
||||||
if taicpu(hp).ops<>0 then
|
if taicpu(hp).ops<>0 then
|
||||||
begin
|
begin
|
||||||
{
|
{
|
||||||
@ -292,7 +324,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.5 2003-08-28 13:26:10 florian
|
Revision 1.6 2003-08-29 21:36:28 florian
|
||||||
|
* fixed procedure entry/exit code
|
||||||
|
* started to fix reference handling
|
||||||
|
|
||||||
|
Revision 1.5 2003/08/28 13:26:10 florian
|
||||||
* another couple of arm fixes
|
* another couple of arm fixes
|
||||||
|
|
||||||
Revision 1.4 2003/08/28 00:05:29 florian
|
Revision 1.4 2003/08/28 00:05:29 florian
|
||||||
|
@ -54,6 +54,7 @@ unit cgcpu;
|
|||||||
size: tcgsize; src1, src2, dst: tregister); override;
|
size: tcgsize; src1, src2, dst: tregister); override;
|
||||||
|
|
||||||
{ move instructions }
|
{ move instructions }
|
||||||
|
procedure handle_load_store(list:taasmoutput;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference);
|
||||||
procedure a_load_const_reg(list : taasmoutput; size: tcgsize; a : aword;reg : tregister);override;
|
procedure a_load_const_reg(list : taasmoutput; size: tcgsize; a : aword;reg : tregister);override;
|
||||||
procedure a_load_reg_ref(list : taasmoutput; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);override;
|
procedure a_load_reg_ref(list : taasmoutput; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);override;
|
||||||
procedure a_load_ref_reg(list : taasmoutput; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);override;
|
procedure a_load_ref_reg(list : taasmoutput; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);override;
|
||||||
@ -267,7 +268,7 @@ unit cgcpu;
|
|||||||
tmpreg : tregister;
|
tmpreg : tregister;
|
||||||
so : tshifterop;
|
so : tshifterop;
|
||||||
begin
|
begin
|
||||||
if is_shifter_const(a,shift) and (op<>OP_MUL) then
|
if is_shifter_const(a,shift) and (not(op in [OP_IMUL,OP_MUL])) then
|
||||||
case op of
|
case op of
|
||||||
OP_NEG,OP_NOT,
|
OP_NEG,OP_NOT,
|
||||||
OP_DIV,OP_IDIV:
|
OP_DIV,OP_IDIV:
|
||||||
@ -316,6 +317,7 @@ unit cgcpu;
|
|||||||
size: tcgsize; src1, src2, dst: tregister);
|
size: tcgsize; src1, src2, dst: tregister);
|
||||||
var
|
var
|
||||||
so : tshifterop;
|
so : tshifterop;
|
||||||
|
tmpreg : tregister;
|
||||||
begin
|
begin
|
||||||
case op of
|
case op of
|
||||||
OP_NEG:
|
OP_NEG:
|
||||||
@ -345,6 +347,23 @@ unit cgcpu;
|
|||||||
so.shiftertype:=SO_LSL;
|
so.shiftertype:=SO_LSL;
|
||||||
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src1,so));
|
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src1,so));
|
||||||
end;
|
end;
|
||||||
|
OP_IMUL,
|
||||||
|
OP_MUL:
|
||||||
|
begin
|
||||||
|
{ the arm doesn't allow that rd and rm are the same }
|
||||||
|
if dst.number=src2.number then
|
||||||
|
begin
|
||||||
|
if src1.number<>src2.number then
|
||||||
|
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,src1,src2))
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
writeln('Warning: Fix MUL');
|
||||||
|
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,src2,src1));
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,src2,src1));
|
||||||
|
end;
|
||||||
else
|
else
|
||||||
list.concat(taicpu.op_reg_reg_reg(op_reg_reg_opcg2asmop[op],dst,src2,src1));
|
list.concat(taicpu.op_reg_reg_reg(op_reg_reg_opcg2asmop[op],dst,src2,src1));
|
||||||
end;
|
end;
|
||||||
@ -398,13 +417,128 @@ unit cgcpu;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcgarm.handle_load_store(list:taasmoutput;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference);
|
||||||
|
var
|
||||||
|
tmpreg : tregister;
|
||||||
|
tmpref : treference;
|
||||||
|
instr : taicpu;
|
||||||
|
begin
|
||||||
|
tmpreg.enum:=R_INTREGISTER;
|
||||||
|
tmpreg.number:=NR_NO;
|
||||||
|
|
||||||
|
{ Be sure to have a base register }
|
||||||
|
if (ref.base.number=NR_NO) then
|
||||||
|
begin
|
||||||
|
if ref.shiftmode<>SM_None then
|
||||||
|
internalerror(200308294);
|
||||||
|
ref.base:=ref.index;
|
||||||
|
ref.index.number:=NR_NO;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ When need to use SETHI, do it first }
|
||||||
|
if assigned(ref.symbol) or
|
||||||
|
(ref.offset<-4095) or
|
||||||
|
(ref.offset>4095) then
|
||||||
|
begin
|
||||||
|
{
|
||||||
|
tmpreg:=rg.getregisterint(list,OS_INT);
|
||||||
|
reference_reset(tmpref);
|
||||||
|
tmpref.symbol:=ref.symbol;
|
||||||
|
tmpref.offset:=ref.offset;
|
||||||
|
tmpref.symaddr:=refs_hi;
|
||||||
|
list.concat(taicpu.op_ref_reg(A_SETHI,tmpref,tmpreg));
|
||||||
|
{ Load the low part is left }
|
||||||
|
{$warning TODO Maybe not needed to load symbol}
|
||||||
|
tmpref.symaddr:=refs_lo;
|
||||||
|
list.concat(taicpu.op_reg_ref_reg(A_OR,tmpreg,tmpref,tmpreg));
|
||||||
|
{ The offset and symbol are loaded, reset in reference }
|
||||||
|
ref.offset:=0;
|
||||||
|
ref.symbol:=nil;
|
||||||
|
{ Only an index register or offset is allowed }
|
||||||
|
if tmpreg.number<>NR_NO then
|
||||||
|
begin
|
||||||
|
if (ref.index.number<>NR_NO) then
|
||||||
|
begin
|
||||||
|
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,ref.index,tmpreg));
|
||||||
|
ref.index:=tmpreg;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if ref.base.number<>NR_NO then
|
||||||
|
ref.index:=tmpreg
|
||||||
|
else
|
||||||
|
ref.base:=tmpreg;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
end;
|
||||||
|
{
|
||||||
|
if (ref.base.number<>NR_NO) then
|
||||||
|
begin
|
||||||
|
if (ref.index.number<>NR_NO) and
|
||||||
|
((ref.offset<>0) or assigned(ref.symbol)) then
|
||||||
|
begin
|
||||||
|
if tmpreg.number=NR_NO then
|
||||||
|
tmpreg:=rg.getregisterint(list,OS_INT);
|
||||||
|
if (ref.index.number<>NR_NO) then
|
||||||
|
begin
|
||||||
|
list.concat(taicpu.op_reg_reg_reg(A_ADD,ref.base,ref.index,tmpreg));
|
||||||
|
ref.index.number:=NR_NO;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
instr:=taicpu.op_reg_ref(op,reg,ref);
|
||||||
|
instr.oppostfix:=oppostfix;
|
||||||
|
list.concat(instr);
|
||||||
|
if (tmpreg.number<>NR_NO) then
|
||||||
|
rg.ungetregisterint(list,tmpreg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcgarm.a_load_reg_ref(list : taasmoutput; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);
|
procedure tcgarm.a_load_reg_ref(list : taasmoutput; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);
|
||||||
|
var
|
||||||
|
oppostfix:toppostfix;
|
||||||
begin
|
begin
|
||||||
|
case ToSize of
|
||||||
|
{ signed integer registers }
|
||||||
|
OS_8,
|
||||||
|
OS_S8:
|
||||||
|
oppostfix:=PF_B;
|
||||||
|
OS_16,
|
||||||
|
OS_S16:
|
||||||
|
oppostfix:=PF_H;
|
||||||
|
OS_32,
|
||||||
|
OS_S32:
|
||||||
|
oppostfix:=PF_None;
|
||||||
|
else
|
||||||
|
InternalError(200308295);
|
||||||
|
end;
|
||||||
|
handle_load_store(list,A_STR,oppostfix,reg,ref);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcgarm.a_load_ref_reg(list : taasmoutput; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);
|
procedure tcgarm.a_load_ref_reg(list : taasmoutput; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);
|
||||||
|
var
|
||||||
|
oppostfix:toppostfix;
|
||||||
begin
|
begin
|
||||||
|
case ToSize of
|
||||||
|
{ signed integer registers }
|
||||||
|
OS_8:
|
||||||
|
oppostfix:=PF_B;
|
||||||
|
OS_S8:
|
||||||
|
oppostfix:=PF_SB;
|
||||||
|
OS_16:
|
||||||
|
oppostfix:=PF_H;
|
||||||
|
OS_S16:
|
||||||
|
oppostfix:=PF_SH;
|
||||||
|
OS_32,
|
||||||
|
OS_S32:
|
||||||
|
oppostfix:=PF_None;
|
||||||
|
else
|
||||||
|
InternalError(200308291);
|
||||||
|
end;
|
||||||
|
handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -522,12 +656,59 @@ unit cgcpu;
|
|||||||
|
|
||||||
|
|
||||||
procedure tcgarm.g_stackframe_entry(list : taasmoutput;localsize : longint);
|
procedure tcgarm.g_stackframe_entry(list : taasmoutput;localsize : longint);
|
||||||
|
var
|
||||||
|
rip,rsp,rfp : tregister;
|
||||||
|
instr : taicpu;
|
||||||
begin
|
begin
|
||||||
|
rsp.enum:=R_INTREGISTER;
|
||||||
|
rsp.number:=NR_STACK_POINTER_REG;
|
||||||
|
a_reg_alloc(list,rsp);
|
||||||
|
|
||||||
|
rfp.enum:=R_INTREGISTER;
|
||||||
|
rfp.number:=NR_FRAME_POINTER_REG;
|
||||||
|
a_reg_alloc(list,rfp);
|
||||||
|
|
||||||
|
rip.enum:=R_INTREGISTER;
|
||||||
|
rip.number:=NR_R12;
|
||||||
|
a_reg_alloc(list,rip);
|
||||||
|
|
||||||
|
list.concat(taicpu.op_reg_reg(A_MOV,rip,rsp));
|
||||||
|
{ restore int registers and return }
|
||||||
|
instr:=taicpu.op_reg_regset(A_STM,rsp,rg.used_in_proc_int-[RS_R0..RS_R4]+[RS_R11,RS_R12,RS_R15]);
|
||||||
|
instr.oppostfix:=PF_FD;
|
||||||
|
list.concat(instr);
|
||||||
|
|
||||||
|
list.concat(taicpu.op_reg_reg_const(A_SUB,rfp,rip,4));
|
||||||
|
a_reg_alloc(list,rip);
|
||||||
|
|
||||||
|
{ allocate necessary stack size }
|
||||||
|
list.concat(taicpu.op_reg_reg_const(A_SUB,rsp,rsp,4));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcgarm.g_return_from_proc(list : taasmoutput;parasize : aword);
|
procedure tcgarm.g_return_from_proc(list : taasmoutput;parasize : aword);
|
||||||
|
var
|
||||||
|
r1,r2 : tregister;
|
||||||
|
instr : taicpu;
|
||||||
begin
|
begin
|
||||||
|
if (current_procinfo.framepointer.number=NR_STACK_POINTER_REG) then
|
||||||
|
begin
|
||||||
|
r1.enum:=R_INTREGISTER;
|
||||||
|
r1.number:=NR_R15;
|
||||||
|
r2.enum:=R_INTREGISTER;
|
||||||
|
r2.number:=NR_R14;
|
||||||
|
|
||||||
|
list.concat(taicpu.op_reg_reg(A_MOV,r1,r2));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
r1.enum:=R_INTREGISTER;
|
||||||
|
r1.number:=NR_R11;
|
||||||
|
{ restore int registers and return }
|
||||||
|
instr:=taicpu.op_reg_regset(A_LDM,r1,rg.used_in_proc_int-[RS_R0..RS_R4]+[RS_R11,RS_R13,RS_R15]);
|
||||||
|
instr.oppostfix:=PF_EA;
|
||||||
|
list.concat(instr);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -617,7 +798,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.7 2003-08-28 13:26:10 florian
|
Revision 1.8 2003-08-29 21:36:28 florian
|
||||||
|
* fixed procedure entry/exit code
|
||||||
|
* started to fix reference handling
|
||||||
|
|
||||||
|
Revision 1.7 2003/08/28 13:26:10 florian
|
||||||
* another couple of arm fixes
|
* another couple of arm fixes
|
||||||
|
|
||||||
Revision 1.6 2003/08/28 00:05:29 florian
|
Revision 1.6 2003/08/28 00:05:29 florian
|
||||||
|
@ -134,7 +134,7 @@ uses
|
|||||||
last_supreg = RS_R15;
|
last_supreg = RS_R15;
|
||||||
|
|
||||||
{ registers which may be destroyed by calls }
|
{ registers which may be destroyed by calls }
|
||||||
VOLATILE_INTREGISTERS = [RS_R0..RS_R3];
|
VOLATILE_INTREGISTERS = [RS_R0..RS_R3,RS_R12..RS_R15];
|
||||||
VOLATILE_FPUREGISTERS = [R_F0..R_F3];
|
VOLATILE_FPUREGISTERS = [R_F0..R_F3];
|
||||||
|
|
||||||
{ Number of first and last imaginary register. }
|
{ Number of first and last imaginary register. }
|
||||||
@ -201,7 +201,7 @@ uses
|
|||||||
{ load/store }
|
{ load/store }
|
||||||
PF_B,PF_SB,PF_BT,PF_H,PF_SH,PF_T,
|
PF_B,PF_SB,PF_BT,PF_H,PF_SH,PF_T,
|
||||||
{ multiple load/store address modes }
|
{ multiple load/store address modes }
|
||||||
PF_IA,PF_IB,PF_DA,PF_DB,PF_DF,PF_FA,PF_ED,PF_EA
|
PF_IA,PF_IB,PF_DA,PF_DB,PF_FD,PF_FA,PF_ED,PF_EA
|
||||||
);
|
);
|
||||||
|
|
||||||
TRoundingMode = (RM_None,RM_P,RM_M,RM_Z);
|
TRoundingMode = (RM_None,RM_P,RM_M,RM_Z);
|
||||||
@ -211,7 +211,7 @@ uses
|
|||||||
's',
|
's',
|
||||||
'd','e','p','ep',
|
'd','e','p','ep',
|
||||||
'b','sb','bt','h','sh','t',
|
'b','sb','bt','h','sh','t',
|
||||||
'ia','ib','da','db','df','fa','ed','ea');
|
'ia','ib','da','db','fd','fa','ed','ea');
|
||||||
|
|
||||||
roundingmode2str : array[TRoundingMode] of string[1] = ('',
|
roundingmode2str : array[TRoundingMode] of string[1] = ('',
|
||||||
'p','m','z');
|
'p','m','z');
|
||||||
@ -253,14 +253,15 @@ uses
|
|||||||
trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
|
trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
|
||||||
|
|
||||||
taddressmode = (AM_OFFSET,AM_PREINDEXED,AM_POSTINDEXED);
|
taddressmode = (AM_OFFSET,AM_PREINDEXED,AM_POSTINDEXED);
|
||||||
tshiftmode = (SM_LSL,SM_LSR,SM_ASR,SM_ROR,SM_RRX);
|
tshiftmode = (SM_None,SM_LSL,SM_LSR,SM_ASR,SM_ROR,SM_RRX);
|
||||||
|
|
||||||
{ reference record }
|
{ reference record }
|
||||||
preference = ^treference;
|
preference = ^treference;
|
||||||
treference = packed record
|
treference = packed record
|
||||||
base,
|
base,
|
||||||
index : tregister;
|
index : tregister;
|
||||||
scalefactor : byte;
|
shiftimm : byte;
|
||||||
|
signindex : shortint;
|
||||||
offset : longint;
|
offset : longint;
|
||||||
symbol : tasmsymbol;
|
symbol : tasmsymbol;
|
||||||
offsetfixup : longint;
|
offsetfixup : longint;
|
||||||
@ -483,8 +484,8 @@ uses
|
|||||||
Constants
|
Constants
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
firstsaveintreg = R_R4;
|
firstsaveintreg = RS_R4;
|
||||||
lastsaveintreg = R_R10;
|
lastsaveintreg = RS_R10;
|
||||||
firstsavefpureg = R_F4;
|
firstsavefpureg = R_F4;
|
||||||
lastsavefpureg = R_F7;
|
lastsavefpureg = R_F7;
|
||||||
firstsavemmreg = R_S16;
|
firstsavemmreg = R_S16;
|
||||||
@ -690,7 +691,11 @@ uses
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.8 2003-08-28 00:05:29 florian
|
Revision 1.9 2003-08-29 21:36:28 florian
|
||||||
|
* fixed procedure entry/exit code
|
||||||
|
* started to fix reference handling
|
||||||
|
|
||||||
|
Revision 1.8 2003/08/28 00:05:29 florian
|
||||||
* today's arm patches
|
* today's arm patches
|
||||||
|
|
||||||
Revision 1.7 2003/08/25 23:20:38 florian
|
Revision 1.7 2003/08/25 23:20:38 florian
|
||||||
|
Loading…
Reference in New Issue
Block a user