x64: rename to `native` to not conflict with the x64 comptime variable
parent
7587458521
commit
6750ed254f
|
@ -398,7 +398,7 @@ jobs:
|
||||||
./v build-module vlib/v/gen/c
|
./v build-module vlib/v/gen/c
|
||||||
./v build-module vlib/v/depgraph
|
./v build-module vlib/v/depgraph
|
||||||
./v build-module vlib/os/cmdline
|
./v build-module vlib/os/cmdline
|
||||||
- name: x64 machine code generation
|
- name: native machine code generation
|
||||||
run: |
|
run: |
|
||||||
exit
|
exit
|
||||||
./v -o vprod -prod cmd/v
|
./v -o vprod -prod cmd/v
|
||||||
|
@ -407,12 +407,12 @@ jobs:
|
||||||
../../vprod gen1m.v
|
../../vprod gen1m.v
|
||||||
./gen1m > 1m.v
|
./gen1m > 1m.v
|
||||||
echo "Building it..."
|
echo "Building it..."
|
||||||
../../vprod -backend x64 -o 1m 1m.v
|
../../vprod -backend native -o 1m 1m.v
|
||||||
echo "Running it..."
|
echo "Running it..."
|
||||||
ls
|
ls
|
||||||
|
|
||||||
# ./1m
|
# ./1m
|
||||||
#run: echo "TODO" #cd examples/x64 && ../../v -x64 hello_world.v && ./hello_world
|
#run: echo "TODO" #cd examples/native && ../../v -native hello_world.v && ./hello_world
|
||||||
# - name: Coveralls GitHub Action
|
# - name: Coveralls GitHub Action
|
||||||
# uses: coverallsapp/github-action@v1.0.1
|
# uses: coverallsapp/github-action@v1.0.1
|
||||||
# with:
|
# with:
|
||||||
|
@ -482,7 +482,7 @@ jobs:
|
||||||
./v build-module vlib/v/gen/c
|
./v build-module vlib/v/gen/c
|
||||||
./v build-module vlib/v/depgraph
|
./v build-module vlib/v/depgraph
|
||||||
./v build-module vlib/os/cmdline
|
./v build-module vlib/os/cmdline
|
||||||
- name: x64 machine code generation
|
- name: native machine code generation
|
||||||
run: |
|
run: |
|
||||||
exit
|
exit
|
||||||
./v -o vprod -prod cmd/v
|
./v -o vprod -prod cmd/v
|
||||||
|
@ -491,7 +491,7 @@ jobs:
|
||||||
../../vprod gen1m.v
|
../../vprod gen1m.v
|
||||||
./gen1m > 1m.v
|
./gen1m > 1m.v
|
||||||
echo "Building it..."
|
echo "Building it..."
|
||||||
../../vprod -backend x64 -o 1m 1m.v
|
../../vprod -backend native -o 1m 1m.v
|
||||||
echo "Running it..."
|
echo "Running it..."
|
||||||
ls
|
ls
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ The main files are:
|
||||||
- Constructs the compiler object (`struct V`).
|
- Constructs the compiler object (`struct V`).
|
||||||
- Creates a list of .v files that need to be parsed.
|
- Creates a list of .v files that need to be parsed.
|
||||||
- Creates a parser object for each file and runs `parse()` on them.
|
- Creates a parser object for each file and runs `parse()` on them.
|
||||||
- The correct backend is called (C, JS, x64), and a binary is compiled.
|
- The correct backend is called (C, JS, native), and a binary is compiled.
|
||||||
|
|
||||||
2. `v/scanner` The scanner's job is to parse a list of characters and convert
|
2. `v/scanner` The scanner's job is to parse a list of characters and convert
|
||||||
them to tokens.
|
them to tokens.
|
||||||
|
@ -60,11 +60,11 @@ compiled with Clang, GCC, Visual Studio, and TCC.
|
||||||
supports comptime code generation, and it will be possible to do this using the
|
supports comptime code generation, and it will be possible to do this using the
|
||||||
language's tools.
|
language's tools.
|
||||||
|
|
||||||
9. `v/gen/x64` is the directory with all the machine code generation logic. It
|
9. `v/gen/native` is the directory with all the machine code generation logic. It
|
||||||
defines a set of functions that translate assembly instructions to machine code
|
defines a set of functions that translate assembly instructions to machine code
|
||||||
and build the binary from scratch byte by byte. It manually builds all headers,
|
and build the binary from scratch byte by byte. It manually builds all headers,
|
||||||
segments, sections, symtable, relocations, etc. Right now it only has basic
|
segments, sections, symtable, relocations, etc. Right now it only has basic
|
||||||
support of the x64 platform/ELF format.
|
support of the native platform (ELF, MACHO format).
|
||||||
|
|
||||||
The rest of the directories are vlib modules: `builtin/` (strings, arrays,
|
The rest of the directories are vlib modules: `builtin/` (strings, arrays,
|
||||||
maps), `time/`, `os/`, etc. Their documentation is pretty clear.
|
maps), `time/`, `os/`, etc. Their documentation is pretty clear.
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
- Simplicity: the language can be learned in less than an hour
|
- Simplicity: the language can be learned in less than an hour
|
||||||
- Fast compilation: ≈110k loc/s with a Clang backend,
|
- Fast compilation: ≈110k loc/s with a Clang backend,
|
||||||
≈1 million loc/s with x64 and tcc backends *(Intel i5-7500, SSD, no optimization)* ([demo video](https://www.youtube.com/watch?v=pvP6wmcl_Sc))
|
≈1 million loc/s with native and tcc backends *(Intel i5-7500, SSD, no optimization)* ([demo video](https://www.youtube.com/watch?v=pvP6wmcl_Sc))
|
||||||
- Easy to develop: V compiles itself in less than a second
|
- Easy to develop: V compiles itself in less than a second
|
||||||
- Performance: as fast as C (V's main backend compiles to human readable C)
|
- Performance: as fast as C (V's main backend compiles to human readable C)
|
||||||
- Safety: no null, no globals, no undefined behavior, immutability by default
|
- Safety: no null, no globals, no undefined behavior, immutability by default
|
||||||
|
|
|
@ -44,7 +44,7 @@ fn main() {
|
||||||
tcc_path = '/usr/local/bin/tcc'
|
tcc_path = '/usr/local/bin/tcc'
|
||||||
}
|
}
|
||||||
diff2 := measure('$vdir/vprod -cc $tcc_path -o v2 $vdir/cmd/v', 'v2')
|
diff2 := measure('$vdir/vprod -cc $tcc_path -o v2 $vdir/cmd/v', 'v2')
|
||||||
diff3 := 0 // measure('$vdir/vprod -x64 $vdir/cmd/tools/1mil.v', 'x64 1mil')
|
diff3 := 0 // measure('$vdir/vprod -native $vdir/cmd/tools/1mil.v', 'native 1mil')
|
||||||
diff4 := measure('$vdir/vprod -cc clang $vdir/examples/hello_world.v', 'hello.v')
|
diff4 := measure('$vdir/vprod -cc clang $vdir/examples/hello_world.v', 'hello.v')
|
||||||
vc_size := os.file_size('v.c') / 1000
|
vc_size := os.file_size('v.c') / 1000
|
||||||
// scan/parse/check/cgen
|
// scan/parse/check/cgen
|
||||||
|
|
|
@ -53,7 +53,7 @@ Source code: <a target=blank href='https://github.com/vlang/v/blob/master/cmd/to
|
||||||
<td>commit message</td>
|
<td>commit message</td>
|
||||||
<td style='width:120px'>v -o v.c</td>
|
<td style='width:120px'>v -o v.c</td>
|
||||||
<td style='width:120px'>v -o v</td>
|
<td style='width:120px'>v -o v</td>
|
||||||
<td style='width:130px'>v -x64 1mil.v</td>
|
<td style='width:130px'>v -native 1mil.v</td>
|
||||||
<td style='width:120px'>v hello.v</td>
|
<td style='width:120px'>v hello.v</td>
|
||||||
<td style='width:85px'>v.c size</td>
|
<td style='width:85px'>v.c size</td>
|
||||||
<td style='width:55px'>parse</td>
|
<td style='width:55px'>parse</td>
|
||||||
|
|
|
@ -125,7 +125,7 @@ const (
|
||||||
'-usecache',
|
'-usecache',
|
||||||
'-prealloc',
|
'-prealloc',
|
||||||
'-parallel',
|
'-parallel',
|
||||||
'-x64',
|
'-native',
|
||||||
'-W',
|
'-W',
|
||||||
'-keepc',
|
'-keepc',
|
||||||
'-w',
|
'-w',
|
||||||
|
|
|
@ -73,7 +73,7 @@ const (
|
||||||
'vlib/v/fmt/',
|
'vlib/v/fmt/',
|
||||||
'vlib/v/gen/c/',
|
'vlib/v/gen/c/',
|
||||||
'vlib/v/gen/js/',
|
'vlib/v/gen/js/',
|
||||||
'vlib/v/gen/x64/',
|
'vlib/v/gen/native/',
|
||||||
'vlib/v/live/',
|
'vlib/v/live/',
|
||||||
'vlib/v/markused/',
|
'vlib/v/markused/',
|
||||||
'vlib/v/parser/',
|
'vlib/v/parser/',
|
||||||
|
|
|
@ -3881,7 +3881,7 @@ If a file has an environment-specific suffix, it will only be compiled for that
|
||||||
|
|
||||||
- `.js.v` => will be used only by the JS backend. These files can contain JS. code.
|
- `.js.v` => will be used only by the JS backend. These files can contain JS. code.
|
||||||
- `.c.v` => will be used only by the C backend. These files can contain C. code.
|
- `.c.v` => will be used only by the C backend. These files can contain C. code.
|
||||||
- `.x64.v` => will be used only by V's x64 backend.
|
- `.native.v` => will be used only by V's native backend.
|
||||||
- `_nix.c.v` => will be used only on Unix systems (non Windows).
|
- `_nix.c.v` => will be used only on Unix systems (non Windows).
|
||||||
- `_${os}.c.v` => will be used only on the specific `os` system.
|
- `_${os}.c.v` => will be used only on the specific `os` system.
|
||||||
For example, `_windows.c.v` will be used only when compiling on Windows, or with `-os windows`.
|
For example, `_windows.c.v` will be used only when compiling on Windows, or with `-os windows`.
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
//}
|
//}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println('x64 test')
|
println('native test')
|
||||||
// i := 0
|
// i := 0
|
||||||
// for i < 5 {
|
// for i < 5 {
|
||||||
for _ in 1 .. 5 {
|
for _ in 1 .. 5 {
|
||||||
println('Hello world from V x64 machine code generator!')
|
println('Hello world from V native machine code generator!')
|
||||||
// i++
|
// i++
|
||||||
}
|
}
|
||||||
/*
|
/*
|
|
@ -42,7 +42,7 @@ pub fn compile(command string, pref &pref.Preferences) {
|
||||||
match pref.backend {
|
match pref.backend {
|
||||||
.c { b.compile_c() }
|
.c { b.compile_c() }
|
||||||
.js { b.compile_js() }
|
.js { b.compile_js() }
|
||||||
.x64 { b.compile_x64() }
|
.native { b.compile_native() }
|
||||||
}
|
}
|
||||||
if pref.is_stats {
|
if pref.is_stats {
|
||||||
compilation_time_micros := 1 + sw.elapsed().microseconds()
|
compilation_time_micros := 1 + sw.elapsed().microseconds()
|
||||||
|
|
|
@ -3,12 +3,12 @@ module builder
|
||||||
import v.parser
|
import v.parser
|
||||||
import v.pref
|
import v.pref
|
||||||
import v.util
|
import v.util
|
||||||
import v.gen.x64
|
import v.gen.native
|
||||||
import v.markused
|
import v.markused
|
||||||
|
|
||||||
pub fn (mut b Builder) build_x64(v_files []string, out_file string) {
|
pub fn (mut b Builder) build_native(v_files []string, out_file string) {
|
||||||
$if !linux && !macos {
|
$if !linux && !macos {
|
||||||
eprintln('Warning: v -x64 can only generate macOS and Linux binaries for now')
|
eprintln('Warning: v -native can only generate macOS and Linux binaries for now')
|
||||||
}
|
}
|
||||||
util.timing_start('PARSE')
|
util.timing_start('PARSE')
|
||||||
b.parsed_files = parser.parse_files(v_files, b.table, b.pref, b.global_scope)
|
b.parsed_files = parser.parse_files(v_files, b.table, b.pref, b.global_scope)
|
||||||
|
@ -24,14 +24,14 @@ pub fn (mut b Builder) build_x64(v_files []string, out_file string) {
|
||||||
if b.pref.skip_unused {
|
if b.pref.skip_unused {
|
||||||
markused.mark_used(mut b.table, b.pref, b.parsed_files)
|
markused.mark_used(mut b.table, b.pref, b.parsed_files)
|
||||||
}
|
}
|
||||||
util.timing_start('x64 GEN')
|
util.timing_start('Native GEN')
|
||||||
b.stats_lines, b.stats_bytes = x64.gen(b.parsed_files, b.table, out_file, b.pref)
|
b.stats_lines, b.stats_bytes = native.gen(b.parsed_files, b.table, out_file, b.pref)
|
||||||
util.timing_measure('x64 GEN')
|
util.timing_measure('Native GEN')
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut b Builder) compile_x64() {
|
pub fn (mut b Builder) compile_native() {
|
||||||
// v.files << v.v_files_from_dir(os.join_path(v.pref.vlib_path,'builtin','bare'))
|
// v.files << v.v_files_from_dir(os.join_path(v.pref.vlib_path,'builtin','bare'))
|
||||||
files := [b.pref.path]
|
files := [b.pref.path]
|
||||||
b.set_module_lookup_paths()
|
b.set_module_lookup_paths()
|
||||||
b.build_x64(files, b.pref.out_name)
|
b.build_native(files, b.pref.out_name)
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
module x64
|
module native
|
||||||
|
|
||||||
import term
|
import term
|
||||||
import v.ast
|
import v.ast
|
||||||
|
@ -459,16 +459,16 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) {
|
||||||
match expr {
|
match expr {
|
||||||
ast.IntegerLiteral {
|
ast.IntegerLiteral {
|
||||||
// `foo(2)` => `mov edi,0x2`
|
// `foo(2)` => `mov edi,0x2`
|
||||||
g.mov(x64.fn_arg_registers[i], expr.val.int())
|
g.mov(native.fn_arg_registers[i], expr.val.int())
|
||||||
}
|
}
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
// `foo(x)` => `mov edi,DWORD PTR [rbp-0x8]`
|
// `foo(x)` => `mov edi,DWORD PTR [rbp-0x8]`
|
||||||
var_offset := g.get_var_offset(expr.name)
|
var_offset := g.get_var_offset(expr.name)
|
||||||
if g.pref.is_verbose {
|
if g.pref.is_verbose {
|
||||||
println('i=$i fn name= $name offset=$var_offset')
|
println('i=$i fn name= $name offset=$var_offset')
|
||||||
println(int(x64.fn_arg_registers[i]))
|
println(int(native.fn_arg_registers[i]))
|
||||||
}
|
}
|
||||||
g.mov_var_to_reg(x64.fn_arg_registers[i], var_offset)
|
g.mov_var_to_reg(native.fn_arg_registers[i], var_offset)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
verror('unhandled call_fn (name=$name) node: ' + expr.type_name())
|
verror('unhandled call_fn (name=$name) node: ' + expr.type_name())
|
||||||
|
@ -514,7 +514,7 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
g.error_with_pos('x64 assign_stmt unhandled expr: ' + right.type_name(),
|
g.error_with_pos('native assign_stmt unhandled expr: ' + right.type_name(),
|
||||||
right.position())
|
right.position())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -616,7 +616,7 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
|
||||||
g.allocate_var(name, 4, 0)
|
g.allocate_var(name, 4, 0)
|
||||||
// `mov DWORD PTR [rbp-0x4],edi`
|
// `mov DWORD PTR [rbp-0x4],edi`
|
||||||
offset += 4
|
offset += 4
|
||||||
g.mov_reg_to_rbp(offset, x64.fn_arg_registers[i])
|
g.mov_reg_to_rbp(offset, native.fn_arg_registers[i])
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
g.stmts(node.stmts)
|
g.stmts(node.stmts)
|
||||||
|
@ -634,7 +634,10 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut x Amd64) allocate_var(name string, size int, initial_val int) {
|
pub fn (mut x Amd64) allocate_var(name string, size int, initial_val int) {
|
||||||
mut g := x.g
|
// do nothing as interface call is crashing
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut g Gen) allocate_var(name string, size int, initial_val int) {
|
||||||
// `a := 3` =>
|
// `a := 3` =>
|
||||||
// `move DWORD [rbp-0x4],0x3`
|
// `move DWORD [rbp-0x4],0x3`
|
||||||
match size {
|
match size {
|
|
@ -1,4 +1,4 @@
|
||||||
module x64
|
module native
|
||||||
|
|
||||||
pub struct Aarch64 {
|
pub struct Aarch64 {
|
||||||
mut:
|
mut:
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
||||||
// Use of this source code is governed by an MIT license
|
// Use of this source code is governed by an MIT license
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
module x64
|
module native
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -35,22 +35,22 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
pub fn (mut g Gen) generate_elf_header() {
|
pub fn (mut g Gen) generate_elf_header() {
|
||||||
g.buf << [byte(x64.mag0), x64.mag1, x64.mag2, x64.mag3]
|
g.buf << [byte(native.mag0), native.mag1, native.mag2, native.mag3]
|
||||||
g.buf << x64.elfclass64 // file class
|
g.buf << native.elfclass64 // file class
|
||||||
g.buf << x64.elfdata2lsb // data encoding
|
g.buf << native.elfdata2lsb // data encoding
|
||||||
g.buf << x64.ev_current // file version
|
g.buf << native.ev_current // file version
|
||||||
g.buf << 1 // elf_osabi
|
g.buf << 1 // elf_osabi
|
||||||
g.write64(0) // et_rel) // et_rel for .o
|
g.write64(0) // et_rel) // et_rel for .o
|
||||||
g.write16(2) // e_type
|
g.write16(2) // e_type
|
||||||
if g.pref.arch == .aarch64 {
|
if g.pref.arch == .aarch64 {
|
||||||
g.write16(x64.e_machine_aarch64)
|
g.write16(native.e_machine_aarch64)
|
||||||
} else {
|
} else {
|
||||||
g.write16(x64.e_machine_amd64)
|
g.write16(native.e_machine_amd64)
|
||||||
}
|
}
|
||||||
g.write32(x64.ev_current) // e_version
|
g.write32(native.ev_current) // e_version
|
||||||
eh_size := 0x40
|
eh_size := 0x40
|
||||||
phent_size := 0x38
|
phent_size := 0x38
|
||||||
g.write64(x64.segment_start + eh_size + phent_size) // e_entry
|
g.write64(native.segment_start + eh_size + phent_size) // e_entry
|
||||||
g.write64(0x40) // e_phoff
|
g.write64(0x40) // e_phoff
|
||||||
g.write64(0) // e_shoff
|
g.write64(0) // e_shoff
|
||||||
g.write32(0) // e_flags
|
g.write32(0) // e_flags
|
||||||
|
@ -64,8 +64,8 @@ pub fn (mut g Gen) generate_elf_header() {
|
||||||
g.write32(1) // p_type
|
g.write32(1) // p_type
|
||||||
g.write32(5) // p_flags
|
g.write32(5) // p_flags
|
||||||
g.write64(0) // p_offset
|
g.write64(0) // p_offset
|
||||||
g.write64(x64.segment_start) // p_vaddr addr:050
|
g.write64(native.segment_start) // p_vaddr addr:050
|
||||||
g.write64(x64.segment_start) //
|
g.write64(native.segment_start) //
|
||||||
g.file_size_pos = i64(g.buf.len)
|
g.file_size_pos = i64(g.buf.len)
|
||||||
g.write64(0) // p_filesz PLACEHOLDER, set to file_size later // addr: 060
|
g.write64(0) // p_filesz PLACEHOLDER, set to file_size later // addr: 060
|
||||||
g.write64(0) // p_memsz
|
g.write64(0) // p_memsz
|
||||||
|
@ -75,7 +75,7 @@ pub fn (mut g Gen) generate_elf_header() {
|
||||||
println('code_start_pos = $g.buf.len.hex()')
|
println('code_start_pos = $g.buf.len.hex()')
|
||||||
g.code_start_pos = i64(g.buf.len)
|
g.code_start_pos = i64(g.buf.len)
|
||||||
g.debug_pos = g.buf.len
|
g.debug_pos = g.buf.len
|
||||||
g.call(x64.placeholder) // call main function, it's not guaranteed to be the first, we don't know its address yet
|
g.call(native.placeholder) // call main function, it's not guaranteed to be the first, we don't know its address yet
|
||||||
g.println('call fn main')
|
g.println('call fn main')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ pub fn (mut g Gen) generate_elf_footer() {
|
||||||
// Strings table
|
// Strings table
|
||||||
// Loop thru all strings and set the right addresses
|
// Loop thru all strings and set the right addresses
|
||||||
for i, s in g.strings {
|
for i, s in g.strings {
|
||||||
g.write64_at(x64.segment_start + g.buf.len, int(g.str_pos[i]))
|
g.write64_at(native.segment_start + g.buf.len, int(g.str_pos[i]))
|
||||||
g.write_string(s)
|
g.write_string(s)
|
||||||
g.write8(0)
|
g.write8(0)
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,6 @@ pub fn (mut g Gen) generate_elf_footer() {
|
||||||
unsafe { f.write_ptr(g.buf.data, g.buf.len) }
|
unsafe { f.write_ptr(g.buf.data, g.buf.len) }
|
||||||
f.close()
|
f.close()
|
||||||
if g.pref.is_verbose {
|
if g.pref.is_verbose {
|
||||||
println('\nx64 elf binary has been successfully generated')
|
println('\nnative elf binary has been successfully generated')
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
||||||
// Use of this source code is governed by an MIT license
|
// Use of this source code is governed by an MIT license
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
module x64
|
module native
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file is unused right now, since binaries without sections
|
This file is unused right now, since binaries without sections
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
||||||
// Use of this source code is governed by an MIT license
|
// Use of this source code is governed by an MIT license
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
module x64
|
module native
|
||||||
|
|
||||||
import v.ast
|
import v.ast
|
||||||
import v.util
|
import v.util
|
||||||
|
@ -88,7 +88,7 @@ pub fn (mut g Gen) generate_header() {
|
||||||
}
|
}
|
||||||
.raw {}
|
.raw {}
|
||||||
else {
|
else {
|
||||||
verror('Error: only `raw`, `linux` and `macos` are supported for -os in -x64')
|
verror('Error: only `raw`, `linux` and `macos` are supported for -os in -native')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
ast.StructDecl {}
|
ast.StructDecl {}
|
||||||
else {
|
else {
|
||||||
println('x64.stmt(): bad node: ' + node.type_name())
|
println('native.stmt(): bad node: ' + node.type_name())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -313,14 +313,16 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||||
ast.StringLiteral {}
|
ast.StringLiteral {}
|
||||||
ast.StructInit {}
|
ast.StructInit {}
|
||||||
else {
|
else {
|
||||||
println(term.red('x64.expr(): unhandled node: ' + node.type_name()))
|
println(term.red('native.expr(): unhandled node: ' + node.type_name()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
fn (mut g Gen) allocate_var(name string, size int, initial_val int) {
|
fn (mut g Gen) allocate_var(name string, size int, initial_val int) {
|
||||||
g.cgen.allocate_var(name, size, initial_val)
|
g.cgen.allocate_var(name, size, initial_val)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
fn (mut g Gen) postfix_expr(node ast.PostfixExpr) {
|
fn (mut g Gen) postfix_expr(node ast.PostfixExpr) {
|
||||||
if node.expr !is ast.Ident {
|
if node.expr !is ast.Ident {
|
||||||
|
@ -334,7 +336,7 @@ fn (mut g Gen) postfix_expr(node ast.PostfixExpr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verror(s string) {
|
fn verror(s string) {
|
||||||
util.verror('x64 gen error', s)
|
util.verror('native gen error', s)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut g Gen) error_with_pos(s string, pos token.Position) {
|
pub fn (mut g Gen) error_with_pos(s string, pos token.Position) {
|
|
@ -1,7 +1,7 @@
|
||||||
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
||||||
// Use of this source code is governed by an MIT license
|
// Use of this source code is governed by an MIT license
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
module x64
|
module native
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ pub fn (mut g Gen) generate_macho_header() {
|
||||||
g.write32(0x4) // alignment
|
g.write32(0x4) // alignment
|
||||||
g.write32(0x160) // relocation offset
|
g.write32(0x160) // relocation offset
|
||||||
g.write32(0x1) // # of relocations
|
g.write32(0x1) // # of relocations
|
||||||
g.write32(x64.s_attr_some_instructions | x64.s_attr_pure_instructions)
|
g.write32(native.s_attr_some_instructions | native.s_attr_pure_instructions)
|
||||||
g.write32(0)
|
g.write32(0)
|
||||||
g.write32(0)
|
g.write32(0)
|
||||||
g.write32(0)
|
g.write32(0)
|
||||||
|
@ -88,8 +88,8 @@ pub fn (mut g Gen) generate_macho_header() {
|
||||||
// lc_symtab
|
// lc_symtab
|
||||||
g.sym_table_command()
|
g.sym_table_command()
|
||||||
//
|
//
|
||||||
g.write32(x64.lc_dymsymtab)
|
g.write32(native.lc_dymsymtab)
|
||||||
g.write32(x64.macho_d_size)
|
g.write32(native.macho_d_size)
|
||||||
g.write32(0)
|
g.write32(0)
|
||||||
g.write32(2)
|
g.write32(2)
|
||||||
g.write32(2)
|
g.write32(2)
|
||||||
|
@ -166,8 +166,8 @@ fn (mut g Gen) sym_table_command() {
|
||||||
name: 'ltmp1'
|
name: 'ltmp1'
|
||||||
is_ext: false
|
is_ext: false
|
||||||
}
|
}
|
||||||
g.write32(x64.lc_symtab)
|
g.write32(native.lc_symtab)
|
||||||
g.write32(x64.macho_symcmd_size)
|
g.write32(native.macho_symcmd_size)
|
||||||
sym_table_offset := 0x168
|
sym_table_offset := 0x168
|
||||||
g.write32(sym_table_offset)
|
g.write32(sym_table_offset)
|
||||||
g_syms_len := 4
|
g_syms_len := 4
|
|
@ -1,9 +1,9 @@
|
||||||
import v.gen.x64
|
import v.gen.native
|
||||||
import v.pref
|
import v.pref
|
||||||
import v.ast
|
import v.ast
|
||||||
|
|
||||||
fn test_macho() {
|
fn test_macho() {
|
||||||
mut g := x64.Gen{
|
mut g := native.Gen{
|
||||||
pref: &pref.Preferences{}
|
pref: &pref.Preferences{}
|
||||||
out_name: 'test.bin'
|
out_name: 'test.bin'
|
||||||
table: &ast.Table{}
|
table: &ast.Table{}
|
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println('hello from native V')
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
hello from native V
|
|
@ -3,26 +3,26 @@ import benchmark
|
||||||
import term
|
import term
|
||||||
|
|
||||||
// TODO some logic copy pasted from valgrind_test.v and compiler_test.v, move to a module
|
// TODO some logic copy pasted from valgrind_test.v and compiler_test.v, move to a module
|
||||||
fn test_x64() {
|
fn test_native() {
|
||||||
$if !amd64 {
|
$if !amd64 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if os.user_os() != 'linux' {
|
if os.user_os() != 'linux' {
|
||||||
eprintln('x64 tests can only be run on Linux for now.')
|
eprintln('native tests can only be run on Linux for now.')
|
||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
mut bench := benchmark.new_benchmark()
|
mut bench := benchmark.new_benchmark()
|
||||||
vexe := os.getenv('VEXE')
|
vexe := os.getenv('VEXE')
|
||||||
vroot := os.dir(vexe)
|
vroot := os.dir(vexe)
|
||||||
dir := os.join_path(vroot, 'vlib/v/gen/x64/tests')
|
dir := os.join_path(vroot, 'vlib/v/gen/native/tests')
|
||||||
files := os.ls(dir) or { panic(err) }
|
files := os.ls(dir) or { panic(err) }
|
||||||
//
|
//
|
||||||
wrkdir := os.join_path(os.temp_dir(), 'vtests', 'x64')
|
wrkdir := os.join_path(os.temp_dir(), 'vtests', 'native')
|
||||||
os.mkdir_all(wrkdir) or { panic(err) }
|
os.mkdir_all(wrkdir) or { panic(err) }
|
||||||
os.chdir(wrkdir)
|
os.chdir(wrkdir)
|
||||||
tests := files.filter(it.ends_with('.vv'))
|
tests := files.filter(it.ends_with('.vv'))
|
||||||
if tests.len == 0 {
|
if tests.len == 0 {
|
||||||
println('no x64 tests found')
|
println('no native tests found')
|
||||||
assert false
|
assert false
|
||||||
}
|
}
|
||||||
bench.set_total_expected_steps(tests.len)
|
bench.set_total_expected_steps(tests.len)
|
||||||
|
@ -32,10 +32,10 @@ fn test_x64() {
|
||||||
relative_test_path := full_test_path.replace(vroot + '/', '')
|
relative_test_path := full_test_path.replace(vroot + '/', '')
|
||||||
work_test_path := '$wrkdir/x.v'
|
work_test_path := '$wrkdir/x.v'
|
||||||
os.cp(full_test_path, work_test_path) or {}
|
os.cp(full_test_path, work_test_path) or {}
|
||||||
res_x64 := os.execute('$vexe -o exe -x64 $work_test_path')
|
res_native := os.execute('$vexe -o exe -native $work_test_path')
|
||||||
if res_x64.exit_code != 0 {
|
if res_native.exit_code != 0 {
|
||||||
bench.fail()
|
bench.fail()
|
||||||
eprintln(bench.step_message_fail('x64 $test failed'))
|
eprintln(bench.step_message_fail('native $test failed'))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
res := os.execute('./exe')
|
res := os.execute('./exe')
|
||||||
|
@ -64,7 +64,7 @@ fn test_x64() {
|
||||||
}
|
}
|
||||||
bench.stop()
|
bench.stop()
|
||||||
eprintln(term.h_divider('-'))
|
eprintln(term.h_divider('-'))
|
||||||
eprintln(bench.total_message('x64'))
|
eprintln(bench.total_message('native'))
|
||||||
if bench.nfail > 0 {
|
if bench.nfail > 0 {
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
fn print_greeting(){
|
fn print_greeting(){
|
||||||
println('hello from x64')
|
println('hello from native V')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_123() {
|
fn print_123() {
|
|
@ -0,0 +1,4 @@
|
||||||
|
start
|
||||||
|
hello from native V
|
||||||
|
123
|
||||||
|
end
|
|
@ -1,3 +0,0 @@
|
||||||
fn main() {
|
|
||||||
println('hello from x64')
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
hello from x64
|
|
|
@ -1,4 +0,0 @@
|
||||||
start
|
|
||||||
hello from x64
|
|
||||||
123
|
|
||||||
end
|
|
|
@ -47,7 +47,7 @@ pub enum ColorOutput {
|
||||||
pub enum Backend {
|
pub enum Backend {
|
||||||
c // The (default) C backend
|
c // The (default) C backend
|
||||||
js // The JavaScript backend
|
js // The JavaScript backend
|
||||||
x64 // The x64 backend
|
native // The Native backend
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum CompilerType {
|
pub enum CompilerType {
|
||||||
|
@ -429,8 +429,8 @@ pub fn parse_args(known_external_commands []string, args []string) (&Preferences
|
||||||
'-parallel' {
|
'-parallel' {
|
||||||
res.is_parallel = true
|
res.is_parallel = true
|
||||||
}
|
}
|
||||||
'-x64' {
|
'-native' {
|
||||||
res.backend = .x64
|
res.backend = .native
|
||||||
res.build_options << arg
|
res.build_options << arg
|
||||||
}
|
}
|
||||||
'-W' {
|
'-W' {
|
||||||
|
@ -700,7 +700,7 @@ pub fn backend_from_string(s string) ?Backend {
|
||||||
match s {
|
match s {
|
||||||
'c' { return .c }
|
'c' { return .c }
|
||||||
'js' { return .js }
|
'js' { return .js }
|
||||||
'x64' { return .x64 }
|
'native' { return .native }
|
||||||
else { return error('Unknown backend type $s') }
|
else { return error('Unknown backend type $s') }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ fn fname_without_platform_postfix(file string) string {
|
||||||
'_',
|
'_',
|
||||||
'solaris.c.v',
|
'solaris.c.v',
|
||||||
'_',
|
'_',
|
||||||
'x64.v',
|
'native.v',
|
||||||
'_',
|
'_',
|
||||||
])
|
])
|
||||||
return res
|
return res
|
||||||
|
@ -126,7 +126,7 @@ pub fn (prefs &Preferences) should_compile_c(file string) bool {
|
||||||
if prefs.os == .all {
|
if prefs.os == .all {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if prefs.backend != .x64 && file.ends_with('_x64.v') {
|
if prefs.backend != .native && file.ends_with('_native.v') {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if prefs.os != .windows && (file.ends_with('_windows.c.v') || file.ends_with('_windows.v')) {
|
if prefs.os != .windows && (file.ends_with('_windows.c.v') || file.ends_with('_windows.v')) {
|
||||||
|
|
Loading…
Reference in New Issue