-
Notifications
You must be signed in to change notification settings - Fork 0
/
target.h
128 lines (100 loc) · 2.64 KB
/
target.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#ifndef TARGET_H
#define TARGET_H
#include "alloc.h"
#include <stdio.h>
enum relocation_ty {
RELOCATION_TY_POINTER,
RELOCATION_TY_SINGLE,
RELOCATION_TY_LOCAL_PAIR,
RELOCATION_TY_UNDEF_PAIR,
};
struct relocation {
enum relocation_ty ty;
size_t symbol_index;
size_t address;
size_t size;
};
enum symbol_ty {
SYMBOL_TY_DECL,
SYMBOL_TY_FUNC,
SYMBOL_TY_STRING,
SYMBOL_TY_CONST_DATA,
SYMBOL_TY_DATA,
};
enum symbol_visibility {
SYMBOL_VISIBILITY_PRIVATE,
SYMBOL_VISIBILITY_GLOBAL,
SYMBOL_VISIBILITY_UNDEF,
};
struct symbol {
enum symbol_ty ty;
enum symbol_visibility visibility;
const char *name;
};
struct external_symbol {
const char *name;
};
struct emitted_unit {
size_t num_entries;
struct object_entry *entries;
};
enum object_entry_ty {
OBJECT_ENTRY_TY_FUNC,
OBJECT_ENTRY_TY_C_STRING,
OBJECT_ENTRY_TY_CONST_DATA,
OBJECT_ENTRY_TY_MUT_DATA,
OBJECT_ENTRY_TY_DECL // undefined symbols
};
struct object_entry {
enum object_entry_ty ty;
struct symbol symbol;
const void *data;
size_t len_data;
size_t alignment;
const struct relocation *relocations;
size_t num_relocations;
};
struct build_object_args {
const struct compile_args *compile_args;
const char *output;
const struct object_entry *entries;
size_t num_entries;
};
enum target_lp_sz {
TARGET_LP_SZ_LP32,
TARGET_LP_SZ_LP64,
};
struct ir_unit;
// This follows a very specific ordering. Indices are used to represent
// registers For register N, if `N < num_volatile`, it represents a volatile reg
// For register N, if `N >= num_volatile && N < (num_volatile +
// num_nonvolatile)`, it is an involatile reg Else, it is a reserved reg
struct reg_set_info {
size_t num_volatile;
size_t num_nonvolatile;
size_t num_reserved; // e.g x29 and x30 - can't be touched by regalloc
};
struct reg_info {
struct reg_set_info gp_registers;
struct reg_set_info fp_registers;
};
typedef const char *(*mangle)(struct arena_allocator *arena, const char *name);
typedef void (*target_lower)(struct ir_unit *unit);
typedef struct codegen_unit *(*codegen)(struct ir_unit *unit);
typedef struct emitted_unit (*emit_function)(const struct codegen_unit *unit);
typedef void (*build_object)(const struct build_object_args *args);
typedef void (*debug_disasm)(const char *filename);
typedef void (*debug_print_codegen)(FILE *file, struct codegen_unit *unit);
struct target {
enum target_lp_sz lp_sz;
struct reg_info reg_info;
size_t function_alignment;
mangle mangle;
target_lower lower;
codegen codegen;
emit_function emit_function;
build_object build_object;
debug_disasm debug_disasm;
debug_print_codegen debug_print_codegen;
};
#endif