mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 23:09:18 +02:00
Pass aggregates larger than 2*XLEN as a reference.
Fix load_reg_reg and make it do proper type conversions. Added maybeadjust to tcgrv. git-svn-id: branches/laksen/riscv_new@39485 -
This commit is contained in:
parent
9776ea2afe
commit
2499129ba5
@ -71,6 +71,7 @@ unit cgrv;
|
|||||||
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
|
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
|
||||||
protected
|
protected
|
||||||
function fixref(list: TAsmList; var ref: treference): boolean;
|
function fixref(list: TAsmList; var ref: treference): boolean;
|
||||||
|
procedure maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -202,7 +203,10 @@ unit cgrv;
|
|||||||
|
|
||||||
if (TOpCG2AsmConstOp[op]<>A_None) and
|
if (TOpCG2AsmConstOp[op]<>A_None) and
|
||||||
is_imm12(a) then
|
is_imm12(a) then
|
||||||
list.concat(taicpu.op_reg_reg_const(TOpCG2AsmConstOp[op],dst,src,a))
|
begin
|
||||||
|
list.concat(taicpu.op_reg_reg_const(TOpCG2AsmConstOp[op],dst,src,a));
|
||||||
|
maybeadjustresult(list,op,size,dst);
|
||||||
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
tmpreg:=getintregister(list,size);
|
tmpreg:=getintregister(list,size);
|
||||||
@ -216,13 +220,20 @@ unit cgrv;
|
|||||||
begin
|
begin
|
||||||
case op of
|
case op of
|
||||||
OP_NOT:
|
OP_NOT:
|
||||||
list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src1,-1));
|
begin
|
||||||
|
list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src1,-1));
|
||||||
|
maybeadjustresult(list,op,size,dst);
|
||||||
|
end;
|
||||||
OP_NEG:
|
OP_NEG:
|
||||||
list.concat(taicpu.op_reg_reg_reg(A_SUB,dst,NR_X0,src1));
|
begin
|
||||||
|
list.concat(taicpu.op_reg_reg_reg(A_SUB,dst,NR_X0,src1));
|
||||||
|
maybeadjustresult(list,op,size,dst);
|
||||||
|
end;
|
||||||
OP_MOVE:
|
OP_MOVE:
|
||||||
a_load_reg_reg(list,size,size,src1,dst);
|
a_load_reg_reg(list,size,size,src1,dst);
|
||||||
else
|
else
|
||||||
list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
|
list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
|
||||||
|
maybeadjustresult(list,op,size,dst);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -652,4 +663,14 @@ unit cgrv;
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcgrv.maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister);
|
||||||
|
const
|
||||||
|
overflowops = [OP_MUL,OP_IMUL,OP_SHL,OP_ADD,OP_SUB,OP_NOT,OP_NEG];
|
||||||
|
begin
|
||||||
|
if (op in overflowops) and
|
||||||
|
(size in [OS_8,OS_S8,OS_16,OS_S16{$ifdef RISCV64},OS_32,OS_S32{$endif RISCV64}]) then
|
||||||
|
a_load_reg_reg(list,OS_INT,size,dst,dst)
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -96,32 +96,36 @@ implementation
|
|||||||
var
|
var
|
||||||
ai: taicpu;
|
ai: taicpu;
|
||||||
begin
|
begin
|
||||||
if (fromsize=tosize) or
|
if (tcgsize2size[fromsize] > tcgsize2size[tosize]) or
|
||||||
((tcgsize2unsigned[fromsize]=tcgsize2unsigned[tosize]) and
|
((tcgsize2size[fromsize] = tcgsize2size[tosize]) and (fromsize <> tosize)) or
|
||||||
(tcgsize2unsigned[fromsize]=OS_64)) then
|
{ 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
|
||||||
|
(tcgsize2size[fromsize] < tcgsize2size[tosize]) and (tcgsize2size[tosize] <> sizeof(pint)) ) then
|
||||||
|
begin
|
||||||
|
if tcgsize2size[fromsize]<tcgsize2size[tosize] then
|
||||||
|
begin
|
||||||
|
list.Concat(taicpu.op_reg_reg_const(A_SLLI,reg2,reg1,8*(8-tcgsize2size[fromsize])));
|
||||||
|
|
||||||
|
if tcgsize2unsigned[fromsize]<>fromsize then
|
||||||
|
list.Concat(taicpu.op_reg_reg_const(A_SRAI,reg2,reg2,8*(tcgsize2size[tosize]-tcgsize2size[fromsize])))
|
||||||
|
else
|
||||||
|
list.Concat(taicpu.op_reg_reg_const(A_SRLI,reg2,reg2,8*(tcgsize2size[tosize]-tcgsize2size[fromsize])));
|
||||||
|
end
|
||||||
|
else if tcgsize2unsigned[tosize]<>OS_64 then
|
||||||
|
list.Concat(taicpu.op_reg_reg_const(A_SLLI,reg2,reg1,8*(8-tcgsize2size[tosize])))
|
||||||
|
else
|
||||||
|
a_load_reg_reg(list,tosize,tosize,reg1,reg2);
|
||||||
|
|
||||||
|
if tcgsize2unsigned[tosize]=tosize then
|
||||||
|
list.Concat(taicpu.op_reg_reg_const(A_SRLI,reg2,reg2,8*(8-tcgsize2size[tosize])))
|
||||||
|
else
|
||||||
|
list.Concat(taicpu.op_reg_reg_const(A_SRAI,reg2,reg2,8*(8-tcgsize2size[tosize])));
|
||||||
|
end
|
||||||
|
else
|
||||||
begin
|
begin
|
||||||
ai:=taicpu.op_reg_reg_const(A_ADDI,reg2,reg1,0);
|
ai:=taicpu.op_reg_reg_const(A_ADDI,reg2,reg1,0);
|
||||||
list.concat(ai);
|
list.concat(ai);
|
||||||
rg[R_INTREGISTER].add_move_instruction(ai);
|
rg[R_INTREGISTER].add_move_instruction(ai);
|
||||||
end
|
|
||||||
{else if (fromsize=OS_S32) then
|
|
||||||
list.Concat(taicpu.op_reg_reg_const(A_ADDIW,reg2,reg1,0))
|
|
||||||
else if (fromsize=OS_8) then
|
|
||||||
list.Concat(taicpu.op_reg_reg_const(A_ANDI,reg2,reg1,$FF))}
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if tcgsize2size[tosize]<tcgsize2size[fromsize] then
|
|
||||||
fromsize:=tosize;
|
|
||||||
|
|
||||||
if tcgsize2unsigned[fromsize]<>OS_64 then
|
|
||||||
list.Concat(taicpu.op_reg_reg_const(A_SLLI,reg2,reg1,8*(8-tcgsize2size[fromsize])))
|
|
||||||
else
|
|
||||||
a_load_reg_reg(list,fromsize,fromsize,reg1,reg2);
|
|
||||||
|
|
||||||
if tcgsize2unsigned[fromsize]=fromsize then
|
|
||||||
list.Concat(taicpu.op_reg_reg_const(A_SRLI,reg2,reg2,8*(8-tcgsize2size[fromsize])))
|
|
||||||
else
|
|
||||||
list.Concat(taicpu.op_reg_reg_const(A_SRAI,reg2,reg2,8*(8-tcgsize2size[fromsize])));
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -172,15 +172,7 @@ implementation
|
|||||||
result := true;
|
result := true;
|
||||||
procvardef,
|
procvardef,
|
||||||
recorddef:
|
recorddef:
|
||||||
result :=
|
result := (def.size > 8);
|
||||||
(varspez = vs_const) and
|
|
||||||
(
|
|
||||||
(
|
|
||||||
(not (calloption in [pocall_cdecl, pocall_cppdecl]) and
|
|
||||||
(def.size > 8))
|
|
||||||
) or
|
|
||||||
(calloption = pocall_mwpascal)
|
|
||||||
);
|
|
||||||
arraydef:
|
arraydef:
|
||||||
result := (tarraydef(def).highrange >= tarraydef(def).lowrange) or
|
result := (tarraydef(def).highrange >= tarraydef(def).lowrange) or
|
||||||
is_open_array(def) or
|
is_open_array(def) or
|
||||||
|
Loading…
Reference in New Issue
Block a user