mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 18:49:11 +02:00
+ support 'SEG' in the i8086 inline assembler
git-svn-id: trunk@31428 -
This commit is contained in:
parent
4e0d546323
commit
e9c790f4eb
@ -141,6 +141,8 @@ interface
|
|||||||
aitconst_64bit_unaligned,
|
aitconst_64bit_unaligned,
|
||||||
{ i8086 far pointer; emits: 'DW symbol, SEG symbol' }
|
{ i8086 far pointer; emits: 'DW symbol, SEG symbol' }
|
||||||
aitconst_farptr,
|
aitconst_farptr,
|
||||||
|
{ i8086 segment of symbol; emits: 'DW SEG symbol' }
|
||||||
|
aitconst_seg,
|
||||||
{ 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 }
|
||||||
@ -632,6 +634,9 @@ interface
|
|||||||
constructor Create_nil_dataptr;
|
constructor Create_nil_dataptr;
|
||||||
constructor Create_int_codeptr(_value: int64);
|
constructor Create_int_codeptr(_value: int64);
|
||||||
constructor Create_int_dataptr(_value: int64);
|
constructor Create_int_dataptr(_value: int64);
|
||||||
|
{$ifdef i8086}
|
||||||
|
constructor Create_seg_name(const name:string);
|
||||||
|
{$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;
|
||||||
procedure derefimpl;override;
|
procedure derefimpl;override;
|
||||||
@ -1822,6 +1827,15 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{$ifdef i8086}
|
||||||
|
constructor tai_const.Create_seg_name(const name:string);
|
||||||
|
begin
|
||||||
|
self.Createname(name,0);
|
||||||
|
self.consttype:=aitconst_seg;
|
||||||
|
end;
|
||||||
|
{$endif i8086}
|
||||||
|
|
||||||
|
|
||||||
constructor tai_const.ppuload(t:taitype;ppufile:tcompilerppufile);
|
constructor tai_const.ppuload(t:taitype;ppufile:tcompilerppufile);
|
||||||
begin
|
begin
|
||||||
inherited ppuload(t,ppufile);
|
inherited ppuload(t,ppufile);
|
||||||
@ -1886,6 +1900,8 @@ implementation
|
|||||||
result:=2;
|
result:=2;
|
||||||
aitconst_farptr:
|
aitconst_farptr:
|
||||||
result:=4;
|
result:=4;
|
||||||
|
aitconst_seg:
|
||||||
|
result:=2;
|
||||||
aitconst_got:
|
aitconst_got:
|
||||||
result:=sizeof(pint);
|
result:=sizeof(pint);
|
||||||
aitconst_gotoff_symbol:
|
aitconst_gotoff_symbol:
|
||||||
|
@ -2449,7 +2449,7 @@ cg_f_max_units_reached=06057_F_Maximum number of units ($1) reached for the curr
|
|||||||
#
|
#
|
||||||
# Assembler reader
|
# Assembler reader
|
||||||
#
|
#
|
||||||
# 07125 is the last used one
|
# 07126 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
|
||||||
@ -2750,6 +2750,9 @@ asmr_e_invalid_ref_register=07125_E_Invalid register used in memory reference ex
|
|||||||
% FPU, vector and sometimes integer registers cannot be used in memory reference
|
% FPU, vector and sometimes integer registers cannot be used in memory reference
|
||||||
% expressions, due to limitations of the cpu architecture or simple because
|
% expressions, due to limitations of the cpu architecture or simple because
|
||||||
% it is not meaningful.
|
% it is not meaningful.
|
||||||
|
asmr_e_seg_without_identifier=07126_E_SEG used without identifier
|
||||||
|
% You can only use SEG with an identifier. Other syntaxes are not
|
||||||
|
% supported
|
||||||
|
|
||||||
#
|
#
|
||||||
# Assembler/binary writers
|
# Assembler/binary writers
|
||||||
|
@ -795,6 +795,7 @@ const
|
|||||||
asmr_w_check_mem_operand_negative_offset=07123;
|
asmr_w_check_mem_operand_negative_offset=07123;
|
||||||
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;
|
||||||
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;
|
||||||
@ -1016,9 +1017,9 @@ const
|
|||||||
option_info=11024;
|
option_info=11024;
|
||||||
option_help_pages=11025;
|
option_help_pages=11025;
|
||||||
|
|
||||||
MsgTxtSize = 75786;
|
MsgTxtSize = 75822;
|
||||||
|
|
||||||
MsgIdxMax : array[1..20] of longint=(
|
MsgIdxMax : array[1..20] of longint=(
|
||||||
26,99,342,124,96,58,126,32,207,64,
|
26,99,342,124,96,58,127,32,207,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
@ -49,7 +49,7 @@ type
|
|||||||
case typ:TOprType of
|
case typ:TOprType of
|
||||||
OPR_NONE : ();
|
OPR_NONE : ();
|
||||||
OPR_CONSTANT : (val:aint);
|
OPR_CONSTANT : (val:aint);
|
||||||
OPR_SYMBOL : (symbol:tasmsymbol;symofs:aint);
|
OPR_SYMBOL : (symbol:tasmsymbol;symofs:aint;symseg:boolean);
|
||||||
OPR_REFERENCE : (varsize:asizeint; constoffset: asizeint; ref:treference);
|
OPR_REFERENCE : (varsize:asizeint; constoffset: asizeint; ref:treference);
|
||||||
OPR_LOCAL : (localvarsize, localconstoffset: asizeint;localsym:tabstractnormalvarsym;localsymofs:aint;localindexreg:tregister;localscale:byte;localgetoffset,localforceref:boolean);
|
OPR_LOCAL : (localvarsize, localconstoffset: asizeint;localsym:tabstractnormalvarsym;localsymofs:aint;localindexreg:tregister;localscale:byte;localgetoffset,localforceref:boolean);
|
||||||
OPR_REGISTER : (reg:tregister);
|
OPR_REGISTER : (reg:tregister);
|
||||||
|
@ -350,6 +350,9 @@ interface
|
|||||||
function is_same_reg_move(regtype: Tregistertype):boolean;override;
|
function is_same_reg_move(regtype: Tregistertype):boolean;override;
|
||||||
{ register spilling code }
|
{ register spilling code }
|
||||||
function spilling_get_operation_type(opnr: longint): topertype;override;
|
function spilling_get_operation_type(opnr: longint): topertype;override;
|
||||||
|
{$ifdef i8086}
|
||||||
|
procedure loadsegsymbol(opidx:longint;s:tasmsymbol);
|
||||||
|
{$endif i8086}
|
||||||
private
|
private
|
||||||
{ next fields are filled in pass1, so pass2 is faster }
|
{ next fields are filled in pass1, so pass2 is faster }
|
||||||
insentry : PInsEntry;
|
insentry : PInsEntry;
|
||||||
@ -3538,6 +3541,17 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{$ifdef i8086}
|
||||||
|
procedure taicpu.loadsegsymbol(opidx:longint;s:tasmsymbol);
|
||||||
|
var
|
||||||
|
r: treference;
|
||||||
|
begin
|
||||||
|
reference_reset_symbol(r,s,0,1);
|
||||||
|
r.refaddr:=addr_seg;
|
||||||
|
loadref(opidx,r);
|
||||||
|
end;
|
||||||
|
{$endif i8086}
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
Instruction table
|
Instruction table
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
@ -1164,7 +1164,12 @@ begin
|
|||||||
OPR_REGISTER:
|
OPR_REGISTER:
|
||||||
ai.loadreg(i-1,operands[i].opr.reg);
|
ai.loadreg(i-1,operands[i].opr.reg);
|
||||||
OPR_SYMBOL:
|
OPR_SYMBOL:
|
||||||
ai.loadsymbol(i-1,operands[i].opr.symbol,operands[i].opr.symofs);
|
{$ifdef i8086}
|
||||||
|
if operands[i].opr.symseg then
|
||||||
|
taicpu(ai).loadsegsymbol(i-1,operands[i].opr.symbol)
|
||||||
|
else
|
||||||
|
{$endif i8086}
|
||||||
|
ai.loadsymbol(i-1,operands[i].opr.symbol,operands[i].opr.symofs);
|
||||||
OPR_LOCAL :
|
OPR_LOCAL :
|
||||||
with operands[i].opr do
|
with operands[i].opr do
|
||||||
ai.loadlocal(i-1,localsym,localsymofs,localindexreg,
|
ai.loadlocal(i-1,localsym,localsymofs,localindexreg,
|
||||||
|
@ -63,7 +63,7 @@ Unit Rax86int;
|
|||||||
function consume(t : tasmtoken):boolean;
|
function consume(t : tasmtoken):boolean;
|
||||||
procedure RecoverConsume(allowcomma:boolean);
|
procedure RecoverConsume(allowcomma:boolean);
|
||||||
procedure BuildRecordOffsetSize(const expr: string;var offset:aint;var size:aint; var mangledname: string; needvmtofs: boolean);
|
procedure BuildRecordOffsetSize(const expr: string;var offset:aint;var size:aint; var mangledname: string; needvmtofs: boolean);
|
||||||
procedure BuildConstSymbolExpression(needofs,isref,startingminus:boolean;var value:aint;var asmsym:string;var asmsymtyp:TAsmsymtype);
|
procedure BuildConstSymbolExpression(needofs,isref,startingminus:boolean;var value:aint;var asmsym:string;var asmsymtyp:TAsmsymtype;out isseg:boolean);
|
||||||
function BuildConstExpression:aint;
|
function BuildConstExpression:aint;
|
||||||
function BuildRefConstExpression(startingminus:boolean=false):aint;
|
function BuildRefConstExpression(startingminus:boolean=false):aint;
|
||||||
procedure BuildReference(oper : tx86operand);
|
procedure BuildReference(oper : tx86operand);
|
||||||
@ -762,7 +762,7 @@ Unit Rax86int;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
Procedure tx86intreader.BuildConstSymbolExpression(needofs,isref,startingminus:boolean;var value:aint;var asmsym:string;var asmsymtyp:TAsmsymtype);
|
Procedure tx86intreader.BuildConstSymbolExpression(needofs,isref,startingminus:boolean;var value:aint;var asmsym:string;var asmsymtyp:TAsmsymtype;out isseg:boolean);
|
||||||
var
|
var
|
||||||
tempstr,expr,hs,mangledname : string;
|
tempstr,expr,hs,mangledname : string;
|
||||||
parenlevel : longint;
|
parenlevel : longint;
|
||||||
@ -781,6 +781,7 @@ Unit Rax86int;
|
|||||||
value:=0;
|
value:=0;
|
||||||
asmsym:='';
|
asmsym:='';
|
||||||
asmsymtyp:=AT_DATA;
|
asmsymtyp:=AT_DATA;
|
||||||
|
isseg:=false;
|
||||||
errorflag:=FALSE;
|
errorflag:=FALSE;
|
||||||
tempstr:='';
|
tempstr:='';
|
||||||
expr:='';
|
expr:='';
|
||||||
@ -874,6 +875,15 @@ Unit Rax86int;
|
|||||||
expr:=expr + actasmpattern;
|
expr:=expr + actasmpattern;
|
||||||
Consume(AS_INTNUM);
|
Consume(AS_INTNUM);
|
||||||
end;
|
end;
|
||||||
|
{$ifdef i8086}
|
||||||
|
AS_SEG:
|
||||||
|
begin
|
||||||
|
isseg:=true;
|
||||||
|
Consume(actasmtoken);
|
||||||
|
if actasmtoken<>AS_ID then
|
||||||
|
Message(asmr_e_seg_without_identifier);
|
||||||
|
end;
|
||||||
|
{$endif i8086}
|
||||||
AS_VMTOFFSET,
|
AS_VMTOFFSET,
|
||||||
AS_OFFSET:
|
AS_OFFSET:
|
||||||
begin
|
begin
|
||||||
@ -1134,8 +1144,9 @@ Unit Rax86int;
|
|||||||
l : aint;
|
l : aint;
|
||||||
hs : string;
|
hs : string;
|
||||||
hssymtyp : TAsmsymtype;
|
hssymtyp : TAsmsymtype;
|
||||||
|
isseg : boolean;
|
||||||
begin
|
begin
|
||||||
BuildConstSymbolExpression(false,false,false,l,hs,hssymtyp);
|
BuildConstSymbolExpression(false,false,false,l,hs,hssymtyp,isseg);
|
||||||
if hs<>'' then
|
if hs<>'' then
|
||||||
Message(asmr_e_relocatable_symbol_not_allowed);
|
Message(asmr_e_relocatable_symbol_not_allowed);
|
||||||
BuildConstExpression:=l;
|
BuildConstExpression:=l;
|
||||||
@ -1147,8 +1158,9 @@ Unit Rax86int;
|
|||||||
l : aint;
|
l : aint;
|
||||||
hs : string;
|
hs : string;
|
||||||
hssymtyp : TAsmsymtype;
|
hssymtyp : TAsmsymtype;
|
||||||
|
isseg : boolean;
|
||||||
begin
|
begin
|
||||||
BuildConstSymbolExpression(false,true,startingminus,l,hs,hssymtyp);
|
BuildConstSymbolExpression(false,true,startingminus,l,hs,hssymtyp,isseg);
|
||||||
if hs<>'' then
|
if hs<>'' then
|
||||||
Message(asmr_e_relocatable_symbol_not_allowed);
|
Message(asmr_e_relocatable_symbol_not_allowed);
|
||||||
BuildRefConstExpression:=l;
|
BuildRefConstExpression:=l;
|
||||||
@ -1166,6 +1178,7 @@ Unit Rax86int;
|
|||||||
GotStar,GotOffset,HadVar,
|
GotStar,GotOffset,HadVar,
|
||||||
GotPlus,Negative : boolean;
|
GotPlus,Negative : boolean;
|
||||||
hl : tasmlabel;
|
hl : tasmlabel;
|
||||||
|
isseg: boolean;
|
||||||
Begin
|
Begin
|
||||||
Consume(AS_LBRACKET);
|
Consume(AS_LBRACKET);
|
||||||
if not(oper.opr.typ in [OPR_LOCAL,OPR_REFERENCE]) then
|
if not(oper.opr.typ in [OPR_LOCAL,OPR_REFERENCE]) then
|
||||||
@ -1478,7 +1491,7 @@ Unit Rax86int;
|
|||||||
begin
|
begin
|
||||||
if not GotPlus and not GotStar then
|
if not GotPlus and not GotStar then
|
||||||
Message(asmr_e_invalid_reference_syntax);
|
Message(asmr_e_invalid_reference_syntax);
|
||||||
BuildConstSymbolExpression(true,true,GotPlus and negative,l,tempstr,tempsymtyp);
|
BuildConstSymbolExpression(true,true,GotPlus and negative,l,tempstr,tempsymtyp,isseg);
|
||||||
{ already handled by BuildConstSymbolExpression(); must be
|
{ already handled by BuildConstSymbolExpression(); must be
|
||||||
handled there to avoid [reg-1+1] being interpreted as
|
handled there to avoid [reg-1+1] being interpreted as
|
||||||
[reg-(1+1)] }
|
[reg-(1+1)] }
|
||||||
@ -1489,7 +1502,13 @@ Unit Rax86int;
|
|||||||
if GotStar then
|
if GotStar then
|
||||||
Message(asmr_e_only_add_relocatable_symbol);
|
Message(asmr_e_only_add_relocatable_symbol);
|
||||||
if not assigned(oper.opr.ref.symbol) then
|
if not assigned(oper.opr.ref.symbol) then
|
||||||
oper.opr.ref.symbol:=current_asmdata.RefAsmSymbol(tempstr)
|
begin
|
||||||
|
oper.opr.ref.symbol:=current_asmdata.RefAsmSymbol(tempstr);
|
||||||
|
{$ifdef i8086}
|
||||||
|
if isseg then
|
||||||
|
oper.opr.ref.refaddr:=addr_seg;
|
||||||
|
{$endif i8086}
|
||||||
|
end
|
||||||
else
|
else
|
||||||
Message(asmr_e_cant_have_multiple_relocatable_symbols);
|
Message(asmr_e_cant_have_multiple_relocatable_symbols);
|
||||||
end;
|
end;
|
||||||
@ -1557,15 +1576,17 @@ Unit Rax86int;
|
|||||||
l : aint;
|
l : aint;
|
||||||
tempstr : string;
|
tempstr : string;
|
||||||
tempsymtyp : tasmsymtype;
|
tempsymtyp : tasmsymtype;
|
||||||
|
isseg: boolean;
|
||||||
begin
|
begin
|
||||||
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);
|
BuildConstSymbolExpression(true,false,false,l,tempstr,tempsymtyp,isseg);
|
||||||
if tempstr<>'' then
|
if tempstr<>'' then
|
||||||
begin
|
begin
|
||||||
oper.opr.typ:=OPR_SYMBOL;
|
oper.opr.typ:=OPR_SYMBOL;
|
||||||
oper.opr.symofs:=l;
|
oper.opr.symofs:=l;
|
||||||
oper.opr.symbol:=current_asmdata.RefAsmSymbol(tempstr);
|
oper.opr.symbol:=current_asmdata.RefAsmSymbol(tempstr);
|
||||||
|
oper.opr.symseg:=isseg;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if oper.opr.typ=OPR_NONE then
|
if oper.opr.typ=OPR_NONE then
|
||||||
@ -1669,6 +1690,15 @@ Unit Rax86int;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
case actasmtoken of
|
case actasmtoken of
|
||||||
|
{$ifndef i8086}
|
||||||
|
AS_SEG :
|
||||||
|
Begin
|
||||||
|
Message(asmr_e_seg_not_supported);
|
||||||
|
Consume(actasmtoken);
|
||||||
|
end;
|
||||||
|
{$else not i8086}
|
||||||
|
AS_SEG,
|
||||||
|
{$endif not i8086}
|
||||||
AS_OFFSET,
|
AS_OFFSET,
|
||||||
AS_SIZEOF,
|
AS_SIZEOF,
|
||||||
AS_VMTOFFSET,
|
AS_VMTOFFSET,
|
||||||
@ -1891,12 +1921,6 @@ Unit Rax86int;
|
|||||||
BuildReference(oper);
|
BuildReference(oper);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
AS_SEG :
|
|
||||||
Begin
|
|
||||||
Message(asmr_e_seg_not_supported);
|
|
||||||
Consume(actasmtoken);
|
|
||||||
end;
|
|
||||||
|
|
||||||
AS_DWORD,
|
AS_DWORD,
|
||||||
AS_BYTE,
|
AS_BYTE,
|
||||||
AS_WORD,
|
AS_WORD,
|
||||||
@ -2189,6 +2213,7 @@ Unit Rax86int;
|
|||||||
asmsym,
|
asmsym,
|
||||||
expr: string;
|
expr: string;
|
||||||
value : aint;
|
value : aint;
|
||||||
|
isseg: boolean;
|
||||||
Begin
|
Begin
|
||||||
Repeat
|
Repeat
|
||||||
Case actasmtoken of
|
Case actasmtoken of
|
||||||
@ -2219,12 +2244,17 @@ Unit Rax86int;
|
|||||||
AS_INTNUM,
|
AS_INTNUM,
|
||||||
AS_ID :
|
AS_ID :
|
||||||
Begin
|
Begin
|
||||||
BuildConstSymbolExpression(false,false,false,value,asmsym,asmsymtyp);
|
BuildConstSymbolExpression(false,false,false,value,asmsym,asmsymtyp,isseg);
|
||||||
if asmsym<>'' then
|
if asmsym<>'' then
|
||||||
begin
|
begin
|
||||||
if constsize<>sizeof(pint) then
|
if constsize<>sizeof(pint) then
|
||||||
Message1(asmr_w_const32bit_for_address,asmsym);
|
Message1(asmr_w_const32bit_for_address,asmsym);
|
||||||
ConcatConstSymbol(curlist,asmsym,asmsymtyp,value)
|
{$ifdef i8086}
|
||||||
|
if isseg then
|
||||||
|
curlist.concat(Tai_const.Create_seg_name(asmsym))
|
||||||
|
else
|
||||||
|
{$endif i8086}
|
||||||
|
ConcatConstSymbol(curlist,asmsym,asmsymtyp,value);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
ConcatConstant(curlist,value,constsize);
|
ConcatConstant(curlist,value,constsize);
|
||||||
|
Loading…
Reference in New Issue
Block a user