|
1 | 1 | from uctypes import struct, addressof, LITTLE_ENDIAN, UINT16, UINT32 |
2 | | -from esp32_ulp.opcodes import RD_REG_PERIPH_RTC_CNTL, RD_REG_PERIPH_RTC_IO, RD_REG_PERIPH_RTC_I2C, \ |
3 | | - RD_REG_PERIPH_SENS, DR_REG_MAX_DIRECT |
4 | | -import esp32_ulp.opcodes as opcodes |
5 | | -import esp32_ulp.soc as soc |
| 2 | +from .decode import decode_instruction, get_instruction_fields |
6 | 3 | import ubinascii |
7 | 4 | import sys |
8 | 5 |
|
9 | 6 |
|
10 | | -alu_cnt_ops = ('STAGE_INC', 'STAGE_DEC', 'STAGE_RST') |
11 | | -alu_ops = ('ADD', 'SUB', 'AND', 'OR', 'MOVE', 'LSH', 'RSH') |
12 | | -jump_types = ('--', 'EQ', 'OV') |
13 | | -cmp_ops = ('LT', 'GE', 'LE', 'EQ', 'GT') |
14 | | - |
15 | | -lookup = { |
16 | | - opcodes.OPCODE_ADC: ('ADC', opcodes._adc, lambda op: 'ADC r%s, %s, %s' % (op.dreg, op.mux, op.sar_sel)), |
17 | | - opcodes.OPCODE_ALU: ('ALU', opcodes._alu_imm, { |
18 | | - opcodes.SUB_OPCODE_ALU_CNT: ( |
19 | | - 'ALU_CNT', |
20 | | - opcodes._alu_cnt, |
21 | | - lambda op: '%s%s' % (alu_cnt_ops[op.sel], '' if op.sel == opcodes.ALU_SEL_RST else ' %s' % op.imm) |
22 | | - ), |
23 | | - opcodes.SUB_OPCODE_ALU_IMM: ( |
24 | | - 'ALU_IMM', |
25 | | - opcodes._alu_imm, |
26 | | - lambda op: '%s r%s, %s' % (alu_ops[op.sel], op.dreg, op.imm) if op.sel == opcodes.ALU_SEL_MOV |
27 | | - else '%s r%s, r%s, %s' % (alu_ops[op.sel], op.dreg, op.sreg, op.imm) |
28 | | - ), |
29 | | - opcodes.SUB_OPCODE_ALU_REG: ( |
30 | | - 'ALU_REG', |
31 | | - opcodes._alu_reg, |
32 | | - lambda op: '%s r%s, r%s' % (alu_ops[op.sel], op.dreg, op.sreg) if op.sel == opcodes.ALU_SEL_MOV |
33 | | - else '%s r%s, r%s, r%s' % (alu_ops[op.sel], op.dreg, op.sreg, op.treg) |
34 | | - ), |
35 | | - }), |
36 | | - opcodes.OPCODE_BRANCH: ('BRANCH', opcodes._bx, { |
37 | | - opcodes.SUB_OPCODE_BX: ( |
38 | | - 'BX', |
39 | | - opcodes._bx, |
40 | | - lambda op: 'JUMP %s%s' % (op.addr if op.reg == 0 else 'r%s' % op.dreg, ', %s' % jump_types[op.type] |
41 | | - if op.type != 0 else '') |
42 | | - ), |
43 | | - opcodes.SUB_OPCODE_BR: ( |
44 | | - 'BR', |
45 | | - opcodes._br, |
46 | | - lambda op: 'JUMPR %s, %s, %s' % ('%s%s' % ('-' if op.sign == 1 else '', op.offset), op.imm, cmp_ops[op.cmp]) |
47 | | - ), |
48 | | - opcodes.SUB_OPCODE_BS: ( |
49 | | - 'BS', |
50 | | - opcodes._bs, |
51 | | - lambda op: 'JUMPS %s, %s, %s' % ('%s%s' % ('-' if op.sign == 1 else '', op.offset), op.imm, cmp_ops[op.cmp]) |
52 | | - ), |
53 | | - }), |
54 | | - opcodes.OPCODE_DELAY: ( |
55 | | - 'DELAY', |
56 | | - opcodes._delay, |
57 | | - lambda op: 'NOP' if op.cycles == 0 else 'WAIT %s' % op.cycles |
58 | | - ), |
59 | | - opcodes.OPCODE_END: ('END', opcodes._end, { |
60 | | - opcodes.SUB_OPCODE_END: ( |
61 | | - 'WAKE', |
62 | | - opcodes._end |
63 | | - ), |
64 | | - opcodes.SUB_OPCODE_SLEEP: ( |
65 | | - 'SLEEP', |
66 | | - opcodes._sleep, |
67 | | - lambda op: 'SLEEP %s' % op.cycle_sel |
68 | | - ), |
69 | | - }), |
70 | | - opcodes.OPCODE_HALT: ('HALT', opcodes._halt), |
71 | | - opcodes.OPCODE_I2C: ( |
72 | | - 'I2C', |
73 | | - opcodes._i2c, |
74 | | - lambda op: 'I2C_%s %s, %s, %s, %s' % ('RD' if op.rw == 0 else 'WR', op.sub_addr, op.high, op.low, op.i2c_sel) |
75 | | - ), |
76 | | - opcodes.OPCODE_LD: ('LD', opcodes._ld, lambda op: 'LD r%s, r%s, %s' % (op.dreg, op.sreg, op.offset)), |
77 | | - opcodes.OPCODE_ST: ('ST', opcodes._st, lambda op: 'ST r%s, r%s, %s' % (op.sreg, op.dreg, op.offset)), |
78 | | - opcodes.OPCODE_RD_REG: ( |
79 | | - 'RD_REG', |
80 | | - opcodes._rd_reg, |
81 | | - lambda op: 'REG_RD 0x%x, %s, %s' % (op.periph_sel << 8 | op.addr, op.high, op.low) |
82 | | - ), |
83 | | - opcodes.OPCODE_WR_REG: ( |
84 | | - 'WR_REG', |
85 | | - opcodes._wr_reg, |
86 | | - lambda op: 'REG_WR 0x%x, %s, %s, %s' % (op.periph_sel << 8 | op.addr, op.high, op.low, op.data) |
87 | | - ), |
88 | | - opcodes.OPCODE_TSENS: ('TSENS', opcodes._tsens, lambda op: 'TSENS r%s, %s' % (op.dreg, op.delay)), |
89 | | -} |
90 | | - |
91 | | - |
92 | | -def decode_instruction(i): |
93 | | - if i == 0: |
94 | | - raise Exception('<empty>') |
95 | | - |
96 | | - ins = opcodes._end |
97 | | - ins.all = i # abuse a struct to get opcode |
98 | | - |
99 | | - params = lookup.get(ins.opcode, None) |
100 | | - |
101 | | - if not params: |
102 | | - raise Exception('Unknown instruction') |
103 | | - |
104 | | - if len(params) == 3: |
105 | | - name, ins, third = params |
106 | | - ins.all = i |
107 | | - |
108 | | - if callable(third): |
109 | | - params = (third(ins), ins) |
110 | | - else: |
111 | | - params = third.get(ins.sub_opcode, ()) |
112 | | - |
113 | | - if len(params) == 3: |
114 | | - name, ins, pretty = params |
115 | | - ins.all = i |
116 | | - name = pretty(ins) |
117 | | - else: |
118 | | - name, ins = params |
119 | | - ins.all = i |
120 | | - |
121 | | - return ins, name |
122 | | - |
123 | | - |
124 | | -def get_instruction_fields(ins): |
125 | | - possible_fields = ( |
126 | | - 'addr', 'cmp', 'cycle_sel', 'cycles', 'data', 'delay', 'dreg', |
127 | | - 'high', 'i2c_sel', 'imm', 'low', 'mux', 'offset', 'opcode', |
128 | | - 'periph_sel', 'reg', 'rw', 'sar_sel', 'sel', 'sign', 'sreg', |
129 | | - 'sub_addr', 'sub_opcode', 'treg', 'type', 'unused', 'unused1', |
130 | | - 'unused2', 'wakeup' |
131 | | - ) |
132 | | - field_details = [] |
133 | | - for field in possible_fields: |
134 | | - extra = '' |
135 | | - try: |
136 | | - # eval is ugly but constrained to possible_fields and variable ins |
137 | | - val = eval('i.%s' % field, {}, {'i': ins}) |
138 | | - if (val>9): |
139 | | - extra = ' (0x%02x)' % val |
140 | | - except KeyError: |
141 | | - continue |
142 | | - |
143 | | - if field == 'sel': # ALU |
144 | | - if ins.sub_opcode == opcodes.SUB_OPCODE_ALU_CNT: |
145 | | - extra = ' (%s)' % alu_cnt_ops[val] |
146 | | - else: |
147 | | - extra = ' (%s)' % alu_ops[val] |
148 | | - elif field == 'type': # JUMP |
149 | | - extra = ' (%s)' % jump_types[val] |
150 | | - elif field == 'cmp': # JUMPR/JUMPS |
151 | | - extra = ' (%s)' % cmp_ops[val] |
152 | | - |
153 | | - field_details.append((field, val, extra)) |
154 | | - |
155 | | - return field_details |
156 | | - |
157 | | - |
158 | 7 | def chunk_into_words(code, bytes_per_word, byteorder): |
159 | 8 | chunks = [ |
160 | 9 | ubinascii.hexlify(code[i:i + bytes_per_word]) |
|
0 commit comments