mirror of
https://github.com/danog/ir.git
synced 2025-01-21 21:21:19 +01:00
Start Aarch64 back-end
This commit is contained in:
parent
a45d40277c
commit
00c300fc9f
4
Makefile
4
Makefile
@ -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
2
ir.h
@ -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
140
ir_aarch64.h
Normal 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 */
|
10
ir_disasm.c
10
ir_disasm.c
@ -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);
|
||||
|
2
ir_elf.h
2
ir_elf.h
@ -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
|
||||
|
39
ir_private.h
39
ir_private.h
@ -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);
|
||||
|
||||
|
5
ir_ra.c
5
ir_ra.c
@ -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
|
||||
|
@ -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
|
||||
|
28
ir_x86.h
28
ir_x86.h
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user