diff options
author | laksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2016-10-24 22:47:53 +0000 |
---|---|---|
committer | laksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2016-10-24 22:47:53 +0000 |
commit | 7fc5f32e265e128d00f71e8179f551ab6a7e55f1 (patch) | |
tree | 67cd942942a6fbd6c7208296f91bbc33473e2199 | |
parent | dc66f939637d3c5d50ed0591f6a3f25ac5dc6eb9 (diff) | |
download | fpc-7fc5f32e265e128d00f71e8179f551ab6a7e55f1.tar.gz |
Fixed up RiscV 32bit code generation.
Moved a lot more code to common classes.
Fixed FPU code generation when using soft FPU and native FPU.
git-svn-id: http://svn.freepascal.org/svn/fpc/branches/laksen@34763 3ad0048d-3df7-0310-abae-a5850022a9f2
24 files changed, 683 insertions, 655 deletions
diff --git a/riscv/trunk/compiler/fpcdefs.inc b/riscv/trunk/compiler/fpcdefs.inc index b5f2f79304..ffbd7fc5fe 100644 --- a/riscv/trunk/compiler/fpcdefs.inc +++ b/riscv/trunk/compiler/fpcdefs.inc @@ -234,9 +234,13 @@ {$ifdef riscv32} {$define cpu32bit} {$define cpu32bitaddr} - {$define cpu32bitalu} - {$define cputargethasfixedstack} - {$define cpuneedsdivhelper} + {$define cpu32bitalu} + {$define cpufpemu} + {$define cputargethasfixedstack} + {$define cpuneedsmulhelper} + {$define cpuneedsdivhelper} + {$define cpucapabilities} + {$define cpurequiresproperalignment} {$endif riscv32} {$ifdef riscv64} diff --git a/riscv/trunk/compiler/globals.pas b/riscv/trunk/compiler/globals.pas index 3e54279a1d..492f69e7a1 100644 --- a/riscv/trunk/compiler/globals.pas +++ b/riscv/trunk/compiler/globals.pas @@ -501,8 +501,8 @@ interface fputype : fpu_x87; {$endif i8086} {$ifdef riscv32} - cputype : cpu_rv32g; - optimizecputype : cpu_rv32g; + cputype : cpu_rv32imafd; + optimizecputype : cpu_rv32imafd; asmcputype : cpu_none; fputype : fpu_fd; {$endif riscv32} diff --git a/riscv/trunk/compiler/options.pas b/riscv/trunk/compiler/options.pas index dbc2385866..8c9f79bd75 100644 --- a/riscv/trunk/compiler/options.pas +++ b/riscv/trunk/compiler/options.pas @@ -3773,14 +3773,15 @@ begin if not(option.FPUSetExplicitly) and ((target_info.system in [system_arm_wince,system_arm_gba, system_m68k_amiga,system_m68k_atari,system_m68k_linux, - system_arm_nds,system_arm_embedded]) + system_arm_nds,system_arm_embedded, + system_riscv32_embedded,system_riscv64_embedded]) {$ifdef arm} or (target_info.abi=abi_eabi) {$endif arm} ) -{$if defined(arm) or defined(riscv64) or defined (m68k)} +{$if defined(arm) or defined(riscv32) or defined(riscv64) or defined (m68k)} or (init_settings.fputype=fpu_soft) -{$endif arm or riscv64 or m68k} +{$endif arm or riscv32 or riscv64 or m68k} then begin {$ifdef cpufpemu} diff --git a/riscv/trunk/compiler/riscv/cgrv.pas b/riscv/trunk/compiler/riscv/cgrv.pas index 5f38fef75a..9ba638bf93 100644 --- a/riscv/trunk/compiler/riscv/cgrv.pas +++ b/riscv/trunk/compiler/riscv/cgrv.pas @@ -42,14 +42,24 @@ unit cgrv; procedure a_load_reg_ref(list: TAsmList; fromsize, tosize: TCGSize; reg: tregister; const ref: treference); override; procedure a_load_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override; - procedure a_load_const_reg(list: TAsmList; size: tcgsize; a: tcgint; register: tregister); override; + procedure a_load_const_reg(list: TAsmList; size: tcgsize; a: tcgint; register: tregister); override; + + procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override; + procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override; + + procedure a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister); override; + procedure a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); override; procedure a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);override; + procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : tcgint;reg : tregister; l : tasmlabel); override; procedure a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel); override; procedure a_jmp_name(list : TAsmList;const s : string); override; - procedure a_jmp_always(list : TAsmList;l: tasmlabel); override; + procedure a_jmp_always(list : TAsmList;l: tasmlabel); override; + + procedure g_save_registers(list: TAsmList); override; + procedure g_restore_registers(list: TAsmList); override; { fpu move instructions } procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override; @@ -61,7 +71,15 @@ 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_LT,C_GE,C_NONE); + + const + TOpCG2AsmConstOp: Array[topcg] of TAsmOp = (A_NONE, + A_NONE,A_ADDI,A_ANDI,A_NONE,A_NONE,A_NONE,A_NONE, + A_None,A_None,A_ORI,A_SRAI,A_SLLI,A_SRLI,A_NONE,A_XORI,A_None,A_None); + TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_NONE, + A_NONE,A_ADD,A_AND,A_DIVU,A_DIV,A_MUL,A_MUL, + A_None,A_None,A_OR,A_SRA,A_SLL,A_SRL,A_SUB,A_XOR,A_None,A_None); implementation @@ -136,6 +154,63 @@ unit cgrv; procedure tcgrv.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tcgsize; src, dst: TRegister); begin internalerror(2016060401); + end; + + + procedure tcgrv.a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); + begin + a_op_const_reg_reg(list,op,size,a,reg,reg); + end; + + + procedure tcgrv.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); + begin + a_op_reg_reg_reg(list,op,size,src,dst,dst); + end; + + + procedure tcgrv.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister); + var + tmpreg: TRegister; + begin + optimize_op_const(size,op,a); + + if op=OP_NONE then + begin + a_load_reg_reg(list,size,size,src,dst); + exit; + end; + + if op=OP_SUB then + begin + op:=OP_ADD; + a:=-a; + end; + + if (TOpCG2AsmConstOp[op]<>A_None) and + is_imm12(a) then + list.concat(taicpu.op_reg_reg_const(TOpCG2AsmConstOp[op],dst,src,a)) + else + begin + tmpreg:=getintregister(list,OS_INT); + a_load_const_reg(list,size,a,tmpreg); + a_op_reg_reg_reg(list,op,size,tmpreg,src,dst); + end; + end; + + + procedure tcgrv.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); + begin + case op of + OP_NOT: + list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src1,-1)); + OP_NEG: + list.concat(taicpu.op_reg_reg_reg(A_SUB,dst,NR_X0,src1)); + OP_MOVE: + a_load_reg_reg(list,size,size,src1,dst); + else + list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1)); + end; end; @@ -231,6 +306,31 @@ unit cgrv; end else internalerror(2016060504); + end; + + + procedure tcgrv.a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel); + var + reg1: TRegister; + ai: taicpu; + begin + if a=0 then + begin + reg1:=NR_X0; + if TOpCmp2AsmCond[cmp_op]=C_None then + begin + cmp_op:=swap_opcmp(cmp_op); + reg1:=reg; + reg:=NR_X0; + end; + + ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,reg,reg1,l,0); + ai.is_jmp:=true; + ai.condition:=TOpCmp2AsmCond[cmp_op]; + list.concat(ai); + end + else + inherited; end; @@ -308,6 +408,16 @@ unit cgrv; end; + procedure tcgrv.g_save_registers(list: TAsmList); + begin + end; + + + procedure tcgrv.g_restore_registers(list: TAsmList); + begin + end; + + procedure tcgrv.a_call_reg(list : TAsmList;reg: tregister); begin list.concat(taicpu.op_reg_reg(A_JALR,NR_RETURN_ADDRESS_REG,reg)); @@ -442,7 +552,14 @@ unit cgrv; l: TAsmLabel; begin href:=ref; - fixref(list,href); + fixref(list,href); + + if href.refaddr=addr_pcrel then + begin + tmpreg:=getintregister(list,OS_ADDR); + a_loadaddr_ref_reg(list,href,tmpreg); + reference_reset_base(href,tmpreg,0,0); + end; if fromsize=OS_F32 then op:=A_FLW @@ -463,7 +580,14 @@ unit cgrv; tmpreg: TRegister; begin href:=ref; - fixref(list,href); + fixref(list,href); + + if href.refaddr=addr_pcrel then + begin + tmpreg:=getintregister(list,OS_ADDR); + a_loadaddr_ref_reg(list,href,tmpreg); + reference_reset_base(href,tmpreg,0,0); + end; if fromsize<>tosize then begin diff --git a/riscv/trunk/compiler/riscv/nrvadd.pas b/riscv/trunk/compiler/riscv/nrvadd.pas index 706b9c8d37..67f0732029 100644 --- a/riscv/trunk/compiler/riscv/nrvadd.pas +++ b/riscv/trunk/compiler/riscv/nrvadd.pas @@ -33,8 +33,19 @@ unit nrvadd; type trvaddnode = class(tcgaddnode) function pass_1: tnode; override; - protected - procedure pass_left_and_right; + protected + procedure Cmp(signed: boolean); + + procedure second_cmpsmallset;override; + procedure second_cmpordinal;override; + procedure second_cmp64bit; override; + + procedure second_addordinal; override; + + procedure pass_left_and_right; + + function use_fma: boolean; override; + procedure second_addfloat;override; procedure second_cmpfloat;override; end; @@ -42,10 +53,6 @@ unit nrvadd; implementation -{***************************************************************************** - Pass 1 -*****************************************************************************} - uses globtype,systems, cutils,verbose,globals, @@ -56,31 +63,207 @@ implementation ncon,nset, ncgutil,tgobj,rgobj,rgcpu,cgobj,hlcgobj; + procedure trvaddnode.Cmp(signed: boolean); + var + flabel,tlabel: tasmlabel; + op, opi: TAsmOp; + begin + pass_left_right; + + force_reg_left_right(true,true); + + if nf_swapped in flags then + swapleftright; + + location_reset(location,LOC_REGISTER,OS_INT); + location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); + + if signed then op:=A_SLT else op:=A_SLTU; + if signed then opi:=A_SLTI else opi:=A_SLTIU; + + case nodetype of + equaln: + begin + if not (left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); + + if (right.location.loc=LOC_CONSTANT) and + (not is_imm12(-right.location.value)) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); + + if right.location.loc=LOC_CONSTANT then + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_ADDI,location.register,left.location.register,-right.location.value)) + else + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(A_SUB,location.register,left.location.register,right.location.register)); + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_SLTIU,location.register,location.register,1)); + end; + unequaln: + begin + if not (left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); + + if (right.location.loc=LOC_CONSTANT) and + (not is_imm12(-right.location.value)) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); + + if right.location.loc=LOC_CONSTANT then + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_ADDI,location.register,left.location.register,-right.location.value)) + else + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(A_SUB,location.register,left.location.register,right.location.register)); + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(A_SLTU,location.register,NR_X0,location.register)); + end; + ltn: + begin + if not (left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); + + if (right.location.loc=LOC_CONSTANT) and + (not is_imm12(right.location.value)) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); + + if right.location.loc=LOC_CONSTANT then + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(opi,location.register,left.location.register,right.location.value)) + else + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register)); + end; + gtn: + begin + if not (right.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); + + if (left.location.loc=LOC_CONSTANT) and + (not is_imm12(left.location.value)) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); + + if left.location.loc=LOC_CONSTANT then + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(opi,location.register,right.location.register,left.location.value)) + else + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(op,location.register,right.location.register,left.location.register)); + end; + + lten: + begin + if not (right.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); + + if (left.location.loc=LOC_CONSTANT) and + (not is_imm12(left.location.value)) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); + + if left.location.loc=LOC_CONSTANT then + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(opi,location.register,right.location.register,left.location.value)) + else + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(op,location.register,right.location.register,left.location.register)); + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_SLTIU,location.register,location.register,1)); + end; + gten: + begin + if not (left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); + + if (right.location.loc=LOC_CONSTANT) and + (not is_imm12(right.location.value)) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); + + if right.location.loc=LOC_CONSTANT then + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(opi,location.register,left.location.register,right.location.value)) + else + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register)); + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_SLTIU,location.register,location.register,1)); + end; + else + Internalerror(2016061101); + end; + end; + + + procedure trvaddnode.second_cmpsmallset; + begin + Cmp(true); + end; + + + procedure trvaddnode.second_cmpordinal; + var + unsigned: Boolean; + begin + unsigned:=not(is_signed(left.resultdef)) or + not(is_signed(right.resultdef)); + + Cmp(not unsigned); + end; + + + procedure trvaddnode.second_cmp64bit; + var + unsigned: Boolean; + begin + unsigned:=not(is_signed(left.resultdef)) or + not(is_signed(right.resultdef)); + + Cmp(not unsigned); + end; + + + procedure trvaddnode.second_addordinal; + var + unsigned: boolean; + begin + { 32x32->64 multiplication } + if (nodetype=muln) and + is_32bit(left.resultdef) and + is_32bit(right.resultdef) and + is_64bit(resultdef) then + begin + unsigned:=not(is_signed(left.resultdef)) or + not(is_signed(right.resultdef)); + pass_left_right; + force_reg_left_right(true,true); + { force_reg_left_right can leave right as a LOC_CONSTANT (we can't + say "a constant register is okay, but an ordinal constant isn't) } + if right.location.loc=LOC_CONSTANT then + hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true); + location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); + location.register:=cg.getintregister(current_asmdata.CurrAsmList,def_cgsize(resultdef)); + current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(A_MUL,location.register,left.location.register,right.location.register)); + end + else + inherited second_addordinal; + end; -{***************************************************************************** - Pass 1 -*****************************************************************************} function trvaddnode.pass_1: tnode; begin - {typecheckpass(left); - if (nodetype in [equaln,unequaln]) and - (left.resultdef.typ = orddef) and - is_64bit(left.resultdef) then + if (nodetype=muln) and + (left.resultdef.typ=orddef) and (left.resultdef.typ=orddef) and + (CPURV_HAS_MUL in cpu_capabilities[current_settings.cputype]) +{$ifdef cpu32bitalu} + and (not (is_64bit(left.resultdef) or + is_64bit(right.resultdef))) +{$endif cpu32bitalu} + then begin - result := nil; + result:=nil; + firstpass(left); firstpass(right); - expectloc := LOC_FLAGS; - exit; - end;} - result := inherited pass_1; + expectloc:=LOC_REGISTER; + end + else if (nodetype=muln) and + (not (CPURV_HAS_MUL in cpu_capabilities[current_settings.cputype])) and + (is_64bit(left.resultdef) or + is_64bit(right.resultdef)) then + begin + result:=first_add64bitint; + end + else + Result:=inherited pass_1; + + if expectloc=LOC_FLAGS then + expectloc:=LOC_REGISTER; end; -{***************************************************************************** - Helpers -*****************************************************************************} procedure trvaddnode.pass_left_and_right; begin @@ -96,6 +279,12 @@ implementation end; + function trvaddnode.use_fma: boolean; + begin + Result:=current_settings.fputype in [fpu_fd]; + end; + + procedure trvaddnode.second_addfloat; var op : TAsmOp; diff --git a/riscv/trunk/compiler/riscv/nrvset.pas b/riscv/trunk/compiler/riscv/nrvset.pas index 2561f28990..c625a2af53 100644 --- a/riscv/trunk/compiler/riscv/nrvset.pas +++ b/riscv/trunk/compiler/riscv/nrvset.pas @@ -129,7 +129,6 @@ implementation { create reference, indexreg := indexreg * sizeof(jtentry) (= 4) } cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_MUL, OS_INT, 4, indexreg); reference_reset_symbol(href, table, 0, 4); - href.refaddr:=addr_pcrel; hregister:=cg.getaddressregister(current_asmdata.CurrAsmList); cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href,hregister); diff --git a/riscv/trunk/compiler/riscv32/cgcpu.pas b/riscv/trunk/compiler/riscv32/cgcpu.pas index 0547c6dbfb..b1830b938b 100644 --- a/riscv/trunk/compiler/riscv32/cgcpu.pas +++ b/riscv/trunk/compiler/riscv32/cgcpu.pas @@ -37,27 +37,15 @@ unit cgcpu; procedure init_register_allocators;override; procedure done_register_allocators;override; - procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override; - procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override; - - procedure a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister); override; - procedure a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); override; - { move instructions } procedure a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);override; - { comparison operations } - procedure a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel); override; - { 32x32 to 64 bit multiplication } procedure a_mul_reg_reg_pair(list: TAsmList;size: tcgsize; src1,src2,dstlo,dsthi: tregister); override; procedure g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);override; procedure g_proc_exit(list : TAsmList;parasize : longint;nostackframe:boolean); override; - procedure g_save_registers(list: TAsmList); override; - procedure g_restore_registers(list: TAsmList); override; - procedure g_concatcopy_move(list: tasmlist; const Source, dest: treference; len: tcgint); procedure g_concatcopy(list : TAsmList;const source,dest : treference;len : tcgint);override; @@ -73,14 +61,6 @@ unit cgcpu; procedure create_codegen; - const - TOpCG2AsmConstOp: Array[topcg] of TAsmOp = (A_NONE, - A_NONE,A_ADDI,A_ANDI,A_NONE,A_NONE,A_NONE,A_NONE, - A_None,A_None,A_ORI,A_SRAI,A_SLLI,A_SRLI,A_NONE,A_XORI,A_None,A_None); - TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_NONE, - A_NONE,A_ADD,A_AND,A_DIVU,A_DIV,A_MUL,A_MUL, - A_None,A_None,A_OR,A_SRA,A_SLL,A_SRL,A_SUB,A_XOR,A_None,A_None); - implementation uses @@ -101,12 +81,12 @@ unit cgcpu; RS_X9,RS_X27,RS_X26,RS_X25,RS_X24,RS_X23,RS_X22, RS_X21,RS_X20,RS_X19,RS_X18],first_int_imreg,[]); rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE, - [RS_F10,RS_F11,RS_F12,RS_F13,RS_F14,RS_F15,RS_F16,RS_F17, - RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7, - RS_F28,RS_F29,RS_F30,RS_F31, - RS_F8,RS_F9, - RS_F27, - RS_F26,RS_F25,RS_F24,RS_F23,RS_F22,RS_F21,RS_F20,RS_F19,RS_F18],first_fpu_imreg,[]); + [RS_F10,RS_F11,RS_F12,RS_F13,RS_F14,RS_F15,RS_F16,RS_F17, + RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7, + RS_F28,RS_F29,RS_F30,RS_F31, + RS_F8,RS_F9, + RS_F27, + RS_F26,RS_F25,RS_F24,RS_F23,RS_F22,RS_F21,RS_F20,RS_F19,RS_F18],first_fpu_imreg,[]); end; @@ -152,84 +132,6 @@ unit cgcpu; end; - procedure tcgrv32.a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel); - var - reg1: TRegister; - ai: taicpu; - begin - if a=0 then - begin - reg1:=NR_X0; - if TOpCmp2AsmCond[cmp_op]=C_None then - begin - cmp_op:=swap_opcmp(cmp_op); - reg1:=reg; - reg:=NR_X0; - end; - - ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,reg,reg1,l,0); - ai.is_jmp:=true; - ai.condition:=TOpCmp2AsmCond[cmp_op]; - list.concat(ai); - end - else - inherited; - end; - - - procedure tcgrv32.a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); - begin - a_op_const_reg_reg(list,op,size,a,reg,reg); - end; - - - procedure tcgrv32.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); - begin - a_op_reg_reg_reg(list,op,size,src,dst,dst); - end; - - - procedure tcgrv32.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister); - var - tmpreg: TRegister; - begin - optimize_op_const(size,op,a); - - if op=OP_NONE then exit; - - if op=OP_SUB then - begin - op:=OP_ADD; - a:=-a; - end; - - if (TOpCG2AsmConstOp[op]<>A_None) and - is_imm12(a) then - list.concat(taicpu.op_reg_reg_const(TOpCG2AsmConstOp[op],dst,src,a)) - else - begin - tmpreg:=getintregister(list,size); - a_load_const_reg(list,size,a,tmpreg); - a_op_reg_reg_reg(list,op,size,tmpreg,src,dst); - end; - end; - - - procedure tcgrv32.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); - begin - case op of - OP_NOT: - list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src1,-1)); - OP_NEG: - list.concat(taicpu.op_reg_reg_reg(A_SUB,dst,NR_X0,src1)); - OP_MOVE: - list.concat(taicpu.op_reg_reg_const(A_ADDI,dst,src1,0)); - else - list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1)); - end; - end; - - procedure tcgrv32.a_mul_reg_reg_pair(list: TAsmList;size: tcgsize; src1,src2,dstlo,dsthi: tregister); var op: tasmop; @@ -283,9 +185,6 @@ unit cgcpu; if r in fregs then inc(stackcount,8); - if current_procinfo.framepointer<>NR_STACK_POINTER_REG then - list.concat(taicpu.op_reg_reg_const(A_ADDI,NR_FRAME_POINTER_REG,NR_STACK_POINTER_REG,0)); - inc(localsize,stackcount); if not is_imm12(-localsize) then begin @@ -310,10 +209,15 @@ unit cgcpu; begin list.concat(taicpu.op_reg_ref(A_FSD,newreg(R_FPUREGISTER,r,R_SUBWHOLE),href)); dec(href.offset,8); - end; + end; + + if current_procinfo.framepointer<>NR_STACK_POINTER_REG then + list.concat(taicpu.op_reg_reg_const(A_ADDI,NR_FRAME_POINTER_REG,NR_STACK_POINTER_REG,0)); if localsize>0 then begin + localsize:=align(localsize,4); + if is_imm12(-localsize) then list.concat(taicpu.op_reg_reg_const(A_ADDI,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-localsize)) else @@ -359,7 +263,9 @@ unit cgcpu; if current_procinfo.framepointer<>NR_STACK_POINTER_REG then list.concat(taicpu.op_reg_reg_const(A_ADDI,NR_STACK_POINTER_REG,NR_FRAME_POINTER_REG,0)) else if localsize>0 then - begin + begin + localsize:=align(localsize,4); + if is_imm12(localsize) then list.concat(taicpu.op_reg_reg_const(A_ADDI,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,localsize)) else @@ -396,14 +302,6 @@ unit cgcpu; list.concat(taicpu.op_reg_reg(A_JALR,NR_X0,NR_RETURN_ADDRESS_REG)); end; - procedure tcgrv32.g_save_registers(list: TAsmList); - begin - end; - - procedure tcgrv32.g_restore_registers(list: TAsmList); - begin - end; - procedure tcgrv32.g_concatcopy_move(list: tasmlist; const Source, dest: treference; len: tcgint); var diff --git a/riscv/trunk/compiler/riscv32/cpubase.pas b/riscv/trunk/compiler/riscv32/cpubase.pas index a1c69caeba..feb63fc5b5 100644 --- a/riscv/trunk/compiler/riscv32/cpubase.pas +++ b/riscv/trunk/compiler/riscv32/cpubase.pas @@ -47,14 +47,18 @@ uses A_SLLI,A_SRLI,A_SRAI, A_ADD,A_SUB,A_SLL,A_SLT,A_SLTU, A_XOR,A_SRL,A_SRA,A_OR,A_AND, - A_FENCE,A_FENCE_I,A_SCALL,A_SBREAK, - A_RDCYCLE,A_RDCYCLEH,A_RDTIME,A_RDTIMEH,A_RDINSTRET,A_RDINSTRETH, + A_FENCE,A_FENCE_I, + A_ECALL,A_EBREAK, + A_CSRRW,A_CSRRS,A_CSRRC,A_CSRRWI,A_CSRRSI,A_CSRRCI, + { M-extension } A_MUL,A_MULH,A_MULHSU,A_MULHU, A_DIV,A_DIVU,A_REM,A_REMU, + { A-extension } A_LR_W,A_SC_W,A_AMOSWAP_W,A_AMOADD_W,A_AMOXOR_W,A_AMOAND_W, A_AMOOR_W,A_AMOMIN_W,A_AMOMAX_W,A_AMOMINU_W,A_AMOMAXU_W, + { F-extension } A_FLW,A_FSW, A_FMADD_S,A_FMSUB_S,A_FNMSUB_S,A_FNMADD_S, @@ -66,6 +70,7 @@ uses A_FMV_S_X, A_FRCSR,A_FRRM,A_FRFLAGS,A_FSCSR,A_FSRM, A_FSFLAGS,A_FSRMI,A_FSFLAGSI, + { D-extension } A_FLD,A_FSD, A_FMADD_D,A_FMSUB_D,A_FNMSUB_D,A_FNMADD_D, @@ -74,7 +79,14 @@ uses A_FMIN_D,A_FMAX_D, A_FEQ_D,A_FLT_D,A_FLE_D,A_FCLASS_D, A_FCVT_D_S,A_FCVT_S_D, - A_FCVT_W_D,A_FCVT_WU_D,A_FCVT_D_W,A_FCVT_D_WU + A_FCVT_W_D,A_FCVT_WU_D,A_FCVT_D_W,A_FCVT_D_WU, + + { Machine mode } + A_MRET,A_HRET,A_SRET,A_URET, + A_WFI, + + { Supervisor } + A_SFENCE_VM ); {# This should define the array of instructions as string } diff --git a/riscv/trunk/compiler/riscv32/cpuinfo.pas b/riscv/trunk/compiler/riscv32/cpuinfo.pas index 5068f1a892..755da23976 100644 --- a/riscv/trunk/compiler/riscv32/cpuinfo.pas +++ b/riscv/trunk/compiler/riscv32/cpuinfo.pas @@ -35,11 +35,15 @@ Type { possible supported processors for this target } tcputype = (cpu_none, - cpu_rv32g + cpu_rv32imafd, + cpu_rv32ima, + cpu_rv32im, + cpu_rv32i ); tfputype = - (fpu_none, + (fpu_none, + fpu_libgcc, fpu_soft, fpu_fd ); @@ -82,10 +86,14 @@ Const ]; cputypestr : array[tcputype] of string[10] = ('', - 'RV32G' + 'RV32IMAFD', + 'RV32IMA', + 'RV32IM', + 'RV32I' ); - fputypestr : array[tfputype] of string[8] = ( + fputypestr : array[tfputype] of string[8] = ( + 'LIBGCC', 'NONE', 'SOFT', 'FD' @@ -104,7 +112,23 @@ Const level1optimizerswitches = genericlevel1optimizerswitches; level2optimizerswitches = genericlevel2optimizerswitches + level1optimizerswitches + [cs_opt_regvar,cs_opt_nodecse,cs_opt_tailrecursion]; level3optimizerswitches = genericlevel3optimizerswitches + level2optimizerswitches + [{,cs_opt_loopunroll}]; - level4optimizerswitches = genericlevel4optimizerswitches + level3optimizerswitches + [cs_opt_stackframe]; + level4optimizerswitches = genericlevel4optimizerswitches + level3optimizerswitches + [cs_opt_stackframe]; + + type + tcpuflags = + (CPURV_HAS_MUL, + CPURV_HAS_ATOMIC, + CPURV_HAS_COMPACT + ); + + const + cpu_capabilities : array[tcputype] of set of tcpuflags = + ( { cpu_none } [], + { cpu_rv32imafd } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC], + { cpu_rv32ima } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC], + { cpu_rv32im } [CPURV_HAS_MUL], + { cpu_rv32i } [] + ); Implementation diff --git a/riscv/trunk/compiler/riscv32/cpunode.pas b/riscv/trunk/compiler/riscv32/cpunode.pas index a9339b2b00..08190a8a57 100644 --- a/riscv/trunk/compiler/riscv32/cpunode.pas +++ b/riscv/trunk/compiler/riscv32/cpunode.pas @@ -40,7 +40,7 @@ unit cpunode; nrvset, nrvinl, nrv32mat, - nrvcnv, + nrv32cnv, nrvcon ; diff --git a/riscv/trunk/compiler/riscv32/cpupara.pas b/riscv/trunk/compiler/riscv32/cpupara.pas index d98a7917f5..7c90ebd074 100644 --- a/riscv/trunk/compiler/riscv32/cpupara.pas +++ b/riscv/trunk/compiler/riscv32/cpupara.pas @@ -50,6 +50,7 @@ unit cpupara; implementation uses + cpuinfo,globals, verbose,systems, defutil,symtable, procinfo,cpupi; @@ -115,7 +116,11 @@ unit cpupara; orddef: result:=LOC_REGISTER; floatdef: - result:=LOC_FPUREGISTER; + if (cs_fp_emulation in current_settings.moduleswitches) or + (current_settings.fputype in [fpu_soft]) then + result := LOC_REGISTER + else + result := LOC_FPUREGISTER; enumdef: result:=LOC_REGISTER; pointerdef: diff --git a/riscv/trunk/compiler/riscv32/cpupi.pas b/riscv/trunk/compiler/riscv32/cpupi.pas index 3931b11057..138d9ab915 100644 --- a/riscv/trunk/compiler/riscv32/cpupi.pas +++ b/riscv/trunk/compiler/riscv32/cpupi.pas @@ -44,7 +44,8 @@ unit cpupi; needs_frame_pointer: boolean; // procedure handle_body_start;override; - // procedure after_pass1;override; + // procedure after_pass1;override; + constructor create(aparent: tprocinfo); override; procedure set_first_temp_offset;override; function calc_stackframe_size:longint;override; end; @@ -60,7 +61,14 @@ unit cpupi; cgutils, cgobj, defutil, - aasmcpu; + aasmcpu; + + + constructor trv32procinfo.create(aparent: tprocinfo); + begin + inherited create(aparent); + maxpushedparasize := 0; + end; procedure trv32procinfo.set_first_temp_offset; @@ -72,10 +80,9 @@ unit cpupi; tg.setfirsttemp(maxpushedparasize); exit; end; + if tg.direction = -1 then - begin - tg.setfirsttemp(-(1+12)*4); - end + tg.setfirsttemp(-(1+12)*4) else tg.setfirsttemp(maxpushedparasize); end; diff --git a/riscv/trunk/compiler/riscv32/cputarg.pas b/riscv/trunk/compiler/riscv32/cputarg.pas index 187d95af90..0643083eee 100644 --- a/riscv/trunk/compiler/riscv32/cputarg.pas +++ b/riscv/trunk/compiler/riscv32/cputarg.pas @@ -38,6 +38,9 @@ implementation {$ifndef NOTARGETLINUX} ,t_linux {$endif} + {$ifndef NOTARGETEMBEDDED} + ,t_embed + {$endif} {************************************** Assemblers diff --git a/riscv/trunk/compiler/riscv32/itcpugas.pas b/riscv/trunk/compiler/riscv32/itcpugas.pas index 7126512580..190b7bfbb2 100644 --- a/riscv/trunk/compiler/riscv32/itcpugas.pas +++ b/riscv/trunk/compiler/riscv32/itcpugas.pas @@ -29,7 +29,7 @@ interface cpubase,cgbase; const - gas_op2str : array[tasmop] of string[14] = ('<none>', + gas_op2str: array[tasmop] of string[14] = ('<none>', 'lui','auipc','jal','jalr', 'b','lb','lh','lw','lbu','lhu', 'sb','sh','sw', @@ -38,14 +38,18 @@ interface 'slli','srli','srai', 'add','sub','sll','slt','sltu', 'xor','srl','sra','or','and', - 'fence','fence.i','scall','sbreak', - 'rdcycle','rdcycleh','rdtime','rdtimeh','rdinstret','rdinstreth', + 'fence','fence.i', + 'ecall','ebreak', + 'csrrw','csrrs','csrrc','csrrwi','csrrsi','csrrci', + { m-extension } 'mul','mulh','mulhsu','mulhu', 'div','divu','rem','remu', + { a-extension } - 'lr','sc','amoswap','amoadd','amoxor','amoand', - 'amoor','amomin','amomax','amominu','amomaxu', + 'lr.w','sc.w','amoswap.w','amoadd.w','amoxor.w','amoand.w', + 'amoor.w','amomin.w','amomax.w','amominu.w','amomaxu.w', + { f-extension } 'flw','fsw', 'fmadd.s','fmsub.s','fnmsub.s','fnmadd.s', @@ -57,6 +61,7 @@ interface 'fmv.s.x', 'frcsr','frrm','frflags','fscsr','fsrm', 'fsflags','fsrmi','fsflagsi', + { d-extension } 'fld','fsd', 'fmadd.d','fmsub.d','fnmsub.d','fnmadd.d', @@ -65,7 +70,15 @@ interface 'fmin.d','fmax.d', 'feq.d','flt.d','fle.d','fclass.d', 'fcvt.d.s','fcvt.s.d', - 'fcvt.w.d','fcvt.wu.d','fcvt.d.w','fcvt.d.wu'); + 'fcvt.w.d','fcvt.wu.d','fcvt.d.w','fcvt.d.wu', + + { Machine mode } + 'mret','hret','sret','uret', + 'wfi', + + { Supervisor mode } + 'sfence.vm' + ); function gas_regnum_search(const s:string):Tregister; function gas_regname(r:Tregister):string; diff --git a/riscv/trunk/compiler/riscv32/nrv32add.pas b/riscv/trunk/compiler/riscv32/nrv32add.pas index f4a1d6d4ed..836663390d 100644 --- a/riscv/trunk/compiler/riscv32/nrv32add.pas +++ b/riscv/trunk/compiler/riscv32/nrv32add.pas @@ -31,12 +31,6 @@ unit nrv32add; type trv32addnode = class(trvaddnode) protected - procedure second_cmpsmallset;override; - procedure second_cmpordinal;override; - procedure second_cmp64bit; override; - procedure second_addordinal; override; - procedure second_add64bit; override; - function use_generic_mul32to64: boolean; override; end; @@ -52,125 +46,6 @@ unit nrv32add; ncon,nset, hlcgobj, ncgutil,cgobj; - - function GetCompare(signed: boolean; nt: tnodetype): TOpCmp; - begin - result:=OC_NONE; - - if signed then - case nt of - ltn: result:=OC_LT; - lten: result:=OC_LTE; - gtn: result:=OC_GT; - gten: result:=OC_GTE; - equaln: result:=OC_EQ; - unequaln: result:=OC_NE; - end - else - case nt of - ltn: result:=OC_B; - lten: result:=OC_BE; - gtn: result:=OC_A; - gten: result:=OC_AE; - equaln: result:=OC_EQ; - unequaln: result:=OC_NE; - end - end; - - procedure trv32addnode.second_cmpsmallset; - var - tlabel, flabel: tasmlabel; - begin - pass_left_right; - - force_reg_left_right(true,false); - - current_asmdata.getjumplabel(tlabel); - current_asmdata.getjumplabel(flabel); - - location_reset_jump(location,tlabel,flabel); - - cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,def_cgsize(left.resultdef),GetCompare(false,nodetype),right.location.register,left.location.register,tlabel); - cg.a_jmp_always(current_asmdata.CurrAsmList,flabel); - end; - - procedure trv32addnode.second_cmpordinal; - var - tlabel, flabel: tasmlabel; - unsigned: Boolean; - begin - pass_left_right; - - force_reg_left_right(true,false); - - current_asmdata.getjumplabel(tlabel); - current_asmdata.getjumplabel(flabel); - - location_reset_jump(location,tlabel,flabel); - - unsigned:=not(is_signed(left.resultdef)) or - not(is_signed(right.resultdef)); - - cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,def_cgsize(left.resultdef),GetCompare(not unsigned,nodetype),right.location.register,left.location.register,tlabel); - cg.a_jmp_always(current_asmdata.CurrAsmList,flabel); - end; - - procedure trv32addnode.second_cmp64bit; - var - tlabel, flabel: tasmlabel; - unsigned: Boolean; - begin - pass_left_right; - - force_reg_left_right(true,false); - - current_asmdata.getjumplabel(tlabel); - current_asmdata.getjumplabel(flabel); - - location_reset_jump(location,tlabel,flabel); - - unsigned:=not(is_signed(left.resultdef)) or - not(is_signed(right.resultdef)); - - cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,def_cgsize(left.resultdef),GetCompare(not unsigned,nodetype),right.location.register,left.location.register,tlabel); - cg.a_jmp_always(current_asmdata.CurrAsmList,flabel); - end; - - - procedure trv32addnode.second_addordinal; - var - unsigned: boolean; - begin - { 32x32->64 multiplication } - if (nodetype=muln) and - is_32bit(left.resultdef) and - is_32bit(right.resultdef) and - is_64bit(resultdef) then - begin - unsigned:=not(is_signed(left.resultdef)) or - not(is_signed(right.resultdef)); - pass_left_right; - force_reg_left_right(true,true); - - { force_reg_left_right can leave right as a LOC_CONSTANT (we can't - say "a constant register is okay, but an ordinal constant isn't) } - if right.location.loc=LOC_CONSTANT then - hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true); - - location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); - location.register:=cg.getintregister(current_asmdata.CurrAsmList,def_cgsize(resultdef)); - - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(A_MUL,location.register,left.location.register,right.location.register)); - end - else - inherited second_addordinal; - end; - - procedure trv32addnode.second_add64bit; - begin - inherited; - end; - function trv32addnode.use_generic_mul32to64: boolean; begin result:=true; diff --git a/riscv/trunk/compiler/riscv32/nrv32cnv.pas b/riscv/trunk/compiler/riscv32/nrv32cnv.pas index 0a28446ccb..dd56a22d49 100644 --- a/riscv/trunk/compiler/riscv32/nrv32cnv.pas +++ b/riscv/trunk/compiler/riscv32/nrv32cnv.pas @@ -73,36 +73,41 @@ implementation function trv32typeconvnode.first_int_to_real: tnode; var fname: string[19]; - begin + begin + if (cs_fp_emulation in current_settings.moduleswitches) then + result:=inherited first_int_to_real { converting a 64bit integer to a float requires a helper } - if is_64bitint(left.resultdef) or - is_currency(left.resultdef) then - begin - { hack to avoid double division by 10000, as it's } - { already done by typecheckpass.resultdef_int_to_real } - if is_currency(left.resultdef) then - left.resultdef := s64inttype; - if is_signed(left.resultdef) then - fname := 'fpc_int64_to_double' - else - fname := 'fpc_qword_to_double'; - result := ccallnode.createintern(fname,ccallparanode.create( - left,nil)); - left:=nil; - firstpass(result); - exit; - end else - { other integers are supposed to be 32 bit } begin - if is_signed(left.resultdef) then - inserttypeconv(left,s32inttype) + if is_64bitint(left.resultdef) or + is_currency(left.resultdef) then + begin + { hack to avoid double division by 10000, as it's } + { already done by typecheckpass.resultdef_int_to_real } + if is_currency(left.resultdef) then + left.resultdef := s64inttype; + if is_signed(left.resultdef) then + fname := 'fpc_int64_to_double' + else + fname := 'fpc_qword_to_double'; + result := ccallnode.createintern(fname,ccallparanode.create( + left,nil)); + left:=nil; + firstpass(result); + exit; + end else - inserttypeconv(left,u32inttype); - firstpass(left); + { other integers are supposed to be 32 bit } + begin + if is_signed(left.resultdef) then + inserttypeconv(left,s32inttype) + else + inserttypeconv(left,u32inttype); + firstpass(left); + end; + result := nil; + expectloc:=LOC_FPUREGISTER; end; - result := nil; - expectloc:=LOC_FPUREGISTER; end; @@ -143,3 +148,4 @@ implementation begin ctypeconvnode:=trv32typeconvnode; end. + diff --git a/riscv/trunk/compiler/riscv32/rarv32gas.pas b/riscv/trunk/compiler/riscv32/rarv32gas.pas index a1263f9383..b4ca7843c6 100644 --- a/riscv/trunk/compiler/riscv32/rarv32gas.pas +++ b/riscv/trunk/compiler/riscv32/rarv32gas.pas @@ -29,7 +29,8 @@ Unit rarv32gas; raatt,rarv32; type - trv32attreader = class(tattreader) + trv32attreader = class(tattreader) + function is_register(const s: string): boolean; override; function is_asmopcode(const s: string):boolean;override; procedure handleopcode;override; procedure BuildReference(oper : trvoperand); @@ -375,9 +376,42 @@ Unit rarv32gas; var tempreg : tregister; hl : tasmlabel; - ofs : aint; + ofs : aint; + refaddr: trefaddr; Begin - expr:=''; + expr:=''; + + refaddr:=addr_full; + if actasmtoken=AS_MOD then + begin + consume(AS_MOD); + + if actasmtoken<>AS_ID then + begin + Message(asmr_e_invalid_reference_syntax); + RecoverConsume(false); + end + else + begin + if lower(actasmpattern)='pcrel_hi' then + refaddr:=addr_pcrel_hi20 + else if lower(actasmpattern)='pcrel_lo' then + refaddr:=addr_pcrel_lo12 + else if lower(actasmpattern)='hi' then + refaddr:=addr_hi20 + else if lower(actasmpattern)='lo' then + refaddr:=addr_lo12 + else + begin + Message(asmr_e_invalid_reference_syntax); + RecoverConsume(false); + end; + + consume(AS_ID); + consume(AS_LPAREN); + end; + end; + case actasmtoken of AS_LPAREN: { Memory reference or constant expression } Begin @@ -520,7 +554,16 @@ Unit rarv32gas; Message(asmr_e_syn_operand); Consume(actasmtoken); end; - end; { end case } + end; { end case } + + if refaddr<>addr_full then + begin + if oper.opr.typ<>OPR_REFERENCE then + oper.InitRef; + + oper.opr.ref.refaddr:=refaddr; + Consume(AS_RPAREN); + end; end; @@ -587,6 +630,72 @@ Unit rarv32gas; end; + function trv32attreader.is_register(const s: string): boolean; + type + treg2str = record + name : string[3]; + reg : tregister; + end; + + const + extraregs : array[0..31] of treg2str = ( + (name: 'A0'; reg : NR_X10), + (name: 'A1'; reg : NR_X11), + (name: 'A2'; reg : NR_X12), + (name: 'A3'; reg : NR_X13), + (name: 'A5'; reg : NR_X14), + (name: 'A6'; reg : NR_X15), + (name: 'A7'; reg : NR_X16), + (name: 'A8'; reg : NR_X17), + (name: 'RA'; reg : NR_X1), + (name: 'SP'; reg : NR_X2), + (name: 'GP'; reg : NR_X3), + (name: 'TP'; reg : NR_X4), + (name: 'T0'; reg : NR_X5), + (name: 'T1'; reg : NR_X6), + (name: 'T2'; reg : NR_X7), + (name: 'S0'; reg : NR_X8), + (name: 'FP'; reg : NR_X8), + (name: 'S1'; reg : NR_X9), + (name: 'S2'; reg : NR_X18), + (name: 'S3'; reg : NR_X19), + (name: 'S4'; reg : NR_X20), + (name: 'S5'; reg : NR_X21), + (name: 'S6'; reg : NR_X22), + (name: 'S7'; reg : NR_X23), + (name: 'S8'; reg : NR_X24), + (name: 'S9'; reg : NR_X25), + (name: 'S10';reg : NR_X26), + (name: 'S11';reg : NR_X27), + (name: 'T3'; reg : NR_X28), + (name: 'T4'; reg : NR_X29), + (name: 'T5'; reg : NR_X30), + (name: 'T6'; reg : NR_X31) + ); + + var + i : longint; + + begin + result:=inherited is_register(s); + { reg found? + possible aliases are always 2 char + } + if result or (not (length(s) in [2,3])) then + exit; + for i:=low(extraregs) to high(extraregs) do + begin + if s=extraregs[i].name then + begin + actasmregister:=extraregs[i].reg; + result:=true; + actasmtoken:=AS_REGISTER; + exit; + end; + end; + end; + + function trv32attreader.is_asmopcode(const s: string):boolean; var cond : tasmcond; diff --git a/riscv/trunk/compiler/riscv64/cgcpu.pas b/riscv/trunk/compiler/riscv64/cgcpu.pas index 43ed2c0d76..0e37950732 100644 --- a/riscv/trunk/compiler/riscv64/cgcpu.pas +++ b/riscv/trunk/compiler/riscv64/cgcpu.pas @@ -37,41 +37,21 @@ unit cgcpu; procedure init_register_allocators; override; procedure done_register_allocators; override; - procedure a_op_const_reg(list: TAsmList; Op: TOpCG; size: TCGSize; a: aint; reg: TRegister); override; - procedure a_op_reg_reg(list: TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override; - - procedure a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: aint; src, dst: tregister); override; - procedure a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); override; - { move instructions } 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; - { comparison operations } - procedure a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: aint; reg: tregister; l: tasmlabel); override; - procedure g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef); override; procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean); override; procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean); override; - procedure g_save_registers(list: TAsmList); override; - procedure g_restore_registers(list: TAsmList); override; - procedure g_concatcopy_move(list: tasmlist; const Source, dest: treference; len: tcgint); procedure g_concatcopy(list: TAsmList; const source, dest: treference; len: aint); override; end; procedure create_codegen; - const - TOpCG2AsmConstOp: Array[topcg] of TAsmOp = (A_NONE, - A_NONE,A_ADDI,A_ANDI,A_NONE,A_NONE,A_NONE,A_NONE, - A_None,A_None,A_ORI,A_SRAI,A_SLLI,A_SRLI,A_NONE,A_XORI,A_None,A_None); - TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_NONE, - A_NONE,A_ADD,A_AND,A_DIVU,A_DIV,A_MUL,A_MUL, - A_None,A_None,A_OR,A_SRA,A_SLL,A_SRL,A_SUB,A_XOR,A_None,A_None); - implementation uses @@ -92,12 +72,12 @@ implementation RS_X9,RS_X27,RS_X26,RS_X25,RS_X24,RS_X23,RS_X22, RS_X21,RS_X20,RS_X19,RS_X18],first_int_imreg,[]); rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE, - [RS_F10,RS_F11,RS_F12,RS_F13,RS_F14,RS_F15,RS_F16,RS_F17, - RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7, - RS_F28,RS_F29,RS_F30,RS_F31, - RS_F8,RS_F9, - RS_F27, - RS_F26,RS_F25,RS_F24,RS_F23,RS_F22,RS_F21,RS_F20,RS_F19,RS_F18],first_fpu_imreg,[]); + [RS_F10,RS_F11,RS_F12,RS_F13,RS_F14,RS_F15,RS_F16,RS_F17, + RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7, + RS_F28,RS_F29,RS_F30,RS_F31, + RS_F8,RS_F9, + RS_F27, + RS_F26,RS_F25,RS_F24,RS_F23,RS_F22,RS_F21,RS_F20,RS_F19,RS_F18],first_fpu_imreg,[]); end; @@ -190,103 +170,9 @@ implementation end; end; - procedure tcgrv64.a_op_const_reg(list: TAsmList; Op: TOpCG; size: TCGSize; a: aint; reg: TRegister); - begin - a_op_const_reg_reg(list, op, size, a, reg, reg); - end; - - procedure tcgrv64.a_op_reg_reg(list: TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); - begin - a_op_reg_reg_reg(list, op, size, src, dst, dst); - end; - - procedure tcgrv64.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: aint; src, dst: tregister); - var - tmpreg: TRegister; - begin - optimize_op_const(size,op,a); - - if op=OP_NONE then - begin - a_load_reg_reg(list,size,size,src,dst); - exit; - end; - - if op=OP_SUB then - begin - op:=OP_ADD; - a:=-a; - end; - - if (TOpCG2AsmConstOp[op]<>A_None) and - is_imm12(a) then - list.concat(taicpu.op_reg_reg_const(TOpCG2AsmConstOp[op],dst,src,a)) - {else if (dst<>src) then - begin - a_load_const_reg(list,size,a,dst); - a_op_reg_reg_reg(list,op,size,dst,src,dst); - end} - else - begin - tmpreg:=getintregister(list,OS_INT); - a_load_const_reg(list,size,a,tmpreg); - a_op_reg_reg_reg(list,op,size,tmpreg,src,dst); - end; - end; - - - procedure tcgrv64.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); - begin - case op of - OP_NOT: - list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src1,-1)); - OP_NEG: - list.concat(taicpu.op_reg_reg_reg(A_SUB,dst,NR_X0,src1)); - OP_MOVE: - a_load_reg_reg(list,size,size,src1,dst); - else - list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1)); - end; - end; - - - procedure tcgrv64.a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; a: aint; reg: tregister; l: tasmlabel); - var - reg1: TRegister; - ai: taicpu; - begin - if a=0 then - begin - reg1:=NR_X0; - if TOpCmp2AsmCond[cmp_op]=C_None then - begin - cmp_op:=swap_opcmp(cmp_op); - reg1:=reg; - reg:=NR_X0; - end; - - ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,reg,reg1,l,0); - ai.is_jmp:=true; - ai.condition:=TOpCmp2AsmCond[cmp_op]; - list.concat(ai); - end - else - inherited; - end; procedure tcgrv64.g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef); begin - - end; - - - procedure tcgrv64.g_save_registers(list: TAsmList); - begin - end; - - - procedure tcgrv64.g_restore_registers(list: TAsmList); - begin end; diff --git a/riscv/trunk/compiler/riscv64/cpuinfo.pas b/riscv/trunk/compiler/riscv64/cpuinfo.pas index 4513671e0f..0c3f2b1124 100644 --- a/riscv/trunk/compiler/riscv64/cpuinfo.pas +++ b/riscv/trunk/compiler/riscv64/cpuinfo.pas @@ -1,7 +1,7 @@ { Copyright (c) 1998-2002 by the Free Pascal development team - Basic Processor information for the RiscV64 + Basic Processor information for the Risc-V64 See the file COPYING.FPC, included in this distribution, for details about the copyright. diff --git a/riscv/trunk/compiler/riscv64/nrv64add.pas b/riscv/trunk/compiler/riscv64/nrv64add.pas index 9727ffc388..37356772ff 100644 --- a/riscv/trunk/compiler/riscv64/nrv64add.pas +++ b/riscv/trunk/compiler/riscv64/nrv64add.pas @@ -1,7 +1,7 @@ { Copyright (c) 2000-2002 by Florian Klaempfl and Jonas Maebe - Code generation for add nodes on the RiscV64 + Code generation for add nodes on the Risc-V64 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,20 +30,11 @@ unit nrv64add; type trv64addnode = class(trvaddnode) - private - procedure Cmp(signed: boolean); protected function pass_1: tnode; override; - procedure second_cmpsmallset;override; - procedure second_cmpordinal;override; - procedure second_cmp64bit; override; - - procedure second_addordinal; override; procedure second_add64bit; override; - function use_fma: boolean; override; - function use_generic_mul32to64: boolean; override; end; @@ -62,144 +53,6 @@ unit nrv64add; symconst, hlcgobj, ncgutil,cgobj; - - function GetCompare(signed: boolean; nt: tnodetype): TOpCmp; - begin - result:=OC_NONE; - - if signed then - case nt of - ltn: result:=OC_LT; - lten: result:=OC_LTE; - gtn: result:=OC_GT; - gten: result:=OC_GTE; - equaln: result:=OC_EQ; - unequaln: result:=OC_NE; - end - else - case nt of - ltn: result:=OC_B; - lten: result:=OC_BE; - gtn: result:=OC_A; - gten: result:=OC_AE; - equaln: result:=OC_EQ; - unequaln: result:=OC_NE; - end - end; - - procedure trv64addnode.Cmp(signed: boolean); - var - flabel,tlabel: tasmlabel; - op, opi: TAsmOp; - begin - pass_left_right; - - force_reg_left_right(true,true); - - if nf_swapped in flags then - swapleftright; - - location_reset(location,LOC_REGISTER,OS_INT); - location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); - - if signed then op:=A_SLT else op:=A_SLTU; - if signed then opi:=A_SLTI else opi:=A_SLTIU; - - case nodetype of - equaln: - begin - if not (left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); - - if (right.location.loc=LOC_CONSTANT) and - (not is_imm12(-right.location.value)) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); - - if right.location.loc=LOC_CONSTANT then - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_ADDI,location.register,left.location.register,-right.location.value)) - else - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(A_SUB,location.register,left.location.register,right.location.register)); - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_SLTIU,location.register,location.register,1)); - end; - unequaln: - begin - if not (left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); - - if (right.location.loc=LOC_CONSTANT) and - (not is_imm12(-right.location.value)) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); - - if right.location.loc=LOC_CONSTANT then - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_ADDI,location.register,left.location.register,-right.location.value)) - else - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(A_SUB,location.register,left.location.register,right.location.register)); - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(A_SLTU,location.register,NR_X0,location.register)); - end; - ltn: - begin - if not (left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); - - if (right.location.loc=LOC_CONSTANT) and - (not is_imm12(right.location.value)) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); - - if right.location.loc=LOC_CONSTANT then - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(opi,location.register,left.location.register,right.location.value)) - else - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register)); - end; - gtn: - begin - if not (right.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); - - if (left.location.loc=LOC_CONSTANT) and - (not is_imm12(left.location.value)) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); - - if left.location.loc=LOC_CONSTANT then - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(opi,location.register,right.location.register,left.location.value)) - else - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(op,location.register,right.location.register,left.location.register)); - end; - - lten: - begin - if not (right.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); - - if (left.location.loc=LOC_CONSTANT) and - (not is_imm12(left.location.value)) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); - - if left.location.loc=LOC_CONSTANT then - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(opi,location.register,right.location.register,left.location.value)) - else - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(op,location.register,right.location.register,left.location.register)); - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_SLTIU,location.register,location.register,1)); - end; - gten: - begin - if not (left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false); - - if (right.location.loc=LOC_CONSTANT) and - (not is_imm12(right.location.value)) then - hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false); - - if right.location.loc=LOC_CONSTANT then - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(opi,location.register,left.location.register,right.location.value)) - else - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register)); - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_const(A_SLTIU,location.register,location.register,1)); - end; - else - Internalerror(2016061101); - end; - end; - function trv64addnode.pass_1: tnode; begin if (nodetype=muln) and @@ -227,67 +80,12 @@ unit nrv64add; expectloc:=LOC_REGISTER; end; - procedure trv64addnode.second_cmpsmallset; - begin - Cmp(true); - end; - - procedure trv64addnode.second_cmpordinal; - var - unsigned: Boolean; - begin - unsigned:=not(is_signed(left.resultdef)) or - not(is_signed(right.resultdef)); - - Cmp(not unsigned); - end; - - procedure trv64addnode.second_cmp64bit; - var - unsigned: Boolean; - begin - unsigned:=not(is_signed(left.resultdef)) or - not(is_signed(right.resultdef)); - - Cmp(not unsigned); - end; - - - procedure trv64addnode.second_addordinal; - var - unsigned: boolean; - begin - { 32x32->64 multiplication } - if (nodetype=muln) and - is_32bit(left.resultdef) and - is_32bit(right.resultdef) and - is_64bit(resultdef) then - begin - unsigned:=not(is_signed(left.resultdef)) or - not(is_signed(right.resultdef)); - pass_left_right; - force_reg_left_right(true,true); - { force_reg_left_right can leave right as a LOC_CONSTANT (we can't - say "a constant register is okay, but an ordinal constant isn't) } - if right.location.loc=LOC_CONSTANT then - hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true); - location_reset(location,LOC_REGISTER,def_cgsize(resultdef)); - location.register:=cg.getintregister(current_asmdata.CurrAsmList,def_cgsize(resultdef)); - current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg_reg(A_MUL,location.register,left.location.register,right.location.register)); - end - else - inherited second_addordinal; - end; procedure trv64addnode.second_add64bit; begin second_addordinal; end; - function trv64addnode.use_fma: boolean; - begin - Result:=current_settings.fputype in [fpu_fd]; - end; function trv64addnode.use_generic_mul32to64: boolean; begin diff --git a/riscv/trunk/compiler/riscv64/rarv64gas.pas b/riscv/trunk/compiler/riscv64/rarv64gas.pas index 4aa8f2bef1..41b6b4b884 100644 --- a/riscv/trunk/compiler/riscv64/rarv64gas.pas +++ b/riscv/trunk/compiler/riscv64/rarv64gas.pas @@ -117,7 +117,7 @@ unit rarv64gas; end; - procedure trv64attreader.BuildReference(oper: trvoperand); + procedure trv64attreader.BuildReference(oper: trvoperand); procedure Consume_RParen; begin @@ -252,7 +252,7 @@ unit rarv64gas; end; - procedure trv64attreader.BuildOperand(oper: trvoperand); + procedure trv64attreader.BuildOperand(oper: trvoperand); var expr : string; typesize,l : aint; diff --git a/riscv/trunk/compiler/systems.inc b/riscv/trunk/compiler/systems.inc index e30eeda4fc..6d41e0fe18 100644 --- a/riscv/trunk/compiler/systems.inc +++ b/riscv/trunk/compiler/systems.inc @@ -176,7 +176,8 @@ system_i8086_win16, { 89 } system_riscv32_linux, { 90 } system_riscv64_linux, { 91 } - system_riscv64_embedded { 92 } + system_riscv64_embedded, { 92 } + system_riscv32_embedded { 93 } ); type diff --git a/riscv/trunk/compiler/systems/i_embed.pas b/riscv/trunk/compiler/systems/i_embed.pas index 246cc3a581..5f8d567514 100644 --- a/riscv/trunk/compiler/systems/i_embed.pas +++ b/riscv/trunk/compiler/systems/i_embed.pas @@ -346,7 +346,71 @@ unit i_embed; stackalign : 16; abi : abi_default; llvmdatalayout : 'e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128'; - ); + ); + + system_riscv32_embedded_info : tsysteminfo = + ( + system : system_riscv32_embedded; + name : 'Embedded'; + shortname : 'embedded'; + flags : [tf_needs_symbol_size,tf_needs_symbol_type,tf_files_case_sensitive, + tf_requires_proper_alignment,tf_smartlink_sections]; + cpu : cpu_riscv32; + unit_env : ''; + extradefines : ''; + exeext : ''; + defext : '.def'; + scriptext : '.sh'; + smartext : '.sl'; + unitext : '.ppu'; + unitlibext : '.ppl'; + asmext : '.s'; + objext : '.o'; + resext : '.res'; + resobjext : '.or'; + sharedlibext : '.so'; + staticlibext : '.a'; + staticlibprefix : 'libp'; + sharedlibprefix : 'lib'; + sharedClibext : '.so'; + staticClibext : '.a'; + staticClibprefix : 'lib'; + sharedClibprefix : 'lib'; + importlibprefix : 'libimp'; + importlibext : '.a'; + Cprefix : ''; + newline : #10; + dirsep : '/'; + assem : as_gas; + assemextern : as_gas; + link : ld_none; + linkextern : ld_embedded; + ar : ar_gnu_ar; + res : res_none; + dbg : dbg_dwarf2; + script : script_unix; + endian : endian_little; + alignment : + ( + procalign : 4; + loopalign : 4; + jumpalign : 0; + constalignmin : 4; + constalignmax : 4; + varalignmin : 4; + varalignmax : 4; + localalignmin : 4; + localalignmax : 4; + recordalignmin : 0; + recordalignmax : 4; + maxCrecordalign : 4 + ); + first_parm_offset : 0; + stacksize : 262144; + stackalign : 4; + abi : abi_default; + llvmdatalayout : 'e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32'; + ); system_riscv64_embedded_info : tsysteminfo = ( @@ -440,6 +504,11 @@ initialization set_source_info(system_x86_64_embedded_info); {$endif embedded} {$endif CPUX86_64} +{$ifdef CPURISCV32} + {$ifdef embedded} + set_source_info(system_riscv32_embedded_info); + {$endif embedded} +{$endif CPURISCV32} {$ifdef CPURISCV64} {$ifdef embedded} set_source_info(system_riscv64_embedded_info); diff --git a/riscv/trunk/compiler/systems/t_embed.pas b/riscv/trunk/compiler/systems/t_embed.pas index 7d1b8438aa..c1168a4ea3 100644 --- a/riscv/trunk/compiler/systems/t_embed.pas +++ b/riscv/trunk/compiler/systems/t_embed.pas @@ -1535,6 +1535,11 @@ initialization RegisterTarget(system_mipsel_embedded_info); {$endif mipsel} +{$ifdef riscv32} + RegisterLinker(ld_embedded,TLinkerEmbedded); + RegisterTarget(system_riscv32_embedded_info); +{$endif riscv32} + {$ifdef riscv64} RegisterLinker(ld_embedded,TLinkerEmbedded); RegisterTarget(system_riscv64_embedded_info); |