mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 19:59:18 +02:00
Changed order in stack unravelling RTL code, to match the most common cases.
Fixed unsigned conditions for branch conditions. Added some additional const loading cases. Changed the temporary register used during calls because it could otherwise clash with the argument passing registers. git-svn-id: branches/laksen/riscv_new@39492 -
This commit is contained in:
parent
f3b7e3281a
commit
b98eb3daa9
@ -76,7 +76,7 @@ unit cgrv;
|
||||
|
||||
const
|
||||
TOpCmp2AsmCond: Array[topcmp] of TAsmCond = (C_NONE,C_EQ,C_NONE,
|
||||
C_LT,C_GE,C_None,C_NE,C_NONE,C_LT,C_GE,C_NONE);
|
||||
C_LT,C_GE,C_None,C_NE,C_NONE,C_LTU,C_GEU,C_NONE);
|
||||
|
||||
const
|
||||
TOpCG2AsmConstOp: Array[topcg] of TAsmOp = (A_NONE,
|
||||
@ -98,7 +98,6 @@ unit cgrv;
|
||||
|
||||
procedure tcgrv.a_call_name(list : TAsmList;const s : string; weak: boolean);
|
||||
var
|
||||
tmpreg: TRegister;
|
||||
href: treference;
|
||||
l: TAsmLabel;
|
||||
begin
|
||||
@ -107,26 +106,20 @@ unit cgrv;
|
||||
else
|
||||
reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(s,AT_FUNCTION),0,0,[]);
|
||||
|
||||
tmpreg:=getintregister(list,OS_ADDR);
|
||||
|
||||
current_asmdata.getjumplabel(l);
|
||||
|
||||
a_label(list,l);
|
||||
|
||||
href.refaddr:=addr_pcrel_hi20;
|
||||
list.concat(taicpu.op_reg_ref(A_AUIPC,tmpreg,href));
|
||||
list.concat(taicpu.op_reg_ref(A_AUIPC,NR_RETURN_ADDRESS_REG,href));
|
||||
|
||||
reference_reset_symbol(href,l,0,0,[]);
|
||||
href.refaddr:=addr_pcrel_lo12;
|
||||
list.concat(taicpu.op_reg_reg_ref(A_JALR,NR_RETURN_ADDRESS_REG,tmpreg,href));
|
||||
list.concat(taicpu.op_reg_reg_ref(A_JALR,NR_RETURN_ADDRESS_REG,NR_RETURN_ADDRESS_REG,href));
|
||||
|
||||
{if not(weak) then
|
||||
list.concat(taicpu.op_reg_sym(A_JAL,NR_RETURN_ADDRESS_REG,current_asmdata.RefAsmSymbol(s,AT_FUNCTION)))
|
||||
else
|
||||
list.concat(taicpu.op_reg_sym(A_JAL,NR_RETURN_ADDRESS_REG,current_asmdata.WeakRefAsmSymbol(s,AT_FUNCTION)));}
|
||||
{ not assigned while generating external wrappers }
|
||||
if assigned(current_procinfo) then
|
||||
include(current_procinfo.flags,pi_do_call);
|
||||
{ not assigned while generating external wrappers }
|
||||
if assigned(current_procinfo) then
|
||||
include(current_procinfo.flags,pi_do_call);
|
||||
end;
|
||||
|
||||
|
||||
@ -239,46 +232,41 @@ unit cgrv;
|
||||
|
||||
procedure tcgrv.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister);
|
||||
begin
|
||||
case op of
|
||||
OP_NOT:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src1,-1));
|
||||
maybeadjustresult(list,op,size,dst);
|
||||
end;
|
||||
OP_NEG:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUB,dst,NR_X0,src1));
|
||||
maybeadjustresult(list,op,size,dst);
|
||||
end;
|
||||
OP_MOVE:
|
||||
a_load_reg_reg(list,size,size,src1,dst);
|
||||
if op=OP_NOT then
|
||||
a_op_const_reg_reg(list,OP_XOR,size,-1,src1,dst)
|
||||
else if op=OP_NEG then
|
||||
a_op_reg_reg_reg(list,OP_SUB,size,src1,NR_X0,dst)
|
||||
else
|
||||
{$ifdef RISCV64}
|
||||
if (op=OP_SHL) and
|
||||
(size in [OS_32,OS_S32]) then
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLLW,dst,src2,src1));
|
||||
maybeadjustresult(list,op,size,dst);
|
||||
end
|
||||
else if (op=OP_SHR) and
|
||||
(size in [OS_32,OS_S32]) then
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SRLW,dst,src2,src1));
|
||||
maybeadjustresult(list,op,size,dst);
|
||||
end
|
||||
else if (op=OP_SAR) and
|
||||
(size in [OS_32,OS_S32]) then
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SRAW,dst,src2,src1));
|
||||
maybeadjustresult(list,op,size,dst);
|
||||
end
|
||||
case op of
|
||||
OP_MOVE:
|
||||
a_load_reg_reg(list,size,size,src1,dst);
|
||||
else
|
||||
{$ifdef RISCV64}
|
||||
if (op=OP_SHL) and
|
||||
(size in [OS_32,OS_S32]) then
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLLW,dst,src2,src1));
|
||||
maybeadjustresult(list,op,size,dst);
|
||||
end
|
||||
else if (op=OP_SHR) and
|
||||
(size in [OS_32,OS_S32]) then
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SRLW,dst,src2,src1));
|
||||
maybeadjustresult(list,op,size,dst);
|
||||
end
|
||||
else if (op=OP_SAR) and
|
||||
(size in [OS_32,OS_S32]) then
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SRAW,dst,src2,src1));
|
||||
maybeadjustresult(list,op,size,dst);
|
||||
end
|
||||
else
|
||||
{$endif RISCV64}
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
|
||||
maybeadjustresult(list,op,size,dst);
|
||||
end;
|
||||
end;
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
|
||||
maybeadjustresult(list,op,size,dst);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@ -509,6 +497,8 @@ unit cgrv;
|
||||
end;
|
||||
|
||||
list.concat(taicpu.op_reg_ref(op,reg,href));
|
||||
if fromsize<>tosize then
|
||||
a_load_reg_reg(list,fromsize,tosize,reg,reg);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -96,7 +96,11 @@ implementation
|
||||
var
|
||||
ai: taicpu;
|
||||
begin
|
||||
if (tcgsize2size[fromsize] > tcgsize2size[tosize]) or
|
||||
if (tcgsize2unsigned[tosize]=OS_64) and (fromsize=OS_S32) then
|
||||
list.Concat(taicpu.op_reg_reg_const(A_ADDIW,reg2,reg1,0))
|
||||
else if (tcgsize2unsigned[tosize]=OS_64) and (fromsize=OS_8) then
|
||||
list.Concat(taicpu.op_reg_reg_const(A_ANDI,reg2,reg1,$FF))
|
||||
else if (tcgsize2size[fromsize] > tcgsize2size[tosize]) or
|
||||
((tcgsize2size[fromsize] = tcgsize2size[tosize]) and (fromsize <> tosize)) or
|
||||
{ do we need to mask out the sign when loading from smaller signed to larger unsigned type? }
|
||||
((tcgsize2unsigned[fromsize]<>fromsize) and ((tcgsize2unsigned[tosize]=tosize)) and
|
||||
@ -142,8 +146,7 @@ implementation
|
||||
list.concat(taicpu.op_reg_reg_const(A_ADDI,register,NR_X0,a))
|
||||
else if is_lui_imm(a) then
|
||||
list.concat(taicpu.op_reg_const(A_LUI,register,(a shr 12) and $FFFFF))
|
||||
else if (qword(longint(a))=a) and
|
||||
(size in [OS_32,OS_S32]) then
|
||||
else if (int64(longint(a))=a) then
|
||||
begin
|
||||
if (a and $800)<>0 then
|
||||
list.concat(taicpu.op_reg_const(A_LUI,register,((a shr 12)+1) and $FFFFF))
|
||||
@ -227,6 +230,11 @@ implementation
|
||||
jump if not sum<x
|
||||
}
|
||||
tmpreg:=getintregister(list,OS_INT);
|
||||
if size in [OS_S32,OS_32] then
|
||||
begin
|
||||
a_load_reg_reg(list,size,OS_64,dst,tmpreg);
|
||||
dst:=tmpreg;
|
||||
end;
|
||||
list.Concat(taicpu.op_reg_reg_reg(A_SLTU,tmpreg,dst,src));
|
||||
|
||||
ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,tmpreg,NR_X0,l,0);
|
||||
@ -287,6 +295,12 @@ implementation
|
||||
jump if not sum<x
|
||||
}
|
||||
tmpreg:=getintregister(list,OS_INT);
|
||||
if size in [OS_S32,OS_32] then
|
||||
begin
|
||||
a_load_reg_reg(list,size,OS_64,dst,tmpreg);
|
||||
dst:=tmpreg;
|
||||
end;
|
||||
tmpreg:=getintregister(list,OS_INT);
|
||||
list.Concat(taicpu.op_reg_reg_reg(A_SLTU,tmpreg,dst,src2));
|
||||
|
||||
ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,tmpreg,NR_X0,l,0);
|
||||
|
@ -32,14 +32,14 @@ function get_frame:pointer;assembler;nostackframe;
|
||||
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
|
||||
function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;
|
||||
asm
|
||||
ld a0, -8*2(a0)
|
||||
ld a0, -8*1(a0)
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
|
||||
function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;
|
||||
asm
|
||||
ld a0, -8*1(a0)
|
||||
ld a0, -8*2(a0)
|
||||
end;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user