Skip to content

Commit 3cba36f

Browse files
aykevldeadprogram
authored andcommitted
compiler: add syscalls for 64-bit arm
1 parent 93d5269 commit 3cba36f

File tree

4 files changed

+49
-1
lines changed

4 files changed

+49
-1
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ addons:
1818
- gcc-arm-linux-gnueabi
1919
- binutils-arm-none-eabi
2020
- libc6-dev-armel-cross
21+
- gcc-aarch64-linux-gnu
22+
- libc6-dev-arm64-cross
2123
- qemu-system-arm
2224
- qemu-user
2325
- gcc-avr

compiler/syscall.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,41 @@ func (c *Compiler) emitSyscall(frame *Frame, call *ssa.CallCommon) (llvm.Value,
8181
fnType := llvm.FunctionType(c.uintptrType, argTypes, false)
8282
target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0)
8383
syscallResult = c.builder.CreateCall(target, args, "")
84+
case c.GOARCH == "arm64" && c.GOOS == "linux":
85+
// Source: syscall(2) man page.
86+
args := []llvm.Value{}
87+
argTypes := []llvm.Type{}
88+
// Constraints will look something like:
89+
// ={x0},0,{x1},{x2},{x8},~{x3},~{x4},~{x5},~{x6},~{x7},~{x16},~{x17}
90+
constraints := "={x0}"
91+
for i, arg := range call.Args[1:] {
92+
constraints += "," + [...]string{
93+
"0", // tie to output
94+
"{x1}",
95+
"{x2}",
96+
"{x3}",
97+
"{x4}",
98+
"{x5}",
99+
}[i]
100+
llvmValue, err := c.parseExpr(frame, arg)
101+
if err != nil {
102+
return llvm.Value{}, err
103+
}
104+
args = append(args, llvmValue)
105+
argTypes = append(argTypes, llvmValue.Type())
106+
}
107+
args = append(args, llvm.ConstInt(c.uintptrType, num, false))
108+
argTypes = append(argTypes, c.uintptrType)
109+
constraints += ",{x8}" // syscall number
110+
for i := len(call.Args) - 1; i < 8; i++ {
111+
// x0-x7 may get clobbered during the syscall following the aarch64
112+
// calling convention.
113+
constraints += ",~{x" + strconv.Itoa(i) + "}"
114+
}
115+
constraints += ",~{x16},~{x17}" // scratch registers
116+
fnType := llvm.FunctionType(c.uintptrType, argTypes, false)
117+
target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0)
118+
syscallResult = c.builder.CreateCall(target, args, "")
84119
default:
85120
return llvm.Value{}, c.makeError(call.Pos(), "unknown GOOS/GOARCH for syscall: "+c.GOOS+"/"+c.GOARCH)
86121
}

main_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ func TestCompiler(t *testing.T) {
6363
})
6464
}
6565

66+
t.Log("running tests for linux/arm64...")
67+
for _, path := range matches {
68+
if path == "testdata/cgo/" {
69+
continue // TODO: improve CGo
70+
}
71+
t.Run(path, func(t *testing.T) {
72+
runTest(path, tmpdir, "aarch64--linux-gnueabi", t)
73+
})
74+
}
75+
6676
t.Log("running tests for emulated cortex-m3...")
6777
for _, path := range matches {
6878
t.Run(path, func(t *testing.T) {

target.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,11 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
224224
spec.GDB = "arm-linux-gnueabi-gdb"
225225
spec.Emulator = []string{"qemu-arm", "-L", "/usr/arm-linux-gnueabi"}
226226
}
227-
if goarch == "arm64" {
227+
if goarch == "arm64" && goos == "linux" {
228228
spec.Linker = "aarch64-linux-gnu-gcc"
229229
spec.Objcopy = "aarch64-linux-gnu-objcopy"
230230
spec.GDB = "aarch64-linux-gnu-gdb"
231+
spec.Emulator = []string{"qemu-aarch64", "-L", "/usr/aarch64-linux-gnu"}
231232
}
232233
if goarch == "386" {
233234
spec.CFlags = []string{"-m32"}

0 commit comments

Comments
 (0)