diff options
author | laksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2018-07-23 01:11:31 +0000 |
---|---|---|
committer | laksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2018-07-23 01:11:31 +0000 |
commit | 3d513c151f7b60e80febeb2640bb7b05cad7e776 (patch) | |
tree | cdb3528c589007be5e500fd7f4cee62431b863ec | |
parent | 611d1e6231a372409ded47db3bea07e5c57046bd (diff) | |
download | fpc-3d513c151f7b60e80febeb2640bb7b05cad7e776.tar.gz |
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: https://svn.freepascal.org/svn/fpc/branches/laksen@39492 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | riscv_new/compiler/riscv/cgrv.pas | 92 | ||||
-rw-r--r-- | riscv_new/compiler/riscv64/cgcpu.pas | 20 | ||||
-rw-r--r-- | riscv_new/rtl/riscv64/riscv64.inc | 4 |
3 files changed, 60 insertions, 56 deletions
diff --git a/riscv_new/compiler/riscv/cgrv.pas b/riscv_new/compiler/riscv/cgrv.pas index ed75d2241d..63c1d453ea 100644 --- a/riscv_new/compiler/riscv/cgrv.pas +++ b/riscv_new/compiler/riscv/cgrv.pas @@ -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)); - - {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); + list.concat(taicpu.op_reg_reg_ref(A_JALR,NR_RETURN_ADDRESS_REG,NR_RETURN_ADDRESS_REG,href)); + + { 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; diff --git a/riscv_new/compiler/riscv64/cgcpu.pas b/riscv_new/compiler/riscv64/cgcpu.pas index 429b128b11..84237945e0 100644 --- a/riscv_new/compiler/riscv64/cgcpu.pas +++ b/riscv_new/compiler/riscv64/cgcpu.pas @@ -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); diff --git a/riscv_new/rtl/riscv64/riscv64.inc b/riscv_new/rtl/riscv64/riscv64.inc index 3b71640ca5..bf1b1cad75 100644 --- a/riscv_new/rtl/riscv64/riscv64.inc +++ b/riscv_new/rtl/riscv64/riscv64.inc @@ -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; |