diff options
author | laksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2018-07-22 14:15:29 +0000 |
---|---|---|
committer | laksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2018-07-22 14:15:29 +0000 |
commit | 1b7c2166643e3faae1a65cd336dbcb7e8bceb807 (patch) | |
tree | 29da1bf06f016d687fbf533752c9d88b2e786325 | |
parent | 1d5ca183eb50c4f58fc531dab487b9d1745886b5 (diff) | |
download | fpc-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.pas | 27 | ||||
-rw-r--r-- | riscv_new/compiler/riscv64/cgcpu.pas | 46 | ||||
-rw-r--r-- | riscv_new/compiler/riscv64/cpupara.pas | 10 |
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 |