@@ -81,6 +81,41 @@ func (c *Compiler) emitSyscall(frame *Frame, call *ssa.CallCommon) (llvm.Value,
81
81
fnType := llvm .FunctionType (c .uintptrType , argTypes , false )
82
82
target := llvm .InlineAsm (fnType , "svc #0" , constraints , true , false , 0 )
83
83
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 , "" )
84
119
default :
85
120
return llvm.Value {}, c .makeError (call .Pos (), "unknown GOOS/GOARCH for syscall: " + c .GOOS + "/" + c .GOARCH )
86
121
}
0 commit comments