+ 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;
begin
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
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
begin
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
if i<>0 then
writer.AsmWrite(',');
if is_calljmp(hp.opcode) then
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_REALNUM,AS_COMMA,AS_LPAREN,
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_EQUAL,
{------------------ Assembler directives --------------------}
@ -58,7 +58,7 @@ Unit raz80asm;
'','Label','LLabel','string','integer',
'float',',','(',
')',':','.','+','-','*',
';','identifier','register','opcode','/','$',
';','identifier','register','opcode','condition','/','$',
'#','{','}','[',']',
'=',
'defb','defw','END',
@ -88,6 +88,7 @@ Unit raz80asm;
{ tz80reader }
tz80reader = class(tasmreader)
actasmcond : TAsmCond;
actasmpattern_origcase : string;
actasmtoken : tasmtoken;
prevasmtoken : tasmtoken;
@ -101,6 +102,7 @@ Unit raz80asm;
function is_asmopcode(const s: string):boolean;
Function is_asmdirective(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;
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);
@ -156,8 +158,12 @@ Unit raz80asm;
len: Integer;
srsym : tsym;
srsymtable : TSymtable;
can_be_condition : Boolean;
begin
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 }
prevasmtoken:=actasmtoken;
actasmtoken:=AS_NONE;
@ -313,6 +319,11 @@ Unit raz80asm;
actasmtoken:=AS_VMTOFFSET;
exit;
end;
if can_be_condition and is_condition(actasmpattern) then
begin
actasmtoken:=AS_CONDITION;
exit;
end;
if is_register(actasmpattern) then
begin
actasmtoken:=AS_REGISTER;
@ -942,6 +953,25 @@ Unit raz80asm;
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;
begin
result:=false;
@ -2197,6 +2227,18 @@ Unit raz80asm;
AS_SEPARATOR :
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 }
AS_COMMA :
begin