diff options
Diffstat (limited to 'compiler/i386')
-rw-r--r-- | compiler/i386/cgcpu.pas | 7 | ||||
-rw-r--r-- | compiler/i386/cpuelf.pas | 2 | ||||
-rw-r--r-- | compiler/i386/cpuinfo.pas | 20 | ||||
-rw-r--r-- | compiler/i386/cpupara.pas | 18 | ||||
-rw-r--r-- | compiler/i386/cputarg.pas | 3 | ||||
-rw-r--r-- | compiler/i386/n386add.pas | 148 | ||||
-rw-r--r-- | compiler/i386/n386cal.pas | 38 | ||||
-rw-r--r-- | compiler/i386/n386flw.pas | 15 | ||||
-rw-r--r-- | compiler/i386/symcpu.pas | 59 |
9 files changed, 237 insertions, 73 deletions
diff --git a/compiler/i386/cgcpu.pas b/compiler/i386/cgcpu.pas index 21e715860c..de73fc0b05 100644 --- a/compiler/i386/cgcpu.pas +++ b/compiler/i386/cgcpu.pas @@ -314,6 +314,13 @@ unit cgcpu; end; begin + { Release PIC register } + if (cs_create_pic in current_settings.moduleswitches) and + (tf_pic_uses_got in target_info.flags) and + (pi_needs_got in current_procinfo.flags) and + not(target_info.system in systems_darwin) then + list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG,nil)); + { MMX needs to call EMMS } if assigned(rg[R_MMXREGISTER]) and (rg[R_MMXREGISTER].uses_registers) then diff --git a/compiler/i386/cpuelf.pas b/compiler/i386/cpuelf.pas index f61e83f05a..fd171e3ed0 100644 --- a/compiler/i386/cpuelf.pas +++ b/compiler/i386/cpuelf.pas @@ -509,7 +509,7 @@ implementation system_i386_openbsd,system_i386_netbsd, system_i386_Netware,system_i386_netwlibc, system_i386_solaris,system_i386_embedded, - system_i386_android]; + system_i386_android,system_i386_aros]; flags : [af_outputbinary,af_smartlink_sections,af_supports_dwarf]; labelprefix : '.L'; comment : ''; diff --git a/compiler/i386/cpuinfo.pas b/compiler/i386/cpuinfo.pas index 97894c14ac..ced7496d15 100644 --- a/compiler/i386/cpuinfo.pas +++ b/compiler/i386/cpuinfo.pas @@ -30,6 +30,9 @@ Interface Type bestreal = extended; +{$if FPC_FULLVERSION>20700} + bestrealrec = TExtended80Rec; +{$endif FPC_FULLVERSION>20700} ts32real = single; ts64real = double; ts80real = extended; @@ -66,8 +69,25 @@ Type fpu_avx2 ); + tcontrollertype = + (ct_none + ); + Const + { Is there support for dealing with multiple microcontrollers available } + { for this platform? } + ControllerSupport = false; + + { We know that there are fields after sramsize + but we don't care about this warning } + {$PUSH} + {$WARN 3177 OFF} + embedded_controllers : array [tcontrollertype] of tcontrollerdatatype = + ( + (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0)); + {$POP} + { calling conventions supported by the code generator } supported_calling_conventions : tproccalloptions = [ pocall_internproc, diff --git a/compiler/i386/cpupara.pas b/compiler/i386/cpupara.pas index 5cfed2c1dc..41b83a892c 100644 --- a/compiler/i386/cpupara.pas +++ b/compiler/i386/cpupara.pas @@ -114,6 +114,23 @@ unit cpupara; end; end; end; + system_i386_os2, + system_i386_emx: + begin + case def.typ of + recorddef : + begin + { EMX port of GCC returns small records in the FUNCTION_RETURN_REG up to 4 bytes in registers. } + if ((pd.proccalloption in [pocall_cdecl,pocall_cppdecl]) and + (def.size>0) and + (def.size<=4)) then + begin + result:=false; + exit; + end; + end; + end; + end; system_i386_freebsd, system_i386_openbsd, system_i386_darwin, @@ -243,6 +260,7 @@ unit cpupara; pocall_safecall, pocall_stdcall, pocall_cdecl, + pocall_syscall, pocall_cppdecl, pocall_mwpascal : result:=[RS_EAX,RS_EDX,RS_ECX]; diff --git a/compiler/i386/cputarg.pas b/compiler/i386/cputarg.pas index 64cd649c87..427cc1196b 100644 --- a/compiler/i386/cputarg.pas +++ b/compiler/i386/cputarg.pas @@ -86,6 +86,9 @@ implementation {$ifndef NOTARGETEMBEDDED} ,t_embed {$endif} + {$ifndef NOTARGETAROS} + ,t_aros + {$endif} {************************************** Assemblers diff --git a/compiler/i386/n386add.pas b/compiler/i386/n386add.pas index 3f42b639c8..b75b18d83d 100644 --- a/compiler/i386/n386add.pas +++ b/compiler/i386/n386add.pas @@ -229,8 +229,7 @@ interface procedure ti386addnode.second_cmp64bit; var - hregister, - hregister2 : tregister; + hlab : tasmlabel; href : treference; unsigned : boolean; @@ -247,10 +246,12 @@ interface case nodetype of ltn,gtn: begin - cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel); + if (hlab<>current_procinfo.CurrTrueLabel) then + cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel); { cheat a little bit for the negative test } toggleflag(nf_swapped); - cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel); + if (hlab<>current_procinfo.CurrFalseLabel) then + cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel); toggleflag(nf_swapped); end; lten,gten: @@ -260,13 +261,15 @@ interface nodetype:=ltn else nodetype:=gtn; - cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel); + if (hlab<>current_procinfo.CurrTrueLabel) then + cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel); { cheat for the negative test } if nodetype=ltn then nodetype:=gtn else nodetype:=ltn; - cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel); + if (hlab<>current_procinfo.CurrFalseLabel) then + cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel); nodetype:=oldnodetype; end; equaln: @@ -309,24 +312,46 @@ interface ((right.resultdef.typ=orddef) and (torddef(right.resultdef).ordtype=u64bit)); + { we have LOC_JUMP as result } + location_reset(location,LOC_JUMP,OS_NO); + + { Relational compares against constants having low dword=0 can omit the + second compare based on the fact that any unsigned value is >=0 } + hlab:=nil; + if (right.location.loc=LOC_CONSTANT) and + (lo(right.location.value64)=0) then + begin + case getresflags(true) of + F_AE: hlab:=current_procinfo.CurrTrueLabel; + F_B: hlab:=current_procinfo.CurrFalseLabel; + end; + end; + + if (right.location.loc=LOC_CONSTANT) and + (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then + begin + tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,left.location.reference); + href:=left.location.reference; + inc(href.offset,4); + emit_const_ref(A_CMP,S_L,aint(hi(right.location.value64)),href); + firstjmp64bitcmp; + if assigned(hlab) then + cg.a_jmp_always(current_asmdata.CurrAsmList,hlab) + else + begin + emit_const_ref(A_CMP,S_L,aint(lo(right.location.value64)),left.location.reference); + secondjmp64bitcmp; + end; + location_freetemp(current_asmdata.CurrAsmList,left.location); + exit; + end; + { left and right no register? } { then one must be demanded } - if (left.location.loc<>LOC_REGISTER) then + if not (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then begin - if (right.location.loc<>LOC_REGISTER) then - begin - { we can reuse a CREGISTER for comparison } - if (left.location.loc<>LOC_CREGISTER) then - begin - hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); - hregister2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT); - cg64.a_load64_loc_reg(current_asmdata.CurrAsmList,left.location,joinreg64(hregister,hregister2)); - location_freetemp(current_asmdata.CurrAsmList,left.location); - location_reset(left.location,LOC_REGISTER,left.location.size); - left.location.register64.reglo:=hregister; - left.location.register64.reghi:=hregister2; - end; - end + if not (right.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then + hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true) else begin location_swap(left.location,right.location); @@ -334,51 +359,44 @@ interface end; end; - { at this point, left.location.loc should be LOC_REGISTER } - if right.location.loc=LOC_REGISTER then - begin - emit_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi); - firstjmp64bitcmp; - emit_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo); - secondjmp64bitcmp; - end + { at this point, left.location.loc should be LOC_[C]REGISTER } + case right.location.loc of + LOC_REGISTER, + LOC_CREGISTER : + begin + emit_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi); + firstjmp64bitcmp; + emit_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo); + secondjmp64bitcmp; + end; + LOC_CREFERENCE, + LOC_REFERENCE : + begin + tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,right.location.reference); + href:=right.location.reference; + inc(href.offset,4); + emit_ref_reg(A_CMP,S_L,href,left.location.register64.reghi); + firstjmp64bitcmp; + emit_ref_reg(A_CMP,S_L,right.location.reference,left.location.register64.reglo); + secondjmp64bitcmp; + location_freetemp(current_asmdata.CurrAsmList,right.location); + end; + LOC_CONSTANT : + begin + current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(hi(right.location.value64)),left.location.register64.reghi)); + firstjmp64bitcmp; + if assigned(hlab) then + cg.a_jmp_always(current_asmdata.CurrAsmList,hlab) + else + begin + current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(lo(right.location.value64)),left.location.register64.reglo)); + secondjmp64bitcmp; + end; + end; else - begin - case right.location.loc of - LOC_CREGISTER : - begin - emit_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi); - firstjmp64bitcmp; - emit_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo); - secondjmp64bitcmp; - end; - LOC_CREFERENCE, - LOC_REFERENCE : - begin - tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,right.location.reference); - href:=right.location.reference; - inc(href.offset,4); - emit_ref_reg(A_CMP,S_L,href,left.location.register64.reghi); - firstjmp64bitcmp; - emit_ref_reg(A_CMP,S_L,right.location.reference,left.location.register64.reglo); - secondjmp64bitcmp; - cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel); - location_freetemp(current_asmdata.CurrAsmList,right.location); - end; - LOC_CONSTANT : - begin - current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(hi(right.location.value64)),left.location.register64.reghi)); - firstjmp64bitcmp; - current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(lo(right.location.value64)),left.location.register64.reglo)); - secondjmp64bitcmp; - end; - else - internalerror(200203282); - end; - end; + internalerror(200203282); + end; - { we have LOC_JUMP as result } - location_reset(location,LOC_JUMP,OS_NO) end; @@ -424,6 +442,8 @@ interface begin pass_left_right; + reg:=NR_NO; + reference_reset(ref,sizeof(pint)); { Mul supports registers and references, so if not register/reference, load the location into a register. diff --git a/compiler/i386/n386cal.pas b/compiler/i386/n386cal.pas index d032174611..052359c4c8 100644 --- a/compiler/i386/n386cal.pas +++ b/compiler/i386/n386cal.pas @@ -28,13 +28,16 @@ interface { $define AnsiStrRef} uses - nx86cal; + nx86cal,ncal; type ti386callnode = class(tx86callnode) protected + procedure gen_syscall_para(para: tcallparanode); override; procedure pop_parasize(pop_size:longint);override; procedure extra_interrupt_code;override; + public + procedure do_syscall;override; end; @@ -46,7 +49,8 @@ implementation cgbase,cgutils, cpubase,paramgr, aasmtai,aasmdata,aasmcpu, - ncal,nbas,nmem,nld,ncnv, + nbas,nmem,nld,ncnv, + symdef,symsym,symcpu, cga,cgobj,cpuinfo; @@ -55,6 +59,36 @@ implementation *****************************************************************************} + procedure ti386callnode.do_syscall; + var + tmpref: treference; + begin + case target_info.system of + system_i386_aros: + begin + // one syscall convention for AROS + current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall'))); + reference_reset(tmpref,sizeof(pint)); + tmpref.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(tcpuprocdef(procdefinition).libsym).mangledname); + cg.getcpuregister(current_asmdata.CurrAsmList,NR_EAX); + cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_EAX); + reference_reset_base(tmpref,NR_EAX,-tprocdef(procdefinition).extnumber,sizeof(pint)); + cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_EAX); + cg.a_call_reg(current_asmdata.CurrAsmList,NR_EAX); + cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_EAX); + end; + else + internalerror(2014081801); + end; + end; + + + procedure ti386callnode.gen_syscall_para(para: tcallparanode); + begin + { lib parameter has no special type but proccalloptions must be a syscall } + para.left:=cloadnode.create(tcpuprocdef(procdefinition).libsym,tcpuprocdef(procdefinition).libsym.owner); + end; + procedure ti386callnode.extra_interrupt_code; begin if not(target_info.system in [system_i386_darwin,system_i386_iphonesim,system_i386_android]) then diff --git a/compiler/i386/n386flw.pas b/compiler/i386/n386flw.pas index dee3320a9d..624b35423b 100644 --- a/compiler/i386/n386flw.pas +++ b/compiler/i386/n386flw.pas @@ -316,6 +316,7 @@ procedure ti386tryfinallynode.pass_generate_code; breakfinallylabel:=nil; exceptlabel:=nil; safecalllabel:=nil; + hreg:=NR_NO; is_safecall:=implicitframe and (current_procinfo.procdef.proccalloption=pocall_safecall); { check if child nodes do a break/continue/exit } @@ -489,6 +490,12 @@ procedure ti386tryexceptnode.pass_generate_code; end; location_reset(location,LOC_VOID,OS_NO); + exceptflowcontrol:=[]; + breakexceptlabel:=nil; + continueexceptlabel:=nil; + breaktrylabel:=nil; + continuetrylabel:=nil; + oldflowcontrol:=flowcontrol; flowcontrol:=[fc_inflowcontrol]; { this can be called recursivly } @@ -528,7 +535,7 @@ procedure ti386tryexceptnode.pass_generate_code; { start of scope } if assigned(right) then begin - current_asmdata.getdatalabel(filterlabel); + current_asmdata.getaddrlabel(filterlabel); emit_scope_start( current_asmdata.RefAsmSymbol('__FPC_on_handler'), filterlabel); @@ -602,8 +609,7 @@ procedure ti386tryexceptnode.pass_generate_code; begin if hnode.nodetype<>onn then InternalError(2011103101); - { TODO: make it done without using global label } - current_asmdata.getglobaljumplabel(onlabel); + current_asmdata.getjumplabel(onlabel); hlist.concat(tai_const.create_sym(current_asmdata.RefAsmSymbol(tonnode(hnode).excepttype.vmt_mangledname,AT_DATA))); hlist.concat(tai_const.create_sym(onlabel)); cg.a_label(current_asmdata.CurrAsmList,onlabel); @@ -619,8 +625,7 @@ procedure ti386tryexceptnode.pass_generate_code; inc(onnodecount.value); end; { now move filter table to permanent list all at once } - maybe_new_object_file(current_asmdata.asmlists[al_typedconsts]); - current_asmdata.asmlists[al_typedconsts].concatlist(hlist); + current_procinfo.aktlocaldata.concatlist(hlist); hlist.free; end; diff --git a/compiler/i386/symcpu.pas b/compiler/i386/symcpu.pas index 9fbc65bab5..6e4ab4bd78 100644 --- a/compiler/i386/symcpu.pas +++ b/compiler/i386/symcpu.pas @@ -26,7 +26,7 @@ unit symcpu; interface uses - symtype,symdef,symsym,symx86,symi86; + symconst,symtype,symdef,symsym,symx86,symi86; type { defs } @@ -91,6 +91,15 @@ type tcpuprocvardefclass = class of tcpuprocvardef; tcpuprocdef = class(ti86procdef) + procedure ppuload_platform(ppufile: tcompilerppufile); override; + procedure ppuwrite_platform(ppufile: tcompilerppufile); override; + public + { library symbol for AROS } + libsym : tsym; + libsymderef : tderef; + function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef; override; + procedure buildderef; override; + procedure deref; override; end; tcpuprocdefclass = class of tcpuprocdef; @@ -170,6 +179,52 @@ const implementation +{**************************************************************************** + tcpuprocdef +****************************************************************************} + + procedure tcpuprocdef.ppuload_platform(ppufile: tcompilerppufile); + begin + inherited; + if po_syscall_has_libsym in procoptions then + ppufile.getderef(libsymderef); + end; + + + procedure tcpuprocdef.ppuwrite_platform(ppufile: tcompilerppufile); + begin + inherited; + if po_syscall_has_libsym in procoptions then + ppufile.putderef(libsymderef); + end; + + + function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef; + begin + result:=inherited; + if newtyp=procdef then + tcpuprocdef(result).libsym:=libsym; + end; + + + procedure tcpuprocdef.buildderef; + begin + inherited; + if po_syscall_has_libsym in procoptions then + libsymderef.build(libsym); + end; + + + procedure tcpuprocdef.deref; + begin + inherited; + if po_syscall_has_libsym in procoptions then + libsym:=tsym(libsymderef.resolve) + else + libsym:=nil; + end; + + begin { used tdef classes } cfiledef:=tcpufiledef; @@ -207,5 +262,7 @@ begin cconstsym:=tcpuconstsym; cenumsym:=tcpuenumsym; csyssym:=tcpusyssym; + + cPtrDefHashSet:=tx86PtrDefHashSet; end. |