summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-07-22 14:15:29 +0000
committerlaksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-07-22 14:15:29 +0000
commit1b7c2166643e3faae1a65cd336dbcb7e8bceb807 (patch)
tree29da1bf06f016d687fbf533752c9d88b2e786325
parent1d5ca183eb50c4f58fc531dab487b9d1745886b5 (diff)
downloadfpc-1b7c2166643e3faae1a65cd336dbcb7e8bceb807.tar.gz
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: https://svn.freepascal.org/svn/fpc/branches/laksen@39485 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--riscv_new/compiler/riscv/cgrv.pas27
-rw-r--r--riscv_new/compiler/riscv64/cgcpu.pas46
-rw-r--r--riscv_new/compiler/riscv64/cpupara.pas10
3 files changed, 50 insertions, 33 deletions
diff --git a/riscv_new/compiler/riscv/cgrv.pas b/riscv_new/compiler/riscv/cgrv.pas
index e340bebd93..ee739183ad 100644
--- a/riscv_new/compiler/riscv/cgrv.pas
+++ b/riscv_new/compiler/riscv/cgrv.pas
@@ -71,6 +71,7 @@ unit cgrv;
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
protected
function fixref(list: TAsmList; var ref: treference): boolean;
+ procedure maybeadjustresult(list: TAsmList; op: topcg; size: tcgsize; dst: tregister);
end;
const
@@ -202,7 +203,10 @@ unit cgrv;
if (TOpCG2AsmConstOp[op]<>A_None) and
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
begin
tmpreg:=getintregister(list,size);
@@ -216,13 +220,20 @@ unit cgrv;
begin
case op of
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:
- 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:
a_load_reg_reg(list,size,size,src1,dst);
else
list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
+ maybeadjustresult(list,op,size,dst);
end;
end;
@@ -652,4 +663,14 @@ unit cgrv;
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.
diff --git a/riscv_new/compiler/riscv64/cgcpu.pas b/riscv_new/compiler/riscv64/cgcpu.pas
index 6e8c584235..429b128b11 100644
--- a/riscv_new/compiler/riscv64/cgcpu.pas
+++ b/riscv_new/compiler/riscv64/cgcpu.pas
@@ -96,32 +96,36 @@ implementation
var
ai: taicpu;
begin
- if (fromsize=tosize) or
- ((tcgsize2unsigned[fromsize]=tcgsize2unsigned[tosize]) and
- (tcgsize2unsigned[fromsize]=OS_64)) then
+ 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
+ (tcgsize2size[fromsize] < tcgsize2size[tosize]) and (tcgsize2size[tosize] <> sizeof(pint)) ) then
begin
- ai:=taicpu.op_reg_reg_const(A_ADDI,reg2,reg1,0);
- list.concat(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 tcgsize2size[fromsize]<tcgsize2size[tosize] then
+ begin
+ list.Concat(taicpu.op_reg_reg_const(A_SLLI,reg2,reg1,8*(8-tcgsize2size[fromsize])));
- if tcgsize2unsigned[fromsize]<>OS_64 then
- 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,fromsize,fromsize,reg1,reg2);
+ a_load_reg_reg(list,tosize,tosize,reg1,reg2);
- if tcgsize2unsigned[fromsize]=fromsize then
- list.Concat(taicpu.op_reg_reg_const(A_SRLI,reg2,reg2,8*(8-tcgsize2size[fromsize])))
+ 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[fromsize])));
+ list.Concat(taicpu.op_reg_reg_const(A_SRAI,reg2,reg2,8*(8-tcgsize2size[tosize])));
+ end
+ else
+ begin
+ ai:=taicpu.op_reg_reg_const(A_ADDI,reg2,reg1,0);
+ list.concat(ai);
+ rg[R_INTREGISTER].add_move_instruction(ai);
end;
end;
diff --git a/riscv_new/compiler/riscv64/cpupara.pas b/riscv_new/compiler/riscv64/cpupara.pas
index 4c85ae9861..010e51d3eb 100644
--- a/riscv_new/compiler/riscv64/cpupara.pas
+++ b/riscv_new/compiler/riscv64/cpupara.pas
@@ -172,15 +172,7 @@ implementation
result := true;
procvardef,
recorddef:
- result :=
- (varspez = vs_const) and
- (
- (
- (not (calloption in [pocall_cdecl, pocall_cppdecl]) and
- (def.size > 8))
- ) or
- (calloption = pocall_mwpascal)
- );
+ result := (def.size > 8);
arraydef:
result := (tarraydef(def).highrange >= tarraydef(def).lowrange) or
is_open_array(def) or