mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-23 07:09:18 +02:00
+ implemented the 'SEG @DATA' inline assembler directive for i8086
git-svn-id: trunk@32280 -
This commit is contained in:
parent
43dabca8ab
commit
995ca4fb12
@ -135,6 +135,17 @@ interface
|
|||||||
aitconst_farptr,
|
aitconst_farptr,
|
||||||
{ i8086 segment of symbol; emits: 'DW SEG symbol' }
|
{ i8086 segment of symbol; emits: 'DW SEG symbol' }
|
||||||
aitconst_seg,
|
aitconst_seg,
|
||||||
|
{ i8086 data segment group; emits: 'DW dgroup'
|
||||||
|
generated by the this inline asm:
|
||||||
|
DW SEG @DATA
|
||||||
|
in all memory models, except huge }
|
||||||
|
aitconst_dgroup,
|
||||||
|
{ i8086 far data segment of the current pascal module (unit or program);
|
||||||
|
emits: 'DW CURRENTMODULENAME_DATA'
|
||||||
|
generated by the this inline asm:
|
||||||
|
DW SEG @DATA
|
||||||
|
in the huge memory model }
|
||||||
|
aitconst_fardataseg,
|
||||||
{ offset of symbol's GOT slot in GOT }
|
{ offset of symbol's GOT slot in GOT }
|
||||||
aitconst_got,
|
aitconst_got,
|
||||||
{ offset of symbol itself from GOT }
|
{ offset of symbol itself from GOT }
|
||||||
@ -620,6 +631,8 @@ interface
|
|||||||
constructor Create_int_dataptr(_value: int64);
|
constructor Create_int_dataptr(_value: int64);
|
||||||
{$ifdef i8086}
|
{$ifdef i8086}
|
||||||
constructor Create_seg_name(const name:string);
|
constructor Create_seg_name(const name:string);
|
||||||
|
constructor Create_dgroup;
|
||||||
|
constructor Create_fardataseg;
|
||||||
{$endif i8086}
|
{$endif i8086}
|
||||||
constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
|
constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
|
||||||
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
||||||
@ -1817,6 +1830,20 @@ implementation
|
|||||||
self.Createname(name,0);
|
self.Createname(name,0);
|
||||||
self.consttype:=aitconst_seg;
|
self.consttype:=aitconst_seg;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
constructor tai_const.Create_dgroup;
|
||||||
|
begin
|
||||||
|
self.Create_16bit(0);
|
||||||
|
self.consttype:=aitconst_dgroup;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
constructor tai_const.Create_fardataseg;
|
||||||
|
begin
|
||||||
|
self.Create_16bit(0);
|
||||||
|
self.consttype:=aitconst_fardataseg;
|
||||||
|
end;
|
||||||
{$endif i8086}
|
{$endif i8086}
|
||||||
|
|
||||||
|
|
||||||
@ -1884,6 +1911,8 @@ implementation
|
|||||||
result:=2;
|
result:=2;
|
||||||
aitconst_farptr:
|
aitconst_farptr:
|
||||||
result:=4;
|
result:=4;
|
||||||
|
aitconst_dgroup,
|
||||||
|
aitconst_fardataseg,
|
||||||
aitconst_seg:
|
aitconst_seg:
|
||||||
result:=2;
|
result:=2;
|
||||||
aitconst_got:
|
aitconst_got:
|
||||||
|
@ -1866,6 +1866,10 @@ Implementation
|
|||||||
ObjData.writereloc(0,2,Objdata.SymbolRef(tai_const(hp).sym),RELOC_SEG)
|
ObjData.writereloc(0,2,Objdata.SymbolRef(tai_const(hp).sym),RELOC_SEG)
|
||||||
else
|
else
|
||||||
internalerror(2015110502);
|
internalerror(2015110502);
|
||||||
|
aitconst_dgroup:
|
||||||
|
ObjData.writereloc(0,2,nil,RELOC_DGROUP);
|
||||||
|
aitconst_fardataseg:
|
||||||
|
ObjData.writereloc(0,2,nil,RELOC_FARDATASEG);
|
||||||
{$endif i8086}
|
{$endif i8086}
|
||||||
{$ifdef arm}
|
{$ifdef arm}
|
||||||
aitconst_got:
|
aitconst_got:
|
||||||
|
@ -2457,7 +2457,7 @@ cg_f_max_units_reached=06057_F_Maximum number of units ($1) reached for the curr
|
|||||||
#
|
#
|
||||||
# Assembler reader
|
# Assembler reader
|
||||||
#
|
#
|
||||||
# 07126 is the last used one
|
# 07127 is the last used one
|
||||||
#
|
#
|
||||||
asmr_d_start_reading=07000_DL_Starting $1 styled assembler parsing
|
asmr_d_start_reading=07000_DL_Starting $1 styled assembler parsing
|
||||||
% This informs you that an assembler block is being parsed
|
% This informs you that an assembler block is being parsed
|
||||||
@ -2761,6 +2761,8 @@ asmr_e_invalid_ref_register=07125_E_Invalid register used in memory reference ex
|
|||||||
asmr_e_seg_without_identifier=07126_E_SEG used without identifier
|
asmr_e_seg_without_identifier=07126_E_SEG used without identifier
|
||||||
% You can only use SEG with an identifier. Other syntaxes are not
|
% You can only use SEG with an identifier. Other syntaxes are not
|
||||||
% supported
|
% supported
|
||||||
|
asmr_e_CODE_or_DATA_without_SEG=07127_E_@CODE and @DATA can only be used with the SEG operator
|
||||||
|
% You can only use @CODE and @DATA symbols together with the SEG operator
|
||||||
|
|
||||||
#
|
#
|
||||||
# Assembler/binary writers
|
# Assembler/binary writers
|
||||||
|
@ -799,6 +799,7 @@ const
|
|||||||
asmr_w_check_mem_operand_automap_multiple_size=07124;
|
asmr_w_check_mem_operand_automap_multiple_size=07124;
|
||||||
asmr_e_invalid_ref_register=07125;
|
asmr_e_invalid_ref_register=07125;
|
||||||
asmr_e_seg_without_identifier=07126;
|
asmr_e_seg_without_identifier=07126;
|
||||||
|
asmr_e_CODE_or_DATA_without_SEG=07127;
|
||||||
asmw_f_too_many_asm_files=08000;
|
asmw_f_too_many_asm_files=08000;
|
||||||
asmw_f_assembler_output_not_supported=08001;
|
asmw_f_assembler_output_not_supported=08001;
|
||||||
asmw_f_comp_not_supported=08002;
|
asmw_f_comp_not_supported=08002;
|
||||||
@ -1021,9 +1022,9 @@ const
|
|||||||
option_info=11024;
|
option_info=11024;
|
||||||
option_help_pages=11025;
|
option_help_pages=11025;
|
||||||
|
|
||||||
MsgTxtSize = 76316;
|
MsgTxtSize = 76379;
|
||||||
|
|
||||||
MsgIdxMax : array[1..20] of longint=(
|
MsgIdxMax : array[1..20] of longint=(
|
||||||
27,99,344,124,96,58,127,32,208,64,
|
27,99,344,124,96,58,128,32,208,64,
|
||||||
58,20,1,1,1,1,1,1,1,1
|
58,20,1,1,1,1,1,1,1,1
|
||||||
);
|
);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -777,6 +777,10 @@ interface
|
|||||||
internalerror(2015110501);
|
internalerror(2015110501);
|
||||||
writer.AsmLn;
|
writer.AsmLn;
|
||||||
end;
|
end;
|
||||||
|
aitconst_dgroup:
|
||||||
|
writer.AsmWriteLn(#9'DW'#9'DGROUP');
|
||||||
|
aitconst_fardataseg:
|
||||||
|
writer.AsmWriteLn(#9'DW'#9+current_module.modulename^+'_DATA');
|
||||||
{$endif i8086}
|
{$endif i8086}
|
||||||
aitconst_32bit,
|
aitconst_32bit,
|
||||||
aitconst_16bit,
|
aitconst_16bit,
|
||||||
|
@ -296,7 +296,15 @@ end;
|
|||||||
|
|
||||||
procedure Tx86Operand.SetupData;
|
procedure Tx86Operand.SetupData;
|
||||||
begin
|
begin
|
||||||
|
{$ifdef i8086}
|
||||||
|
InitRef;
|
||||||
|
if current_settings.x86memorymodel=mm_huge then
|
||||||
|
opr.ref.refaddr:=addr_fardataseg
|
||||||
|
else
|
||||||
|
opr.ref.refaddr:=addr_dgroup;
|
||||||
|
{$else i8086}
|
||||||
Message(asmr_w_CODE_and_DATA_not_supported);
|
Message(asmr_w_CODE_and_DATA_not_supported);
|
||||||
|
{$endif i8086}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -984,7 +984,17 @@ Unit Rax86int;
|
|||||||
is_asmopcode(actasmpattern) then
|
is_asmopcode(actasmpattern) then
|
||||||
break;
|
break;
|
||||||
consume(AS_ID);
|
consume(AS_ID);
|
||||||
if SearchIConstant(tempstr,l) then
|
if (tempstr='@CODE') or (tempstr='@DATA') then
|
||||||
|
begin
|
||||||
|
if asmsym='' then
|
||||||
|
begin
|
||||||
|
asmsym:=tempstr;
|
||||||
|
asmsymtyp:=AT_SECTION;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Message(asmr_e_cant_have_multiple_relocatable_symbols);
|
||||||
|
end
|
||||||
|
else if SearchIConstant(tempstr,l) then
|
||||||
begin
|
begin
|
||||||
str(l, tempstr);
|
str(l, tempstr);
|
||||||
expr:=expr + tempstr;
|
expr:=expr + tempstr;
|
||||||
@ -1518,7 +1528,10 @@ Unit Rax86int;
|
|||||||
oper.opr.ref.symbol:=current_asmdata.RefAsmSymbol(tempstr);
|
oper.opr.ref.symbol:=current_asmdata.RefAsmSymbol(tempstr);
|
||||||
{$ifdef i8086}
|
{$ifdef i8086}
|
||||||
if isseg then
|
if isseg then
|
||||||
oper.opr.ref.refaddr:=addr_seg
|
begin
|
||||||
|
if not (oper.opr.ref.refaddr in [addr_fardataseg,addr_dgroup]) then
|
||||||
|
oper.opr.ref.refaddr:=addr_seg;
|
||||||
|
end
|
||||||
else if (tempsymtyp=AT_FUNCTION) and (oper.opr.ref.segment=NR_NO) then
|
else if (tempsymtyp=AT_FUNCTION) and (oper.opr.ref.segment=NR_NO) then
|
||||||
oper.opr.ref.segment:=NR_CS;
|
oper.opr.ref.segment:=NR_CS;
|
||||||
{$endif i8086}
|
{$endif i8086}
|
||||||
@ -1596,6 +1609,15 @@ Unit Rax86int;
|
|||||||
if not (oper.opr.typ in [OPR_NONE,OPR_CONSTANT]) then
|
if not (oper.opr.typ in [OPR_NONE,OPR_CONSTANT]) then
|
||||||
Message(asmr_e_invalid_operand_type);
|
Message(asmr_e_invalid_operand_type);
|
||||||
BuildConstSymbolExpression(true,false,false,l,tempstr,tempsymtyp,isseg,is_farproc_entry);
|
BuildConstSymbolExpression(true,false,false,l,tempstr,tempsymtyp,isseg,is_farproc_entry);
|
||||||
|
{$ifdef i8086}
|
||||||
|
if tempstr='@DATA' then
|
||||||
|
begin
|
||||||
|
if not isseg then
|
||||||
|
Message(asmr_e_CODE_or_DATA_without_SEG);
|
||||||
|
oper.SetupData;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{$endif i8086}
|
||||||
if tempstr<>'' then
|
if tempstr<>'' then
|
||||||
begin
|
begin
|
||||||
oper.opr.typ:=OPR_SYMBOL;
|
oper.opr.typ:=OPR_SYMBOL;
|
||||||
@ -1803,15 +1825,13 @@ Unit Rax86int;
|
|||||||
Consume(AS_ID);
|
Consume(AS_ID);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if actasmpattern = '@CODE' then
|
if (actasmpattern = '@CODE') or (actasmpattern = '@DATA') then
|
||||||
begin
|
begin
|
||||||
oper.SetupCode;
|
{$ifdef i8086}
|
||||||
Consume(AS_ID);
|
Message(asmr_e_CODE_or_DATA_without_SEG);
|
||||||
end
|
{$else i8086}
|
||||||
else
|
Message(asmr_w_CODE_and_DATA_not_supported);
|
||||||
if actasmpattern = '@DATA' then
|
{$endif i8086}
|
||||||
begin
|
|
||||||
oper.SetupData;
|
|
||||||
Consume(AS_ID);
|
Consume(AS_ID);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -2328,7 +2348,22 @@ Unit Rax86int;
|
|||||||
if constsize<>sizeof(pint) then
|
if constsize<>sizeof(pint) then
|
||||||
Message1(asmr_w_const32bit_for_address,asmsym);
|
Message1(asmr_w_const32bit_for_address,asmsym);
|
||||||
{$ifdef i8086}
|
{$ifdef i8086}
|
||||||
if isseg then
|
if (asmsym='@CODE') or (asmsym='@DATA') then
|
||||||
|
begin
|
||||||
|
if not isseg then
|
||||||
|
Message(asmr_e_CODE_or_DATA_without_SEG);
|
||||||
|
if asmsym='@DATA' then
|
||||||
|
begin
|
||||||
|
if current_settings.x86memorymodel=mm_huge then
|
||||||
|
curlist.concat(Tai_const.Create_fardataseg)
|
||||||
|
else
|
||||||
|
curlist.concat(Tai_const.Create_dgroup);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{ todo: implement @CODE }
|
||||||
|
internalerror(2015111001);
|
||||||
|
end
|
||||||
|
else if isseg then
|
||||||
curlist.concat(Tai_const.Create_seg_name(asmsym))
|
curlist.concat(Tai_const.Create_seg_name(asmsym))
|
||||||
else
|
else
|
||||||
{$endif i8086}
|
{$endif i8086}
|
||||||
|
Loading…
Reference in New Issue
Block a user