|
@@ -86,7 +86,9 @@ interface
|
|
{ used to mark assembler blocks and inlined functions }
|
|
{ used to mark assembler blocks and inlined functions }
|
|
ait_marker,
|
|
ait_marker,
|
|
{ used to describe a new location of a variable }
|
|
{ used to describe a new location of a variable }
|
|
- ait_varloc
|
|
|
|
|
|
+ ait_varloc,
|
|
|
|
+ { SEH directives used in ARM,MIPS and x86_64 COFF targets }
|
|
|
|
+ ait_seh_directive
|
|
);
|
|
);
|
|
|
|
|
|
taiconst_type = (
|
|
taiconst_type = (
|
|
@@ -173,7 +175,8 @@ interface
|
|
'regalloc',
|
|
'regalloc',
|
|
'tempalloc',
|
|
'tempalloc',
|
|
'marker',
|
|
'marker',
|
|
- 'varloc'
|
|
|
|
|
|
+ 'varloc',
|
|
|
|
+ 'seh_directive'
|
|
);
|
|
);
|
|
|
|
|
|
type
|
|
type
|
|
@@ -237,7 +240,7 @@ interface
|
|
SkipInstr = [ait_comment, ait_symbol,ait_section
|
|
SkipInstr = [ait_comment, ait_symbol,ait_section
|
|
,ait_stab, ait_function_name, ait_force_line
|
|
,ait_stab, ait_function_name, ait_force_line
|
|
,ait_regalloc, ait_tempalloc, ait_symbol_end, ait_directive
|
|
,ait_regalloc, ait_tempalloc, ait_symbol_end, ait_directive
|
|
- ,ait_varloc];
|
|
|
|
|
|
+ ,ait_varloc,ait_seh_directive];
|
|
|
|
|
|
{ ait_* types which do not have line information (and hence which are of type
|
|
{ ait_* types which do not have line information (and hence which are of type
|
|
tai, otherwise, they are of type tailineinfo }
|
|
tai, otherwise, they are of type tailineinfo }
|
|
@@ -250,7 +253,8 @@ interface
|
|
ait_thumb_func,
|
|
ait_thumb_func,
|
|
{$endif arm}
|
|
{$endif arm}
|
|
ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit,ait_real_128bit,
|
|
ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit,ait_real_128bit,
|
|
- ait_symbol
|
|
|
|
|
|
+ ait_symbol,
|
|
|
|
+ ait_seh_directive
|
|
];
|
|
];
|
|
|
|
|
|
|
|
|
|
@@ -276,6 +280,15 @@ interface
|
|
asd_weak_definition
|
|
asd_weak_definition
|
|
);
|
|
);
|
|
|
|
|
|
|
|
+ TAsmSehDirective=(
|
|
|
|
+ ash_proc,ash_endproc,
|
|
|
|
+ ash_endprologue,ash_handler,ash_handlerdata,
|
|
|
|
+ ash_eh,ash_32,ash_no32,
|
|
|
|
+ ash_setframe,ash_stackalloc,ash_pushreg,
|
|
|
|
+ ash_savereg,ash_savexmm,ash_pushframe
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+
|
|
const
|
|
const
|
|
regallocstr : array[tregalloctype] of string[10]=('allocated','released','sync','resized');
|
|
regallocstr : array[tregalloctype] of string[10]=('allocated','released','sync','resized');
|
|
tempallocstr : array[boolean] of string[10]=('released','allocated');
|
|
tempallocstr : array[boolean] of string[10]=('released','allocated');
|
|
@@ -285,6 +298,13 @@ interface
|
|
'extern','nasm_import', 'tc', 'reference',
|
|
'extern','nasm_import', 'tc', 'reference',
|
|
'no_dead_strip','weak_reference','lazy_reference','weak_definition'
|
|
'no_dead_strip','weak_reference','lazy_reference','weak_definition'
|
|
);
|
|
);
|
|
|
|
+ sehdirectivestr : array[TAsmSehDirective] of string[15]=(
|
|
|
|
+ 'seh_proc','seh_endproc',
|
|
|
|
+ 'seh_endprologue','seh_handler','seh_handlerdata',
|
|
|
|
+ 'seh_eh','seh_32','seh_no32',
|
|
|
|
+ 'seh_setframe','seh_stackalloc','seh_pushreg',
|
|
|
|
+ 'seh_savereg','seh_savexmm','seh_pushframe'
|
|
|
|
+ );
|
|
|
|
|
|
type
|
|
type
|
|
{ abstract assembler item }
|
|
{ abstract assembler item }
|
|
@@ -399,7 +419,7 @@ interface
|
|
private
|
|
private
|
|
{ this constructor is made private on purpose }
|
|
{ this constructor is made private on purpose }
|
|
{ because sections should be created via new_section() }
|
|
{ because sections should be created via new_section() }
|
|
- constructor Create(Asectype:TAsmSectiontype;Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default);
|
|
|
|
|
|
+ constructor Create(Asectype:TAsmSectiontype;const Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -661,6 +681,31 @@ interface
|
|
procedure derefimpl;override;
|
|
procedure derefimpl;override;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ TSehDirectiveDatatype=(sd_none,sd_string,sd_reg,sd_offset,sd_regoffset);
|
|
|
|
+
|
|
|
|
+ TSehDirectiveData=record
|
|
|
|
+ case typ: TSehDirectiveDatatype of
|
|
|
|
+ sd_none: ();
|
|
|
|
+ sd_string: (name:pshortstring);
|
|
|
|
+ sd_reg,sd_offset,sd_regoffset: (reg:TRegister;offset:dword);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ tai_seh_directive = class(tai)
|
|
|
|
+ kind: TAsmSehDirective;
|
|
|
|
+ data: TSehDirectiveData;
|
|
|
|
+ constructor create(_kind:TAsmSehDirective);
|
|
|
|
+ constructor create_name(_kind:TAsmSehDirective;const _name: string);
|
|
|
|
+ constructor create_reg(_kind:TAsmSehDirective;r:TRegister);
|
|
|
|
+ constructor create_offset(_kind:TAsmSehDirective;ofs:dword);
|
|
|
|
+ constructor create_reg_offset(_kind:TAsmSehDirective;r:TRegister;ofs:dword);
|
|
|
|
+ constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
|
|
|
|
+ destructor destroy;override;
|
|
|
|
+ procedure ppuwrite(ppufile:tcompilerppufile);override;
|
|
|
|
+ procedure generate_code(objdata:TObjData);virtual;
|
|
|
|
+ property datatype: TSehDirectiveDatatype read data.typ;
|
|
|
|
+ end;
|
|
|
|
+ tai_seh_directive_class=class of tai_seh_directive;
|
|
|
|
+
|
|
var
|
|
var
|
|
{ array with all class types for tais }
|
|
{ array with all class types for tais }
|
|
aiclass : taiclassarray;
|
|
aiclass : taiclassarray;
|
|
@@ -668,12 +713,13 @@ interface
|
|
{ target specific tais, possibly overwritten in target specific aasmcpu }
|
|
{ target specific tais, possibly overwritten in target specific aasmcpu }
|
|
cai_align : tai_align_class = tai_align_abstract;
|
|
cai_align : tai_align_class = tai_align_abstract;
|
|
cai_cpu : tai_cpu_class = tai_cpu_abstract;
|
|
cai_cpu : tai_cpu_class = tai_cpu_abstract;
|
|
|
|
+ cai_seh_directive: tai_seh_directive_class = tai_seh_directive;
|
|
|
|
|
|
{ hook to notify uses of registers }
|
|
{ hook to notify uses of registers }
|
|
add_reg_instruction_hook : tadd_reg_instruction_proc;
|
|
add_reg_instruction_hook : tadd_reg_instruction_proc;
|
|
|
|
|
|
procedure maybe_new_object_file(list:TAsmList);
|
|
procedure maybe_new_object_file(list:TAsmList);
|
|
- procedure new_section(list:TAsmList;Asectype:TAsmSectiontype;Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default);
|
|
|
|
|
|
+ procedure new_section(list:TAsmList;Asectype:TAsmSectiontype;const Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default);
|
|
procedure section_symbol_start(list:TAsmList;const Aname:string;Asymtyp:Tasmsymtype;
|
|
procedure section_symbol_start(list:TAsmList;const Aname:string;Asymtyp:Tasmsymtype;
|
|
Aglobal:boolean;Asectype:TAsmSectiontype;Aalign:byte);
|
|
Aglobal:boolean;Asectype:TAsmSectiontype;Aalign:byte);
|
|
procedure section_symbol_end(list:TAsmList;const Aname:string);
|
|
procedure section_symbol_end(list:TAsmList;const Aname:string);
|
|
@@ -705,7 +751,7 @@ implementation
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- procedure new_section(list:TAsmList;Asectype:TAsmSectiontype;Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default);
|
|
|
|
|
|
+ procedure new_section(list:TAsmList;Asectype:TAsmSectiontype;const Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default);
|
|
begin
|
|
begin
|
|
list.concat(tai_section.create(Asectype,Aname,Aalign,Asecorder));
|
|
list.concat(tai_section.create(Asectype,Aname,Aalign,Asecorder));
|
|
list.concat(cai_align.create(Aalign));
|
|
list.concat(cai_align.create(Aalign));
|
|
@@ -893,7 +939,7 @@ implementation
|
|
TAI_SECTION
|
|
TAI_SECTION
|
|
****************************************************************************}
|
|
****************************************************************************}
|
|
|
|
|
|
- constructor tai_section.Create(Asectype:TAsmSectiontype;Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default);
|
|
|
|
|
|
+ constructor tai_section.Create(Asectype:TAsmSectiontype;const Aname:string;Aalign:byte;Asecorder:TasmSectionorder=secorder_default);
|
|
begin
|
|
begin
|
|
inherited Create;
|
|
inherited Create;
|
|
typ:=ait_section;
|
|
typ:=ait_section;
|
|
@@ -2486,6 +2532,110 @@ implementation
|
|
ppufile.putbyte(fillop);
|
|
ppufile.putbyte(fillop);
|
|
ppufile.putbyte(byte(use_op));
|
|
ppufile.putbyte(byte(use_op));
|
|
end;
|
|
end;
|
|
|
|
+
|
|
|
|
+{****************************************************************************
|
|
|
|
+ tai_seh_directive
|
|
|
|
+ ****************************************************************************}
|
|
|
|
+
|
|
|
|
+ const
|
|
|
|
+ datatypemap: array[TAsmSehDirective] of TSehDirectiveDatatype=(
|
|
|
|
+ sd_string, { proc }
|
|
|
|
+ sd_none, { endproc }
|
|
|
|
+ sd_none, { endprologue }
|
|
|
|
+ sd_none, { TODO: handler }
|
|
|
|
+ sd_none, { handlerdata }
|
|
|
|
+ sd_none,sd_none,sd_none, { eh, 32, no32 }
|
|
|
|
+ sd_regoffset, { setframe }
|
|
|
|
+ sd_offset, { stackalloc }
|
|
|
|
+ sd_reg, { pushreg }
|
|
|
|
+ sd_regoffset, { savereg }
|
|
|
|
+ sd_regoffset, { savexmm }
|
|
|
|
+ sd_none { pushframe }
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ constructor tai_seh_directive.create(_kind:TAsmSehDirective);
|
|
|
|
+ begin
|
|
|
|
+ inherited Create;
|
|
|
|
+ typ:=ait_seh_directive;
|
|
|
|
+ kind:=_kind;
|
|
|
|
+ data.typ:=datatypemap[_kind];
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ constructor tai_seh_directive.create_name(_kind:TAsmSehDirective;const _name:string);
|
|
|
|
+ begin
|
|
|
|
+ create(_kind);
|
|
|
|
+ data.name:=stringdup(_name);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ constructor tai_seh_directive.create_reg(_kind:TAsmSehDirective;r:TRegister);
|
|
|
|
+ begin
|
|
|
|
+ create(_kind);
|
|
|
|
+ data.reg:=r;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ constructor tai_seh_directive.create_offset(_kind:TAsmSehDirective;ofs:dword);
|
|
|
|
+ begin
|
|
|
|
+ create(_kind);
|
|
|
|
+ data.offset:=ofs;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ constructor tai_seh_directive.create_reg_offset(_kind:TAsmSehDirective;
|
|
|
|
+ r:TRegister;ofs:dword);
|
|
|
|
+ begin
|
|
|
|
+ create(_kind);
|
|
|
|
+ data.offset:=ofs;
|
|
|
|
+ data.reg:=r;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ constructor tai_seh_directive.ppuload(t:taitype;ppufile:tcompilerppufile);
|
|
|
|
+ begin
|
|
|
|
+ inherited ppuload(t, ppufile);
|
|
|
|
+ kind:=TAsmSehDirective(ppufile.getbyte);
|
|
|
|
+ data.typ:=datatypemap[kind];
|
|
|
|
+ case data.typ of
|
|
|
|
+ sd_none: ;
|
|
|
|
+ sd_string:
|
|
|
|
+ data.name:=stringdup(ppufile.getstring);
|
|
|
|
+
|
|
|
|
+ sd_reg,sd_offset,sd_regoffset:
|
|
|
|
+ begin
|
|
|
|
+ ppufile.getdata(data.reg,sizeof(TRegister));
|
|
|
|
+ data.offset:=ppufile.getdword;
|
|
|
|
+ end;
|
|
|
|
+ else
|
|
|
|
+ InternalError(2011091201);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ destructor tai_seh_directive.destroy;
|
|
|
|
+ begin
|
|
|
|
+ if data.typ=sd_string then
|
|
|
|
+ stringdispose(data.name);
|
|
|
|
+ inherited destroy;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ procedure tai_seh_directive.ppuwrite(ppufile:tcompilerppufile);
|
|
|
|
+ begin
|
|
|
|
+ inherited ppuwrite(ppufile);
|
|
|
|
+ ppufile.putbyte(ord(kind));
|
|
|
|
+ case data.typ of
|
|
|
|
+ sd_none: ;
|
|
|
|
+ sd_string:
|
|
|
|
+ ppufile.putstring(data.name^);
|
|
|
|
+ sd_reg,sd_offset,sd_regoffset:
|
|
|
|
+ begin
|
|
|
|
+ ppufile.putdata(data.reg,sizeof(TRegister));
|
|
|
|
+ ppufile.putdword(data.offset);
|
|
|
|
+ end;
|
|
|
|
+ else
|
|
|
|
+ InternalError(2011091202);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ procedure tai_seh_directive.generate_code(objdata:TObjData);
|
|
|
|
+ begin
|
|
|
|
+ end;
|
|
|
|
+
|
|
begin
|
|
begin
|
|
{ taitype should fit into a 4 byte set for speed reasons }
|
|
{ taitype should fit into a 4 byte set for speed reasons }
|
|
if ord(high(taitype))>31 then
|
|
if ord(high(taitype))>31 then
|