mirror of
https://github.com/Nexoniarz/Finch.git
synced 2026-11-04 00:54:25 +00:00
Compiler and docs on every system: macOS Intel in CI, releases made by CI, docs for vectors and --cpu
- CI: macOS on Apple Silicon and Intel (macos-15, macos-15-intel); a tag v* attaches every package (Linux x64/ARM64, macOS ARM64/x64, Windows x64, the VS Code extension) to its release - vectors: fma is llvm.fmuladd (llvm.fma was a libm call per lane without FMA hardware: 3.5x slower) - examples/simd.fch: a dot product eight at a time, timed against the plain loop - README and the English guides: installing on Linux, macOS and Windows; vectors (SIMD); --cpu; -g is DWARF on Windows too (lldb from llvm-mingw); no more mention of the C++ compiler - comments left from the C++ compiler (src/target.cpp, src/codegen.cpp, "never frees") brought up to date Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Psc42moPLwP43Cmb9oZqSR
This commit is contained in:
parent
68a9493572
commit
0bf66740df
15 changed files with 463 additions and 171 deletions
|
|
@ -1,10 +1,9 @@
|
|||
// C headers, read through libclang, written in Finch.
|
||||
//
|
||||
// What `import "stdio.h"` teaches the compiler: the C functions, the constants (enum values and
|
||||
// plain #define numbers), the extern variables (stdout) and the structs. The same job as
|
||||
// src/cimport.cpp, done by calling libclang's C API through Finch's own C import -- which is
|
||||
// what makes this the part that closes the bootstrap: to compile this file the self-hosted
|
||||
// compiler has to read libclang's headers with this very code.
|
||||
// plain #define numbers), the extern variables (stdout) and the structs. It calls libclang's C API
|
||||
// through Finch's own C import -- so to compile this file, the compiler reads libclang's headers
|
||||
// with this very code.
|
||||
//
|
||||
// C structs by value appear in types as the named type `module "C"`.
|
||||
import ast
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ fn vecMethods() -> []Doc {
|
|||
doc("ceil", "ceil() -> V", "Every lane rounded up (f32/f64 lanes)."),
|
||||
doc("round", "round() -> V", "Every lane rounded to the nearest whole number, halves away from 0 (f32/f64 lanes)."),
|
||||
doc("abs", "abs() -> V", "Every lane without its minus sign."),
|
||||
doc("fma", "fma(V b, V c) -> V", "v * b + c in one step, with one rounding (f32/f64 lanes)."),
|
||||
doc("fma", "fma(V b, V c) -> V", "v * b + c, as one instruction where the processor has one (f32/f64 lanes)."),
|
||||
doc("store", "store([]T list, int i)", "Writes the lanes into list[i], list[i+1], ... (or through a ptr[T]).")
|
||||
]
|
||||
}
|
||||
|
|
|
|||
18
src/gen.fch
18
src/gen.fch
|
|
@ -1,8 +1,7 @@
|
|||
// Type checking and LLVM IR generation (as text), written in Finch.
|
||||
//
|
||||
// The output is a .ll file that clang turns into a program, linked with the same
|
||||
// C runtime the main compiler uses. This compiler copies values like the main one
|
||||
// (so programs behave the same) but never frees them: it is the bootstrap compiler.
|
||||
// The output is a .ll file that clang turns into a program, linked with Finch's C runtime
|
||||
// (runtime/finch_rt.c). Values are copied when assigned and freed when their block ends.
|
||||
import ast
|
||||
import docs
|
||||
import cimport
|
||||
|
|
@ -477,7 +476,7 @@ fn T(str kind) -> ast.Type {
|
|||
return ast.simple(kind)
|
||||
}
|
||||
|
||||
// `int` is i64 and `float` is f64, as in the C++ compiler: the everyday names
|
||||
// `int` is i64 and `float` is f64: the everyday names
|
||||
// for the two default sizes, and the only way they are ever written back.
|
||||
fn isSigned(ast.Type t) -> bool {
|
||||
k := t.kind
|
||||
|
|
@ -4642,11 +4641,12 @@ fn convert(ptr[Gen] g, ast.Node c, ast.Type to) -> Val {
|
|||
return v
|
||||
}
|
||||
|
||||
// ---------- the C calling convention for structs passed by value (System V x86-64) ----------
|
||||
// ---------- the C calling convention for structs passed by value ----------
|
||||
//
|
||||
// A struct of up to 16 bytes travels in registers, one INTEGER or SSE class per eightbyte;
|
||||
// System V x86-64: a struct of up to 16 bytes travels in registers, one INTEGER or SSE class per eightbyte;
|
||||
// bigger ones are copied to the stack (byval) and returned through a hidden pointer (sret).
|
||||
// Other targets (Windows, ARM64) have their own rules and are not done here yet.
|
||||
// ARM64 (AAPCS64, and Apple's variant) and Windows x64 have their own rules: classifyArm64, and the
|
||||
// windows branch of classify.
|
||||
|
||||
struct Abi {
|
||||
str kind // "direct", "expand" (in registers: `parts`) or "memory"
|
||||
|
|
@ -6992,7 +6992,9 @@ fn vecMethod(ptr[Gen] g, ast.Node m, Val v) -> Val {
|
|||
need(g, m, 2)
|
||||
b := asVec(g, expr(g, m.kids[1]), vt, "fma", m.kids[1])
|
||||
c := asVec(g, expr(g, m.kids[2]), vt, "fma", m.kids[2])
|
||||
return Val(v: vecIntrinsic(g, lt, "fma", vt, [lt, lt, lt], [v.v, b.v, c.v], ""), ty: vt)
|
||||
// fmuladd: one fused instruction where the processor has one (FMA, NEON), a multiply and an add where
|
||||
// it doesn't (llvm.fma would call a slow library function there, to round only once)
|
||||
return Val(v: vecIntrinsic(g, lt, "fmuladd", vt, [lt, lt, lt], [v.v, b.v, c.v], ""), ty: vt)
|
||||
}
|
||||
need(g, m, 0)
|
||||
return Val(v: vecIntrinsic(g, lt, n, vt, [lt], [v.v], ""), ty: vt)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
// finch-boot: the Finch compiler written in Finch.
|
||||
//
|
||||
// finch-boot build <file.fch> [-o name] compile a program
|
||||
// finch-boot ir <file.fch> print the LLVM IR
|
||||
// finch: the Finch compiler, written in Finch (`finch` with no arguments lists the commands).
|
||||
//
|
||||
// It reads the program and the modules it imports, checks it, writes LLVM IR as text
|
||||
// and lets clang turn that into a program, linked with Finch's C runtime.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// The system a program is built for, and what depends on it: the C compiler that links, the file
|
||||
// name of the program, how it is run here, and (through the flags) the C calling convention.
|
||||
// The same as src/target.cpp.
|
||||
import host
|
||||
import "stdlib.h"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue