summaryrefslogtreecommitdiff
path: root/compiler/riscv/cgrv.pas
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/riscv/cgrv.pas')
-rw-r--r--compiler/riscv/cgrv.pas45
1 files changed, 45 insertions, 0 deletions
diff --git a/compiler/riscv/cgrv.pas b/compiler/riscv/cgrv.pas
index 66f02bdaf6..9b5443b7cf 100644
--- a/compiler/riscv/cgrv.pas
+++ b/compiler/riscv/cgrv.pas
@@ -258,6 +258,10 @@ unit cgrv;
procedure tcgrv.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister);
+ var
+ name: String;
+ pd: tprocdef;
+ paraloc1, paraloc2: tcgpara;
begin
if op=OP_NOT then
begin
@@ -295,6 +299,47 @@ unit cgrv;
end
else
{$endif RISCV64}
+ if (op in [OP_IMUL,OP_MUL]) and not(CPURV_HAS_MUL in cpu_capabilities[current_settings.cputype]) then
+ begin
+ case size of
+ OS_8:
+ name:='fpc_mul_byte';
+ OS_S8:
+ name:='fpc_mul_shortint';
+ OS_16:
+ name:='fpc_mul_word';
+ OS_S16:
+ name:='fpc_mul_integer';
+ OS_32:
+ name:='fpc_mul_dword';
+ OS_S32:
+ name:='fpc_mul_longint';
+ else
+ Internalerror(2021030601);
+ end;
+
+// if check_overflow then
+// name:=name+'_checkoverflow';
+
+ pd:=search_system_proc(name);
+ paraloc1.init;
+ paraloc2.init;
+ paramanager.getcgtempparaloc(list,pd,1,paraloc1);
+ paramanager.getcgtempparaloc(list,pd,2,paraloc2);
+ a_load_reg_cgpara(list,OS_8,src1,paraloc2);
+ a_load_reg_cgpara(list,OS_8,src2,paraloc1);
+ paramanager.freecgpara(list,paraloc2);
+ paramanager.freecgpara(list,paraloc1);
+ alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+ a_call_name(list,upper(name),false);
+ dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+ cg.a_reg_alloc(list,NR_FUNCTION_RESULT_REG);
+ cg.a_load_reg_reg(list,size,size,NR_FUNCTION_RESULT_REG,dst);
+ cg.a_reg_dealloc(list,NR_FUNCTION_RESULT_REG);
+ paraloc2.done;
+ paraloc1.done;
+ end
+ else
begin
list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
maybeadjustresult(list,op,size,dst);