Start Aarch64 back-end

This commit is contained in:
Dmitry Stogov 2022-05-31 11:22:31 +03:00
parent a45d40277c
commit 00c300fc9f
9 changed files with 189 additions and 43 deletions

View File

@ -55,10 +55,8 @@ ir_load.c: ir.g
ir_fold_hash.h: gen_ir_fold_hash ir_fold.h ir.h
./gen_ir_fold_hash > ir_fold_hash.h
gen_ir_fold_hash: gen_ir_fold_hash.o ir_strtab.o
gen_ir_fold_hash: gen_ir_fold_hash.c ir_strtab.c
$(CC) $(CFLAGS) $(LDFALGS) -o $@ $^
gen_ir_fold_hash.o: gen_ir_fold_hash.c ir.h
$(CC) $(CFLAGS) -o $@ -c $<
minilua: dynasm/minilua.c
$(CC) dynasm/minilua.c -lm -o $@

2
ir.h
View File

@ -11,6 +11,8 @@
# define IR_TARGET "x86"
#elif defined(IR_TARGET_X64)
# define IR_TARGET "x86_64"
#elif defined(IR_TARGET_AARCH64)
# define IR_TARGET "aarch64"
#else
# error "Unknown IR target"
#endif

140
ir_aarch64.h Normal file
View File

@ -0,0 +1,140 @@
#ifndef IR_AARCH64_H
#define IR_AARCH64_H
#define IR_GP_REGS(_) \
_(X0, x0, w0) \
_(X1, x1, w1) \
_(X2, x2, w2) \
_(X3, x3, w3) \
_(X4, x4, w4) \
_(X5, x5, w5) \
_(X6, x6, w6) \
_(X7, x7, w7) \
_(X8, x8, w8) \
_(X9, x9, w9) \
_(X10, x10, w10) \
_(X11, x11, w11) \
_(X12, x12, w12) \
_(X13, x13, w13) \
_(X14, x14, w14) \
_(X15, x15, w15) \
_(X16, x16, w16) \
_(X17, x17, w17) \
_(X18, x18, w18) \
_(X19, x19, w18) \
_(X20, x20, w20) \
_(X21, x21, w21) \
_(X22, x22, w22) \
_(X23, x23, w23) \
_(X24, x24, w24) \
_(X25, x25, w25) \
_(X26, x26, w26) \
_(X27, x27, w27) \
_(X28, x28, w28) \
_(X29, x29, w29) \
_(X30, x30, w30) \
_(X31, x31, w31) \
# define IR_FP_REGS(_) \
_(V0, d0, s0, h0, b0) \
_(V1, d1, s1, h1, b1) \
_(V2, d2, s2, h2, b2) \
_(V3, d3, s3, h3, b3) \
_(V4, d4, s4, h4, b4) \
_(V5, d5, s5, h5, b5) \
_(V6, d6, s6, h6, b6) \
_(V7, d7, s7, h7, b7) \
_(V8, d8, s8, h8, b8) \
_(V9, d9, s9, h9, b9) \
_(V10, d10, s10, h10, b10) \
_(V11, d11, s11, h11, b11) \
_(V12, d12, s12, h12, b12) \
_(V13, d13, s13, h13, b13) \
_(V14, d14, s14, h14, b14) \
_(V15, d15, s15, h15, b15) \
_(V16, d16, s16, h16, b16) \
_(V17, d17, s17, h17, b17) \
_(V18, d18, s18, h18, b18) \
_(V19, d19, s19, h19, b18) \
_(V20, d20, s20, h20, b20) \
_(V21, d21, s21, h21, b21) \
_(V22, d22, s22, h22, b22) \
_(V23, d23, s23, h23, b23) \
_(V24, d24, s24, h24, b24) \
_(V25, d25, s25, h25, b25) \
_(V26, d26, s26, h26, b26) \
_(V27, d27, s27, h27, b27) \
_(V28, d28, s28, h28, b28) \
_(V29, d29, s29, h29, b29) \
_(V30, d30, s30, h30, b30) \
_(V31, d31, s31, h31, b31) \
#define IR_GP_REG_ENUM(code, name64, name32) \
IR_REG_ ## code,
#define IR_FP_REG_ENUM(code, name64, name32, name16, name8) \
IR_REG_ ## code,
enum _ir_reg {
IR_REG_NONE = -1,
IR_GP_REGS(IR_GP_REG_ENUM)
IR_FP_REGS(IR_FP_REG_ENUM)
IR_REG_NUM,
};
#define IR_REG_GP_FIRST IR_REG_X0
#define IR_REG_FP_FIRST IR_REG_V0
#define IR_REG_GP_LAST (IR_REG_FP_FIRST - 1)
#define IR_REG_FP_LAST (IR_REG_NUM - 1)
#define IR_REGSET_64BIT 1
#define IR_REG_STACK_POINTER \
IR_REG_X31
#define IR_REG_FRAME_POINTER \
IR_REG_X29
#define IR_REGSET_FIXED \
(IR_REGSET(IR_REG_X18) | IR_REGSET_INTERVAL(IR_REG_X29, IR_REG_X31))
#define IR_REGSET_GP \
IR_REGSET_DIFFERENCE(IR_REGSET_INTERVAL(IR_REG_GP_FIRST, IR_REG_GP_LAST), IR_REGSET_FIXED)
#define IR_REGSET_FP \
IR_REGSET_DIFFERENCE(IR_REGSET_INTERVAL(IR_REG_FP_FIRST, IR_REG_FP_LAST), IR_REGSET_FIXED)
#define IR_REG_IP0 IR_REG_X16
#define IR_REG_IP1 IR_REG_X17
#define IR_REG_PR IR_REG_X18
#define IR_REG_LR IR_REG_X30
#define IR_REG_ZR IR_REG_X31
/* Calling Convention */
#define IR_REG_INT_RET1 IR_REG_X0
#define IR_REG_FP_RET1 IR_REG_V0
#define IR_REG_INT_ARGS 8
#define IR_REG_FP_ARGS 8
#define IR_REG_INT_ARG1 IR_REG_X0
#define IR_REG_INT_ARG2 IR_REG_X1
#define IR_REG_INT_ARG3 IR_REG_X2
#define IR_REG_INT_ARG4 IR_REG_X3
#define IR_REG_INT_ARG5 IR_REG_X4
#define IR_REG_INT_ARG6 IR_REG_X5
#define IR_REG_INT_ARG7 IR_REG_X6
#define IR_REG_INT_ARG8 IR_REG_R7
#define IR_REG_FP_ARG1 IR_REG_V0
#define IR_REG_FP_ARG2 IR_REG_V1
#define IR_REG_FP_ARG3 IR_REG_V2
#define IR_REG_FP_ARG4 IR_REG_V3
#define IR_REG_FP_ARG5 IR_REG_V4
#define IR_REG_FP_ARG6 IR_REG_V5
#define IR_REG_FP_ARG7 IR_REG_V6
#define IR_REG_FP_ARG8 IR_REG_V7
# define IR_REGSET_SCRATCH \
(IR_REGSET_INTERVAL(IR_REG_X0, IR_REG_X17) \
| IR_REGSET_INTERVAL(IR_REG_V0, IR_REG_V7) \
| IR_REGSET_INTERVAL(IR_REG_V16, IR_REG_V31))
# define IR_REGSET_PRESERVED \
(IR_REGSET_INTERVAL(IR_REG_R19, IR_REG_R30) \
| IR_REGSET_INTERVAL(IR_REG_V8, IR_REG_V15))
#endif /* IR_AARCH64_H */

View File

@ -200,7 +200,7 @@ static uint64_t ir_disasm_branch_target(csh cs, const cs_insn *insn)
}
}
}
#elif defined(IR_TARGET_ARM64)
#elif defined(IR_TARGET_AARCH64)
if (cs_insn_group(cs, insn, ARM64_GRP_JUMP)
|| insn->id == ARM64_INS_BL
|| insn->id == ARM64_INS_ADR) {
@ -216,9 +216,9 @@ static uint64_t ir_disasm_branch_target(csh cs, const cs_insn *insn)
static uint64_t ir_disasm_rodata_reference(csh cs, const cs_insn *insn)
{
#if defined(IR_TARGET_X86)
unsigned int i;
#if defined(IR_TARGET_X86)
for (i = 0; i < insn->detail->x86.op_count; i++) {
if (insn->detail->x86.operands[i].type == X86_OP_MEM
&& insn->detail->x86.operands[i].mem.base == X86_REG_INVALID
@ -237,6 +237,8 @@ static uint64_t ir_disasm_rodata_reference(csh cs, const cs_insn *insn)
}
}
#elif defined(IR_TARGET_X64)
unsigned int i;
for (i = 0; i < insn->detail->x86.op_count; i++) {
if (insn->detail->x86.operands[i].type == X86_OP_MEM
&& insn->detail->x86.operands[i].mem.base == X86_REG_RIP
@ -247,7 +249,7 @@ static uint64_t ir_disasm_rodata_reference(csh cs, const cs_insn *insn)
return insn->detail->x86.operands[i].mem.disp + insn->address + insn->size;
}
}
#elif defined(IR_TARGET_ARM64)
#elif defined(IR_TARGET_AARCH64)
return 0; // TODO:
#endif
@ -476,7 +478,7 @@ int ir_disasm(const char *name,
# else
cs_option(cs, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT);
# endif
# elif defined(IR_TARGET_ARM64)
# elif defined(IR_TARGET_AARCH64)
if (cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &cs) != CS_ERR_OK)
return 0;
cs_option(cs, CS_OPT_DETAIL, CS_OPT_ON);

View File

@ -1,7 +1,7 @@
#ifndef IR_ELF
#define IR_ELF
#if defined(IR_TARGET_X64) || defined(IR_TARGET_ARM64)
#if defined(IR_TARGET_X64) || defined(IR_TARGET_AARCH64)
# define ELF64
#else
# undef ELF64

View File

@ -743,13 +743,9 @@ int ir_gen_dessa_moves(ir_ctx *ctx, int b, emit_copy_t emit_copy);
void ir_free_live_ranges(ir_live_range *live_range);
void ir_free_live_intervals(ir_live_interval **live_intervals, int count);
/*** Register Sets ***/
#if (IR_REG_NUM <= 32)
# define IR_REGSET_64BIT 0
#else
# define IR_REGSET_64BIT 1
#endif
#if defined(IR_REGSET_64BIT)
/*** Register Sets ***/
#if IR_REGSET_64BIT
typedef uint64_t ir_regset;
#else
@ -764,20 +760,20 @@ typedef uint32_t ir_regset;
#define IR_REGSET_IS_SINGLETON(regset) \
(regset && !(regset & (regset - 1)))
#if (!IR_REGSET_64BIT)
#define IR_REGSET(reg) \
(1u << (reg))
#else
#define IR_REGSET(reg) \
#if IR_REGSET_64BIT
# define IR_REGSET(reg) \
(1ull << (reg))
#else
# define IR_REGSET(reg) \
(1u << (reg))
#endif
#if (!IR_REGSET_64BIT)
#define IR_REGSET_INTERVAL(reg1, reg2) \
(((1u << ((reg2) - (reg1) + 1)) - 1) << (reg1))
#else
#define IR_REGSET_INTERVAL(reg1, reg2) \
#if IR_REGSET_64BIT
# define IR_REGSET_INTERVAL(reg1, reg2) \
(((1ull << ((reg2) - (reg1) + 1)) - 1) << (reg1))
#else
# define IR_REGSET_INTERVAL(reg1, reg2) \
(((1u << ((reg2) - (reg1) + 1)) - 1) << (reg1))
#endif
#define IR_REGSET_IN(regset, reg) \
@ -798,12 +794,12 @@ typedef uint32_t ir_regset;
#define IR_REGSET_DIFFERENCE(set1, set2) \
((set1) & ~(set2))
#if (!IR_REGSET_64BIT)
# define IR_REGSET_FIRST(set) ((ir_reg)ir_ntz(set))
# define IR_REGSET_LAST(set) ((ir_reg)(ir_nlz(set)^31))
#else
#if IR_REGSET_64BIT
# define IR_REGSET_FIRST(set) ((ir_reg)ir_ntzl(set))
# define ir_REGSET_LAST(set) ((ir_reg)(ir_nlzl(set)(set)^63))
#else
# define IR_REGSET_FIRST(set) ((ir_reg)ir_ntz(set))
# define IR_REGSET_LAST(set) ((ir_reg)(ir_nlz(set)^31))
#endif
#define IR_REGSET_FOREACH(set, reg) \
@ -853,6 +849,9 @@ uint8_t ir_get_def_flags(ir_ctx *ctx, ir_ref ref);
uint8_t ir_get_use_flags(ir_ctx *ctx, ir_ref ref, int op_num);
int ir_get_temporary_regs(ir_ctx *ctx, ir_ref ref, ir_tmp_reg *tmp_regs);
#endif /* defined(IR_REGSET_64BIT) */
int ir_regs_number(void);
const char *ir_reg_name(int8_t reg, ir_type type);

View File

@ -2,12 +2,15 @@
#include <stdlib.h>
#include "ir.h"
#include "ir_private.h"
#if defined(IR_TARGET_X86) || defined(IR_TARGET_X64)
# include "ir_x86.h"
#elif defined(IR_TARGET_AARCH64)
# include "ir_aarch64.h"
#endif
#include "ir_private.h"
#ifdef IR_DEBUG_REGSET
uint32_t debug_regset = 0xffffffff; /* all 32 regisers */
#endif

View File

@ -1,8 +1,8 @@
#define IR_X64 1
#include "ir.h"
#include "ir_private.h"
#include "ir_x86.h"
#include "ir_private.h"
#ifdef _WIN32
# define IR_SET_ALIGNED(alignment, decl) __declspec(align(alignment)) decl

View File

@ -62,11 +62,26 @@
#endif
#define IR_GP_REG_ENUM(code, name64, name32, name16, name8, name8h) \
IR_REG_ ## code,
#define IR_FP_REG_ENUM(code, name) \
IR_REG_ ## code,
enum _ir_reg {
IR_REG_NONE = -1,
IR_GP_REGS(IR_GP_REG_ENUM)
IR_FP_REGS(IR_FP_REG_ENUM)
IR_REG_NUM,
};
#define IR_REG_GP_FIRST IR_REG_R0
#define IR_REG_FP_FIRST IR_REG_XMM0
#define IR_REG_GP_LAST (IR_REG_FP_FIRST - 1)
#define IR_REG_FP_LAST (IR_REG_NUM - 1)
#define IR_REGSET_64BIT 0
#define IR_REG_STACK_POINTER \
IR_REG_RSP
#define IR_REG_FRAME_POINTER \
@ -87,19 +102,6 @@
#define IR_REG_RSI IR_REG_R6
#define IR_REG_RDI IR_REG_R7
#define IR_GP_REG_ENUM(code, name64, name32, name16, name8, name8h) \
IR_REG_ ## code,
#define IR_FP_REG_ENUM(code, name) \
IR_REG_ ## code,
enum _ir_reg {
IR_REG_NONE = -1,
IR_GP_REGS(IR_GP_REG_ENUM)
IR_FP_REGS(IR_FP_REG_ENUM)
IR_REG_NUM,
};
/* Calling Convention */
#ifdef _WIN64