#include "strcalc.h"
#include <stdlib.h>
+#include <alloca.h>
#include <assert.h> /* assertions */
#include <string.h> /* memset/memcmp */
#include <stdio.h> /* output for error messages */
static void _mul(const char *val1, const char *val2, char *buffer)
{
- char temp_buffer[CALC_BUFFER_SIZE]; /* result buffer */
- char neg_val1[CALC_BUFFER_SIZE]; /* abs of val1 */
- char neg_val2[CALC_BUFFER_SIZE]; /* abs of val2 */
+ char* temp_buffer; /* result buffer */
+ char* neg_val1; /* abs of val1 */
+ char* neg_val2; /* abs of val2 */
const char *mul, *add1, *add2; /* intermediate result containers */
char carry = SC_0; /* container for carries */
char sign = 0; /* marks result sign */
int c_inner, c_outer; /* loop counters */
+ temp_buffer = alloca(CALC_BUFFER_SIZE);
+ neg_val1 = alloca(CALC_BUFFER_SIZE);
+ neg_val2 = alloca(CALC_BUFFER_SIZE);
+
/* init result buffer to zeroes */
memset(temp_buffer, SC_0, CALC_BUFFER_SIZE);
static void _sub(const char *val1, const char *val2, char *buffer)
{
- char temp_buffer[CALC_BUFFER_SIZE]; /* intermediate buffer to hold -val2 */
+ char *temp_buffer; /* intermediate buffer to hold -val2 */
+ temp_buffer = alloca(CALC_BUFFER_SIZE);
_negate(val2, temp_buffer);
_add(val1, temp_buffer, buffer);
static void _divmod(const char *dividend, const char *divisor, char *quot, char *rem)
{
const char *minus_divisor;
- char neg_val1[CALC_BUFFER_SIZE];
- char neg_val2[CALC_BUFFER_SIZE];
+ char *neg_val1;
+ char *neg_val2;
char sign = 0; /* remember result sign */
int c_dividend; /* loop counters */
+ neg_val1 = alloca(CALC_BUFFER_SIZE);
+ neg_val2 = alloca(CALC_BUFFER_SIZE);
+
/* clear result buffer */
memset(quot, SC_0, CALC_BUFFER_SIZE);
memset(rem, SC_0, CALC_BUFFER_SIZE);
/* positive: low-order -> high order, negative other direction */
static void _rot(const char *val1, char *buffer, long offset, int radius, unsigned is_signed)
{
- char temp1[CALC_BUFFER_SIZE];
- char temp2[CALC_BUFFER_SIZE];
+ char *temp1, *temp2;
+ temp1 = alloca(CALC_BUFFER_SIZE);
+ temp2 = alloca(CALC_BUFFER_SIZE);
offset = offset % radius;
unsigned int orig_len = len;
char sign = 0;
- char base[CALC_BUFFER_SIZE];
- char val[CALC_BUFFER_SIZE];
+ char *base, *val;
+
+ base = alloca(CALC_BUFFER_SIZE);
+ val = alloca(CALC_BUFFER_SIZE);
/* verify valid pointers (not null) */
assert(str);
void sc_calc(const void* value1, const void* value2, unsigned op, void *buffer)
{
- char unused_res[CALC_BUFFER_SIZE]; /* temp buffer holding unused result of divmod */
+ char *unused_res; /* temp buffer holding unused result of divmod */
const char *val1 = (const char *)value1;
const char *val2 = (const char *)value2;
+ unused_res = alloca(CALC_BUFFER_SIZE);
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
static const char big_digits[] = "0123456789ABCDEF";
static const char small_digits[] = "0123456789abcdef";
- char base_val[CALC_BUFFER_SIZE];
- char div1_res[CALC_BUFFER_SIZE];
- char div2_res[CALC_BUFFER_SIZE];
- char rem_res[CALC_BUFFER_SIZE];
+ char *base_val, *div1_res, *div2_res, *rem_res;
int counter, nibbles, i, sign;
char x;
char *pos;
const char *digits = small_digits;
+ base_val = alloca(CALC_BUFFER_SIZE);
+ div1_res = alloca(CALC_BUFFER_SIZE);
+ div2_res = alloca(CALC_BUFFER_SIZE);
+ rem_res = alloca(CALC_BUFFER_SIZE);
+
pos = output_buffer + BIT_PATTERN_SIZE;
*(--pos) = '\0';
*/
tarval *tarval_shl(tarval *a, tarval *b)
{
+ char *temp_val = NULL;
ANNOUNCE();
assert(a);
assert(b);
assert(mode_is_int(a->mode) && mode_is_int(b->mode));
- sc_shl(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
+ if (get_mode_modulo_shift(a->mode) != 0)
+ {
+ temp_val = alloca(sc_get_buffer_length());
+
+ sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
+ sc_mod(b->value, temp_val, temp_val);
+ }
+ else
+ temp_val = (char*)b->value;
+
+ sc_shl(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
}
*/
tarval *tarval_shr(tarval *a, tarval *b)
{
+ char *temp_val = NULL;
ANNOUNCE();
assert(a);
assert(b);
assert(mode_is_int(a->mode) && mode_is_int(b->mode));
+ if (get_mode_modulo_shift(a->mode) != 0)
+ {
+ temp_val = alloca(sc_get_buffer_length());
+
+ sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
+ sc_mod(b->value, temp_val, temp_val);
+ }
+ else
+ temp_val = (char*)b->value;
+
sc_shr(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
}
*/
tarval *tarval_shrs(tarval *a, tarval *b)
{
+ char *temp_val = NULL;
ANNOUNCE();
assert(a);
assert(b);
assert(mode_is_int(a->mode) && mode_is_int(b->mode));
+ if (get_mode_modulo_shift(a->mode) != 0)
+ {
+ temp_val = alloca(sc_get_buffer_length());
+
+ sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
+ sc_mod(b->value, temp_val, temp_val);
+ }
+ else
+ temp_val = (char*)b->value;
+
sc_shrs(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
}
*/
tarval *tarval_rot(tarval *a, tarval *b)
{
+ char *temp_val = NULL;
ANNOUNCE();
assert(a);
assert(b);
assert(mode_is_int(a->mode) && mode_is_int(b->mode));
+ if (get_mode_modulo_shift(a->mode) != 0)
+ {
+ temp_val = alloca(sc_get_buffer_length());
+
+ sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
+ sc_mod(b->value, temp_val, temp_val);
+ }
+ else
+ temp_val = (char*)b->value;
+
sc_rot(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
}