-
Notifications
You must be signed in to change notification settings - Fork 1
/
avr_op_decoder.jinja
86 lines (73 loc) · 2.24 KB
/
avr_op_decoder.jinja
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/* Autogenerated file, do not edit */
#include <stdint.h>
#include <stdbool.h>
#include "avr_op_decoder.h"
{% macro unpack_operand(op_spec) %}
{% for run in op_spec %}
{{ '((opcode & 0x%04x) >> %d)' % (run.mask, run.rshift) }}{% if not loop.last %} | {% endif %}
{%- endfor %}
{% endmacro %}
static const char *instr_names[] =
{
"undefined",
{% for opcode in oplist %}
"{{ opcode.instr }}",
{% endfor %}
};
//--- instruction name getters
const char *avr_get_instr_name_by_id(avr_instr_t id)
{
if (id < {{ oplist|length + 1 }})
return instr_names[id];
return "?";
}
//--- instruction decoders
static void decode_undefined(avr_operands_t *result, uint16_t opcode)
{
}
{% for opcode in oplist %}
static void decode_{{ opcode.instr }}(avr_operands_t *result, uint16_t opcode)
{
{% for op in opcode.operands %}
{% set var = operand_map[op] %}
result->{{ var }} = {{ unpack_operand(opcode.unpackers[op]) }};
{% if op == 'l' %}
result->{{ var }} = ((int) result->{{ var }} << 25) >> 25;
{% elif op == 'L' %}
result->{{ var }} = ((int) result->{{ var }} << 20) >> 20;
{% elif op == 'R' or op == 'D' %}
result->{{ var }} += 16;
{% elif op == 'w' %}
result->{{ var }} += 12;
{% endif %}
{% endfor %}
}
{% endfor %}
//--- instruction matcher
avr_instr_t avr_decode(avr_operands_t *result, uint16_t op)
{
static void (* const unpackers[{{ oplist|length + 1 }}])(avr_operands_t *, uint16_t) =
{
decode_undefined,
{% for rows in oplist|batch(8) %}
{%+ for opcode in rows %}decode_{{ opcode.instr }}, {% endfor %}
{% endfor %}
};
static const uint8_t lut0[{{ lut0|length }}] =
{
{% for rows in lut0|dictsort|batch(16) %}
{%+ for i, hash_idx in rows %}{{ hash_idx }}, {% endfor %}
{% endfor %}
};
static const uint8_t lut1[{{ lut1|length }}][{{ lut1[0]|length }}] =
{
{% for idx0, hash in lut1|dictsort %}
{ {% for idx1, instr in hash|dictsort %}{{ instr }}{% if not loop.last %}, {% endif -%}{% endfor %}},
{% endfor %}
};
int hash = lut0[op >> {{ 16 - nmsbits }}];
int instr = lut1[hash][op & {{ '0x%X' % (2 ** (16 - nmsbits) - 1) }}];
if (result)
unpackers[instr](result, op);
return instr;
}