+ support labels in the Z80 inline assembler

git-svn-id: branches/z80@44883 -
This commit is contained in:
nickysn 2020-04-20 15:49:11 +00:00
parent 0f323df7a3
commit 90fa75fb7a

View File

@ -88,6 +88,7 @@ Unit raz80asm;
{ tz80reader }
tz80reader = class(tasmreader)
actasmpattern_origcase : string;
actasmtoken : tasmtoken;
prevasmtoken : tasmtoken;
inexpression : boolean;
@ -217,6 +218,7 @@ Unit raz80asm;
c:=current_scanner.asmgetchar;
end;
actasmpattern[0]:=chr(len);
actasmpattern_origcase:=actasmpattern;
{ Label ? }
if c = ':' then
begin
@ -286,6 +288,7 @@ Unit raz80asm;
c:=current_scanner.asmgetchar;
end;
actasmpattern[0]:=chr(len);
actasmpattern_origcase:=actasmpattern;
uppervar(actasmpattern);
{$ifdef x86}
{ only x86 architectures have instruction prefixes }
@ -1944,9 +1947,28 @@ Unit raz80asm;
procedure tz80reader.BuildOperand(oper: tz80operand; istypecast: boolean);
procedure AddLabelOperand(hl:tasmlabel);
begin
if (oper.opr.typ=OPR_NONE) and
is_calljmp(actopcode) then
begin
oper.opr.typ:=OPR_SYMBOL;
oper.opr.symbol:=hl;
end
else
begin
oper.InitRef;
oper.opr.ref.symbol:=hl;
oper.haslabelref:=true;
end;
end;
var
l: LongInt;
l: tcgint;
tsize: tcgint;
expr: string;
hl: tasmlabel;
begin
repeat
case actasmtoken of
@ -1990,6 +2012,142 @@ Unit raz80asm;
BuildReference(oper);
end;
AS_ID : { A constant expression, or a Variable ref. }
Begin
{ Label or Special symbol reference? }
if actasmpattern[1] = '@' then
Begin
if actasmpattern = '@RESULT' then
Begin
oper.SetupResult;
Consume(AS_ID);
expr:='result';
end
else
if (actasmpattern = '@CODE') or (actasmpattern = '@DATA') then
begin
Message(asmr_w_CODE_and_DATA_not_supported);
Consume(AS_ID);
end
else
{ Local Label }
begin
CreateLocalLabel(actasmpattern,hl,false);
Consume(AS_ID);
AddLabelOperand(hl);
end;
end
else
{ support result for delphi modes }
if (m_objpas in current_settings.modeswitches) and (actasmpattern='RESULT') then
begin
oper.SetUpResult;
Consume(AS_ID);
expr:='result';
end
{ probably a variable or normal expression }
{ or a procedure (such as in CALL ID) }
else
Begin
{ is it a constant ? }
if SearchIConstant(actasmpattern,l) then
Begin
case oper.opr.typ of
OPR_REFERENCE :
begin
l := BuildRefConstExpression(tsize);
if tsize<>0 then
oper.SetSize(tsize,false);
inc(oper.opr.ref.offset,l);
inc(oper.opr.constoffset,l);
end;
OPR_LOCAL :
begin
l := BuildRefConstExpression(tsize);
if tsize<>0 then
oper.SetSize(tsize,false);
inc(oper.opr.localsymofs,l);
inc(oper.opr.localconstoffset,l);
end;
OPR_NONE,
OPR_CONSTANT :
BuildConstantOperand(oper);
else
Message(asmr_e_invalid_operand_type);
end;
end
else
{ Check for pascal label }
if SearchLabel(actasmpattern,hl,false) then
begin
Consume(AS_ID);
AddLabelOperand(hl);
end
else
{ is it a normal variable ? }
Begin
expr:=actasmpattern;
Consume(AS_ID);
{ typecasting? }
if SearchType(expr,l) then
begin
oper.hastype:=true;
oper.typesize:=l;
case actasmtoken of
AS_LPAREN :
begin
{ Support Type([Reference]) }
Consume(AS_LPAREN);
BuildOperand(oper,true);
{ Delphi also supports Type(Register) and
interprets it the same as Type([Register]). }
if (oper.opr.typ = OPR_REGISTER) then
{ This also sets base to the register. }
oper.InitRef;
Consume(AS_RPAREN);
end;
//AS_LBRACKET :
// begin
// { Support Var.Type[Index] }
// { Convert @label.Byte[1] to reference }
// if oper.opr.typ=OPR_SYMBOL then
// oper.initref;
// end;
else
;
end;
end
else
begin
if not oper.SetupVar(expr,false) then
Begin
{ not a variable, check special variables.. }
if expr = 'SELF' then
begin
oper.SetupSelf;
expr:='self';
end
else
begin
Message1(sym_e_unknown_id,expr);
expr:='';
end;
end;
{ indexed access to variable? }
//if actasmtoken=AS_LBRACKET then
// begin
// { ... then the operand size is not known anymore }
// oper.size:=OS_NO;
// BuildReference(oper);
// end;
end;
end;
end;
end;
AS_REGISTER : { Register, a variable reference or a constant reference }
begin
Consume(AS_REGISTER);
@ -2094,6 +2252,8 @@ Unit raz80asm;
function tz80reader.Assemble: tlinkedlist;
var
hl: tasmlabel;
begin
Message1(asmr_d_start_reading,'Z80');
firsttoken:=TRUE;
@ -2114,6 +2274,19 @@ Unit raz80asm;
{ main loop }
repeat
case actasmtoken of
AS_LABEL:
Begin
if SearchLabel(upper(actasmpattern),hl,true) then
begin
if hl.is_public then
ConcatPublic(curlist,actasmpattern_origcase);
ConcatLabel(curlist,hl);
end
else
Message1(asmr_e_unknown_label_identifier,actasmpattern);
Consume(AS_LABEL);
end;
AS_END:
begin
break; { end assembly block }