+ support conditions in the Z80 inline assembler

git-svn-id: branches/z80@44885 -
This commit is contained in:
nickysn 2020-04-20 17:02:03 +00:00
parent e5f4419694
commit a6e72713ad
2 changed files with 53 additions and 10 deletions

View File

@ -294,17 +294,18 @@ unit agsdasz80;
i: Integer; i: Integer;
begin begin
writer.AsmWrite(#9#9+std_op2str[hp.opcode]); writer.AsmWrite(#9#9+std_op2str[hp.opcode]);
if taicpu(hp).ops<>0 then if (taicpu(hp).ops<>0) or (hp.condition<>C_None) then
begin begin
writer.AsmWrite(#9);
if hp.condition<>C_None then
begin
writer.AsmWrite(uppercond2str[hp.condition]);
if taicpu(hp).ops<>0 then
writer.AsmWrite(',');
end;
for i:=0 to taicpu(hp).ops-1 do for i:=0 to taicpu(hp).ops-1 do
begin begin
if i=0 then if i<>0 then
begin
writer.AsmWrite(#9);
if hp.is_jmp and (hp.condition<>C_None) then
writer.AsmWrite(uppercond2str[hp.condition]+',');
end
else
writer.AsmWrite(','); writer.AsmWrite(',');
if is_calljmp(hp.opcode) then if is_calljmp(hp.opcode) then
WriteOper_jmp(taicpu(hp).oper[i]^,hp) WriteOper_jmp(taicpu(hp).oper[i]^,hp)

View File

@ -36,7 +36,7 @@ Unit raz80asm;
AS_NONE,AS_LABEL,AS_LLABEL,AS_STRING,AS_INTNUM, AS_NONE,AS_LABEL,AS_LLABEL,AS_STRING,AS_INTNUM,
AS_REALNUM,AS_COMMA,AS_LPAREN, AS_REALNUM,AS_COMMA,AS_LPAREN,
AS_RPAREN,AS_COLON,AS_DOT,AS_PLUS,AS_MINUS,AS_STAR, AS_RPAREN,AS_COLON,AS_DOT,AS_PLUS,AS_MINUS,AS_STAR,
AS_SEPARATOR,AS_ID,AS_REGISTER,AS_OPCODE,AS_SLASH,AS_DOLLAR, AS_SEPARATOR,AS_ID,AS_REGISTER,AS_OPCODE,AS_CONDITION,AS_SLASH,AS_DOLLAR,
AS_HASH,AS_LSBRACKET,AS_RSBRACKET,AS_LBRACKET,AS_RBRACKET, AS_HASH,AS_LSBRACKET,AS_RSBRACKET,AS_LBRACKET,AS_RBRACKET,
AS_EQUAL, AS_EQUAL,
{------------------ Assembler directives --------------------} {------------------ Assembler directives --------------------}
@ -58,7 +58,7 @@ Unit raz80asm;
'','Label','LLabel','string','integer', '','Label','LLabel','string','integer',
'float',',','(', 'float',',','(',
')',':','.','+','-','*', ')',':','.','+','-','*',
';','identifier','register','opcode','/','$', ';','identifier','register','opcode','condition','/','$',
'#','{','}','[',']', '#','{','}','[',']',
'=', '=',
'defb','defw','END', 'defb','defw','END',
@ -88,6 +88,7 @@ Unit raz80asm;
{ tz80reader } { tz80reader }
tz80reader = class(tasmreader) tz80reader = class(tasmreader)
actasmcond : TAsmCond;
actasmpattern_origcase : string; actasmpattern_origcase : string;
actasmtoken : tasmtoken; actasmtoken : tasmtoken;
prevasmtoken : tasmtoken; prevasmtoken : tasmtoken;
@ -101,6 +102,7 @@ Unit raz80asm;
function is_asmopcode(const s: string):boolean; function is_asmopcode(const s: string):boolean;
Function is_asmdirective(const s: string):boolean; Function is_asmdirective(const s: string):boolean;
function is_register(const s:string):boolean; function is_register(const s:string):boolean;
function is_condition(const s:string):boolean;
function is_targetdirective(const s: string):boolean; function is_targetdirective(const s: string):boolean;
procedure BuildRecordOffsetSize(const expr: string;out offset:tcgint;out size:tcgint; out mangledname: string; needvmtofs: boolean; out hastypecast: boolean); procedure BuildRecordOffsetSize(const expr: string;out offset:tcgint;out size:tcgint; out mangledname: string; needvmtofs: boolean; out hastypecast: boolean);
procedure BuildConstSymbolExpression(in_flags: tconstsymbolexpressioninputflags;out value:tcgint;out asmsym:string;out asmsymtyp:TAsmsymtype;out size:tcgint;out out_flags:tconstsymbolexpressionoutputflags); procedure BuildConstSymbolExpression(in_flags: tconstsymbolexpressioninputflags;out value:tcgint;out asmsym:string;out asmsymtyp:TAsmsymtype;out size:tcgint;out out_flags:tconstsymbolexpressionoutputflags);
@ -156,8 +158,12 @@ Unit raz80asm;
len: Integer; len: Integer;
srsym : tsym; srsym : tsym;
srsymtable : TSymtable; srsymtable : TSymtable;
can_be_condition : Boolean;
begin begin
c:=scanner.c; c:=scanner.c;
{ certain instructions can have a condition, as an operand. We need to set this flag,
because 'C' can be either a register, or a condition, depending on the context }
can_be_condition:=(actasmtoken=AS_OPCODE) and (actopcode in [A_JP,A_JR,A_CALL,A_RET]);
{ save old token and reset new token } { save old token and reset new token }
prevasmtoken:=actasmtoken; prevasmtoken:=actasmtoken;
actasmtoken:=AS_NONE; actasmtoken:=AS_NONE;
@ -313,6 +319,11 @@ Unit raz80asm;
actasmtoken:=AS_VMTOFFSET; actasmtoken:=AS_VMTOFFSET;
exit; exit;
end; end;
if can_be_condition and is_condition(actasmpattern) then
begin
actasmtoken:=AS_CONDITION;
exit;
end;
if is_register(actasmpattern) then if is_register(actasmpattern) then
begin begin
actasmtoken:=AS_REGISTER; actasmtoken:=AS_REGISTER;
@ -942,6 +953,25 @@ Unit raz80asm;
end; end;
function tz80reader.is_condition(const s: string): boolean;
var
condstr: string;
cond: TAsmCond;
begin
is_condition:=false;
actasmcond:=C_None;
condstr:=lower(s);
for cond in TAsmCond do
if (cond<>C_None) and (cond2str[cond]=condstr) then
begin
is_condition:=true;
actasmtoken:=AS_CONDITION;
actasmcond:=cond;
exit;
end;
end;
function tz80reader.is_targetdirective(const s: string): boolean; function tz80reader.is_targetdirective(const s: string): boolean;
begin begin
result:=false; result:=false;
@ -2197,6 +2227,18 @@ Unit raz80asm;
AS_SEPARATOR : AS_SEPARATOR :
break; break;
{ Condition (e.g. 'NC' in 'JP NC, label') }
AS_CONDITION:
begin
instr.condition:=actasmcond;
Consume(AS_CONDITION);
if actasmtoken=AS_COMMA then
Consume(AS_COMMA);
{ Zero operand opcode ? }
if actasmtoken in [AS_SEPARATOR,AS_END] then
exit;
end;
{ Operand delimiter } { Operand delimiter }
AS_COMMA : AS_COMMA :
begin begin