summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-07-20 15:34:22 +0000
committerlaksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-07-20 15:34:22 +0000
commitcebcdb71bd0c16d480fda4e371b6480905d346b6 (patch)
treef11211e95f2032a97d1c27e0adaab6d386c3a7db
parente12bc72aad109fe9e2be29721fc0d0915ee6dd98 (diff)
downloadfpc-cebcdb71bd0c16d480fda4e371b6480905d346b6.tar.gz
Added overflow checking in for add instructions.
git-svn-id: https://svn.freepascal.org/svn/fpc/branches/laksen@39479 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--riscv_new/compiler/riscv64/cgcpu.pas124
1 files changed, 124 insertions, 0 deletions
diff --git a/riscv_new/compiler/riscv64/cgcpu.pas b/riscv_new/compiler/riscv64/cgcpu.pas
index 88b4dd10ee..0cb243c670 100644
--- a/riscv_new/compiler/riscv64/cgcpu.pas
+++ b/riscv_new/compiler/riscv64/cgcpu.pas
@@ -41,6 +41,9 @@ unit cgcpu;
procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;
procedure a_load_const_reg(list: TAsmList; size: tcgsize; a: tcgint; register: tregister); override;
+ procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister; setflags: boolean; var ovloc: tlocation); override;
+ procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation); override;
+
procedure g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef); override;
procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean); override;
@@ -171,6 +174,127 @@ implementation
end;
+ procedure tcgrv64.a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister; setflags: boolean; var ovloc: tlocation);
+ var
+ signed: Boolean;
+ l: TAsmLabel;
+ tmpreg: tregister;
+ ai: taicpu;
+ begin
+ signed:=tcgsize2unsigned[size]<>size;
+
+ if setflags and
+ (op=OP_ADD) and
+ (src=dst) and
+ (not signed) then
+ begin
+ tmpreg:=getintregister(list,size);
+ a_load_reg_reg(list,size,size,src,tmpreg);
+ src:=tmpreg;
+ end;
+
+ a_op_const_reg_reg(list,op,size,a,src,dst);
+
+ if setflags and
+ (op=OP_ADD) then
+ begin
+ current_asmdata.getjumplabel(l);
+ if signed then
+ begin
+ {
+ t0=a<0
+ t1=result<a
+ jump if t0=t1
+ }
+ tmpreg:=getintregister(list,OS_INT);
+ list.Concat(taicpu.op_reg_reg_const(A_SLTI,tmpreg,dst,a));
+
+ ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,tmpreg,NR_X0,l,0);
+ if a<0 then
+ ai.condition:=C_NE
+ else
+ ai.condition:=C_EQ;
+ list.concat(ai);
+ end
+ else
+ begin
+ {
+ jump if not sum<x
+ }
+ tmpreg:=getintregister(list,OS_INT);
+ list.Concat(taicpu.op_reg_reg_reg(A_SLTIU,tmpreg,dst,src));
+
+ ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,tmpreg,NR_X0,l,0);
+ ai.condition:=C_EQ;
+ list.concat(ai);
+ end;
+
+ a_call_name(list,'FPC_OVERFLOW',false);
+ a_label(list,l);
+ end;
+ end;
+
+
+ procedure tcgrv64.a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation);
+ var
+ signed: Boolean;
+ l: TAsmLabel;
+ tmpreg, tmpreg0: tregister;
+ ai: taicpu;
+ begin
+ signed:=tcgsize2unsigned[size]<>size;
+
+ if setflags and
+ (op=OP_ADD) and
+ (src2=dst) and
+ (not signed) then
+ begin
+ tmpreg:=getintregister(list,size);
+ a_load_reg_reg(list,size,size,src2,tmpreg);
+ src2:=tmpreg;
+ end;
+
+ a_op_reg_reg_reg(list,op,size,src1,src2,dst);
+
+ if setflags and
+ (op=OP_ADD) then
+ begin
+ current_asmdata.getjumplabel(l);
+ if signed then
+ begin
+ {
+ t0=src1<0
+ t1=result<src1
+ jump if t0=t1
+ }
+ tmpreg0:=getintregister(list,OS_INT);
+ tmpreg:=getintregister(list,OS_INT);
+ list.Concat(taicpu.op_reg_reg_reg(A_SLT,tmpreg0,src1,NR_X0));
+ list.Concat(taicpu.op_reg_reg_reg(A_SLT,tmpreg,dst,src1));
+
+ ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,tmpreg,tmpreg0,l,0);
+ ai.condition:=C_EQ;
+ list.concat(ai);
+ end
+ else
+ begin
+ {
+ jump if not sum<x
+ }
+ 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);
+ ai.condition:=C_EQ;
+ list.concat(ai);
+ end;
+
+ a_call_name(list,'FPC_OVERFLOW',false);
+ a_label(list,l);
+ end;
+ end;
+
+
procedure tcgrv64.g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef);
begin
end;