98 lines
3.4 KiB
Python
98 lines
3.4 KiB
Python
from typing import Union
|
|
|
|
from assembler.vs.opcodes import ME, VE, MVE
|
|
from assembler.vs.validator import Destination, Source, Instruction
|
|
|
|
import pvs_dst
|
|
import pvs_src
|
|
|
|
def emit_destination_opcode(destination: Destination,
|
|
opcode: Union[ME, VE, MVE],
|
|
saturation: bool):
|
|
assert type(opcode) in {ME, VE, MVE}
|
|
math_inst = int(type(opcode) is ME)
|
|
macro_inst = int(type(opcode) is MVE)
|
|
|
|
ve_sat = int((not math_inst) and saturation)
|
|
me_sat = int(math_inst and saturation)
|
|
|
|
value = (
|
|
pvs_dst.OPCODE_gen(opcode.value)
|
|
| pvs_dst.MATH_INST_gen(math_inst)
|
|
| pvs_dst.MACRO_INST_gen(int(macro_inst))
|
|
| pvs_dst.REG_TYPE_gen(destination.type.value)
|
|
| pvs_dst.OFFSET_gen(destination.offset)
|
|
| pvs_dst.WE_X_gen(int(destination.write_enable[0]))
|
|
| pvs_dst.WE_Y_gen(int(destination.write_enable[1]))
|
|
| pvs_dst.WE_Z_gen(int(destination.write_enable[2]))
|
|
| pvs_dst.WE_W_gen(int(destination.write_enable[3]))
|
|
| pvs_dst.VE_SAT_gen(ve_sat)
|
|
| pvs_dst.ME_SAT_gen(me_sat)
|
|
)
|
|
yield value
|
|
|
|
def emit_source(src: Source, prev: Source):
|
|
if src is not None:
|
|
assert src.offset <= 255
|
|
value = (
|
|
pvs_src.REG_TYPE_gen(src.type.value)
|
|
| pvs_src.OFFSET_gen(src.offset)
|
|
| pvs_src.ABS_XYZW_gen(int(src.absolute))
|
|
| pvs_src.SWIZZLE_X_gen(src.swizzle_selects[0].value)
|
|
| pvs_src.SWIZZLE_Y_gen(src.swizzle_selects[1].value)
|
|
| pvs_src.SWIZZLE_Z_gen(src.swizzle_selects[2].value)
|
|
| pvs_src.SWIZZLE_W_gen(src.swizzle_selects[3].value)
|
|
| pvs_src.MODIFIER_X_gen(int(src.modifiers[0]))
|
|
| pvs_src.MODIFIER_Y_gen(int(src.modifiers[1]))
|
|
| pvs_src.MODIFIER_Z_gen(int(src.modifiers[2]))
|
|
| pvs_src.MODIFIER_W_gen(int(src.modifiers[3]))
|
|
)
|
|
else:
|
|
assert prev is not None
|
|
assert prev.offset <= 255
|
|
value = (
|
|
pvs_src.REG_TYPE_gen(prev.type.value)
|
|
| pvs_src.OFFSET_gen(prev.offset)
|
|
| pvs_src.ABS_XYZW_gen(0)
|
|
| pvs_src.SWIZZLE_X_gen(7)
|
|
| pvs_src.SWIZZLE_Y_gen(7)
|
|
| pvs_src.SWIZZLE_Z_gen(7)
|
|
| pvs_src.SWIZZLE_W_gen(7)
|
|
| pvs_src.MODIFIER_X_gen(0)
|
|
| pvs_src.MODIFIER_Y_gen(0)
|
|
| pvs_src.MODIFIER_Z_gen(0)
|
|
| pvs_src.MODIFIER_W_gen(0)
|
|
)
|
|
yield value
|
|
|
|
def prev_source(ins, ix):
|
|
assert ins.sources[0] is not None
|
|
if ix == 0:
|
|
return ins.sources[0]
|
|
elif ix == 1:
|
|
return ins.sources[0]
|
|
elif ix == 2:
|
|
if len(ins.sources) >= 2 and ins.sources[1] is not None:
|
|
return ins.sources[1]
|
|
else:
|
|
return ins.sources[0]
|
|
else:
|
|
assert False, ix
|
|
|
|
def emit_instruction(ins: Instruction):
|
|
yield from emit_destination_opcode(ins.destination,
|
|
ins.opcode,
|
|
ins.saturation)
|
|
|
|
if len(ins.sources) >= 1:
|
|
yield from emit_source(ins.sources[0], prev_source(ins, 0))
|
|
|
|
source1 = ins.sources[1] if len(ins.sources) >= 2 else None
|
|
source2 = ins.sources[2] if len(ins.sources) >= 3 else None
|
|
yield from emit_source(source1, prev_source(ins, 1))
|
|
yield from emit_source(source2, prev_source(ins, 2))
|
|
else:
|
|
yield 0
|
|
yield 0
|
|
yield 0
|