Exemplo n.º 1
0
    def _emit(self, op_add, dst=REGISTERS['null'], opd1=REGISTERS['r0'],
            opd2=REGISTERS['r0'], sig='no signal', set_flags=True, **kwargs):

        muxes, raddr_a, raddr_b, use_imm, unpack, read_pm = \
                self._encode_read_operands(opd1, opd2)

        if use_imm:
            if sig != 'no signal' and sig != 'alu small imm':
                raise AssembleError(
                        '\'{}\' can not be used with immediate'.format(sig))
            sig = 'alu small imm'
        sig_bits = enc._SIGNAL[sig]

        if op_add == enc._ADD_INSN['nop']:
            set_flags = False

        waddr_add, waddr_mul, write_swap, pack = \
                self._encode_write_operands(dst)

        pm = 0
        if unpack and pack:
            if read_pm != 0:
                raise AssembleError('Conflict of packing and unpacking')
            pm = read_pm
        elif unpack and not pack:
            pm = read_pm
        elif pack and not unpack:
            pm = 0

        cond_add_str = kwargs.get('cond', 'always')
        cond_add = enc._COND[cond_add_str]
        cond_mul = enc._COND['never']

        insn = enc.AluInsn(
                sig=sig_bits, unpack=unpack, pm=pm, pack=pack,
                sf=set_flags, ws=write_swap, cond_add=cond_add,
                cond_mul=cond_mul, op_add=op_add, op_mul=enc._MUL_INSN['nop'],
                waddr_add=waddr_add, waddr_mul=waddr_mul, raddr_a=raddr_a,
                raddr_b=raddr_b, add_a=muxes[0], add_b=muxes[1],
                mul_a=muxes[2], mul_b=muxes[3]
                )

        if self.asm.sanity_check:
            insn.verbose = AddInstr(enc._ADD_INSN_REV[op_add], dst, opd1, opd2, sig, set_flags, cond_add_str)
        self.asm._emit(insn)

        # Create MulEmitter which holds arguments of Add ALU for dual
        # issuing.
        return MulEmitter(
                self.asm, op_add=op_add, add_dst=dst, add_opd1=opd1,
                add_opd2=opd2, cond_add=cond_add, sig=sig, set_flags=set_flags,
                increment=False)
Exemplo n.º 2
0
    def _emit_with_defaults(self,
                            op_mul,
                            mul_dst,
                            mul_opd1,
                            mul_opd2,
                            rotate=0,
                            pack='nop',
                            **kwargs):

        mul_pack = enc._MUL_PACK[pack]

        muxes, raddr_a, raddr_b, use_imm, unpack, read_pm = \
                self._encode_read_operands(self.add_opd1, self.add_opd2,
                                           mul_opd1, mul_opd2)

        waddr_add, waddr_mul, write_swap, regA_pack = \
                self._encode_write_operands(self.add_dst, mul_dst)

        if mul_pack and regA_pack:
            raise AssembleError('Multiple pack operationss')

        write_pm = (mul_pack != 0)
        pack = mul_pack or regA_pack

        pm = 0
        if unpack and pack:
            if read_pm != write_pm:
                raise AssembleError('Conflict of packing and unpacking')
            pm = read_pm
        elif unpack and not pack:
            pm = read_pm
        elif pack and not unpack:
            pm = write_pm

        sig = kwargs.get('sig', 'no signal')
        if self.sig != 'no signal':
            if sig != 'no signal':
                raise AssembleError('Conflict of signals')
            sig = self.sig

        if use_imm or rotate:
            if sig != 'no signal' and sig != 'alu small imm':
                raise AssembleError(
                    '\'{}\' can not be used with immediate'.format(sig))
            sig = 'alu small imm'
        sig_bits = enc._SIGNAL[sig]

        if rotate:
            if muxes[2] == 5 or muxes[2] == 7 or muxes[3] == 5 or muxes[3] == 7:
                raise AssembleError('Rotate operation is only available when'
                                    ' inputs are taken from r0-r4 or ra')

            if use_imm:

                # 'r5 rotate' represents -1.
                # 'n-upward rotate' represents n-16.
                # So these combinations can be used (1 <= n <= 15):
                # +-----------+--------+
                # | small imm | rotate |
                # +-----------+--------+
                # |    -16    |   r5   |
                # |     -n    |   -n   |
                # +-----------+--------+
                # c.f. https://vc4-notes.tumblr.com/post/153467713064/

                if rotate == REGISTERS['r5']:
                    if raddr_b != enc._SMALL_IMM['-16']:
                        raise AssembleError(
                            'Conflict immediate value and r5 rotate')
                elif raddr_b != enc._SMALL_IMM[str(rotate % 16 - 16)]:
                    raise AssembleError(
                        'Conflict immediate value and n rotate')

            if rotate == REGISTERS['r5']:
                raddr_b = 48
            else:
                raddr_b = 48 + rotate % 16

        cond_add = self.cond_add
        cond_mul_str = kwargs.get('cond', 'always')
        cond_mul = enc._COND[cond_mul_str]

        insn = enc.AluInsn(sig=sig_bits,
                           unpack=unpack,
                           pm=pm,
                           pack=pack,
                           sf=self.set_flags,
                           ws=write_swap,
                           cond_add=cond_add,
                           cond_mul=cond_mul,
                           op_add=self.op_add,
                           op_mul=op_mul,
                           waddr_add=waddr_add,
                           waddr_mul=waddr_mul,
                           raddr_a=raddr_a,
                           raddr_b=raddr_b,
                           add_a=muxes[0],
                           add_b=muxes[1],
                           mul_a=muxes[2],
                           mul_b=muxes[3])
        if self.asm.sanity_check:
            insn.verbose = MulInstr(enc._MUL_INSN_REV[op_mul], mul_dst,
                                    mul_opd1, mul_opd2, sig, self.set_flags,
                                    cond_mul_str)
        self.asm._emit(insn, increment=self.increment)
Exemplo n.º 3
0
        reg = REGISTERS[name]
        assert(reg.name == name)
        assert(str(reg) == name)

def test_pack_unpack():
    REGISTERS['ra0'].pack('16a')  # no throw
    assert_raises(AssembleError, REGISTERS['rb0'].pack, '16a')
    REGISTERS['ra0'].unpack('16a')  # no throw
    REGISTERS['r4'].unpack('16a')   # no throw
    assert_raises(AssembleError, REGISTERS['rb0'].unpack, '16a')

#============================ Instruction encoding ============================

SAMPLE_ALU_INSN = enc.AluInsn(
    sig=0, unpack=1, pm=1, pack=2, cond_add=3, cond_mul=4, sf=1, ws=1,
    waddr_add=53, waddr_mul=12, op_mul=4, op_add=2, raddr_a=33, raddr_b=53,
    add_a=4, add_b=7, mul_a=6, mul_b=2
    )

SAMPLE_BRANCH_INSN = enc.BranchInsn(
    sig=0xf, cond_br=13, rel=1, reg=0, raddr_a=27, ws=1, waddr_add=53,
    waddr_mul=12, immediate=0x12345678
    )

SAMPLE_LOAD_INSN = enc.LoadInsn(
    sig=0xe, unpack=1, pm=1, pack=2, cond_add=3, cond_mul=4, sf=1, ws=1,
    waddr_add=53, waddr_mul=12, immediate=0x12345678
    )

SAMPLE_SEMA_INSN = enc.SemaInsn(
    sig=0xe, unpack=4, pm=1, pack=2, cond_add=3, cond_mul=4, sf=1, ws=1,