assembler.fs: add support for omod
This commit is contained in:
parent
399cd6aaf9
commit
90b486e744
@ -17,6 +17,9 @@ def emit_alpha_op(code, alpha_op):
|
||||
if alpha_op.dest.omask is not None:
|
||||
US_CMN_INST.ALPHA_OMASK(code, alpha_op.dest.omask.value)
|
||||
|
||||
# omod
|
||||
US_ALU_ALPHA_INST.OMOD(code, alpha_op.omod.value)
|
||||
|
||||
# opcode
|
||||
US_ALU_ALPHA_INST.ALPHA_OP(code, alpha_op.opcode.value)
|
||||
|
||||
@ -59,6 +62,9 @@ def emit_rgb_op(code, rgb_op):
|
||||
if rgb_op.dest.omask is not None:
|
||||
US_CMN_INST.RGB_OMASK(code, rgb_op.dest.omask.value)
|
||||
|
||||
# omod
|
||||
US_ALU_RGB_INST.OMOD(code, rgb_op.omod.value)
|
||||
|
||||
# opcode
|
||||
US_ALU_RGBA_INST.RGB_OP(code, rgb_op.opcode.value)
|
||||
|
||||
|
||||
@ -110,6 +110,26 @@ class Swizzle(IntEnum):
|
||||
one = 6
|
||||
unused = 7
|
||||
|
||||
class Omod(IntEnum):
|
||||
mul_1 = 0
|
||||
mul_2 = 1
|
||||
mul_4 = 2
|
||||
mul_8 = 3
|
||||
div_2 = 4
|
||||
div_4 = 5
|
||||
div_8 = 6
|
||||
disable = 7
|
||||
|
||||
omod_lexemes = OrderedDict([
|
||||
((b"1", b"0"), Omod.mul_1),
|
||||
((b"2", b"0"), Omod.mul_2),
|
||||
((b"4", b"0"), Omod.mul_4),
|
||||
((b"8", b"0"), Omod.mul_8),
|
||||
((b"0", b"5"), Omod.div_2),
|
||||
((b"0", b"25"), Omod.div_4),
|
||||
((b"0", b"125"), Omod.div_8),
|
||||
])
|
||||
|
||||
@dataclass
|
||||
class SwizzleSel:
|
||||
src: SwizzleSelSrc
|
||||
@ -119,12 +139,14 @@ class SwizzleSel:
|
||||
@dataclass
|
||||
class AlphaOperation:
|
||||
dest: AlphaDest
|
||||
omod: Omod
|
||||
opcode: AlphaOp
|
||||
sels: list[SwizzleSel]
|
||||
|
||||
@dataclass
|
||||
class RGBOperation:
|
||||
dest: RGBDest
|
||||
omod: Omod
|
||||
opcode: RGBOp
|
||||
sels: list[SwizzleSel]
|
||||
|
||||
@ -413,14 +435,27 @@ def validate_instruction_operation_sels(swizzle_sels, is_alpha):
|
||||
sels.append(SwizzleSel(src, swizzle, mod))
|
||||
return sels
|
||||
|
||||
def validate_omod_operation(operation):
|
||||
omod = Omod.mul_1
|
||||
if operation.omod != None:
|
||||
integer, decimal = operation.omod
|
||||
key = (integer.lexeme, decimal.lexeme)
|
||||
if key not in omod_lexemes:
|
||||
valid_omods = b", ".join(b".".join(key) for key in omod_lexemes.keys()).decode('utf-8')
|
||||
raise ValidatorError(f"invalid omod, expected one of [{valid_omods}]", integer)
|
||||
omod = omod_lexemes[key]
|
||||
return omod
|
||||
|
||||
def validate_alpha_instruction_operation(operation):
|
||||
dest = validate_instruction_operation_dest(operation.dest_addr_swizzles,
|
||||
mask_lookup=alpha_masks,
|
||||
type_cls=AlphaDest)
|
||||
omod = validate_omod_operation(operation)
|
||||
opcode = alpha_op_kws[operation.opcode_keyword.keyword]
|
||||
sels = validate_instruction_operation_sels(operation.swizzle_sels, is_alpha=True)
|
||||
return AlphaOperation(
|
||||
dest,
|
||||
omod,
|
||||
opcode,
|
||||
sels
|
||||
)
|
||||
@ -429,10 +464,12 @@ def validate_rgb_instruction_operation(operation):
|
||||
dest = validate_instruction_operation_dest(operation.dest_addr_swizzles,
|
||||
mask_lookup=rgb_masks,
|
||||
type_cls=RGBDest)
|
||||
omod = validate_omod_operation(operation)
|
||||
opcode = rgb_op_kws[operation.opcode_keyword.keyword]
|
||||
sels = validate_instruction_operation_sels(operation.swizzle_sels, is_alpha=False)
|
||||
return RGBOperation(
|
||||
dest,
|
||||
omod,
|
||||
opcode,
|
||||
sels
|
||||
)
|
||||
|
||||
@ -35,6 +35,7 @@ class ALUSwizzleSel:
|
||||
@dataclass
|
||||
class ALUOperation:
|
||||
dest_addr_swizzles: list[DestAddrSwizzle]
|
||||
omod: tuple[Token, Token]
|
||||
opcode_keyword: Token
|
||||
swizzle_sels: list[ALUSwizzleSel]
|
||||
|
||||
@ -115,6 +116,15 @@ class Parser(BaseParser):
|
||||
return token.keyword in opcode_keywords
|
||||
return False
|
||||
|
||||
def alu_is_omod(self):
|
||||
is_omod = (
|
||||
self.match(TT.identifier, offset=0)
|
||||
and self.match(TT.dot, offset=1)
|
||||
and self.match(TT.identifier, offset=2)
|
||||
and self.match(TT.star, offset=3)
|
||||
)
|
||||
return is_omod
|
||||
|
||||
def alu_is_neg(self):
|
||||
result = self.match(TT.minus)
|
||||
if result:
|
||||
@ -154,9 +164,17 @@ class Parser(BaseParser):
|
||||
|
||||
def alu_operation(self):
|
||||
dest_addr_swizzles = []
|
||||
while not self.alu_is_opcode():
|
||||
while not (self.alu_is_opcode() or self.alu_is_omod()):
|
||||
dest_addr_swizzles.append(self.dest_addr_swizzle())
|
||||
|
||||
omod = None
|
||||
if self.alu_is_omod():
|
||||
omod_integer = self.consume(TT.identifier, "expected omod decimal identifier")
|
||||
self.consume(TT.dot, "expected omod decimal dot")
|
||||
omod_decimal = self.consume(TT.identifier, "expected omod decimal identifier")
|
||||
self.consume(TT.star, "expected omod star")
|
||||
omod = (omod_integer, omod_decimal)
|
||||
|
||||
opcode_keyword = self.consume(TT.keyword, "expected opcode keyword")
|
||||
|
||||
swizzle_sels = []
|
||||
@ -165,6 +183,7 @@ class Parser(BaseParser):
|
||||
|
||||
return ALUOperation(
|
||||
dest_addr_swizzles,
|
||||
omod,
|
||||
opcode_keyword,
|
||||
swizzle_sels
|
||||
)
|
||||
|
||||
@ -21,6 +21,7 @@ class TT(Enum):
|
||||
bar = auto()
|
||||
comma = auto()
|
||||
minus = auto()
|
||||
star = auto()
|
||||
|
||||
@dataclass
|
||||
class Token:
|
||||
@ -112,6 +113,8 @@ class Lexer:
|
||||
return Token(*self.pos(), TT.semicolon, self.lexeme())
|
||||
elif c == ord(','):
|
||||
return Token(*self.pos(), TT.comma, self.lexeme())
|
||||
elif c == ord('*'):
|
||||
return Token(*self.pos(), TT.star, self.lexeme())
|
||||
elif c == ord('-') and self.peek() == ord('-'):
|
||||
self.advance()
|
||||
while not self.at_end_p() and self.peek() != ord('\n'):
|
||||
|
||||
@ -22,8 +22,8 @@ class BaseParser:
|
||||
self.current_ix += 1
|
||||
return token
|
||||
|
||||
def match(self, token_type):
|
||||
token = self.peek()
|
||||
def match(self, token_type, offset=0):
|
||||
token = self.peek(offset)
|
||||
return token.type == token_type
|
||||
|
||||
def match_keyword(self, keyword):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user