/* A Bison parser, made by GNU Bison 2.4.2. */
/* Skeleton implementation for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* C LALR(1) parser skeleton written by Richard Stallman, by
simplifying the original so-called "semantic" parser. */
/* All symbols defined below should begin with yy or YY, to avoid
infringing on user name space. This should be done even for local
variables, as they might otherwise be expanded by user macros.
There are some unavoidable exceptions within include files to
define necessary library symbols; they are noted "INFRINGES ON
USER NAME SPACE" below. */
/* Identify Bison output. */
#define YYBISON 1
/* Bison version. */
#define YYBISON_VERSION "2.4.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
/* Pure parsers. */
#define YYPURE 1
/* Push parsers. */
#define YYPUSH 0
/* Pull parsers. */
#define YYPULL 1
/* Using locations. */
#define YYLSP_NEEDED 0
/* Substitute the variable and function names. */
#define yyparse _fmsp_assembler_yyparse
#define yylex _fmsp_assembler_yylex
#define yyerror _fmsp_assembler_yyerror
#define yylval _fmsp_assembler_yylval
#define yychar _fmsp_assembler_yychar
#define yydebug _fmsp_assembler_yydebug
#define yynerrs _fmsp_assembler_yynerrs
/* Copy the first part of user declarations. */
/* Line 189 of yacc.c */
#line 14 "fm_sp_assembler.y"
#ifndef _MSC_VER
#include /* For standard int types and print format macros */
#include /* For the bool type */
#endif
#include /* For errno */
#include /* For strtoull */
#ifdef _MSC_VER
#define _STDLIB_H
#endif
#include /* For strdup */
#include "fm_sp_private.h"
#ifdef _MSC_VER
#pragma warning(disable : 4996)
#endif
/* ---------------------------------------------------------------------------
* Some defines that will make the grammar easier to read
* ---------------------------------------------------------------------------*/
/* An action that take no parameters other than the context. */
#define _FMSP_PROC_TOK_P0(action_ok) \
if (!action_ok(_fmsp_assembler_context_p)) \
{ \
return (1); \
}
/* An action that takes the context and 1 parameter that must be freed
* (lexical analyzer allocated the memory while collecting tokens).
*/
#define _FMSP_PROC_TOK_P1(action_ok, p1) \
if (!action_ok(_fmsp_assembler_context_p, p1)) \
{ \
free p1; \
return (1); \
} \
free p1;
/* An action that takes the context and 2 parameters that must be freed
* (lexical analyzer allocated the memory while collecting tokens).
*/
#define _FMSP_PROC_TOK_P2(action_ok, p1, p2) \
if (!action_ok(_fmsp_assembler_context_p, p1, p2)) \
{ \
free p1; \
free p2; \
return (1); \
} \
free p1; \
free p2;
/* An action that takes the context and 3 parameters that must be freed
* (lexical analyzer allocated the memory while collecting tokens).
*/
#define _FMSP_PROC_TOK_P3(action_ok, p1, p2, p3) \
if (!action_ok(_fmsp_assembler_context_p, p1, p2, p3)) \
{ \
free p1; \
free p2; \
free p3; \
return (1); \
} \
free p1; \
free p2; \
free p3;
/* An action that takes the context and 4 parameters that must be freed
* (lexical analyzer allocated the memory while collecting tokens).
*/
#define _FMSP_PROC_TOK_P4(action_ok, p1, p2, p3, p4) \
if (!action_ok(_fmsp_assembler_context_p, p1, p2, p3, p4)) \
{ \
free p1; \
free p2; \
free p3; \
free p4; \
return (1); \
} \
free p1; \
free p2; \
free p3; \
free p4;
/* An action that takes the context and 5 parameters that must be freed
* (lexical analyzer allocated the memory while collecting tokens).
*/
#define _FMSP_PROC_TOK_P5(action_ok, p1, p2, p3, p4, p5) \
if (!action_ok(_fmsp_assembler_context_p, p1, p2, p3, p4, p5)) \
{ \
free p1; \
free p2; \
free p3; \
free p4; \
free p5; \
return (1); \
} \
free p1; \
free p2; \
free p3; \
free p4; \
free p5;
/* ---------------------------------------------------------------------------
* Constants
* ---------------------------------------------------------------------------*/
#define MAX_RA_DECIMAL_INDEX_SIZE 3
#define MAX_RESULT_ARRAY_BYTE_INDEX 0x7f
#define MAX_PARAMETER_ARRAY_BYTE_INDEX 0x3f
#define MAX_FRAME_WINDOW_BYTE_INDEX 0x0f
#define MAX_FRAME_WINDOW_BIT_INDEX 0x7f
/* ---------------------------------------------------------------------------
* Lexical Analyzer declarations
* ---------------------------------------------------------------------------*/
int _fmsp_assembler_yylex (void *lval_p,
_fmsp_assembler_parser_context_t *context_p);
/* ---------------------------------------------------------------------------
* Action declarations
* ---------------------------------------------------------------------------*/
/* ---------------------------------------------------------------------------
* Action for label
*
* Parameters:
* ctx_p - Parse context
* str_p - String containing label name.
*
* Returns:
* Bool - True means action succeeded.
* False means action did not succeed.
* ---------------------------------------------------------------------------*/
static bool _fmsp_label_action(_fmsp_assembler_parser_context_t *ctx_p,
char *str_p)
{
_fmsp_label_t *label_p;
_fmsp_assembler_instruction_t *instr_p;
char *full_label_p;
/* The context holds a hash table for all labels. Each label object
* in the hash table holds the program counter for the instruction
* which follows the label.
*/
/* Build the label name */
full_label_p = (char *)calloc(strlen(str_p) + 1, 1);
if (full_label_p == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
free (full_label_p); /* ROEE fixed mem leak*/
return (false);
}
strcat(full_label_p, str_p);
/* Store label in a hash table */
label_p = _fmsp_new_label(full_label_p,
ctx_p->next_program_counter);
if (label_p == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate label object.");
free (full_label_p); /* ROEE fixed mem leak*/
return (false);
}
if (!htbl_insert(ctx_p->label_table_p,
&(label_p->htbl_entry)))
{
_fmsp_destroy_label(label_p);
_fmsp_assembler_yyerror(ctx_p,
"Label already exists.");
free (full_label_p); /* ROEE fixed mem leak*/
return (false);
}
instr_p = _fmsp_new_instruction(_fmsp_assembler_label_e,
ctx_p);
if (instr_p == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate instruction object.");
free (full_label_p); /* ROEE fixed mem leak*/
return (false);
}
/* Label is just a place holder, not an actual instruction. */
instr_p->num_valid_hw_words = 0;
instr_p->jump_label1_p = strdup(str_p);
dll_add_to_back(&(ctx_p->instruction_list),
&(instr_p->dll_node));
/* Clear context values */
_fmsp_clear_ctx_instruction_values(ctx_p);
free (full_label_p); /* ROEE fixed mem leak*/
return (true);
}
/* ---------------------------------------------------------------------------
* Action for five words
*
* Parameters:
* ctx_p - Parse context
* str1_p - String containing hex value
* str2_p - String containing hex value
* str3_p - String containing hex value
* str4_p - String containing hex value
* str5_p - String containing hex value
*
* Returns:
* Bool - True means action succeeded.
* False means action did not succeed.
* ---------------------------------------------------------------------------*/
static bool _fmsp_five_hex_words_action(_fmsp_assembler_parser_context_t *ctx_p,
char *str1_p,
char *str2_p,
char *str3_p,
char *str4_p,
char *str5_p)
{
ctx_p->raw_str_p[0] = strdup(str1_p);
ctx_p->raw_str_p[1] = strdup(str2_p);
ctx_p->raw_str_p[2] = strdup(str3_p);
ctx_p->raw_str_p[3] = strdup(str4_p);
ctx_p->raw_str_p[4] = strdup(str5_p);
if (ctx_p->raw_str_p[0] == NULL ||
ctx_p->raw_str_p[1] == NULL ||
ctx_p->raw_str_p[2] == NULL ||
ctx_p->raw_str_p[3] == NULL ||
ctx_p->raw_str_p[4] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
return (false);
}
ctx_p->num_immediate_values = 4;
return (true);
}
/* ---------------------------------------------------------------------------
* Action for four words
*
* Parameters:
* ctx_p - Parse context
* str1_p - String containing hex value
* str2_p - String containing hex value
* str3_p - String containing hex value
* str4_p - String containing hex value
*
* Returns:
* Bool - True means action succeeded.
* False means action did not succeed.
* ---------------------------------------------------------------------------*/
static bool _fmsp_four_hex_words_action(_fmsp_assembler_parser_context_t *ctx_p,
char *str1_p,
char *str2_p,
char *str3_p,
char *str4_p)
{
ctx_p->raw_str_p[0] = strdup(str1_p);
ctx_p->raw_str_p[1] = strdup(str2_p);
ctx_p->raw_str_p[2] = strdup(str3_p);
ctx_p->raw_str_p[3] = strdup(str4_p);
if (ctx_p->raw_str_p[0] == NULL ||
ctx_p->raw_str_p[1] == NULL ||
ctx_p->raw_str_p[2] == NULL ||
ctx_p->raw_str_p[3] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
return (false);
}
ctx_p->num_immediate_values = 3;
return (true);
}
/* ---------------------------------------------------------------------------
* Action for three words
*
* Parameters:
* ctx_p - Parse context
* str1_p - String containing hex value
* str2_p - String containing hex value
* str3_p - String containing hex value
*
* Returns:
* Bool - True means action succeeded.
* False means action did not succeed.
* ---------------------------------------------------------------------------*/
static bool _fmsp_three_hex_words_action(_fmsp_assembler_parser_context_t *ctx_p,
char *str1_p,
char *str2_p,
char *str3_p)
{
ctx_p->raw_str_p[0] = strdup(str1_p);
ctx_p->raw_str_p[1] = strdup(str2_p);
ctx_p->raw_str_p[2] = strdup(str3_p);
if (ctx_p->raw_str_p[0] == NULL ||
ctx_p->raw_str_p[1] == NULL ||
ctx_p->raw_str_p[2] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
return (false);
}
ctx_p->num_immediate_values = 2;
return (true);
}
/* ---------------------------------------------------------------------------
* Action for two words
*
* Parameters:
* ctx_p - Parse context
* str1_p - String containing hex value
* str2_p - String containing hex value
*
* Returns:
* Bool - True means action succeeded.
* False means action did not succeed.
* ---------------------------------------------------------------------------*/
static bool _fmsp_two_hex_words_action(_fmsp_assembler_parser_context_t *ctx_p,
char *str1_p,
char *str2_p)
{
ctx_p->raw_str_p[0] = strdup(str1_p);
ctx_p->raw_str_p[1] = strdup(str2_p);
if (ctx_p->raw_str_p[0] == NULL ||
ctx_p->raw_str_p[1] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
return (false);
}
ctx_p->num_immediate_values = 1;
return (true);
}
/* ---------------------------------------------------------------------------
* Action for one word
*
* Parameters:
* ctx_p - Parse context
* str1_p - String containing hex value
*
* Returns:
* Bool - True means action succeeded.
* False means action did not succeed.
* ---------------------------------------------------------------------------*/
static bool _fmsp_one_hex_word_action(_fmsp_assembler_parser_context_t *ctx_p,
char *str1_p)
{
ctx_p->raw_str_p[0] = strdup(str1_p);
if (ctx_p->raw_str_p[0] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
return (false);
}
ctx_p->num_immediate_values = 0;
return (true);
}
/* ---------------------------------------------------------------------------
* Action for raw instruction
*
* Parameters:
* ctx_p - Parse context
*
* Returns:
* Bool - True means action succeeded.
* False means action did not succeed.
* ---------------------------------------------------------------------------*/
static bool _fmsp_raw_instruction_action(_fmsp_assembler_parser_context_t *ctx_p)
{
_fmsp_assembler_instruction_t *object_p;
uint32_t len;
int32_t count;
object_p = _fmsp_new_instruction(_fmsp_assembler_raw_e,
ctx_p);
if (object_p == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate instruction object.");
return (false);
}
for (count = 0; count < ctx_p->num_immediate_values + 1; count++)
{
len = strlen(ctx_p->raw_str_p[count]);
if (len > 0)
{
object_p->hw_words_str_p[count] = (char *)calloc(len + 1, 1);
if (object_p->hw_words_str_p[count] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
return (false);
}
strncpy(object_p->hw_words_str_p[count],
ctx_p->raw_str_p[count],
len);
object_p->hw_words_p[count] = (uint16_t)strtol(ctx_p->raw_str_p[count],
NULL,
0);
}
}
object_p->num_valid_hw_words = ctx_p->num_immediate_values + 1;
dll_add_to_back(&(ctx_p->instruction_list),
&(object_p->dll_node));
/* Clear context values */
_fmsp_clear_ctx_instruction_values(ctx_p);
return (true);
}
/* ---------------------------------------------------------------------------
* Action for jmp label
*
* Parameters:
* ctx_p - Parse context
* str_p - String containing label name.
* hxs - Header examination sequence?
*
* Returns:
* Bool - True means action succeeded.
* False means action did not succeed.
* ---------------------------------------------------------------------------*/
static bool _fmsp_jmp_label_action(_fmsp_assembler_parser_context_t *ctx_p,
char *str_p,
bool hxs)
{
_fmsp_assembler_instruction_t *object_p;
uint32_t len;
char hxs_bit_p[] = " | 0x400";
/* No immediate values for jump instruction */
ctx_p->num_immediate_values = 0;
object_p = _fmsp_new_instruction(_fmsp_assembler_jump_e,
ctx_p);
if (object_p == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate instruction object.");
return (false);
}
if (hxs)
{
len = strlen(_FMSP_INSTR_CODE_JUMP_STR) +
strlen(hxs_bit_p) +
1;
object_p->hw_words_str_p[0] = (char *)calloc(len + 1, 1);
if (object_p->hw_words_str_p[0] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
_fmsp_destroy_instruction(object_p);
return (false);
}
snprintf(object_p->hw_words_str_p[0],
len,
"%s%s",
_FMSP_INSTR_CODE_JUMP_STR,
hxs_bit_p);
object_p->hw_words_p[0] = _FMSP_INSTR_CODE_JUMP | _FMSP_INSTR_MOD_JMP_HXS;
}
else
{
len = strlen(_FMSP_INSTR_CODE_JUMP_STR) + 1;
object_p->hw_words_str_p[0] = (char *)calloc(len + 1, 1);
if (object_p->hw_words_str_p[0] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
_fmsp_destroy_instruction(object_p);
return (false);
}
snprintf(object_p->hw_words_str_p[0],
len,
"%s",
_FMSP_INSTR_CODE_JUMP_STR);
object_p->hw_words_p[0] = _FMSP_INSTR_CODE_JUMP;
}
object_p->hxs = hxs;
object_p->num_valid_hw_words = 1;
object_p->jump_label1_p = strdup(str_p);
if (object_p->jump_label1_p == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate label object.");
_fmsp_destroy_instruction(object_p);
return (false);
}
dll_add_to_back(&(ctx_p->instruction_list),
&(object_p->dll_node));
/* Clear context values */
_fmsp_clear_ctx_instruction_values(ctx_p);
return (true);
}
/* ---------------------------------------------------------------------------
* Action for jmp label if wr0 wr1
*
* Parameters:
* ctx_p - Parse context
* str_p - String containing label name.
* operator_p - Operator. (==, !=, <=, >=, <, >)
*
* Returns:
* Bool - True means action succeeded.
* False means action did not succeed.
* ---------------------------------------------------------------------------*/
static bool _fmsp_jmp_label_if_wr0_wr1_action(_fmsp_assembler_parser_context_t *ctx_p,
char *str_p,
uint16_t operator)
{
_fmsp_assembler_instruction_t *object_p;
uint32_t len;
char or_str_p[] = " | ";
/* 1 immediate value for jump destination. */
ctx_p->num_immediate_values = 1;
object_p = _fmsp_new_instruction(_fmsp_assembler_compare_working_regs_e,
ctx_p);
if (object_p == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate instruction object.");
return (false);
}
len = strlen(_FMSP_INSTR_CODE_COMPARE_WORKING_REGS_STR) +
strlen(or_str_p) +
6 + /* 0xNNNN */
1;
object_p->hw_words_str_p[0] = (char *)calloc(len + 1, 1);
if (object_p->hw_words_str_p[0] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
_fmsp_destroy_instruction(object_p);
return (false);
}
snprintf(object_p->hw_words_str_p[0],
len,
"%s%s0x%04x",
_FMSP_INSTR_CODE_COMPARE_WORKING_REGS_STR,
or_str_p,
operator);
/* HW opcode */
object_p->hw_words_p[0] = _FMSP_INSTR_CODE_COMPARE_WORKING_REGS | operator;
object_p->num_valid_hw_words = 2;
object_p->function = (uint8_t)operator;
object_p->jump_label1_p = strdup(str_p);
if (object_p->jump_label1_p == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate label object.");
_fmsp_destroy_instruction(object_p);
return (false);
}
dll_add_to_back(&(ctx_p->instruction_list),
&(object_p->dll_node));
/* Clear context values */
_fmsp_clear_ctx_instruction_values(ctx_p);
return (true);
}
/* ---------------------------------------------------------------------------
* Action for jmp label if wr0 immediate value
*
* Parameters:
* ctx_p - Parse context
* str_p - String containing label name.
* operator_p - Operator. (==, !=, <, >)
* iv_p - Immediate value.
*
* Returns:
* Bool - True means action succeeded.
* False means action did not succeed.
* ---------------------------------------------------------------------------*/
static bool _fmsp_jmp_label_if_wr0_iv_action(_fmsp_assembler_parser_context_t *ctx_p,
char *str_p,
uint16_t operator,
char *iv_p)
{
_fmsp_assembler_instruction_t *object_p;
char start_shift_str_p[] = " | (";
char end_shift_12_str_p[] = " << 12)";
char end_shift_10_str_p[] = " << 10)";
uint32_t len;
uint64_t immediate_value = 0;
uint16_t word_1;
uint16_t word_2;
uint16_t word_3;
uint16_t word_4;
uint8_t iv_word_size = 0;
/* Check if the immediate value starts with "0x". If it does then
* convert the value and base the number of immediate value words
* on that. Otherwise, this is a plan id enum which is 1 byte so
* only use 1 immediate value word.
*/
if (strncmp(iv_p, "0x", 2) == 0)
{
immediate_value = (uint64_t)strtoull(iv_p, NULL, 0);
if (immediate_value < 0x10000)
{
ctx_p->num_immediate_values = 1;
}
else if (immediate_value < 0x100000000ULL)
{
ctx_p->num_immediate_values = 2;
}
else if (immediate_value < 0x1000000000000ULL)
{
ctx_p->num_immediate_values = 3;
}
else
{
ctx_p->num_immediate_values = 4;
}
}
object_p = _fmsp_new_instruction(_fmsp_assembler_compare_wr0_to_iv_e,
ctx_p);
if (object_p == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate instruction object.");
return (false);
}
/* Set immediate values. */
if (strncmp(iv_p, "0x", 2) == 0)
{
len = 6 + /* 0xNNNN */
1;
word_1 = immediate_value & 0xffff;
word_2 = (immediate_value >> 16) & 0xffff;
word_3 = (immediate_value >> 32) & 0xffff;
word_4 = (immediate_value >> 48) & 0xffff;
if (immediate_value < 0x10000)
{
object_p->num_valid_hw_words = 2;
iv_word_size = 0;
object_p->hw_words_str_p[1] = (char *)calloc(len + 1, 1);
if (object_p->hw_words_str_p[1] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
_fmsp_destroy_instruction(object_p);
return (false);
}
snprintf(object_p->hw_words_str_p[1],
len,
"0x%04x",
word_1);
object_p->hw_words_p[1] = word_1;
}
else if (immediate_value < 0x100000000ULL)
{
object_p->num_valid_hw_words = 3;
iv_word_size = 1;
object_p->hw_words_str_p[1] = (char *)calloc(len + 1, 1);
object_p->hw_words_str_p[2] = (char *)calloc(len + 1, 1);
if (object_p->hw_words_str_p[1] == NULL ||
object_p->hw_words_str_p[2] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
_fmsp_destroy_instruction(object_p);
return (false);
}
snprintf(object_p->hw_words_str_p[1],
len,
"0x%04x",
word_1);
snprintf(object_p->hw_words_str_p[2],
len,
"0x%04x",
word_2);
object_p->hw_words_p[1] = word_1;
object_p->hw_words_p[2] = word_2;
}
else if (immediate_value < 0x1000000000000ULL)
{
object_p->num_valid_hw_words = 4;
iv_word_size = 2;
object_p->hw_words_str_p[1] = (char *)calloc(len + 1, 1);
object_p->hw_words_str_p[2] = (char *)calloc(len + 1, 1);
object_p->hw_words_str_p[3] = (char *)calloc(len + 1, 1);
if (object_p->hw_words_str_p[1] == NULL ||
object_p->hw_words_str_p[2] == NULL ||
object_p->hw_words_str_p[3] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
_fmsp_destroy_instruction(object_p);
return (false);
}
snprintf(object_p->hw_words_str_p[1],
len,
"0x%04x",
word_1);
snprintf(object_p->hw_words_str_p[2],
len,
"0x%04x",
word_2);
snprintf(object_p->hw_words_str_p[3],
len,
"0x%04x",
word_3);
object_p->hw_words_p[1] = word_1;
object_p->hw_words_p[2] = word_2;
object_p->hw_words_p[3] = word_3;
}
else
{
object_p->num_valid_hw_words = 5;
iv_word_size = 3;
object_p->hw_words_str_p[1] = (char *)calloc(len + 1, 1);
object_p->hw_words_str_p[2] = (char *)calloc(len + 1, 1);
object_p->hw_words_str_p[3] = (char *)calloc(len + 1, 1);
object_p->hw_words_str_p[4] = (char *)calloc(len + 1, 1);
if (object_p->hw_words_str_p[1] == NULL ||
object_p->hw_words_str_p[2] == NULL ||
object_p->hw_words_str_p[3] == NULL ||
object_p->hw_words_str_p[4] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
_fmsp_destroy_instruction(object_p);
return (false);
}
snprintf(object_p->hw_words_str_p[1],
len,
"0x%04x",
word_1);
snprintf(object_p->hw_words_str_p[2],
len,
"0x%04x",
word_2);
snprintf(object_p->hw_words_str_p[3],
len,
"0x%04x",
word_3);
snprintf(object_p->hw_words_str_p[4],
len,
"0x%04x",
word_4);
object_p->hw_words_p[1] = word_1;
object_p->hw_words_p[2] = word_2;
object_p->hw_words_p[3] = word_3;
object_p->hw_words_p[4] = word_4;
}
}
else
{
object_p->num_valid_hw_words = 2;
iv_word_size = 0;
len = strlen(iv_p) + 1;
object_p->hw_words_str_p[1] = (char *)calloc(len + 1, 1);
if (object_p->hw_words_str_p[1] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
_fmsp_destroy_instruction(object_p);
return (false);
}
snprintf(object_p->hw_words_str_p[1],
len,
"%s",
iv_p);
object_p->hw_words_p[1] = 0; /* Variable that must be filled in later */
}
/* Bit layout of this instruction:
*
* 01CC IIJJ JJJJ JJJJ
*
* C - Comparison operator
* I - Immediate value size (0, 1, 2, 3)
* J - Jump destination
*/
object_p->function = (uint8_t)operator;
len = strlen(_FMSP_INSTR_CODE_COMPARE_WR0_TO_IV_STR) +
strlen(start_shift_str_p) +
6 + /* 0xNNNN */
strlen(end_shift_12_str_p) +
strlen(start_shift_str_p) +
6 + /* 0xNNNN */
strlen(end_shift_10_str_p) +
1;
object_p->hw_words_str_p[0] = (char *)calloc(len + 1, 1);
if (object_p->hw_words_str_p[0] == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate string.");
_fmsp_destroy_instruction(object_p);
return (false);
}
snprintf(object_p->hw_words_str_p[0],
len,
"%s%s0x%04x%s%s0x%04x%s",
_FMSP_INSTR_CODE_COMPARE_WR0_TO_IV_STR,
start_shift_str_p,
operator,
end_shift_12_str_p,
start_shift_str_p,
iv_word_size,
end_shift_10_str_p
);
/* HW opcode */
object_p->hw_words_p[0] = _FMSP_INSTR_CODE_COMPARE_WR0_TO_IV |
(operator << 12) |
(iv_word_size << 10);
object_p->jump_label1_p = strdup(str_p);
if (object_p->jump_label1_p == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate label object.");
_fmsp_destroy_instruction(object_p);
return (false);
}
dll_add_to_back(&(ctx_p->instruction_list),
&(object_p->dll_node));
/* Clear context values */
_fmsp_clear_ctx_instruction_values(ctx_p);
return (true);
}
/* ---------------------------------------------------------------------------
* Action for case 1 default jump
*
* Parameters:
* ctx_p - Parse context
* str1_p - String containing label 1 name.
* str2_p - String containing label 2 name.
* hxs - Header examination sequence?
*
* Returns:
* Bool - True means action succeeded.
* False means action did not succeed.
* ---------------------------------------------------------------------------*/
static bool _fmsp_jmp_label_case1dj_action(_fmsp_assembler_parser_context_t *ctx_p,
char *str1_p,
char *str2_p,
bool hxs_1,
bool hxs_2)
{
_fmsp_assembler_instruction_t *object_p;
char or_str_p[] = " | ";
char hxs_1_not_set_str_p[] = " 0";
char hxs_2_not_set_str_p[] = " (0 << 1)";
char hxs_1_set_str_p[] = " 1";
char hxs_2_set_str_p[] = " (1 << 1)";
char *hxs_1_str_p;
char *hxs_2_str_p;
uint32_t len;
/* Set the number of immediate values this instruction will take. */
ctx_p->num_immediate_values = 2;
object_p = _fmsp_new_instruction(_fmsp_assembler_case1_dj_wr_to_wr_e,
ctx_p);
if (object_p == NULL)
{
_fmsp_assembler_yyerror(ctx_p,
"Failed to allocate instruction object.");
return (false);
}
/* Bit layout of this instruction:
*
* 0000 0000 0000 10AB