summaryrefslogtreecommitdiff
path: root/compiler/i386
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/i386')
-rw-r--r--compiler/i386/cgcpu.pas7
-rw-r--r--compiler/i386/cpuelf.pas2
-rw-r--r--compiler/i386/cpuinfo.pas20
-rw-r--r--compiler/i386/cpupara.pas18
-rw-r--r--compiler/i386/cputarg.pas3
-rw-r--r--compiler/i386/n386add.pas148
-rw-r--r--compiler/i386/n386cal.pas38
-rw-r--r--compiler/i386/n386flw.pas15
-rw-r--r--compiler/i386/symcpu.pas59
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.