import logging
log = logging.getLogger(__name__)
from util import A, B, B_reversed, C, D, E, F, G, H, instr, spec, spec_reversed
_mark = set(dir()) ; _mark.add('_mark')
@A
[docs]def jmp(address):
'''
1001 010k kkkk 110k
kkkk kkkk kkkk kkkk
'''
[docs]def cli():
return 16, 0b1001010011111000
@B
[docs]def ldi(register, immediate):
'''
1110 KKKK dddd KKKK
'''
@C
[docs]def out(io_port, register):
'''
1011 1AAr rrrr AAAA
'''
@A
[docs]def rcall(address):
'''
1101 kkkk kkkk kkkk
'''
@B_reversed
[docs]def sts(address, register):
'''
1001 001d dddd 0000
kkkk kkkk kkkk kkkk
'''
@D
[docs]def mov(Rd, Rr):
'''
0010 11rd dddd rrrr
'''
[docs]def sei():
return 16, 0b1001010001111000
[docs]def ret():
return 16, 0b1001010100001000
@A
[docs]def rjmp(address):
'''
1100 kkkk kkkk kkkk
'''
@B
[docs]def lds(register, address):
'''
1001 000d dddd 0000
kkkk kkkk kkkk kkkk
'''
@E
[docs]def sbrs(register, bit):
'''
1111 111r rrrr 0bbb
'''
[docs]def dw(values, data):
return -1, data
[docs]def db(values, data):
return -1, data
@F
[docs]def st_post_incr_Y(Rr):
'''
1001 001r rrrr 1001
'''
@F
[docs]def st_post_incr_Z(Rr):
'''
1001 001r rrrr 0001
'''
@G
[docs]def ld_pre_decr_Y(Rd):
'''
1001 000d dddd 1010
'''
@G
[docs]def ld_post_incr_X(Rd):
'''
1001 000d dddd 1101
'''
@G
[docs]def ld_post_incr_Z(Rd):
'''
1001 000d dddd 0001
'''
@G
[docs]def ld_pre_decr_Z(Rd):
'''
1001 000d dddd 0010
'''
@G
[docs]def lpm(Rd):
'''
1001 000d dddd 0100
'''
@G
[docs]def lpm_post_incr_Z(Rd):
'''
1001 000d dddd 0101
'''
@B
[docs]def cpi(register, immediate):
'''
0011 KKKK dddd KKKK
'''
@A
[docs]def brne(address):
'''
1111 01kk kkkk k001
'''
@A
[docs]def breq(address):
'''
1111 00kk kkkk k001
'''
@A
[docs]def brlo(address):
'''
1111 00kk kkkk k000
'''
@G
[docs]def lsr(Rd):
'''
1001 010d dddd 0110
'''
@D
[docs]def lsl(Rd, Rr): # See Amtel manual! This instruction only takes one register.
'''
0000 11rd dddd rrrr
'''
@D
[docs]def add(Rd, Rr):
'''
0000 11rd dddd rrrr
'''
@A
[docs]def brcc(address):
'''
1111 01kk kkkk k000
'''
@G
[docs]def inc(Rd):
'''
1001 010d dddd 0011
'''
@G
[docs]def dec(Rd):
'''
1001 010d dddd 1010
'''
[docs]def ijmp():
return 16, 0b1001010000001001
@D
[docs]def cp(Rd, Rr):
'''
0001 01rd dddd rrrr
'''
@D
[docs]def cpse(Rd, Rr):
'''
0001 00rd dddd rrrr
'''
@D
[docs]def cpc(Rd, Rr):
'''
0000 01rd dddd rrrr
'''
@A
[docs]def brsh(address):
'''
1111 01kk kkkk k000
'''
@D
[docs]def movw(Rd, Rr):
'''
0000 0001 dddd rrrr
'''
@B
[docs]def andi(register, immediate):
'''
0111 KKKK dddd KKKK
'''
@H
[docs]def sbis(register, bit):
'''
1001 1011 AAAA Abbb
'''
@D
[docs]def clr(Rd, Rr): # See Amtel manual! This instruction only takes one register.
'''
0010 01rd dddd rrrr
'''
@F
[docs]def push(Rr):
'''
1001 001r rrrr 1111
'''
@G
[docs]def pop(Rd):
'''
1001 000d dddd 1111
'''
@D
[docs]def or_(Rd, Rr):
'''
0010 10rd dddd rrrr
'''
@G
[docs]def swap(Rd):
'''
1001 010d dddd 0010
'''
@B
[docs]def adiw(register, immediate):
'''
1001 0110 KKdd KKKK
'''
@B
[docs]def sbiw(register, immediate):
'''
1001 0111 KKdd KKKK
'''
@B
[docs]def subi(register, immediate):
'''
0101 KKKK dddd KKKK
'''
@D
[docs]def mul(Rd, Rr):
'''
1001 11rd dddd rrrr
'''
_ops = dict(
(name, func)
for name, func in locals().iteritems()
if name not in _mark
)
[docs]class InstructionsMixin(object):
ops = _ops
@instr
[docs] def jmp(self, address):
self.here += 2
return address
@instr
[docs] def rjmp(self, address):
return address
@instr
[docs] def rcall(self, address):
return address
@instr
@instr
@instr
@instr
[docs] def ldi(self, target, immediate):
if isinstance(immediate, str):
assert len(immediate) == 1, repr(immediate)
immediate = ord(immediate)
return target, immediate << 1
@instr
[docs] def out(self, target, address):
return target, address
@instr
[docs] def sts(self, address, register):
self.here += 2
return address << 1, register
@instr
[docs] def mov(self, target, source):
return target, source
@instr
[docs] def lds(self, target, address):
self.here += 2
return target, address << 1
@instr
[docs] def sbrs(self, target, address):
return target, address
@spec
[docs] def st_post_incr(self, ptr, register):
pass
@spec_reversed
[docs] def ld_post_incr(self, register, ptr):
pass
@spec_reversed
[docs] def ld_pre_decr(self, register, ptr):
pass
@spec_reversed
[docs] def lpm_post_incr(self, register, ptr):
pass
@instr
[docs] def cpi(self, register, immediate):
if isinstance(immediate, str):
assert len(immediate) == 1, repr(immediate)
immediate = ord(immediate)
return register, immediate << 1
@instr
[docs] def brne(self, address):
return address
@instr
[docs] def breq(self, address):
return address
@instr
[docs] def inc(self, register):
return register
@instr
[docs] def mul(self, target, source):
return target, source
@instr
[docs] def brlo(self, address):
return address
@instr
[docs] def subi(self, register, immediate):
if isinstance(immediate, str):
assert len(immediate) == 1, repr(immediate)
immediate = ord(immediate)
return register, immediate << 1
@instr
[docs] def add(self, target, source):
return target, source
@instr
[docs] def dec(self, address):
return address
@instr
[docs] def clr(self, register):
return register
@instr
[docs] def lsl(self, address):
return address
@instr
[docs] def brcc(self, address):
return address
@instr
[docs] def or_(self, target, source):
return target, source
@instr
[docs] def push(self, address):
return address
@instr
[docs] def swap(self, address):
return address
@instr
[docs] def pop(self, address):
return address
@instr
[docs] def movw(self, target, source):
return target >> 1, source >> 1
@instr
[docs] def andi(self, register, immediate):
return register, immediate << 1
@instr
[docs] def adiw(self, register, immediate):
assert register in (24, 26, 28, 30), repr(register)
return register >> 1, immediate << 1
[docs] def lpm(self, target, source):
assert source == 30, repr(source) # Must be Z
self._one('lpm', target)
@instr
[docs] def cp(self, target, source):
return target, source
@instr
[docs] def cpc(self, target, source):
return target, source
@instr
[docs] def brsh(self, address):
return address
@instr
[docs] def cpse(self, target, source):
return target, source
@instr
[docs] def sbiw(self, target, immediate):
return target >> 1, immediate << 1
@instr
[docs] def lsr(self, address):
return address
@instr
def _one(self, op, address):
name, address = self._name_or_addr(address)
addr = self._get_here()
log.debug('assembling %s instruction at %s to %s', op, addr, name)
self.data[addr] = (op, address)
self.here += 2
def _instruction_namespace(self):
for n in dir(InstructionsMixin):
if n.startswith('_'):
continue
yield n, getattr(self, n)
if __name__ == '__main__':
import pprint
pprint.pprint(_ops)
pprint.pprint(dict(InstructionsMixin()._instruction_namespace()))