7#ifndef PRINTLINES_ALLOWED
8#define PRINTLINES_ALLOWED 0
11static const char *FNAME =
"kest_asm_parser.c";
13#define CH_DELIMITER 'c'
14#define KEST_EXPR_DELIMITER "["
15#define RS_DELIMITER "$"
16#define DQ_CODELIMITER "]"
20static const char *instrs [] = {
21 "nop",
"mov",
"add",
"sub",
"mul",
22 "madd",
"arsh",
"lsh",
"rsh",
"abs",
23 "min",
"max",
"clamp",
"mov_acc",
24 "macz",
"umacz",
"mac",
"umac",
25 "delay_read",
"delay_write",
"delay_mwrite",
26 "mem_read",
"mem_write",
"filter",
30static const int n_instrs =
sizeof(instrs) /
sizeof(instrs[0]);
176 if (!instr)
return NULL;
178 if (strcmp(instr,
"nop" ) == 0)
return &arg_format_std_0;
179 if (strcmp(instr,
"mov" ) == 0)
return &arg_format_std_1;
180 if (strcmp(instr,
"add" ) == 0)
return &arg_format_add;
181 if (strcmp(instr,
"sub" ) == 0)
return &arg_format_std_2;
182 if (strcmp(instr,
"mul" ) == 0)
return &arg_format_std_2;
183 if (strcmp(instr,
"madd" ) == 0)
return &arg_format_std_3;
184 if (strcmp(instr,
"arsh" ) == 0)
return &arg_format_shift;
185 if (strcmp(instr,
"lsh" ) == 0)
return &arg_format_shift;
186 if (strcmp(instr,
"rsh" ) == 0)
return &arg_format_shift;
187 if (strcmp(instr,
"abs" ) == 0)
return &arg_format_std_1;
188 if (strcmp(instr,
"min" ) == 0)
return &arg_format_std_2;
189 if (strcmp(instr,
"max" ) == 0)
return &arg_format_std_2;
190 if (strcmp(instr,
"clamp" ) == 0)
return &arg_format_std_3;
191 if (strcmp(instr,
"mov_acc" ) == 0)
return &arg_format_read;
192 if (strcmp(instr,
"macz" ) == 0)
return &arg_format_mac;
193 if (strcmp(instr,
"umacz" ) == 0)
return &arg_format_mac;
194 if (strcmp(instr,
"mac" ) == 0)
return &arg_format_mac;
195 if (strcmp(instr,
"umac" ) == 0)
return &arg_format_mac;
196 if (strcmp(instr,
"delay_read" ) == 0)
return &arg_format_res_read;
197 if (strcmp(instr,
"delay_write" ) == 0)
return &arg_format_res_write;
198 if (strcmp(instr,
"delay_mwrite") == 0)
return &arg_format_res_write_2;
199 if (strcmp(instr,
"mem_read" ) == 0)
return &arg_format_res_read;
200 if (strcmp(instr,
"mem_write" ) == 0)
return &arg_format_res_write;
201 if (strcmp(instr,
"filter" ) == 0)
return &arg_format_res_rw;
202 if (strcmp(instr,
"tanh4" ) == 0)
return &arg_format_std_1;
203 if (strcmp(instr,
"sin2pi" ) == 0)
return &arg_format_std_1;
250 kest_dsp_resource_pll *current_res;
258 if (!current || !current->
data)
261 goto asm_parse_arg_fin;
270 for (
int i = 1; current->
data[i] != 0; i++)
275 if (
'0' <= current->
data[i] && current->
data[i] <=
'9')
277 n = 10 * n + current->
data[i] -
'0';
279 else if (
'a' <= current->
data[i] && current->
data[i] <=
'f')
281 n = 16 * n + current->
data[i] -
'a' + 10;
283 else if (
'A' <= current->
data[i] && current->
data[i] <=
'F')
285 n = 16 * n + current->
data[i] -
'A' + 10;
296 goto asm_parse_arg_fin;
300 if (arg) arg->
addr = n;
312 if (!tok || strcmp(tok->
data,
"\n") == 0)
316 goto asm_parse_arg_fin;
327 goto asm_parse_arg_fin;
340 current = current->
next;
342 if (!current || !current->
data || strcmp(current->
data,
"\n") == 0)
346 goto asm_parse_arg_fin;
352 while (current_res && !resource_found)
354 if (current_res->data && current_res->data->name)
356 if (strcmp(current->
data, current_res->data->name) == 0)
359 if (arg) arg->
res = current_res->
data;
363 current_res = current_res->next;
366 if (resource_found && arg)
374 goto asm_parse_arg_fin;
382 arg->
val = strtol(current->
data, NULL, 10);
389 goto asm_parse_arg_fin;
395 current = current->
next;
412 kest_dsp_resource_pll *current_res;
421 if (!current || !current->
data)
424 goto asm_parse_arg_fin;
433 for (
int i = 1; current->
data[i] != 0; i++)
438 if (
'0' <= current->
data[i] && current->
data[i] <=
'9')
440 n = 10 * n + current->
data[i] -
'0';
442 else if (
'a' <= current->
data[i] && current->
data[i] <=
'f')
444 n = 16 * n + current->
data[i] -
'a' + 10;
446 else if (
'A' <= current->
data[i] && current->
data[i] <=
'F')
448 n = 16 * n + current->
data[i] -
'A' + 10;
459 goto asm_parse_arg_fin;
478 if (!tok || strcmp(tok->
data,
"\n") == 0)
482 goto asm_parse_arg_fin;
493 goto asm_parse_arg_fin;
506 current = current->
next;
508 if (!current || !current->
data || strcmp(current->
data,
"\n") == 0)
512 goto asm_parse_arg_fin;
533 goto asm_parse_arg_fin;
539 current = current->
next;
551 for (
int i = 0; i < n_instrs; i++)
552 if (strcmp(instrs[i], instr) == 0)
return 1;
577 int line_number = current->
line;
579 KEST_PRINTF(
"Parsing asm line, line %d: \"%s\"\n", line_number, ps->
lines[line_number - 1]);
583 const char *instr_char = current->
data;
597 goto asm_line_parse_fin;
606 goto asm_line_parse_fin;
617 goto asm_line_parse_fin;
620 current = current->
next;
623 for (
int i = 0; ; i++)
625 if (!current || !current->
data || current->
data[0] ==
'\n' || current->
line != line_number)
632 if (current->
data[0] ==
'\n')
634 if (current->
line != line_number)
635 KEST_PRINTF(
"current token is on line %d, instead of %d\n", current->
line, line_number);
642 ret_val = arg_ret_val;
643 goto asm_line_parse_fin;
677 kest_asm_line_pll_safe_append(&ps->
asm_lines, line);
680 if (strcmp(current->
data,
"nop") == 0)
690 else if (strcmp(current->
data,
"mov") == 0)
701 else if (strcmp(current->
data,
"add") == 0)
710 else if (strcmp(current->
data,
"sub") == 0)
718 else if (strcmp(current->
data,
"mul") == 0)
727 else if (strcmp(current->
data,
"madd") == 0)
735 else if (strcmp(current->
data,
"arsh") == 0)
745 else if (strcmp(current->
data,
"lsh") == 0)
753 else if (strcmp(current->
data,
"rsh") == 0)
761 else if (strcmp(current->
data,
"abs") == 0)
768 else if (strcmp(current->
data,
"min") == 0)
772 else if (strcmp(current->
data,
"max") == 0)
776 else if (strcmp(current->
data,
"clamp") == 0)
784 else if (strcmp(current->
data,
"mov_acc") == 0)
793 else if (strcmp(current->
data,
"mov_lacc") == 0)
802 else if (strcmp(current->
data,
"mov_uacc") == 0)
811 else if (strcmp(current->
data,
"macz") == 0)
820 else if (strcmp(current->
data,
"macz_noshift") == 0)
828 else if (strcmp(current->
data,
"umacz") == 0)
838 else if (strcmp(current->
data,
"umacz_noshift") == 0)
849 else if (strcmp(current->
data,
"macz_unsat") == 0)
859 else if (strcmp(current->
data,
"macz_unsat_noshift") == 0)
871 else if (strcmp(current->
data,
"umacz_unsat") == 0)
881 else if (strcmp(current->
data,
"umacz_unsat_noshift") == 0)
893 else if (strcmp(current->
data,
"mac") == 0)
902 else if (strcmp(current->
data,
"mac_noshift") == 0)
913 else if (strcmp(current->
data,
"umac") == 0)
922 else if (strcmp(current->
data,
"umac_noshift") == 0)
933 else if (strcmp(current->
data,
"mac_unsat") == 0)
943 else if (strcmp(current->
data,
"mac_unsat_noshift") == 0)
955 else if (strcmp(current->
data,
"umac_unsat") == 0)
965 else if (strcmp(current->
data,
"umac_unsat_noshift") == 0)
977 else if (strcmp(current->
data,
"delay_read") == 0)
987 else if (strcmp(current->
data,
"delay_write") == 0)
1001 else if (strcmp(current->
data,
"delay_mwrite") == 0)
1008 n_args_expected = 3;
1010 else if (strcmp(current->
data,
"mem_read") == 0)
1018 n_args_expected = 2;
1020 else if (strcmp(current->
data,
"mem_write") == 0)
1028 n_args_expected = 2;
1034 goto asm_line_parse_fin;
1040 shift_pos = dest_pos;
1042 if (arg_a_pos > shift_pos)
1043 shift_pos = arg_a_pos;
1044 if (arg_b_pos > shift_pos)
1045 shift_pos = arg_b_pos;
1046 if (arg_c_pos > shift_pos)
1047 shift_pos = arg_c_pos;
1048 if (arg_c_pos > res_pos)
1049 shift_pos = arg_c_pos;
1054 current = current->
next;
1058 for (
int i = 0; ; i++)
1060 if (!current || !current->
data || current->
data[0] ==
'\n')
1066 ret_val = arg_ret_val;
1067 goto asm_line_parse_fin;
1075 if (n_args_read < n_args_expected)
1077 KEST_PRINTF(
"Error: too few arguments for instruction \"%s\" (expected %d, given %d)\n", instr_char, n_args_expected, n_args_read);
1079 goto asm_line_parse_fin;
1081 else if (n_args_read > n_args_expected)
1083 KEST_PRINTF(
"Error: too many arguments for instruction \"%s\" (expected %d, given %d)\n", instr_char, n_args_expected, n_args_read);
1085 goto asm_line_parse_fin;
1092 KEST_PRINTF(
"Error: destination must be a channel\n");
1094 goto asm_line_parse_fin;
1102 if (shift_pos != -1)
1104 if (args[shift_pos].type !=
KEST_ASM_ARG_INT || args[shift_pos].val < 0 || args[shift_pos].val > 15)
1106 KEST_PRINTF(
"Error: shift value must be an integer between 0 and 15\n");
1108 goto asm_line_parse_fin;
1112 block->
shift = args[shift_pos].
val;
1116 if (arg_a_pos != -1)
1118 switch (args[arg_a_pos].type)
1135 KEST_PRINTF(
"Error: wrong type given for arg a\n");
1140 if (arg_b_pos != -1)
1142 switch (args[arg_b_pos].type)
1171 KEST_PRINTF(
"Error: wrong type given for arg b\n");
1173 goto asm_line_parse_fin;
1178 if (arg_c_pos != -1)
1180 switch (args[arg_c_pos].type)
1197 else if (!reg_1_taken)
1209 goto asm_line_parse_fin;
1214 KEST_PRINTF(
"Error: wrong type given for arg c\n");
1216 goto asm_line_parse_fin;
1225 KEST_PRINTF(
"Error: resource must be a resource\n");
1227 goto asm_line_parse_fin;
1231 block->
res = args[res_pos].
res;
1237 kest_block_pll_safe_append(&ps->
blocks, block);
1281 if (!resources || !name)
1284 kest_dsp_resource_pll *current = resources;
1288 if (current->data && current->data->name && strcmp(current->data->name, name) == 0)
1289 return current->data;
1291 current = current->next;
1316 "Instruction \"%s\" expects %d arguments, but %d were given.", line->
instr, arg_format->
n_args, line->
n_args);
1332 int reg_0_taken = 0;
1334 for (
int i = 0; i < line->
n_args; i++)
1336 arg = line->
args[i];
1348 else if (i == arg_format->
res_pos)
1381 block->
res = resource;
1415 kest_parser_error_at_line(ps, line_number,
"Argument %d of instruction \"%s\" does not correspond to anything (this is a bug!!)", i + 1, line->
instr);
1456 if (strcmp(line->
instr,
"mov") == 0)
1461 else if (strcmp(line->
instr,
"add") == 0)
1465 else if (strcmp(line->
instr,
"sub") == 0)
1469 else if (strcmp(line->
instr,
"mul") == 0)
1473 else if (strcmp(line->
instr,
"delay_write") == 0)
1477 else if (strcmp(line->
instr,
"sin2pi") == 0)
1481 else if (strcmp(line->
instr,
"tanh4") == 0)
1486 kest_block_pll_safe_append(&ps->
blocks, block);
1499 kest_asm_line_pll *current = ps->
asm_lines;
1504 KEST_PRINTF(
"kest_process_asm_lines, line %d\n", i);
1506 current = current->next; i++;
void * kest_alloc(size_t size)
kest_dsp_resource * kest_resource_get_by_name(kest_dsp_resource_pll *resources, const char *name)
int kest_parse_asm(kest_eff_parsing_state *ps)
int kest_process_asm_line(kest_eff_parsing_state *ps, kest_asm_line *line)
const kest_arg_format * kest_instr_arg_format(const char *instr)
int kest_instr_opcode(const char *instr)
#define KEST_EXPR_DELIMITER
int kest_parse_asm_line(kest_eff_parsing_state *ps)
int kest_parse_asm_arg_2(kest_eff_parsing_state *ps, kest_asm_arg *arg)
int kest_parse_asm_arg(kest_eff_parsing_state *ps, kest_asm_operand *arg)
int is_valid_instr(const char *instr)
int kest_process_asm_lines(kest_eff_parsing_state *ps)
#define KEST_ASM_ARG_EXPR
#define KEST_ASM_ARG_CHANNEL
#define KEST_ARG_POS_NONE
kest_block_operand operand_const_one()
kest_block_operand operand_const_minus_one()
kest_block_operand operand_const_zero()
#define BLOCK_INSTR_MEM_WRITE
#define BLOCK_INSTR_DELAY_WRITE
#define BLOCK_OPERAND_TYPE_C
#define BLOCK_INSTR_UMACZ
#define BLOCK_OPERAND_TYPE_R
#define BLOCK_INSTR_DELAY_READ
#define BLOCK_INSTR_MOV_ACC
#define BLOCK_INSTR_CLAMP
#define BLOCK_INSTR_MOV_UACC
#define BLOCK_INSTR_FILTER
#define BLOCK_INSTR_MEM_READ
#define ZERO_REGISTER_ADDR
#define BLOCK_INSTR_MOV_LACC
#define BLOCK_INSTR_LUT_READ
char * kest_parser_strndup(const char *str, int n)
void * kest_parser_alloc(size_t size)
void kest_parser_error_at_line(kest_eff_parsing_state *ps, int line, const char *msg,...)
void kest_parser_error_at(kest_eff_parsing_state *ps, kest_token_ll *token, const char *msg,...)
const char * kest_error_code_to_string(int error_code)
kest_expression * kest_parse_expression(kest_eff_parsing_state *ps, kest_token_ll *tokens, kest_token_ll *tokens_end)
kest_expression * new_m_expression_reference(char *ref_name)
kest_expression * new_m_expression_const(float v)
const char * kest_expression_to_string(kest_expression *expr)
float kest_expression_evaluate(kest_expression *expr, kest_expr_scope *scope)
#define IMPLEMENT_LINKED_PTR_LIST(X)
kest_dsp_resource sin_lut
kest_dsp_resource tanh_lut
int token_is_int(char *token)
float token_to_float(char *token)
int kest_token_ll_skip_ws(kest_token_ll **list)
struct kest_expression * expr
kest_asm_arg args[INSTR_MAX_ARGS]
struct kest_expression * expr
kest_token_ll * current_token
kest_dsp_resource_pll * resources
struct kest_asm_line_pll * asm_lines
union kest_expression::@166010055114121035173062362142367362353107353142 val
struct kest_token_ll * next