From a6e72713ad5772731a954164294d322185ced44f Mon Sep 17 00:00:00 2001 From: nickysn Date: Mon, 20 Apr 2020 17:02:03 +0000 Subject: [PATCH] + support conditions in the Z80 inline assembler git-svn-id: branches/z80@44885 - --- compiler/z80/agsdasz80.pas | 17 +++++++------- compiler/z80/raz80asm.pas | 46 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/compiler/z80/agsdasz80.pas b/compiler/z80/agsdasz80.pas index 896d1b908a..649c3fa739 100644 --- a/compiler/z80/agsdasz80.pas +++ b/compiler/z80/agsdasz80.pas @@ -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) diff --git a/compiler/z80/raz80asm.pas b/compiler/z80/raz80asm.pas index 9cf093bb5e..5db626760e 100644 --- a/compiler/z80/raz80asm.pas +++ b/compiler/z80/raz80asm.pas @@ -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