@@ -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 }
0 commit comments