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:
|
if alpha_op.dest.omask is not None:
|
||||||
US_CMN_INST.ALPHA_OMASK(code, alpha_op.dest.omask.value)
|
US_CMN_INST.ALPHA_OMASK(code, alpha_op.dest.omask.value)
|
||||||
|
|
||||||
|
# omod
|
||||||
|
US_ALU_ALPHA_INST.OMOD(code, alpha_op.omod.value)
|
||||||
|
|
||||||
# opcode
|
# opcode
|
||||||
US_ALU_ALPHA_INST.ALPHA_OP(code, alpha_op.opcode.value)
|
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:
|
if rgb_op.dest.omask is not None:
|
||||||
US_CMN_INST.RGB_OMASK(code, rgb_op.dest.omask.value)
|
US_CMN_INST.RGB_OMASK(code, rgb_op.dest.omask.value)
|
||||||
|
|
||||||
|
# omod
|
||||||
|
US_ALU_RGB_INST.OMOD(code, rgb_op.omod.value)
|
||||||
|
|
||||||
# opcode
|
# opcode
|
||||||
US_ALU_RGBA_INST.RGB_OP(code, rgb_op.opcode.value)
|
US_ALU_RGBA_INST.RGB_OP(code, rgb_op.opcode.value)
|
||||||
|
|
||||||
|
|||||||
@ -110,6 +110,26 @@ class Swizzle(IntEnum):
|
|||||||
one = 6
|
one = 6
|
||||||
unused = 7
|
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
|
@dataclass
|
||||||
class SwizzleSel:
|
class SwizzleSel:
|
||||||
src: SwizzleSelSrc
|
src: SwizzleSelSrc
|
||||||
@ -119,12 +139,14 @@ class SwizzleSel:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class AlphaOperation:
|
class AlphaOperation:
|
||||||
dest: AlphaDest
|
dest: AlphaDest
|
||||||
|
omod: Omod
|
||||||
opcode: AlphaOp
|
opcode: AlphaOp
|
||||||
sels: list[SwizzleSel]
|
sels: list[SwizzleSel]
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class RGBOperation:
|
class RGBOperation:
|
||||||
dest: RGBDest
|
dest: RGBDest
|
||||||
|
omod: Omod
|
||||||
opcode: RGBOp
|
opcode: RGBOp
|
||||||
sels: list[SwizzleSel]
|
sels: list[SwizzleSel]
|
||||||
|
|
||||||
@ -413,14 +435,27 @@ def validate_instruction_operation_sels(swizzle_sels, is_alpha):
|
|||||||
sels.append(SwizzleSel(src, swizzle, mod))
|
sels.append(SwizzleSel(src, swizzle, mod))
|
||||||
return sels
|
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):
|
def validate_alpha_instruction_operation(operation):
|
||||||
dest = validate_instruction_operation_dest(operation.dest_addr_swizzles,
|
dest = validate_instruction_operation_dest(operation.dest_addr_swizzles,
|
||||||
mask_lookup=alpha_masks,
|
mask_lookup=alpha_masks,
|
||||||
type_cls=AlphaDest)
|
type_cls=AlphaDest)
|
||||||
|
omod = validate_omod_operation(operation)
|
||||||
opcode = alpha_op_kws[operation.opcode_keyword.keyword]
|
opcode = alpha_op_kws[operation.opcode_keyword.keyword]
|
||||||
sels = validate_instruction_operation_sels(operation.swizzle_sels, is_alpha=True)
|
sels = validate_instruction_operation_sels(operation.swizzle_sels, is_alpha=True)
|
||||||
return AlphaOperation(
|
return AlphaOperation(
|
||||||
dest,
|
dest,
|
||||||
|
omod,
|
||||||
opcode,
|
opcode,
|
||||||
sels
|
sels
|
||||||
)
|
)
|
||||||
@ -429,10 +464,12 @@ def validate_rgb_instruction_operation(operation):
|
|||||||
dest = validate_instruction_operation_dest(operation.dest_addr_swizzles,
|
dest = validate_instruction_operation_dest(operation.dest_addr_swizzles,
|
||||||
mask_lookup=rgb_masks,
|
mask_lookup=rgb_masks,
|
||||||
type_cls=RGBDest)
|
type_cls=RGBDest)
|
||||||
|
omod = validate_omod_operation(operation)
|
||||||
opcode = rgb_op_kws[operation.opcode_keyword.keyword]
|
opcode = rgb_op_kws[operation.opcode_keyword.keyword]
|
||||||
sels = validate_instruction_operation_sels(operation.swizzle_sels, is_alpha=False)
|
sels = validate_instruction_operation_sels(operation.swizzle_sels, is_alpha=False)
|
||||||
return RGBOperation(
|
return RGBOperation(
|
||||||
dest,
|
dest,
|
||||||
|
omod,
|
||||||
opcode,
|
opcode,
|
||||||
sels
|
sels
|
||||||
)
|
)
|
||||||
|
|||||||
@ -35,6 +35,7 @@ class ALUSwizzleSel:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class ALUOperation:
|
class ALUOperation:
|
||||||
dest_addr_swizzles: list[DestAddrSwizzle]
|
dest_addr_swizzles: list[DestAddrSwizzle]
|
||||||
|
omod: tuple[Token, Token]
|
||||||
opcode_keyword: Token
|
opcode_keyword: Token
|
||||||
swizzle_sels: list[ALUSwizzleSel]
|
swizzle_sels: list[ALUSwizzleSel]
|
||||||
|
|
||||||
@ -115,6 +116,15 @@ class Parser(BaseParser):
|
|||||||
return token.keyword in opcode_keywords
|
return token.keyword in opcode_keywords
|
||||||
return False
|
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):
|
def alu_is_neg(self):
|
||||||
result = self.match(TT.minus)
|
result = self.match(TT.minus)
|
||||||
if result:
|
if result:
|
||||||
@ -154,9 +164,17 @@ class Parser(BaseParser):
|
|||||||
|
|
||||||
def alu_operation(self):
|
def alu_operation(self):
|
||||||
dest_addr_swizzles = []
|
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())
|
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")
|
opcode_keyword = self.consume(TT.keyword, "expected opcode keyword")
|
||||||
|
|
||||||
swizzle_sels = []
|
swizzle_sels = []
|
||||||
@ -165,6 +183,7 @@ class Parser(BaseParser):
|
|||||||
|
|
||||||
return ALUOperation(
|
return ALUOperation(
|
||||||
dest_addr_swizzles,
|
dest_addr_swizzles,
|
||||||
|
omod,
|
||||||
opcode_keyword,
|
opcode_keyword,
|
||||||
swizzle_sels
|
swizzle_sels
|
||||||
)
|
)
|
||||||
|
|||||||
@ -21,6 +21,7 @@ class TT(Enum):
|
|||||||
bar = auto()
|
bar = auto()
|
||||||
comma = auto()
|
comma = auto()
|
||||||
minus = auto()
|
minus = auto()
|
||||||
|
star = auto()
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Token:
|
class Token:
|
||||||
@ -112,6 +113,8 @@ class Lexer:
|
|||||||
return Token(*self.pos(), TT.semicolon, self.lexeme())
|
return Token(*self.pos(), TT.semicolon, self.lexeme())
|
||||||
elif c == ord(','):
|
elif c == ord(','):
|
||||||
return Token(*self.pos(), TT.comma, self.lexeme())
|
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('-'):
|
elif c == ord('-') and self.peek() == ord('-'):
|
||||||
self.advance()
|
self.advance()
|
||||||
while not self.at_end_p() and self.peek() != ord('\n'):
|
while not self.at_end_p() and self.peek() != ord('\n'):
|
||||||
|
|||||||
@ -22,8 +22,8 @@ class BaseParser:
|
|||||||
self.current_ix += 1
|
self.current_ix += 1
|
||||||
return token
|
return token
|
||||||
|
|
||||||
def match(self, token_type):
|
def match(self, token_type, offset=0):
|
||||||
token = self.peek()
|
token = self.peek(offset)
|
||||||
return token.type == token_type
|
return token.type == token_type
|
||||||
|
|
||||||
def match_keyword(self, keyword):
|
def match_keyword(self, keyword):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user