Move Jerry's libc to jerry-libc directory.

This commit is contained in:
Ruben Ayrapetyan
2015-02-11 21:33:45 +03:00
parent 6dfade808f
commit af77eac8e4
13 changed files with 16 additions and 217 deletions
-770
View File
@@ -1,770 +0,0 @@
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Jerry printf implementation
*/
#include "jrt.h"
#include "jerry-libc.h"
#include <stdarg.h>
/**
* printf's length type
*/
typedef enum
{
LIBC_PRINTF_ARG_LENGTH_TYPE_NONE, /**< (none) */
LIBC_PRINTF_ARG_LENGTH_TYPE_HH, /**< hh */
LIBC_PRINTF_ARG_LENGTH_TYPE_H, /**< h */
LIBC_PRINTF_ARG_LENGTH_TYPE_L, /**< l */
LIBC_PRINTF_ARG_LENGTH_TYPE_LL, /**< ll */
LIBC_PRINTF_ARG_LENGTH_TYPE_J, /**< j */
LIBC_PRINTF_ARG_LENGTH_TYPE_Z, /**< z */
LIBC_PRINTF_ARG_LENGTH_TYPE_T, /**< t */
LIBC_PRINTF_ARG_LENGTH_TYPE_HIGHL /**< L */
} libc_printf_arg_length_type_t;
/**
* printf's flags mask
*/
typedef uint8_t libc_printf_arg_flags_mask_t;
/**
* Left justification of field's contents
*/
#define LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY (1 << 0)
/**
* Force print of number's sign
*/
#define LIBC_PRINTF_ARG_FLAG_PRINT_SIGN (1 << 1)
/**
* If no sign is printed, print space before value
*/
#define LIBC_PRINTF_ARG_FLAG_SPACE (1 << 2)
/**
* For o, x, X preceed value with 0, 0x or 0X for non-zero values.
*/
#define LIBC_PRINTF_ARG_FLAG_SHARP (1 << 3)
/**
* Left-pad field with zeroes instead of spaces
*/
#define LIBC_PRINTF_ARG_FLAG_ZERO_PADDING (1 << 4)
/**
* printf helper function that outputs a char
*/
static void
libc_printf_putchar (_FILE *stream, /**< stream pointer */
char character) /**< character */
{
__fwrite (&character, 1, sizeof (character), stream);
} /* libc_printf_putchar */
/**
* printf helper function that outputs justified string
*/
static void
libc_printf_justified_string_output (_FILE *stream, /**< stream pointer */
const char *string_p, /**< string */
size_t width, /**< minimum field width */
bool is_left_justify, /**< justify to left (true) or right (false) */
bool is_zero_padding) /**< left-pad with zeroes (true) or spaces (false) */
{
const size_t str_length = __strlen (string_p);
size_t outputted_length = 0;
if (!is_left_justify)
{
char padding_char = is_zero_padding ? '0' : ' ';
while (outputted_length + str_length < width)
{
libc_printf_putchar (stream, padding_char);
outputted_length++;
}
}
__fwrite (string_p, 1, str_length * sizeof (*string_p), stream);
outputted_length += str_length;
if (is_left_justify)
{
while (outputted_length < width)
{
libc_printf_putchar (stream, ' ');
outputted_length++;
}
}
} /* libc_printf_justified_string_output */
/**
* printf helper function that converts unsigned integer to string
*/
static char*
libc_printf_uint_to_string (uintmax_t value, /**< integer value */
char *buffer_p, /**< buffer for output string */
size_t buffer_size, /**< buffer size */
const char *alphabet, /**< alphabet used for digits */
uint32_t radix) /**< radix */
{
char *str_buffer_end = buffer_p + buffer_size;
char *str_p = str_buffer_end;
*--str_p = '\0';
JERRY_ASSERT(radix >= 2);
if ((radix & (radix - 1)) != 0)
{
/*
* Radix is not power of 2. Only 32-bit numbers are supported in this mode.
*/
JERRY_ASSERT((value >> 32) == 0);
uint32_t value_lo = (uint32_t) value;
while (value_lo != 0)
{
JERRY_ASSERT (str_p != buffer_p);
*--str_p = alphabet[ value_lo % radix ];
value_lo /= radix;
}
}
else
{
uint32_t shift = 0;
while (!(radix & (1u << shift)))
{
shift++;
JERRY_ASSERT(shift <= 32);
}
uint32_t value_lo = (uint32_t) value;
uint32_t value_hi = (uint32_t) (value >> 32);
while (value_lo != 0
|| value_hi != 0)
{
JERRY_ASSERT (str_p != buffer_p);
*--str_p = alphabet[ value_lo & (radix - 1) ];
value_lo >>= shift;
value_lo += (value_hi & (radix - 1)) << (32 - shift);
value_hi >>= shift;
}
}
if (*str_p == '\0')
{
*--str_p = '0';
}
JERRY_ASSERT(str_p >= buffer_p && str_p < str_buffer_end);
return str_p;
} /* libc_printf_uint_to_string */
/**
* printf helper function that prints d and i arguments
*
* @return updated va_list
*/
static void
libc_printf_write_d_i (_FILE *stream, /**< stream pointer */
va_list* args_list_p, /**< args' list */
libc_printf_arg_flags_mask_t flags, /**< field's flags */
libc_printf_arg_length_type_t length, /**< field's length type */
uint32_t width) /**< minimum field width to output */
{
JERRY_ASSERT((flags & LIBC_PRINTF_ARG_FLAG_SHARP) == 0);
bool is_signed = true;
uintmax_t value = 0;
/* true - positive, false - negative */
bool sign = true;
const uintmax_t value_sign_mask = ((uintmax_t)1) << (sizeof (value) * JERRY_BITSINBYTE - 1);
switch (length)
{
case LIBC_PRINTF_ARG_LENGTH_TYPE_NONE:
{
value = (uintmax_t)va_arg (*args_list_p, int);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_HH:
{
value = (uintmax_t)va_arg (*args_list_p, int); /* char is promoted to int */
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_H:
{
value = (uintmax_t)va_arg (*args_list_p, int); /* short int is promoted to int */
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_L:
{
value = (uintmax_t)va_arg (*args_list_p, long int);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_LL:
{
value = (uintmax_t)va_arg (*args_list_p, long long int);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_J:
{
value = (uintmax_t)va_arg (*args_list_p, intmax_t);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_Z:
{
is_signed = false;
value = (uintmax_t)va_arg (*args_list_p, size_t);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_T:
{
is_signed = false;
value = (uintmax_t)va_arg (*args_list_p, ptrdiff_t);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_HIGHL:
{
JERRY_UNREACHABLE();
}
}
if (is_signed)
{
sign = ((value & value_sign_mask) == 0);
if (!sign)
{
value = (uintmax_t) (-value);
}
}
char str_buffer[ 32 ];
char *string_p = libc_printf_uint_to_string (value,
str_buffer,
sizeof (str_buffer),
"0123456789",
10);
if (!sign
|| (flags & LIBC_PRINTF_ARG_FLAG_PRINT_SIGN))
{
JERRY_ASSERT (string_p > str_buffer);
*--string_p = (sign ? '+' : '-');
}
else if (flags & LIBC_PRINTF_ARG_FLAG_SPACE)
{
/* no sign and space flag, printing one space */
libc_printf_putchar (stream, ' ');
if (width > 0)
{
width--;
}
}
libc_printf_justified_string_output (stream,
string_p,
width,
flags & LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY,
flags & LIBC_PRINTF_ARG_FLAG_ZERO_PADDING);
} /** libc_printf_write_d_i */
/**
* printf helper function that prints d and i arguments
*
* @return updated va_list
*/
static void
libc_printf_write_u_o_x_X(_FILE *stream, /**< stream pointer */
char specifier, /**< specifier (u, o, x, X) */
va_list* args_list_p, /**< args' list */
libc_printf_arg_flags_mask_t flags, /**< field's flags */
libc_printf_arg_length_type_t length, /**< field's length type */
uint32_t width) /**< minimum field width to output */
{
uintmax_t value = 0;
switch (length)
{
case LIBC_PRINTF_ARG_LENGTH_TYPE_NONE:
{
value = (uintmax_t)va_arg (*args_list_p, unsigned int);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_HH:
{
value = (uintmax_t)va_arg (*args_list_p, unsigned int); /* char is promoted to int */
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_H:
{
value = (uintmax_t)va_arg (*args_list_p, unsigned int); /* short int is promoted to int */
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_L:
{
value = (uintmax_t)va_arg (*args_list_p, unsigned long int);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_LL:
{
value = (uintmax_t)va_arg (*args_list_p, unsigned long long int);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_J:
{
value = (uintmax_t)va_arg (*args_list_p, uintmax_t);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_Z:
{
value = (uintmax_t)va_arg (*args_list_p, size_t);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_T:
{
value = (uintmax_t)va_arg (*args_list_p, ptrdiff_t);
break;
}
case LIBC_PRINTF_ARG_LENGTH_TYPE_HIGHL:
{
JERRY_UNREACHABLE();
}
}
if (flags & LIBC_PRINTF_ARG_FLAG_SHARP)
{
if (value != 0 && specifier != 'u')
{
libc_printf_putchar (stream, '0');
if (specifier == 'x')
{
libc_printf_putchar (stream, 'x');
}
else if (specifier == 'X')
{
libc_printf_putchar (stream, 'X');
}
else
{
JERRY_ASSERT(specifier == 'o');
}
}
}
uint32_t radix = 10;
const char *alphabet;
switch (specifier)
{
case 'u':
{
alphabet = "0123456789";
radix = 10;
break;
}
case 'o':
{
alphabet = "01234567";
radix = 8;
break;
}
case 'x':
{
alphabet = "0123456789abcdef";
radix = 16;
break;
}
case 'X':
{
alphabet = "0123456789ABCDEF";
radix = 16;
break;
}
default:
{
JERRY_UNREACHABLE();
}
}
char str_buffer[ 32 ];
const char *string_p = libc_printf_uint_to_string (value,
str_buffer,
sizeof (str_buffer),
alphabet,
radix);
if (flags & LIBC_PRINTF_ARG_FLAG_PRINT_SIGN)
{
/* printing sign */
libc_printf_putchar (stream, '+');
if (width > 0)
{
width--;
}
}
else if (flags & LIBC_PRINTF_ARG_FLAG_SPACE)
{
/* no sign and space flag, printing one space */
libc_printf_putchar (stream, ' ');
if (width > 0)
{
width--;
}
}
libc_printf_justified_string_output (stream,
string_p,
width,
flags & LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY,
flags & LIBC_PRINTF_ARG_FLAG_ZERO_PADDING);
} /** libc_printf_write_u_o_x_X */
/**
* vfprintf
*
* @return number of characters printed
*/
static int
__vfprintf (_FILE *stream, /**< stream pointer */
const char *format, /**< format string */
va_list args) /**< arguments */
{
va_list args_copy;
va_copy (args_copy, args);
const char *format_iter_p = format;
while (*format_iter_p)
{
if (*format_iter_p != '%')
{
libc_printf_putchar (stream, *format_iter_p);
}
else
{
libc_printf_arg_flags_mask_t flags = 0;
uint32_t width = 0;
libc_printf_arg_length_type_t length = LIBC_PRINTF_ARG_LENGTH_TYPE_NONE;
while (true)
{
format_iter_p++;
if (*format_iter_p == '-')
{
flags |= LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY;
}
else if (*format_iter_p == '+')
{
flags |= LIBC_PRINTF_ARG_FLAG_PRINT_SIGN;
}
else if (*format_iter_p == ' ')
{
flags |= LIBC_PRINTF_ARG_FLAG_SPACE;
}
else if (*format_iter_p == '#')
{
flags |= LIBC_PRINTF_ARG_FLAG_SHARP;
}
else if (*format_iter_p == '0')
{
flags |= LIBC_PRINTF_ARG_FLAG_ZERO_PADDING;
}
else
{
break;
}
}
if (*format_iter_p == '*')
{
/* Not supported */
JERRY_UNREACHABLE ();
}
// If there is a number, recognize it as field width
while (*format_iter_p >= '0' && *format_iter_p <= '9')
{
width = width * 10u + (uint32_t) (*format_iter_p - '0');
format_iter_p++;
}
if (*format_iter_p == '.')
{
/* Not supported */
JERRY_UNREACHABLE ();
}
switch (*format_iter_p)
{
case 'h':
{
format_iter_p++;
if (*format_iter_p == 'h')
{
format_iter_p++;
length = LIBC_PRINTF_ARG_LENGTH_TYPE_HH;
}
else
{
length = LIBC_PRINTF_ARG_LENGTH_TYPE_H;
}
break;
}
case 'l':
{
format_iter_p++;
if (*format_iter_p == 'l')
{
format_iter_p++;
length = LIBC_PRINTF_ARG_LENGTH_TYPE_LL;
}
else
{
length = LIBC_PRINTF_ARG_LENGTH_TYPE_L;
}
break;
}
case 'j':
{
format_iter_p++;
length = LIBC_PRINTF_ARG_LENGTH_TYPE_J;
break;
}
case 'z':
{
format_iter_p++;
length = LIBC_PRINTF_ARG_LENGTH_TYPE_Z;
break;
}
case 't':
{
format_iter_p++;
length = LIBC_PRINTF_ARG_LENGTH_TYPE_T;
break;
}
case 'L':
{
format_iter_p++;
length = LIBC_PRINTF_ARG_LENGTH_TYPE_HIGHL;
break;
}
}
switch (*format_iter_p)
{
case 'd':
case 'i':
{
libc_printf_write_d_i (stream, &args_copy, flags, length, width);
break;
}
case 'u':
case 'o':
case 'x':
case 'X':
{
libc_printf_write_u_o_x_X(stream, *format_iter_p, &args_copy, flags, length, width);
break;
}
case 'f':
case 'F':
case 'e':
case 'E':
case 'g':
case 'G':
case 'a':
case 'A':
{
/* Not supported */
JERRY_UNREACHABLE ();
break;
}
case 'c':
{
if (length & LIBC_PRINTF_ARG_LENGTH_TYPE_L)
{
/* Not supported */
JERRY_UNREACHABLE ();
}
else
{
char str[2] =
{
(char)va_arg (args_copy, int), /* char is promoted to int */
'\0'
};
libc_printf_justified_string_output (stream,
str,
width,
flags & LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY,
flags & LIBC_PRINTF_ARG_FLAG_ZERO_PADDING);
}
break;
}
case 's':
{
if (length & LIBC_PRINTF_ARG_LENGTH_TYPE_L)
{
/* Not supported */
JERRY_UNREACHABLE ();
}
else
{
char *str_p = va_arg (args_copy, char*);
libc_printf_justified_string_output (stream,
str_p,
width,
flags & LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY,
flags & LIBC_PRINTF_ARG_FLAG_ZERO_PADDING);
}
break;
}
case 'p':
{
va_list args_copy2;
va_copy (args_copy2, args_copy);
void *value = va_arg (args_copy2, void*);
va_end (args_copy2);
if (value == NULL)
{
__printf ("(nil)");
}
else
{
libc_printf_write_u_o_x_X(stream,
'x',
&args_copy,
flags | LIBC_PRINTF_ARG_FLAG_SHARP,
LIBC_PRINTF_ARG_LENGTH_TYPE_Z,
width);
}
break;
}
case 'n':
{
/* Not supported */
JERRY_UNREACHABLE ();
break;
}
}
}
format_iter_p++;
}
va_end (args_copy);
return 0;
} /* __vfprintf */
/**
* fprintf
*
* @return number of characters printed
*/
int
__fprintf (_FILE *stream, /**< stream pointer */
const char *format, /**< format string */
...) /**< parameters' values */
{
va_list args;
va_start (args, format);
int ret = __vfprintf (stream, format, args);
va_end (args);
return ret;
} /* __fprintf */
/**
* printf
*
* @return number of characters printed
*/
int
__printf (const char *format, /**< format string */
...) /**< parameters' values */
{
va_list args;
va_start (args, format);
int ret = __vfprintf (LIBC_STDOUT, format, args);
va_end (args);
return ret;
} /* __printf */
-372
View File
@@ -1,372 +0,0 @@
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Jerry libc's common functions implementation
*/
#include "jerry-libc.h"
/**
* memcpy alias to __memcpy (for compiler usage)
*/
extern "C" void *memcpy (void *s1, const void*s2, size_t n);
/**
* memset alias to __memset (for compiler usage)
*/
extern "C" void *memset (void *s, int c, size_t n);
/**
* memmove alias to __memmove (for compiler usage)
*/
extern "C" void *memmove (void *s1, const void*s2, size_t n);
#ifdef __GNUC__
/*
* Making GCC not to replace:
* - __memcpy -> call to memcpy;
* - __memset -> call to memset;
* - __memmove -> call to memmove.
*/
CALL_PRAGMA(GCC diagnostic push)
CALL_PRAGMA(GCC diagnostic ignored "-Wpragmas")
CALL_PRAGMA(GCC push_options)
CALL_PRAGMA(GCC optimize ("-fno-tree-loop-distribute-patterns"))
#endif /* __GNUC__ */
/**
* memcpy alias to __memcpy (for compiler usage)
*/
void* __used
memcpy (void *s1, /**< destination */
const void* s2, /**< source */
size_t n) /**< bytes number */
{
return __memcpy (s1, s2, n);
} /* memcpy */
/**
* memset alias to __memset (for compiler usage)
*/
void* __used
memset (void *s, /**< area to set values in */
int c, /**< value to set */
size_t n) /**< area size */
{
return __memset (s, c, n);
} /* memset */
/**
* memmove alias to __memmove (for compiler usage)
*/
void* __used
memmove (void *s1, /**< destination*/
const void*s2, /**< source */
size_t n) /**< area size */
{
return __memmove (s1, s2, n);
} /* memmove */
#ifdef __GNUC__
CALL_PRAGMA(GCC pop_options)
CALL_PRAGMA(GCC diagnostic pop)
#endif /* __GNUC__ */
/**
* Unreachable stubs for routines that are never called,
* but referenced from third-party libraries.
*/
#define JRT_UNREACHABLE_STUB_FOR(...) \
extern "C" __VA_ARGS__; \
__used __VA_ARGS__ \
{ \
JERRY_UNREACHABLE (); \
}
JRT_UNREACHABLE_STUB_FOR(void abort (void))
JRT_UNREACHABLE_STUB_FOR(int raise (int sig_no __unused))
#undef JRT_UNREACHABLE_STUB_FOR
/**
* memset
*
* @return @s
*/
void*
__memset (void *s, /**< area to set values in */
int c, /**< value to set */
size_t n) /**< area size */
{
uint8_t *area_p = (uint8_t *) s;
for (size_t index = 0; index < n; index++)
{
area_p[ index ] = (uint8_t) c;
}
return s;
} /* __memset */
/**
* memcmp
*
* @return 0, if areas are equal;
* -1, if first area's content is lexicographically less, than second area's content;
* 1, otherwise
*/
int
__memcmp (const void *s1, /**< first area */
const void *s2, /**< second area */
size_t n) /**< area size */
{
const uint8_t *area1_p = (uint8_t *) s1, *area2_p = (uint8_t *) s2;
for (size_t index = 0; index < n; index++)
{
if (area1_p[ index ] < area2_p[ index ])
{
return -1;
}
else if (area1_p[ index ] > area2_p[ index ])
{
return 1;
}
}
return 0;
} /* __memcmp */
/**
* memcpy
*/
void *
__memcpy (void *s1, /**< destination */
const void *s2, /**< source */
size_t n) /**< bytes number */
{
uint8_t *area1_p = (uint8_t *) s1;
const uint8_t *area2_p = (const uint8_t *) s2;
for (size_t index = 0; index < n; index++)
{
area1_p[ index ] = area2_p[ index ];
}
return s1;
} /* __memcpy */
/**
* memmove
*
* @return the dest pointer's value
*/
void *
__memmove (void *s1, /**< destination */
const void *s2, /**< source */
size_t n) /**< bytes number */
{
uint8_t *dest_p = (uint8_t *) s1;
const uint8_t *src_p = (const uint8_t *) s2;
if (dest_p < src_p)
{ /* from begin to end */
for (size_t index = 0; index < n; index++)
{
dest_p[ index ] = src_p[ index ];
}
}
else if (dest_p > src_p)
{ /* from end to begin */
for (size_t index = 1; index <= n; index++)
{
dest_p[ n - index ] = src_p[ n - index ];
}
}
return s1;
} /* __memmove */
/** Compare two strings. return an integer less than, equal to, or greater than zero
if s1 is found, respectively, to be less than, to match, or be greater than s2. */
int
__strcmp (const char *s1, const char *s2)
{
size_t i;
if (s1 == NULL)
{
if (s2 != NULL)
{
return -1;
}
else
{
return 0;
}
}
if (s2 == NULL)
{
return 1;
}
for (i = 0; s1[i]; i++)
{
if (s1[i] > s2[i])
{
return 1;
}
else if (s1[i] < s2[i])
{
return -1;
}
}
if (s2[i])
{
return -1;
}
return 0;
}
/** Compare two strings. return an integer less than, equal to, or greater than zero
if the first n character of s1 is found, respectively, to be less than, to match,
or be greater than the first n character of s2. */
int
__strncmp (const char *s1, const char *s2, size_t n)
{
size_t i;
if (s1 == NULL)
{
if (s2 != NULL)
{
return -1;
}
else
{
return 0;
}
}
if (s2 == NULL)
{
return 1;
}
for (i = 0; i < n; i++)
{
if (s1[i] > s2[i])
{
return 1;
}
else if (s1[i] < s2[i])
{
return -1;
}
}
return 0;
}
/** Copy a string. At most n bytes of src are copied. Warning: If there is no
null byte among the first n bytes of src, the string placed in dest will not be null-terminated.
@return a pointer to the destination string dest. */
char *
__strncpy (char *dest, const char *src, size_t n)
{
size_t i;
for (i = 0; i < n; i++)
{
dest[i] = src[i];
if (src[i] == '\0')
{
break;
}
}
return dest;
}
/** Calculate the length of a string. */
size_t
__strlen (const char *s)
{
size_t i;
for (i = 0; s[i]; i++)
{
;
}
return i;
}
/** Checks for white-space characters. In the "C" and "POSIX" locales, these are: space,
form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). */
int
__isspace (int c)
{
switch (c)
{
case ' ':
case '\f':
case '\n':
case '\r':
case '\t':
case '\v':
{
return 1;
}
default:
{
return 0;
}
}
}
/** Checks for an uppercase letter. */
int
__isupper (int c)
{
return c >= 'A' && c <= 'Z';
}
/** Checks for an lowercase letter. */
int
__islower (int c)
{
return c >= 'a' && c <= 'z';
}
/** Checks for an alphabetic character.
In the standard "C" locale, it is equivalent to (isupper (c) || islower (c)). */
int
__isalpha (int c)
{
return __isupper (c) || __islower (c);
}
/** Checks for a digit (0 through 9). */
int
__isdigit (int c)
{
return c >= '0' && c <= '9';
}
/** checks for a hexadecimal digits, that is, one of
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F. */
int
__isxdigit (int c)
{
return __isdigit (c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
-86
View File
@@ -1,86 +0,0 @@
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Jerry libc declarations
*/
#ifndef JERRY_LIBC_H
#define JERRY_LIBC_H
#include "jrt.h"
typedef void _FILE;
/**
* stdin file descriptor
*/
#define LIBC_STDIN (_FILE*)0
/**
* stdout file descriptor
*/
#define LIBC_STDOUT (_FILE*)1
/**
* stderr file descriptor
*/
#define LIBC_STDERR (_FILE*)2
extern void* __memset (void *s, int c, size_t n);
extern int __memcmp (const void *s1, const void *s2, size_t n);
extern void* __memcpy (void *s1, const void *s2, size_t n);
extern void* __memmove (void *dest, const void *src, size_t n);
extern int __printf (const char *format, ...);
extern int __putchar (int);
extern "C" void __noreturn __exit (int);
extern int __strcmp (const char *, const char *);
extern int __strncmp (const char *, const char *, size_t);
extern char* __strncpy (char *, const char *, size_t);
extern float __strtof (const char *, char **);
extern size_t __strlen (const char *);
extern int __isspace (int);
extern int __isupper (int);
extern int __islower (int);
extern int __isalpha (int);
extern int __isdigit (int);
extern int __isxdigit (int);
/**
* 'whence' argument of __fseek that identifies position
* the 'offset' argument is added to.
*/
typedef enum
{
__SEEK_SET, /**< relative to begin of file */
__SEEK_CUR, /**< relative to current position */
__SEEK_END /**< relative to end of file */
} _whence_t;
extern _FILE* __fopen (const char *, const char *);
extern int __fclose (_FILE *);
extern int __fseek (_FILE *, long offset, _whence_t);
extern long __ftell (_FILE *);
extern void __rewind (_FILE *);
extern size_t __fread (void *, size_t, size_t, _FILE *);
extern size_t __fwrite (const void *, size_t, size_t, _FILE *);
extern int __fprintf (_FILE *, const char *, ...);
extern void jrt_set_mem_limits (size_t data_size, size_t stack_size);
#define HUGE_VAL (1e37f)
#endif /* JERRY_LIBC_H */
-79
View File
@@ -1,79 +0,0 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ASM_ARM_H
#define ASM_ARM_H
/*
* mov syscall_no (%r0) -> %r7
* mov arg1 (%r1) -> %r0
* svc #0
*/
#define SYSCALL_1 \
push {r4-r12, lr}; \
\
mov r7, r0; \
mov r0, r1; \
\
svc #0; \
\
pop {r4-r12, pc};
/*
* mov syscall_no (%r0) -> %r7
* mov arg1 (%r1) -> %r0
* mov arg2 (%r2) -> %r1
* svc #0
*/
#define SYSCALL_2 \
push {r4-r12, lr}; \
\
mov r7, r0; \
mov r0, r1; \
mov r1, r2; \
\
svc #0; \
\
pop {r4-r12, pc};
/*
* mov syscall_no (%r0) -> %r7
* mov arg1 (%r1) -> %r0
* mov arg2 (%r2) -> %r1
* mov arg3 (%r3) -> %r2
* svc #0
*/
#define SYSCALL_3 \
push {r4-r12, lr}; \
\
mov r7, r0; \
mov r0, r1; \
mov r1, r2; \
mov r2, r3; \
\
svc #0; \
\
pop {r4-r12, pc};
#define _START \
ldr r0, [sp, #0]; \
add r1, sp, #4; \
bl main; \
\
bl __exit; \
1: \
b 1b
#endif /* !ASM_ARM_H */
-69
View File
@@ -1,69 +0,0 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ASM_X64_H
#define ASM_X64_H
/*
* mov syscall_no (%rdi) -> %rax
* mov arg1 (%rsi) -> %rdi
* syscall
*/
#define SYSCALL_1 \
mov %rdi, %rax; \
mov %rsi, %rdi; \
syscall; \
ret;
/*
* mov syscall_no (%rdi) -> %rax
* mov arg1 (%rsi) -> %rdi
* mov arg2 (%rdx) -> %rsi
* syscall
*/
#define SYSCALL_2 \
mov %rdi, %rax; \
mov %rsi, %rdi; \
mov %rdx, %rsi; \
syscall; \
ret;
/*
* mov syscall_no (%rdi) -> %rax
* mov arg1 (%rsi) -> %rdi
* mov arg2 (%rdx) -> %rsi
* mov arg3 (%rcx) -> %rdx
* syscall
*/
#define SYSCALL_3 \
mov %rdi, %rax; \
mov %rsi, %rdi; \
mov %rdx, %rsi; \
mov %rcx, %rdx; \
syscall; \
ret;
#define _START \
mov (%rsp), %rdi; \
mov %rsp, %rsi; \
add $8, %rsi; \
callq main; \
\
mov %rax, %rdi; \
callq __exit; \
1: \
jmp 1b
#endif /* !ASM_X64_H */
-72
View File
@@ -1,72 +0,0 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ASM_X86_H
#define ASM_X86_H
FIXME(Implement x86 ABI);
#error "Not implemented"
/*
* mov syscall_no -> %rax
* mov arg1 -> %rdi
* syscall
* mov %rax -> ret
*/
#define SYSCALL_1 (syscall_no, arg1, ret) \
__asm ("syscall" \
: "=a" (ret) \
: "a" (syscall_no), "D" (arg1) \
: "rcx", "r11");
/*
* mov syscall_no -> %rax
* mov arg1 -> %rdi
* mov arg2 -> %rsi
* syscall
* mov %rax -> ret
*/
#define SYSCALL_2 (syscall_no, arg1, arg2, ret) \
__asm ("syscall" \
: "=a" (ret) \
: "a" (syscall_no), "D" (arg1), "S" (arg2) \
: "rcx", "r11");
/*
* mov syscall_no -> %rax
* mov arg1 -> %rdi
* mov arg2 -> %rsi
* mov arg3 -> %rdx
* syscall
* mov %rax -> ret
*/
#define SYSCALL_3 (syscall_no, arg1, arg2, arg3, ret) \
__asm ("syscall" \
: "=a" (ret) \
: "a" (syscall_no), "D" (arg1), "S" (arg2), "d" (arg3) \
: "rcx", "r11");
#define _START \
mov (%rsp), %rdi; \
mov %rsp, %rsi; \
add $8, %rsi; \
callq main; \
\
mov %rax, %rdi; \
callq __exit; \
1: \
jmp 1b
#endif /* !ASM_X86_H */
-34
View File
@@ -1,34 +0,0 @@
#ifdef __TARGET_HOST_x64
# include "asm_x64.h"
#elif defined (__TARGET_HOST_x86)
# include "asm_x86.h"
#elif defined (__TARGET_HOST_ARMv7)
# include "asm_arm.h"
#else /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
# error "!__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7"
#endif /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
.global _start
.type _start, %function
_start:
_START
.size _start, . - _start
.global syscall_1_asm
.type syscall_1_asm, %function
syscall_1_asm:
SYSCALL_1
.size syscall_1_asm, . - syscall_1_asm
.global syscall_2_asm
.type syscall_2_asm, %function
syscall_2_asm:
SYSCALL_2
.size syscall_2_asm, . - syscall_2_asm
.global syscall_3_asm
.type syscall_3_asm, %function
syscall_3_asm:
SYSCALL_3
.size syscall_3_asm, . - syscall_3_asm
-400
View File
@@ -1,400 +0,0 @@
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Jerry libc platform-specific functions linux implementation
*/
#include "jrt.h"
#include "jerry-libc.h"
#include <stdarg.h>
#include <sys/resource.h>
#ifdef __TARGET_HOST_x64
# include "asm_x64.h"
#elif defined (__TARGET_HOST_x86)
# include "asm_x86.h"
#elif defined (__TARGET_HOST_ARMv7)
# include "asm_arm.h"
#else /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
# error "!__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 "
#endif /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
FIXME(Rename __unused)
#undef __unused
#include <syscall.h>
#include <sys/stat.h>
#include <fcntl.h>
FIXME (/* Include linux/fs.h */)
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
/**
* Exit program with ERR_SYSCALL if syscall_ret_val is negative
*/
#define LIBC_EXIT_ON_ERROR(syscall_ret_val) \
if (unlikely ((syscall_ret_val) < 0)) \
{ \
jerry_fatal (ERR_SYSCALL); \
}
static long int syscall_1 (long int syscall_no, long int arg1);
static long int syscall_2 (long int syscall_no, long int arg1, long int arg2);
static long int syscall_3 (long int syscall_no, long int arg1, long int arg2, long int arg3);
extern "C"
{
extern long int syscall_1_asm (long int syscall_no, long int arg1);
extern long int syscall_2_asm (long int syscall_no, long int arg1, long int arg2);
extern long int syscall_3_asm (long int syscall_no, long int arg1, long int arg2, long int arg3);
}
/**
* System call with one argument.
*
* @return syscall's return value
*/
static __noinline long int
syscall_1 (long int syscall_no, /**< syscall number */
long int arg1) /**< argument */
{
long int ret = syscall_1_asm (syscall_no, arg1);
LIBC_EXIT_ON_ERROR(ret);
return ret;
} /* syscall_1 */
/**
* System call with two arguments.
*
* @return syscall's return value
*/
static __noinline long int
syscall_2 (long int syscall_no, /**< syscall number */
long int arg1, /**< first argument */
long int arg2) /**< second argument */
{
long int ret = syscall_2_asm (syscall_no, arg1, arg2);
LIBC_EXIT_ON_ERROR(ret);
return ret;
} /* syscall_2 */
/**
* System call with three arguments.
*
* @return syscall's return value
*/
static __noinline long int
syscall_3 (long int syscall_no, /**< syscall number */
long int arg1, /**< first argument */
long int arg2, /**< second argument */
long int arg3) /**< third argument */
{
long int ret = syscall_3_asm (syscall_no, arg1, arg2, arg3);
LIBC_EXIT_ON_ERROR(ret);
return ret;
} /* syscall_3 */
/** Output of character. Writes the character c, cast to an unsigned char, to stdout. */
int
__putchar (int c)
{
__fwrite (&c, 1, sizeof (char), LIBC_STDOUT);
return c;
} /* __putchar */
/**
* Exit - cause normal process termination with specified status code
*/
void __noreturn
__exit (int status) /**< status code */
{
syscall_1 (__NR_close, (long int)LIBC_STDIN);
syscall_1 (__NR_close, (long int)LIBC_STDOUT);
syscall_1 (__NR_close, (long int)LIBC_STDERR);
syscall_1 (__NR_exit_group, status);
while (true)
{
/* unreachable */
}
} /* __exit */
/**
* fopen
*
* @return _FILE pointer - upon successful completion,
* NULL - otherwise
*/
_FILE*
__fopen (const char *path, /**< file path */
const char *mode) /**< file open mode */
{
bool may_read = false;
bool may_write = false;
bool truncate = false;
bool create_if_not_exist = false;
bool position_at_end = false;
JERRY_ASSERT(path != NULL && mode != NULL);
JERRY_ASSERT(mode[1] == '+' || mode[1] == '\0');
switch (mode[0])
{
case 'r':
{
may_read = true;
may_write = (mode[1] == '+');
break;
}
case 'w':
{
may_write = true;
truncate = true;
create_if_not_exist = true;
may_read = (mode[1] == '+');
break;
}
case 'a':
{
may_write = true;
position_at_end = true;
create_if_not_exist = true;
if (mode[1] == '+')
{
/* Not supported */
JERRY_UNREACHABLE();
}
break;
}
default:
{
JERRY_UNREACHABLE();
}
}
int flags = 0;
int access = S_IRUSR | S_IWUSR;
if (may_read && !may_write)
{
flags = O_RDONLY;
}
else if (!may_read && may_write)
{
flags = O_WRONLY;
}
else
{
JERRY_ASSERT(may_read && may_write);
flags = O_RDWR;
}
if (truncate)
{
flags |= O_TRUNC;
}
if (create_if_not_exist)
{
flags |= O_CREAT;
}
if (position_at_end)
{
flags |= O_APPEND;
}
long int ret = syscall_3 (__NR_open, (long int) path, flags, access);
return (void*) (uintptr_t) (ret);
} /* __fopen */
/**
* The rewind () function sets the file position indicator
* for the stream pointed to by STREAM to the beginning of the file.
*/
void
__rewind (_FILE *stream) /**< stream pointer */
{
syscall_3 (__NR_lseek, (long int) stream, 0, SEEK_SET);
} /* __rewind */
/**
* fclose
*
* @return 0 - upon successful completion,
* non-zero value - otherwise.
*/
int
__fclose (_FILE *fp) /**< stream pointer */
{
syscall_2 (__NR_close, (long int)fp, 0);
return 0;
} /* __fclose */
/**
* fseek
*/
int
__fseek (_FILE * fp, /**< stream pointer */
long offset, /**< offset */
_whence_t whence) /**< specifies position type
to add offset to */
{
int whence_real = SEEK_CUR;
switch (whence)
{
case __SEEK_SET:
{
whence_real = SEEK_SET;
break;
}
case __SEEK_CUR:
{
whence_real = SEEK_CUR;
break;
}
case __SEEK_END:
{
whence_real = SEEK_END;
break;
}
}
syscall_3 (__NR_lseek, (long int)fp, offset, whence_real);
return 0;
} /* __fseek */
/**
* ftell
*/
long
__ftell (_FILE * fp) /**< stream pointer */
{
long int ret = syscall_3 (__NR_lseek, (long int)fp, 0, SEEK_CUR);
return ret;
} /* __ftell */
/**
* fread
*
* @return number of bytes read
*/
size_t
__fread (void *ptr, /**< address of buffer to read to */
size_t size, /**< size of elements to read */
size_t nmemb, /**< number of elements to read */
_FILE *stream) /**< stream pointer */
{
long int ret;
size_t bytes_read = 0;
do
{
ret = syscall_3 (__NR_read,
(long int) stream,
(long int) ((uint8_t*) ptr + bytes_read),
(long int) (size * nmemb - bytes_read));
bytes_read += (size_t)ret;
}
while (bytes_read != size * nmemb && ret != 0);
return bytes_read;
} /* __fread */
/**
* fwrite
*
* @return number of bytes written
*/
size_t
__fwrite (const void *ptr, /**< data to write */
size_t size, /**< size of elements to write */
size_t nmemb, /**< number of elements */
_FILE *stream) /**< stream pointer */
{
size_t bytes_written = 0;
do
{
long int ret = syscall_3 (__NR_write,
(long int) stream,
(long int) ((uint8_t*) ptr + bytes_written),
(long int) (size * nmemb - bytes_written));
bytes_written += (size_t)ret;
}
while (bytes_written != size * nmemb);
return bytes_written;
} /* __fwrite */
/**
* Setup new memory limits
*/
void
jrt_set_mem_limits (size_t data_size, /**< limit for data + bss + brk heap */
size_t stack_size) /**< limit for stack */
{
struct
{
unsigned long long rlim_cur;
unsigned long long rlim_max;
} data_limit = { data_size, data_size };
struct
{
unsigned long long rlim_cur;
unsigned long long rlim_max;
} stack_limit = { stack_size, stack_size };
long int ret;
#ifdef __TARGET_HOST_x64
ret = syscall_2 (__NR_setrlimit, RLIMIT_DATA, (intptr_t) &data_limit);
JERRY_ASSERT (ret == 0);
ret = syscall_2 (__NR_setrlimit, RLIMIT_STACK, (intptr_t) &stack_limit);
JERRY_ASSERT (ret == 0);
#elif defined (__TARGET_HOST_ARMv7)
ret = syscall_3 (__NR_prlimit64, 0, RLIMIT_DATA, (intptr_t) &data_limit);
JERRY_ASSERT (ret == 0);
ret = syscall_3 (__NR_prlimit64, 0, RLIMIT_STACK, (intptr_t) &stack_limit);
JERRY_ASSERT (ret == 0);
#elif defined (__TARGET_HOST_x86)
# error "__TARGET_HOST_x86 case is not implemented"
#else /* !__TARGET_HOST_x64 && !__TARGET_HOST_ARMv7 && !__TARGET_HOST_x86 */
# error "!__TARGET_HOST_x64 && !__TARGET_HOST_ARMv7 && !__TARGET_HOST_x86"
#endif /* !__TARGET_HOST_x64 && !__TARGET_HOST_ARMv7 && !__TARGET_HOST_x86 */
} /* jrt_set_mem_limits */
-103
View File
@@ -1,103 +0,0 @@
/**
* Runtime ABI for ARM architecture
*/
/**
* long long __aeabi_llsl(long long {r1, r0}, int {r2})
*/
.thumb_func
.global __aeabi_llsl
__aeabi_llsl:
// if (r2 >= 64) goto 2f;
cmp r2, #64
bhs 2f
// if (r2 < 32) goto 1f;
cmp r2, #32
blo 1f
// r1 = (r0 << (r2 - 32));
// r0 = 0;
sub r2, #32
mov r1, r0
lsl r1, r2
mov r0, #0
bx lr
1:
// r1 <<= r2;
lsl r1, r2
// r2 = 32 - r2;
rsb r2, r2, #32
// r1 |= (r0 >> r2);
mov r3, r0
lsr r3, r2
orr r1, r3
// r2 = 32 - r2;
rsb r2, r2, #32
// r0 <<= r2;
lsl r0, r2
bx lr
2:
// r1 = 0;
// r0 = 0;
mov r1, #0
mov r0, #0
bx lr
/**
* long long __aeabi_llsr(long long {r1, r0}, int {r2})
*/
.thumb_func
.global __aeabi_llsr
__aeabi_llsr:
// if (r2 >= 64) goto 2f;
cmp r2, #64
bhs 2f
// if (r2 < 32) goto 1f;
cmp r2, #32
blo 1f
// r0 = (r1 >> (r2 - 32));
// r1 = 0
sub r2, #32
mov r0, r1
lsr r0, r2
mov r1, #0
bx lr
1:
// r0 >>= r2
lsr r0, r2
// r0 |= r1 << (32 - r2)
mov r3, r1
rsb r2, r2, #32
lsl r3, r3, r2
orr r0, r3
rsb r2, r2, #32
// r1 >>= r2
lsr r1, r2
bx lr
2:
// r1 = 0;
// r0 = 0;
mov r1, #0
mov r0, #0
bx lr
-59
View File
@@ -1,59 +0,0 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Jerry libc platform-specific functions stm32f4 implementation
*/
#include "jerry-libc.h"
#include <stdarg.h>
extern void __noreturn exit (int status);
/** Output of character. Writes the character c, cast to an unsigned char, to stdout. */
int
__putchar (int c)
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS("putchar is not implemented for STM32F3.", c);
} /* __putchar */
/** exit - cause normal process termination */
void __noreturn
__exit (int status __unused)
{
/**
* TODO: Blink LEDs? status -> binary -> LEDs?
*/
while (true)
{
}
} /* __exit */
/**
* fwrite
*
* @return number of bytes written
*/
size_t
__fwrite (const void *ptr, /**< data to write */
size_t size, /**< size of elements to write */
size_t nmemb, /**< number of elements */
_FILE *stream) /**< stream pointer */
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS("fwrite is not implemented for STM32F3.", ptr, size, nmemb, stream);
} /* __fwrite */
-103
View File
@@ -1,103 +0,0 @@
/**
* Runtime ABI for ARM architecture
*/
/**
* long long __aeabi_llsl(long long {r1, r0}, int {r2})
*/
.thumb_func
.global __aeabi_llsl
__aeabi_llsl:
// if (r2 >= 64) goto 2f;
cmp r2, #64
bhs 2f
// if (r2 < 32) goto 1f;
cmp r2, #32
blo 1f
// r1 = (r0 << (r2 - 32));
// r0 = 0;
sub r2, #32
mov r1, r0
lsl r1, r2
mov r0, #0
bx lr
1:
// r1 <<= r2;
lsl r1, r2
// r2 = 32 - r2;
rsb r2, r2, #32
// r1 |= (r0 >> r2);
mov r3, r0
lsr r3, r2
orr r1, r3
// r2 = 32 - r2;
rsb r2, r2, #32
// r0 <<= r2;
lsl r0, r2
bx lr
2:
// r1 = 0;
// r0 = 0;
mov r1, #0
mov r0, #0
bx lr
/**
* long long __aeabi_llsr(long long {r1, r0}, int {r2})
*/
.thumb_func
.global __aeabi_llsr
__aeabi_llsr:
// if (r2 >= 64) goto 2f;
cmp r2, #64
bhs 2f
// if (r2 < 32) goto 1f;
cmp r2, #32
blo 1f
// r0 = (r1 >> (r2 - 32));
// r1 = 0
sub r2, #32
mov r0, r1
lsr r0, r2
mov r1, #0
bx lr
1:
// r0 >>= r2
lsr r0, r2
// r0 |= r1 << (32 - r2)
mov r3, r1
rsb r2, r2, #32
lsl r3, r3, r2
orr r0, r3
rsb r2, r2, #32
// r1 >>= r2
lsr r1, r2
bx lr
2:
// r1 = 0;
// r0 = 0;
mov r1, #0
mov r0, #0
bx lr
-59
View File
@@ -1,59 +0,0 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Jerry libc platform-specific functions stm32f4 implementation
*/
#include "jerry-libc.h"
#include <stdarg.h>
extern void __noreturn exit (int status);
/** Output of character. Writes the character c, cast to an unsigned char, to stdout. */
int
__putchar (int c)
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS("putchar is not implemented for STM32F4.", c);
} /* __putchar */
/** exit - cause normal process termination */
void __noreturn
__exit (int status __unused)
{
/**
* TODO: Blink LEDs? status -> binary -> LEDs?
*/
while (true)
{
}
} /* __exit */
/**
* fwrite
*
* @return number of bytes written
*/
size_t
__fwrite (const void *ptr, /**< data to write */
size_t size, /**< size of elements to write */
size_t nmemb, /**< number of elements */
_FILE *stream) /**< stream pointer */
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS("fwrite is not implemented for STM32F4.", ptr, size, nmemb, stream);
} /* __fwrite */