Skip to content

Commit 9deb2a9

Browse files
committed
ir: adding basic Arm64 instruction selection
* remove hardcoded architecture selection (use build-file) * remove hardcoded compilers (use build-file ones) * split build_file into (almost) bare struct + parser
1 parent 735f86b commit 9deb2a9

File tree

16 files changed

+471
-160
lines changed

16 files changed

+471
-160
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
output/
2+
output_arm/
3+
output_riscv/
24
/*.c2

ast_utils/string_buffer.c2

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ public fn void Buf.space(Buf* buf) { buf.add1(' '); }
161161
public fn void Buf.lparen(Buf* buf) { buf.add1('('); }
162162
public fn void Buf.rparen(Buf* buf) { buf.add1(')'); }
163163

164+
public fn void Buf.stripTrailingSpaces(Buf* buf) {
165+
while (buf.size_ && buf.data_[buf.size_-1] == ' ') buf.size_--;
166+
buf.data_[buf.size_] = '\0';
167+
}
168+
164169
public fn void Buf.print(Buf* buf, const char* format @(printf_format), ...) {
165170
char[4096] tmp;
166171
// NOTE: no growing

common/build_file.c2

Lines changed: 3 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,19 @@
1616
module build_file;
1717

1818
import string_pool;
19-
import source_mgr;
2019
import src_loc local;
2120
import string_list;
22-
import yaml;
2321

2422
import stdlib;
2523
import string;
26-
import stdio local;
2724

2825
public type Plugin struct {
2926
u32 name; // index into pool
3027
u32 options; // index into pool
3128
SrcLoc loc; // TODO FILL (is in yaml parser)
3229
}
3330

34-
public type Info struct @(opaque) {
31+
public type Info struct {
3532
string_pool.Pool* pool; // no ownership
3633
const char* filename; // no ownership
3734

@@ -53,7 +50,7 @@ public type Info struct @(opaque) {
5350
u32 plugin_max;
5451
}
5552

56-
fn void Info.addPlugin(Info* info, const char* name, const char* options, SrcLoc loc) {
53+
public fn void Info.addPlugin(Info* info, const char* name, const char* options, SrcLoc loc) {
5754
if (info.plugin_count == info.plugin_max) {
5855
info.plugin_max += 2;
5956
Plugin* plugins2 = stdlib.malloc(info.plugin_max * sizeof(Plugin));
@@ -91,7 +88,7 @@ public fn const char* Info.getCFlags(const Info* info) {
9188
return nil;
9289
}
9390

94-
public fn const char* Info.getLdFlags(const Info* info) {
91+
public fn const char* Info.getLinkerFlags(const Info* info) {
9592
if (info.ldflags) return info.pool.idx2str(info.ldflags);
9693
return nil;
9794
}
@@ -129,129 +126,6 @@ public fn u32 Info.getNumPlugins(const Info* info) {
129126
return info.plugin_count;
130127
}
131128

132-
/*
133-
fn const yaml.Node* get_checked(yaml.Parser* parser, const char* path) {
134-
const yaml.Node* node = parser.findNode(path);
135-
if (!node) {
136-
// TODO print manifest filename
137-
fprintf(stderr, "missing node %s\n", path);
138-
stdlib.exit(-1);
139-
}
140-
return node;
141-
}
142-
*/
143-
144-
fn u32 Info.expand(Info* info, const char* raw) {
145-
if (!raw) return 0;
146-
147-
if (raw[0] == '$') {
148-
// TODO expand with environment variable
149-
const char* expand = stdlib.getenv(raw + 1);
150-
if (!expand) {
151-
fprintf(stderr, "[build-file] warning: environment variable '%s' not set!\n", raw + 1);
152-
return 0;
153-
}
154-
raw = expand;
155-
}
156-
157-
return info.pool.addStr(raw, false);
158-
}
159-
160-
fn bool getYamlInfo(yaml.Parser* parser, Info* info) {
161-
const char* target = parser.getScalarValue("target");
162-
info.target = info.expand(target);
163-
164-
const char* outputDir = parser.getScalarValue("output_dir");
165-
info.output_dir = info.expand(outputDir);
166-
167-
const char* cc = parser.getScalarValue("toolchain.cc");
168-
info.cc = info.expand(cc);
169-
170-
const char* cflags = parser.getScalarValue("toolchain.cflags");
171-
info.cflags = info.expand(cflags);
172-
173-
const char* ldflags = parser.getScalarValue("toolchain.ldflags");
174-
info.ldflags = info.expand(ldflags);
175-
176-
const char* ldflags2 = parser.getScalarValue("toolchain.ldflags2");
177-
info.ldflags2 = info.expand(ldflags2);
178-
179-
const char* asmflags = parser.getScalarValue("toolchain.asmflags");
180-
info.asmflags = info.expand(asmflags);
181-
182-
const char* linkerscript = parser.getScalarValue("toolchain.linkerscript");
183-
info.linkerscript = info.expand(linkerscript);
184-
185-
const yaml.Node* dirs = parser.findNode("libdir");
186-
yaml.Iter iter = parser.getNodeChildIter(dirs);
187-
while (!iter.done()) {
188-
const char* dir = iter.getValue();
189-
info.lib_dirs.add(info.expand(dir));
190-
iter.next();
191-
}
192-
193-
dirs = parser.findNode("plugindir");
194-
iter = parser.getNodeChildIter(dirs);
195-
while (!iter.done()) {
196-
const char* dir = iter.getValue();
197-
info.plugin_dirs.add(info.expand(dir));
198-
iter.next();
199-
}
200-
201-
// TODO iterate all nodes, extract all that start with 'plugin.'
202-
const yaml.Node* root = parser.getRoot();
203-
iter = parser.getNodeChildIter(root);
204-
while (!iter.done()) {
205-
const char* name = iter.getName();
206-
if (string.strncmp(name, "plugin.,", 7) == 0) {
207-
const char* options = iter.getChildScalarValue("options");
208-
if (!options) {
209-
fprintf(stderr, "[build-file] missing options for %s\n", name);
210-
stdlib.exit(-1);
211-
}
212-
SrcLoc loc = 0; // TODO
213-
info.addPlugin(name+7, options, loc);
214-
}
215-
iter.next();
216-
}
217-
218-
return true;
219-
}
220-
221-
fn bool Info.parse(Info* info, const char* data) {
222-
yaml.Parser* parser = yaml.Parser.create();
223-
bool ok = parser.parse(data);
224-
if (ok) {
225-
//parser.dump(true);
226-
ok = getYamlInfo(parser, info);
227-
} else {
228-
fprintf(stderr, "Error: %s\n", parser.getMessage());
229-
}
230-
231-
parser.destroy();
232-
return ok;
233-
}
234-
235-
public fn Info* parse(source_mgr.SourceMgr* sm, string_pool.Pool* pool, const char* filename) {
236-
// create on stack first. After successful parse, alloc on heap and return
237-
Info info = {}
238-
info.pool = pool;
239-
info.filename = filename;
240-
info.lib_dirs.init(pool);
241-
info.plugin_dirs.init(pool);
242-
243-
i32 file_id = sm.loadFile(filename, 0);
244-
if (file_id == -1) return nil;
245-
246-
bool ok = info.parse(sm.get_content(file_id));
247-
248-
if (!ok) return nil;
249-
250-
Info* result = stdlib.malloc(sizeof(Info));
251-
string.memcpy(result, &info, sizeof(Info));
252-
return result;
253-
}
254-
255129
public fn void Info.free(Info* info) {
256130
info.lib_dirs.free();
257131
info.plugin_dirs.free();

common/build_file_parser.c2

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/* Copyright 2022-2025 Bas van den Berg
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
module build_file_parser;
17+
18+
import build_file local;
19+
import string_pool;
20+
import source_mgr;
21+
import src_loc local;
22+
import yaml;
23+
24+
import stdlib;
25+
import string;
26+
import stdio local;
27+
28+
fn u32 expandField(Info* info, const char* raw) {
29+
if (!raw) return 0;
30+
31+
if (raw[0] == '$') {
32+
// TODO expand with environment variable
33+
const char* expand = stdlib.getenv(raw + 1);
34+
if (!expand) {
35+
fprintf(stderr, "[build-file] warning: environment variable '%s' not set!\n", raw + 1);
36+
return 0;
37+
}
38+
raw = expand;
39+
}
40+
41+
return info.pool.addStr(raw, false);
42+
}
43+
44+
fn bool getYamlInfo(yaml.Parser* parser, Info* info) {
45+
const char* target = parser.getScalarValue("target");
46+
info.target = expandField(info, target);
47+
48+
const char* outputDir = parser.getScalarValue("output_dir");
49+
info.output_dir = expandField(info, outputDir);
50+
51+
const char* cc = parser.getScalarValue("toolchain.cc");
52+
info.cc = expandField(info, cc);
53+
54+
const char* cflags = parser.getScalarValue("toolchain.cflags");
55+
info.cflags = expandField(info, cflags);
56+
57+
const char* ldflags = parser.getScalarValue("toolchain.ldflags");
58+
info.ldflags = expandField(info, ldflags);
59+
60+
const char* ldflags2 = parser.getScalarValue("toolchain.ldflags2");
61+
info.ldflags2 = expandField(info, ldflags2);
62+
63+
const char* asmflags = parser.getScalarValue("toolchain.asmflags");
64+
info.asmflags = expandField(info, asmflags);
65+
66+
const char* linkerscript = parser.getScalarValue("toolchain.linkerscript");
67+
info.linkerscript = expandField(info, linkerscript);
68+
69+
const yaml.Node* dirs = parser.findNode("libdir");
70+
yaml.Iter iter = parser.getNodeChildIter(dirs);
71+
while (!iter.done()) {
72+
const char* dir = iter.getValue();
73+
info.lib_dirs.add(expandField(info, dir));
74+
iter.next();
75+
}
76+
77+
dirs = parser.findNode("plugindir");
78+
iter = parser.getNodeChildIter(dirs);
79+
while (!iter.done()) {
80+
const char* dir = iter.getValue();
81+
info.plugin_dirs.add(expandField(info, dir));
82+
iter.next();
83+
}
84+
85+
// TODO iterate all nodes, extract all that start with 'plugin.'
86+
const yaml.Node* root = parser.getRoot();
87+
iter = parser.getNodeChildIter(root);
88+
while (!iter.done()) {
89+
const char* name = iter.getName();
90+
if (string.strncmp(name, "plugin.,", 7) == 0) {
91+
const char* options = iter.getChildScalarValue("options");
92+
if (!options) {
93+
fprintf(stderr, "[build-file] missing options for %s\n", name);
94+
stdlib.exit(-1);
95+
}
96+
SrcLoc loc = 0; // TODO
97+
info.addPlugin(name+7, options, loc);
98+
}
99+
iter.next();
100+
}
101+
102+
return true;
103+
}
104+
105+
fn bool parseInfo(Info* info, const char* data) {
106+
yaml.Parser* parser = yaml.Parser.create();
107+
bool ok = parser.parse(data);
108+
if (ok) {
109+
//parser.dump(true);
110+
ok = getYamlInfo(parser, info);
111+
} else {
112+
fprintf(stderr, "Error: %s\n", parser.getMessage());
113+
}
114+
115+
parser.destroy();
116+
return ok;
117+
}
118+
119+
public fn Info* parse(source_mgr.SourceMgr* sm, string_pool.Pool* pool, const char* filename) {
120+
// create on stack first. After successful parse, alloc on heap and return
121+
Info info = {}
122+
info.pool = pool;
123+
info.filename = filename;
124+
info.lib_dirs.init(pool);
125+
info.plugin_dirs.init(pool);
126+
127+
i32 file_id = sm.loadFile(filename, 0);
128+
if (file_id == -1) return nil;
129+
130+
bool ok = parseInfo(&info, sm.get_content(file_id));
131+
132+
if (!ok) return nil;
133+
134+
Info* result = stdlib.malloc(sizeof(Info));
135+
string.memcpy(result, &info, sizeof(Info));
136+
return result;
137+
}
138+

compiler/compiler_generate.c2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ fn void Compiler.generate(Compiler* c, const char* target_name, const char* outp
9898
&c.components,
9999
c.sm,
100100
&c.targetInfo,
101+
c.build_info,
101102
c.mainFunc,
102103
c.target.hasAsserts(),
103104
c.opts.print_ir,

compiler/main.c2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
module c2c_main;
1717

1818
import build_file;
19+
import build_file_parser;
1920
import build_target;
2021
import color;
2122
import console;
@@ -499,7 +500,7 @@ fn void Context.handle_args(Context* c, i32 argc, char** argv) {
499500

500501
if (c.opts.build_file) {
501502
console.log("using build-file %s", c.opts.build_file);
502-
c.build_info = build_file.parse(c.sm, c.auxPool, c.opts.build_file);
503+
c.build_info = build_file_parser.parse(c.sm, c.auxPool, c.opts.build_file);
503504
if (!c.build_info) exit(EXIT_FAILURE);
504505

505506
const string_list.List* plugin_dirs = c.build_info.getPluginDirs();

generator/c/c_generator_special.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fn void Generator.createMakefile(Generator* gen,
5454
const build_file.Info* info = gen.build_info;
5555
if (info.getCC()) cc = info.getCC();
5656
if (info.getCFlags()) cflags = info.getCFlags();
57-
if (info.getLdFlags()) ldflags = info.getLdFlags();
57+
if (info.getLinkerFlags()) ldflags = info.getLinkerFlags();
5858
if (info.getLdFlags2()) ldflags2 = info.getLdFlags2();
5959
if (info.getAsmFlags()) asmflags = info.getAsmFlags();
6060
}

0 commit comments

Comments
 (0)