diff --git a/regs/assembler/fs/emitter.py b/regs/assembler/fs/emitter.py index d1839eb..49dee47 100644 --- a/regs/assembler/fs/emitter.py +++ b/regs/assembler/fs/emitter.py @@ -161,6 +161,9 @@ def emit_addr(code, addr): US_ALU_RGB_ADDR.SRCP_OP(code, addr.rgb.srcp.value) def emit_instruction(code, ins): + US_CMN_INST.TYPE(code, ins.type.value) + US_CMN_INST.TEX_SEM_WAIT(code, int(ins.tex_sem_wait)) + emit_addr(code, ins.addr) emit_alpha_op(code, ins.alpha_op) emit_rgb_op(code, ins.rgb_op) diff --git a/regs/assembler/fs/parser.py b/regs/assembler/fs/parser.py index 7532785..5310047 100644 --- a/regs/assembler/fs/parser.py +++ b/regs/assembler/fs/parser.py @@ -40,6 +40,8 @@ class Operation: @dataclass class Instruction: + out: bool + tex_sem_wait: bool let_expressions: list[LetExpression] operations: list[Operation] @@ -160,6 +162,15 @@ class Parser(BaseParser): ) def instruction(self): + out = False + if self.match_keyword(KW.OUT): + self.advance() + out = True + tex_sem_wait = False + if self.match_keyword(KW.TEX_SEM_WAIT): + self.advance() + tex_sem_wait = True + let_expressions = [] while not self.match(TT.colon): let_expressions.append(self.let_expression()) @@ -177,6 +188,8 @@ class Parser(BaseParser): self.consume(TT.semicolon, "expected semicolon") return Instruction( + out, + tex_sem_wait, let_expressions, operations, ) @@ -193,6 +206,7 @@ src0.a = float(0), src0.rgb = temp[0] : out[0].none = temp[0].r = DP3 src0.rg0 src0.rg0 ; """ buf = b""" +OUT TEX_SEM_WAIT src0.a = float(0), src1.a = float(0), src2.a = float(0), srcp.a = neg2, src0.rgb = temp[0], src1.rgb = float(0), src2.rgb = float(0), srcp.rgb = neg2 : out[0].none = temp[0].none = MAD src0.r src0.r src0.r , out[0].none = temp[0].r = DP3 src0.rg0 src0.rg0 src0.rrr ; diff --git a/regs/assembler/fs/validator.py b/regs/assembler/fs/validator.py index 646a950..6944f70 100644 --- a/regs/assembler/fs/validator.py +++ b/regs/assembler/fs/validator.py @@ -139,8 +139,16 @@ class RGBOperation: opcode: RGBOp sels: list[SwizzleSel] +class InstructionType(IntEnum): + ALU = 0 + OUT = 1 + FC = 2 + TEX = 3 + @dataclass class Instruction: + type: InstructionType + tex_sem_wait: bool addr: Addr alpha_op: AlphaOperation rgb_op: RGBOperation @@ -474,7 +482,17 @@ def validate_instruction_operations(operations): def validate_instruction(ins): addr_rgb_alpha = validate_instruction_let_expressions(ins.let_expressions) - instruction = Instruction(addr_rgb_alpha, None, None) + + instruction_type = InstructionType.OUT if ins.out else InstructionType.ALU + tex_sem_wait = ins.tex_sem_wait + + instruction = Instruction( + instruction_type, + tex_sem_wait, + addr_rgb_alpha, + None, + None + ) for op in validate_instruction_operations(ins.operations): if type(op) is RGBOperation: instruction.rgb_op = op diff --git a/regs/assembler/parser.py b/regs/assembler/parser.py index ea6f3cb..fd633bf 100644 --- a/regs/assembler/parser.py +++ b/regs/assembler/parser.py @@ -1,5 +1,7 @@ from typing import Any +from assembler.lexer import TT + class ParserError(Exception): pass @@ -24,6 +26,13 @@ class BaseParser: token = self.peek() return token.type == token_type + def match_keyword(self, keyword): + if self.match(TT.keyword): + token = self.peek() + return token.keyword == keyword + else: + return False + def consume(self, token_type, message): token = self.advance() if token.type != token_type: