summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-07-23 01:11:31 +0000
committerlaksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-07-23 01:11:31 +0000
commit3d513c151f7b60e80febeb2640bb7b05cad7e776 (patch)
treecdb3528c589007be5e500fd7f4cee62431b863ec
parent611d1e6231a372409ded47db3bea07e5c57046bd (diff)
downloadfpc-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.pas92
-rw-r--r--riscv_new/compiler/riscv64/cgcpu.pas20
-rw-r--r--riscv_new/rtl/riscv64/riscv64.inc4
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;