Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial armv7 support. #162

Open
wants to merge 7 commits into
base: v0_master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions c2mir/armv7/carmv7-ABI-code.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* This file is a part of MIR project.
Copyright (C) 2018-2021 Vladimir Makarov <[email protected]>.
armv7 call ABI target specific code.
*/

typedef int target_arg_info_t;

static void target_init_arg_vars (c2m_ctx_t c2m_ctx, target_arg_info_t *arg_info) {}

static int target_return_by_addr_p (c2m_ctx_t c2m_ctx, struct type *ret_type) {
return ((ret_type->mode == TM_STRUCT || ret_type->mode == TM_UNION)
&& type_size (c2m_ctx, ret_type) > 2 * 8);
}

static int reg_aggregate_size (c2m_ctx_t c2m_ctx, struct type *type) {
int size;

if (type->mode != TM_STRUCT && type->mode != TM_UNION) return -1;
return (size = type_size (c2m_ctx, type)) <= 2 * 8 ? size : -1;
}

static void target_add_res_proto (c2m_ctx_t c2m_ctx, struct type *ret_type,
target_arg_info_t *arg_info, VARR (MIR_type_t) * res_types,
VARR (MIR_var_t) * arg_vars) {
MIR_var_t var;
int size;

if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0) {
simple_add_res_proto (c2m_ctx, ret_type, arg_info, res_types, arg_vars);
return;
}
if (size == 0) return;
VARR_PUSH (MIR_type_t, res_types, MIR_T_I64);
if (size > 8) VARR_PUSH (MIR_type_t, res_types, MIR_T_I64);
}

static int target_add_call_res_op (c2m_ctx_t c2m_ctx, struct type *ret_type,
target_arg_info_t *arg_info, size_t call_arg_area_offset) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
MIR_context_t ctx = c2m_ctx->ctx;
int size;

if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0)
return simple_add_call_res_op (c2m_ctx, ret_type, arg_info, call_arg_area_offset);
if (size == 0) return -1;
VARR_PUSH (MIR_op_t, call_ops,
MIR_new_reg_op (ctx, get_new_temp (c2m_ctx, MIR_T_I64).mir_op.u.reg));
if (size > 8)
VARR_PUSH (MIR_op_t, call_ops,
MIR_new_reg_op (ctx, get_new_temp (c2m_ctx, MIR_T_I64).mir_op.u.reg));
return size <= 8 ? 1 : 2;
}

static op_t target_gen_post_call_res_code (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res,
MIR_insn_t call, size_t call_ops_start) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
int size;

if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0)
return simple_gen_post_call_res_code (c2m_ctx, ret_type, res, call, call_ops_start);
if (size != 0)
gen_multiple_load_store (c2m_ctx, ret_type, &VARR_ADDR (MIR_op_t, call_ops)[call_ops_start + 2],
res.mir_op, FALSE);
return res;
}

static void target_add_ret_ops (c2m_ctx_t c2m_ctx, struct type *ret_type, op_t res) {
gen_ctx_t gen_ctx = c2m_ctx->gen_ctx;
int i, size;

if ((size = reg_aggregate_size (c2m_ctx, ret_type)) < 0) {
simple_add_ret_ops (c2m_ctx, ret_type, res);
return;
}
assert (res.mir_op.mode == MIR_OP_MEM && VARR_LENGTH (MIR_op_t, ret_ops) == 0 && size <= 2 * 8);
for (i = 0; size > 0; size -= 8, i++)
VARR_PUSH (MIR_op_t, ret_ops, get_new_temp (c2m_ctx, MIR_T_I64).mir_op);
gen_multiple_load_store (c2m_ctx, ret_type, VARR_ADDR (MIR_op_t, ret_ops), res.mir_op, TRUE);
}

static MIR_type_t target_get_blk_type (c2m_ctx_t c2m_ctx, struct type *arg_type) {
return MIR_T_BLK; /* one BLK is enough */
}

static void target_add_arg_proto (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
target_arg_info_t *arg_info, VARR (MIR_var_t) * arg_vars) {
simple_add_arg_proto (c2m_ctx, name, arg_type, arg_info, arg_vars);
}

static void target_add_call_arg_op (c2m_ctx_t c2m_ctx, struct type *arg_type,
target_arg_info_t *arg_info, op_t arg) {
simple_add_call_arg_op (c2m_ctx, arg_type, arg_info, arg);
}

static int target_gen_gather_arg (c2m_ctx_t c2m_ctx, const char *name, struct type *arg_type,
decl_t param_decl, target_arg_info_t *arg_info) {
return FALSE;
}
28 changes: 28 additions & 0 deletions c2mir/armv7/carmv7-code.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <[email protected]>.
*/

#include "../mirc.h"
#include "mirc_armv7_linux.h"

#include "mirc_armv7_float.h"
#include "mirc_armv7_limits.h"
#include "mirc_armv7_stdarg.h"
#include "mirc_armv7_stdint.h"
#include "mirc_armv7_stddef.h"

static string_include_t standard_includes[]
= {{NULL, mirc}, {NULL, armv7_mirc}, TARGET_STD_INCLUDES};

#define MAX_ALIGNMENT 16

#define ADJUST_VAR_ALIGNMENT(c2m_ctx, align, type) \
armv7_adjust_var_alignment (c2m_ctx, align, type)

static int armv7_adjust_var_alignment (c2m_ctx_t c2m_ctx, int align, struct type *type) {
return align;
}

static int invalid_alignment (mir_llong align) {
return align != 0 && align != 1 && align != 2 && align != 4 && align != 8 && align != 16;
}
55 changes: 55 additions & 0 deletions c2mir/armv7/carmv7.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <[email protected]>.
*/

#include <stdint.h>

#define MIR_CHAR_BIT 8

typedef int8_t mir_schar;
typedef int16_t mir_short;
typedef int32_t mir_int;
typedef int64_t mir_long;
typedef int64_t mir_llong;

#define MIR_SCHAR_MIN INT8_MIN
#define MIR_SCHAR_MAX INT8_MAX
#define MIR_SHORT_MIN INT16_MIN
#define MIR_SHORT_MAX INT16_MAX
#define MIR_INT_MIN INT32_MIN
#define MIR_INT_MAX INT32_MAX
#define MIR_LONG_MIN INT64_MIN
#define MIR_LONG_MAX INT64_MAX
#define MIR_LLONG_MIN INT64_MIN
#define MIR_LLONG_MAX INT64_MAX

typedef uint8_t mir_uchar;
typedef uint16_t mir_ushort;
typedef uint32_t mir_uint;
typedef uint64_t mir_ulong;
typedef uint64_t mir_ullong;
typedef uint32_t mir_wchar;
typedef uint16_t mir_char16;
typedef uint32_t mir_char32;

#define MIR_UCHAR_MAX UINT8_MAX
#define MIR_USHORT_MAX UINT16_MAX
#define MIR_UINT_MAX UINT32_MAX
#define MIR_ULONG_MAX UINT64_MAX
#define MIR_ULLONG_MAX UINT64_MAX
#define MIR_WCHAR_MIN 0
#define MIR_WCHAR_MAX UINT32_MAX

typedef mir_schar mir_char;
#define MIR_CHAR_MIN MIR_SCHAR_MIN
#define MIR_CHAR_MAX MIR_SCHAR_MAX

typedef float mir_float;
typedef double mir_double;
typedef long double mir_ldouble;

typedef uint8_t mir_bool;
typedef int64_t mir_ptrdiff_t;
typedef uint64_t mir_size_t;

#define MIR_SIZE_MAX UINT64_MAX
60 changes: 60 additions & 0 deletions c2mir/armv7/mirc_armv7_float.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <[email protected]>.
*/

/* See C11 5.2.4.2.2 */
static char float_str[]
= "#ifndef __FLOAT_H\n"
"#define __FLOAT_H\n"
"\n"
"#define FLT_RADIX 2\n"
"\n"
"#define FLT_MANT_DIG 24\n"
"#define DBL_MANT_DIG 53\n"
"#define LDBL_MANT_DIG DBL_MANT_DIG\n"
"\n"
"#define FLT_DECIMAL_DIG 9\n"
"#define DBL_DECIMAL_DIG 17\n"
"#define LDBL_DECIMAL_DIG DBL_DECIMAL_DIG\n"
"#define FLT_DIG FLT_DECIMAL_DIG\n"
"#define DBL_DIG DBL_DECIMAL_DIG\n"
"#define LDBL_DIG LDBL_DECIMAL_DIG\n"
"\n"
"#define DECIMAL_DIG LDBL_DECIMAL_DIG\n"
"\n"
"#define FLT_MIN_EXP -125\n"
"#define DBL_MIN_EXP -1021\n"
"#define LDBL_MIN_EXP DBL_MIN_EXP\n"
"\n"
"#define FLT_MIN_10_EXP -37\n"
"#define DBL_MIN_10_EXP -307\n"
"#define LDBL_MIN_10_EXP DBL_MIN_10_EXP\n"
"\n"
"#define FLT_MAX_EXP 128\n"
"#define DBL_MAX_EXP 1024\n"
"#define LDBL_MAX_EXP DBL_MAX_EXP\n"
"\n"
"#define FLT_MAX_10_EXP 38\n"
"#define DBL_MAX_10_EXP 308\n"
"#define LDBL_MAX_10_EXP DBL_MAX_10_EXP\n"
"\n"
"#define FLT_MAX 0x1.fffffep+127\n"
"#define DBL_MAX 0x1.fffffffffffffp+1023\n"
"#define LDBL_MAX DBL_MAX\n"
"\n"
"#define FLT_EPSILON 0x1p-23\n"
"#define DBL_EPSILON 0x1p-52\n"
"#define LDBL_EPSILON DBL_EPSILON\n"
"\n"
"#define FLT_MIN 0x1p-126\n"
"#define DBL_MIN 0x1p-1022\n"
"#define LDBL_MIN DBL_MIN\n"
"\n"
"#define FLT_TRUE_MIN 0x1p-149\n"
"#define DBL_TRUE_MIN 0x0.0000000000001p-1022\n"
"#define LDBL_TRUE_MIN DBL_TRUE_MIN\n"
"\n"
"#define FLT_EVAL_METHOD 0\n"
"#define FLT_ROUNDS 1 /* round to the nearest */\n"
"\n"
"#endif /* #ifndef __FLOAT_H */\n";
38 changes: 38 additions & 0 deletions c2mir/armv7/mirc_armv7_limits.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <[email protected]>.
*/

/* See 5.2.4.2 */
static char limits_str[]
= "#ifndef __LIMITS_H\n"
"#define __LIMITS_H\n"
"\n"
"#define CHAR_BIT 8\n"
"\n"
"#define SCHAR_MIN (-SCHAR_MAX - 1)\n"
"#define SCHAR_MAX 127\n"
"#define UCHAR_MAX (SCHAR_MAX * 2 + 1)\n"
"\n"
"#define MB_LEN_MAX 1\n"
"\n"
"#define SHRT_MIN (-SHRT_MAX - 1)\n"
"#define SHRT_MAX 32767\n"
"#define USHRT_MAX (SHRT_MAX * 2 + 1)\n"
"\n"
"#define INT_MIN (-INT_MAX - 1)\n"
"#define INT_MAX 2147483647\n"
"#define UINT_MAX (INT_MAX * 2u + 1u)\n"
"\n"
"#define LONG_MIN (-LONG_MAX - 1l)\n"
"#define LONG_MAX 9223372036854775807l\n"
"#define ULONG_MAX (LONG_MAX * 2ul + 1ul)\n"
"\n"
"#define LLONG_MIN LONG_MIN\n"
"#define LLONG_MAX LONG_MAX\n"
"#define ULLONG_MAX ULONG_MAX\n"
"\n"
"/* signed char by default */\n"
"#define CHAR_MIN SCHAR_MIN\n"
"#define CHAR_MAX SCHAR_MAX\n"
"\n"
"#endif /* #ifndef __LIMITS_H */\n";
110 changes: 110 additions & 0 deletions c2mir/armv7/mirc_armv7_linux.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/* This file is a part of MIR project.
Copyright (C) 2020-2021 Vladimir Makarov <[email protected]>.
*/

static char armv7_mirc[] =
"/*ARM defines*/\n"
"\n"
"#define __ARM_SIZEOF_WCHAR_T 4\n"
"#define __ARM_FEATURE_SAT 1\n"
"#define __ARM_ARCH_ISA_ARM 1\n"
"#define __ARMEL__ 1\n"
"#define __ARM_FEATURE_UNALIGNED 1\n"
"#define __ARM_FP 12\n"
"#define __ARM_ASM_SYNTAX_UNIFIED__ 1\n"
"#define __ARM_SIZEOF_MINIMAL_ENUM 4\n"
"#define __ARM_PCS_VFP 1\n"
"#define __ARM_FEATURE_LDREX 15\n"
"#define __ARM_FEATURE_QBIT 1\n"
"#define __ARM_ARCH_PROFILE 65\n"
"#define __ARM_32BIT_STATE 1\n"
"#define __ARM_FEATURE_CLZ 1\n"
"#define __ARM_ARCH_ISA_THUMB 2\n"
"#define __ARM_ARCH 7\n"
"#define __arm__ 1\n"
"#define __ARM_ARCH_7A__ 1\n"
"#define __ARM_FEATURE_SIMD32 1\n"
"#define __ARM_FEATURE_COPROC 15\n"
"#define __ARM_EABI__ 1\n"
"#define __ARM_FEATURE_DSP 1\n"
"\n"
"/*Standard size defines*/\n"
"#define __SIZEOF_DOUBLE__ 8\n"
"#define __SIZEOF_FLOAT__ 4\n"
"#define __SIZEOF_INT__ 4\n"
"#define __SIZEOF_LONG_DOUBLE__ 8\n"
"#define __SIZEOF_LONG_LONG__ 8\n"
"#define __SIZEOF_LONG__ 4\n"
"#define __SIZEOF_POINTER__ 4\n"
"#define __SIZEOF_PTRDIFF_T__ 4\n"
"#define __SIZEOF_SHORT__ 2\n"
"#define __SIZEOF_SIZE_T__ 4\n"
"\n"
"/*Byte Order*/\n"
"#define __ORDER_LITTLE_ENDIAN__ 1234\n"
"#define __ORDER_BIG_ENDIAN__ 4321\n"
"#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__\n"
"\n"
"/*Some GCC predefined macros: */\n"
"#define __SIZE_TYPE__ unsigned int\n"
"#define __PTRDIFF_TYPE__ int\n"
"#define __INTMAX_TYPE__ long long int\n"
"#define __UINTMAX_TYPE__ long long unsigned int\n"
"#define __INT8_TYPE__ signed char\n"
"#define __INT16_TYPE__ short int\n"
"#define __INT32_TYPE__ int\n"
"#define __UINT64_TYPE__ long long unsigned int\n"
"#define __INTPTR_TYPE__ int\n"
"#define __UINTPTR_TYPE__ unsigned int\n"
"\n"
"#define __CHAR_BIT__ 8\n"
"#define __INT8_MAX__ 0x7f\n"
"#define __INT16_MAX__ 0x7fff\n"
"#define __INT32_MAX__ 0x7fffffff\n"
"#define __INT64_MAX__ 0x7fffffffffffffffLL\n"
"#define __UINT8_MAX__ (__INT8_MAX__ * 2u + 1u)\n"
"#define __UINT16_MAX__ (__INT16_MAX__ * 2u + 1u)\n"
"#define __UINT32_MAX__ (__INT32_MAX__ * 2u + 1u)\n"
"#define __UINT64_MAX__ (__INT64_MAX__ * 2u + 1u)\n"
"#define __SIZE_MAX__ __UINT632_MAX__\n"
"#define __PTRDIFF_MAX__ __INT32_MAX__\n"
"#define __INTMAX_MAX__ __INT32_MAX__\n"
"#define __UINTMAX_MAX__ __UINT32_MAX__\n"
"#define __INTPTR_MAX__ __INT32_MAX__\n"
"#define __UINTPTR_MAX__ __UINT32_MAX__\n"
"\n"
"/*Float */\n"
"#define __FLT_MIN_EXP__ (-125)\n"
"#define __FLT_MAX_EXP__ 128\n"
"#define __FLT_DIG__ 6\n"
"#define __FLT_DECIMAL_DIG__ 9\n"
"#define __FLT_MANT_DIG__ 24\n"
"/*Differs from aarch64*/"
"#define __FLT_MIN__ 1.1754943508222875e-38F\n"
"#define __FLT_MAX__ 3.4028234663852886e+38F\n"
"#define __FLT_EPSILON__ 1.1920928955078125e-7F\n"
"\n"
"/*Double */\n"
"#define __DBL_MIN_EXP__ (-1021)\n"
"#define __DBL_MAX_EXP__ 1024\n"
"#define __DBL_DIG__ 15\n"
"#define __DBL_DECIMAL_DIG__ 17\n"
"#define __DBL_MANT_DIG__ 53\n"
"/*Differs from aarch64*/"
"#define __DBL_MIN__ ((double)2.2250738585072014e-308L)\n"
"#define __DBL_MAX__ ((double)1.7976931348623157e+308L)\n"
"#define __DBL_EPSILON__ ((double)2.2204460492503131e-16L)\n"
"\n"
"typedef unsigned short char16_t;\n"
"typedef unsigned int char32_t;\n"
"\n"
#if defined(__linux__)
"#define __gnu_linux__ 1\n"
"#define __linux 1\n"
"#define __linux__ 1\n"
"#define linux 1\n"
"#define __unix 1\n"
"#define __unix__ 1\n"
#endif
"\n"
"void *alloca (unsigned long);\n";
Loading