Implementing syscall invocation sequence for ARMv7 architecture.

Removing dependencies to third-party libc routine implementations.
Introducing __TARGET_HOST define for host (non-MCU) builds.
This commit is contained in:
Ruben Ayrapetyan 2014-10-16 18:36:55 +04:00
parent 90789453ba
commit 9c3c835a7e
11 changed files with 156 additions and 213 deletions

View File

@ -330,8 +330,18 @@ ifeq ($(OPTION_NDEBUG),enable)
endif
ifeq ($(OPTION_MCU),disable)
DEFINES_JERRY += -D__TARGET_HOST_x64 -DJERRY_SOURCE_BUFFER_SIZE=$$((1024*1024))
CFLAGS_COMMON += -fno-stack-protector
MACHINE_TYPE=$(shell uname -m)
ifeq ($(MACHINE_TYPE),x86_64)
DEFINES_JERRY += -D__TARGET_HOST_x64
else
ifeq ($(MACHINE_TYPE),armv7l)
DEFINES_JERRY += -D__TARGET_HOST_ARMv7
else
$(error Unsupported machine architecture)
endif
endif
DEFINES_JERRY += -D__TARGET_HOST -DJERRY_SOURCE_BUFFER_SIZE=$$((1024*1024))
CFLAGS_COMMON += -fomit-frame-pointer -fno-stack-protector
else
CFLAGS_COMMON += -ffunction-sections -fdata-sections -nostdlib
DEFINES_JERRY += -D__TARGET_MCU

View File

@ -181,8 +181,8 @@ extern void __noreturn jerry_exit (jerry_status_t code);
/**
* Enable --show-opcodes key.
*/
#if defined (__TARGET_HOST_x64) && !defined (JERRY_NDEBUG)
#define JERRY_ENABLE_PP
#if defined (__TARGET_HOST) && !defined (JERRY_NDEBUG)
# define JERRY_ENABLE_PP
#endif
#endif /* !JERRY_GLOBALS_H */

View File

@ -29,7 +29,7 @@
void
led_toggle (uint32_t led_id)
{
#ifdef __TARGET_HOST_x64
#ifdef __TARGET_HOST
__printf ("led_toggle: %d\n", led_id);
#endif
@ -42,7 +42,7 @@ led_toggle (uint32_t led_id)
void
led_on (uint32_t led_id)
{
#ifdef __TARGET_HOST_x64
#ifdef __TARGET_HOST
__printf ("led_on: %d\n", led_id);
#endif
@ -55,7 +55,7 @@ led_on (uint32_t led_id)
void
led_off (uint32_t led_id)
{
#ifdef __TARGET_HOST_x64
#ifdef __TARGET_HOST
__printf ("led_off: %d\n", led_id);
#endif
@ -67,7 +67,7 @@ led_off (uint32_t led_id)
void
led_blink_once (uint32_t led_id)
{
#ifdef __TARGET_HOST_x64
#ifdef __TARGET_HOST
__printf ("led_blink_once: %d\n", led_id);
#endif

View File

@ -58,7 +58,7 @@ analog_write (uint32_t arg1 __unused, uint32_t arg2 __unused)
void
wait_ms (uint32_t time_ms)
{
#ifdef __TARGET_HOST_x64
#ifdef __TARGET_HOST
// 1 millisecond = 1,000,000 Nanoseconds
#define NANO_SECOND_MULTIPLIER 1000000
__printf ("wait_ms: %d\n", time_ms);

View File

@ -23,7 +23,6 @@
typedef void _FILE;
#ifdef LIBC_RAW
/**
* stdin file descriptor
*/
@ -38,26 +37,6 @@ typedef void _FILE;
* stderr file descriptor
*/
#define LIBC_STDERR (_FILE*)2
#else /* !LIBC_RAW */
extern const _FILE **libc_stdin;
extern const _FILE **libc_stdout;
extern const _FILE **libc_stderr;
/**
* stdin file descriptor
*/
#define LIBC_STDIN ((_FILE*)*libc_stdin)
/**
* stdout file descriptor
*/
#define LIBC_STDOUT ((_FILE*)*libc_stdout)
/**
* stderr file descriptor
*/
#define LIBC_STDERR ((_FILE*)*libc_stderr)
#endif /* !LIBC_RAW */
extern void* __memset (void *s, int c, size_t n);
extern int __memcmp (const void *s1, const void *s2, size_t n);

View File

@ -0,0 +1,77 @@
/* 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 -> %r7
* mov arg1 -> %r0
* svc
* mov %r0 -> ret
*/
#define SYSCALL_1(syscall_no, arg1, ret) \
__asm volatile ("mov r0, %[arg1]\n" \
"mov r7, %[syscall_no]\n" \
"svc #0\n" \
"mov %[ret], r0\n" \
: [ret] "=r" (ret) \
: [syscall_no] "r" (syscall_no), [arg1] "r" (arg1) \
: "r0", "r1", "r2", "r3", "r7", "r9", "memory");
/*
* mov syscall_no -> %r7
* mov arg1 -> %r0
* mov arg2 -> %r1
* syscall
* mov %r0 -> ret
*/
#define SYSCALL_2(syscall_no, arg1, arg2, ret) \
__asm volatile ("mov r0, %[arg1]\n" \
"mov r1, %[arg2]\n" \
"mov r7, %[syscall_no]\n" \
"svc #0\n" \
"mov %[ret], r0\n" \
: [ret] "=r" (ret) \
: [syscall_no] "r" (syscall_no), [arg1] "r" (arg1), [arg2] "r" (arg2) \
: "r0", "r1", "r2", "r3", "r7", "r9", "memory");
/*
* mov syscall_no -> %r7
* mov arg1 -> %r0
* mov arg2 -> %r1
* mov arg3 -> %r2
* syscall
* mov %r0 -> ret
*/
#define SYSCALL_3(syscall_no, arg1, arg2, arg3, ret) \
__asm volatile ("mov r0, %[arg1]\n" \
"mov r1, %[arg2]\n" \
"mov r2, %[arg3]\n" \
"mov r7, %[syscall_no]\n" \
"svc #0\n" \
"mov %[ret], r0\n" \
: [ret] "=r" (ret) \
: [syscall_no] "r" (syscall_no), [arg1] "r" (arg1), [arg2] "r" (arg2), [arg3] "r" (arg3) \
: "r0", "r1", "r2", "r3", "r7", "r9", "memory");
#define _START \
bl main; \
\
bl __exit; \
1: \
b 1b
#endif /* !ASM_ARM_H */

View File

@ -13,8 +13,8 @@
* limitations under the License.
*/
#ifndef LINUX_X64_ASM_H
#define LINUX_X64_ASM_H
#ifndef ASM_X64_H
#define ASM_X64_H
/*
* mov syscall_no -> %rax
@ -45,7 +45,7 @@
* mov syscall_no -> %rax
* mov arg1 -> %rdi
* mov arg2 -> %rsi
* mov arg2 -> %rdx
* mov arg3 -> %rdx
* syscall
* mov %rax -> ret
*/
@ -62,6 +62,8 @@
callq main; \
\
mov %rax, %rdi; \
callq __exit;
callq __exit; \
1: \
jmp 1b
#endif /* !LINUX_X64_ASM_H */
#endif /* !ASM_X64_H */

View File

@ -13,8 +13,8 @@
* limitations under the License.
*/
#ifndef LINUX_X86_ASM_H
#define LINUX_X86_ASM_H
#ifndef ASM_X86_H
#define ASM_X86_H
FIXME(Implement x86 ABI);
#error "Not implemented"
@ -48,7 +48,7 @@ FIXME(Implement x86 ABI);
* mov syscall_no -> %rax
* mov arg1 -> %rdi
* mov arg2 -> %rsi
* mov arg2 -> %rdx
* mov arg3 -> %rdx
* syscall
* mov %rax -> ret
*/
@ -65,6 +65,8 @@ FIXME(Implement x86 ABI);
callq main; \
\
mov %rax, %rdi; \
callq __exit;
callq __exit; \
1: \
jmp 1b
#endif /* !LINUX_X86_ASM_H */
#endif /* !ASM_X86_H */

View File

@ -24,22 +24,29 @@
#include <sys/resource.h>
#ifdef LIBC_RAW
#ifdef __TARGET_HOST_x64
# include "asm_x64.h"
#elif defined (__TARGET_HOST_x86)
# include "asm_x86.h"
#endif /* !__TARGET_HOST_x64 && TARGET_HOST_x86 */
#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 <linux/fs.h>
#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
*/
@ -58,7 +65,7 @@ static long int syscall_3 (long int syscall_no, long int arg1, long int arg2, lo
*
* @return syscall's return value
*/
static long int
static __noinline long int
syscall_1 (long int syscall_no, /**< syscall number */
long int arg1) /**< argument */
{
@ -76,7 +83,7 @@ syscall_1 (long int syscall_no, /**< syscall number */
*
* @return syscall's return value
*/
static long int
static __noinline long int
syscall_2 (long int syscall_no, /**< syscall number */
long int arg1, /**< first argument */
long int arg2) /**< second argument */
@ -95,7 +102,7 @@ syscall_2 (long int syscall_no, /**< syscall number */
*
* @return syscall's return value
*/
static long int
static __noinline long int
syscall_3 (long int syscall_no, /**< syscall number */
long int arg1, /**< first argument */
long int arg2, /**< second argument */
@ -357,169 +364,35 @@ void
jrt_set_mem_limits (size_t data_size, /**< limit for data + bss + brk heap */
size_t stack_size) /**< limit for stack */
{
struct rlimit data_limit = { data_size, data_size };
struct rlimit stack_limit = { stack_size, stack_size };
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);
} /* jrt_set_mem_limits */
#elif defined (LIBC_MUSL)
#include <stdio.h>
#include <stdlib.h>
const _FILE **libc_stdin = (void*)&stdin;
const _FILE **libc_stdout = (void*)&stdout;
const _FILE **libc_stderr = (void*)&stderr;
/** Output of character. Writes the character c, cast to an unsigned char, to stdout. */
int
__putchar (int c)
{
return putchar (c);
} /* __putchar */
/**
* Exit - cause normal process termination with specified status code
*/
void __noreturn
__exit (int status) /**< status code */
{
exit (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 */
{
return fopen (path, mode);
} /* __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)
{
rewind (stream);
}
/**
* fclose
*
* @return 0 - upon successful completion,
* non-zero value - otherwise.
*/
int
__fclose (_FILE *fp) /**< stream pointer */
{
return fclose (fp);
} /* __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;
}
}
return fseek (fp, offset, whence_real);
} /* __fseek */
/**
* ftell
*/
long
__ftell (_FILE * fp) /**< stream pointer */
{
return ftell (fp);
} /* __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 */
{
return fread (ptr, size, nmemb, stream);
} /* __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 */
{
return fwrite (ptr, size, nmemb, stream);
} /* __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 rlimit data_limit = { data_size, data_size };
struct rlimit stack_limit = { stack_size, stack_size };
int ret;
ret = setrlimit (RLIMIT_DATA, &data_limit);
#elif defined (__TARGET_HOST_ARMv7)
ret = syscall_3 (__NR_prlimit64, 0, RLIMIT_DATA, (intptr_t) &data_limit);
JERRY_ASSERT (ret == 0);
ret = setrlimit (RLIMIT_STACK, &stack_limit);
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 */
#else /* !LIBC_RAW && !LIBC_MUSL */
# error "!LIBC_RAW && !LIBC_MUSL"
#endif /* !LIBC_RAW && !LIBC_MUSL */

View File

@ -2,15 +2,15 @@
# include "asm_x64.h"
#elif defined (__TARGET_HOST_x86)
# include "asm_x86.h"
#else /* !__HOST && !__TARGET_HOST_x86 */
# error "!__HOST && !__TARGET_HOST_x86"
#endif /* !__HOST && !__TARGET_HOST_x86 */
#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 */
#ifdef LIBC_RAW
.global _start
_start:
_START
1:
jmp 1b
.end _start
#endif /* LIBC_RAW */

View File

@ -48,9 +48,9 @@ jerry_run (const char *script_source, size_t script_source_size,
optimizer_run_passes ((opcode_t *) opcodes);
#ifdef __TARGET_HOST_x64
#ifdef __TARGET_HOST
serializer_print_opcodes ();
#endif
#endif /* __TARGET_HOST */
parser_free ();
if (is_parse_only)
@ -70,7 +70,7 @@ jerry_run (const char *script_source, size_t script_source_size,
return is_success;
} /* jerry_run */
#ifdef __TARGET_HOST_x64
#ifdef __TARGET_HOST
static uint8_t source_buffer[ JERRY_SOURCE_BUFFER_SIZE ];
static const char*
@ -174,10 +174,10 @@ main (int argc __unused,
{
#ifdef JERRY_ENABLE_PP
show_opcodes = true;
#else
#else /* !JERRY_ENABLE_PP */
__printf ("Ignoring --show-opcodes since target is not x86_64 or debug is not enabled.\n");
show_opcodes = false;
#endif
#endif /* JERRY_ENABLE_PP */
}
else
{
@ -197,7 +197,7 @@ main (int argc __unused,
jerry_exit (is_success ? ERR_OK : ERR_FAILED_ASSERTION_IN_SCRIPT);
}
#endif
#endif /* __TARGET_HOST */
#ifdef __TARGET_MCU
static uint32_t start __unused;
@ -221,4 +221,4 @@ main (void)
source_size, false, false, false);
finish_parse_ms = (start - get_sys_tick_counter ()) / 1000;
}
#endif
#endif /* __TARGET_MCU */