+ support 'SEG' in the i8086 inline assembler

git-svn-id: trunk@31428 -
This commit is contained in:
nickysn 2015-08-26 15:57:44 +00:00
parent 4e0d546323
commit e9c790f4eb
8 changed files with 351 additions and 277 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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