+ implemented the 'SEG @DATA' inline assembler directive for i8086

git-svn-id: trunk@32280 -
This commit is contained in:
nickysn 2015-11-10 17:26:21 +00:00
parent 43dabca8ab
commit 995ca4fb12
8 changed files with 413 additions and 325 deletions

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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}