podman

Форк
0
182 строки · 6.9 Кб
1
//go:build !go1.17
2
// +build !go1.17
3

4
/*
5
 * Copyright 2022 ByteDance Inc.
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19

20
package abi
21

22
import (
23
    `fmt`
24
    `reflect`
25
    `runtime`
26

27
    . `github.com/chenzhuoyu/iasm/x86_64`
28
)
29

30
func ReservedRegs(callc bool) []Register {
31
    return nil
32
}
33

34
func salloc(p []Parameter, sp uint32, vt reflect.Type) (uint32, []Parameter) {
35
    switch vt.Kind() {
36
        case reflect.Bool          : return sp + 8, append(p, mkStack(reflect.TypeOf(false), sp))
37
        case reflect.Int           : return sp + 8, append(p, mkStack(intType, sp))
38
        case reflect.Int8          : return sp + 8, append(p, mkStack(reflect.TypeOf(int8(0)), sp))
39
        case reflect.Int16         : return sp + 8, append(p, mkStack(reflect.TypeOf(int16(0)), sp))
40
        case reflect.Int32         : return sp + 8, append(p, mkStack(reflect.TypeOf(int32(0)), sp))
41
        case reflect.Int64         : return sp + 8, append(p, mkStack(reflect.TypeOf(int64(0)), sp))
42
        case reflect.Uint          : return sp + 8, append(p, mkStack(reflect.TypeOf(uint(0)), sp))
43
        case reflect.Uint8         : return sp + 8, append(p, mkStack(reflect.TypeOf(uint8(0)), sp))
44
        case reflect.Uint16        : return sp + 8, append(p, mkStack(reflect.TypeOf(uint16(0)), sp))
45
        case reflect.Uint32        : return sp + 8, append(p, mkStack(reflect.TypeOf(uint32(0)), sp))
46
        case reflect.Uint64        : return sp + 8, append(p, mkStack(reflect.TypeOf(uint64(0)), sp))
47
        case reflect.Uintptr       : return sp + 8, append(p, mkStack(reflect.TypeOf(uintptr(0)), sp))
48
        case reflect.Float32       : return sp + 8, append(p, mkStack(reflect.TypeOf(float32(0)), sp))
49
        case reflect.Float64       : return sp + 8, append(p, mkStack(reflect.TypeOf(float64(0)), sp))
50
        case reflect.Complex64     : panic("abi: go116: not implemented: complex64")
51
        case reflect.Complex128    : panic("abi: go116: not implemented: complex128")
52
        case reflect.Array         : panic("abi: go116: not implemented: arrays")
53
        case reflect.Chan          : return sp +  8, append(p, mkStack(reflect.TypeOf((chan int)(nil)), sp))
54
        case reflect.Func          : return sp +  8, append(p, mkStack(reflect.TypeOf((func())(nil)), sp))
55
        case reflect.Map           : return sp +  8, append(p, mkStack(reflect.TypeOf((map[int]int)(nil)), sp))
56
        case reflect.Ptr           : return sp +  8, append(p, mkStack(reflect.TypeOf((*int)(nil)), sp))
57
        case reflect.UnsafePointer : return sp +  8, append(p, mkStack(ptrType, sp))
58
        case reflect.Interface     : return sp + 16, append(p, mkStack(ptrType, sp), mkStack(ptrType, sp + 8))
59
        case reflect.Slice         : return sp + 24, append(p, mkStack(ptrType, sp), mkStack(intType, sp + 8), mkStack(intType, sp + 16))
60
        case reflect.String        : return sp + 16, append(p, mkStack(ptrType, sp), mkStack(intType, sp + 8))
61
        case reflect.Struct        : panic("abi: go116: not implemented: structs")
62
        default                    : panic("abi: invalid value type")
63
    }
64
}
65

66
func NewFunctionLayout(ft reflect.Type) FunctionLayout {
67
    var sp uint32
68
    var fn FunctionLayout
69

70
    /* assign every arguments */
71
    for i := 0; i < ft.NumIn(); i++ {
72
        sp, fn.Args = salloc(fn.Args, sp, ft.In(i))
73
    }
74

75
    /* assign every return value */
76
    for i := 0; i < ft.NumOut(); i++ {
77
        sp, fn.Rets = salloc(fn.Rets, sp, ft.Out(i))
78
    }
79

80
    /* update function ID and stack pointer */
81
    fn.FP = sp
82
    return fn
83
}
84

85
func (self *Frame) emitExchangeArgs(p *Program) {
86
    iregArgs, xregArgs := 0, 0
87
    for _, v := range self.desc.Args {
88
        if v.IsFloat != notFloatKind {
89
            xregArgs += 1
90
        } else {
91
            iregArgs += 1
92
        }
93
    }
94

95
    if iregArgs > len(iregOrderC) {
96
        panic("too many arguments, only support at most 6 integer arguments now")
97
    }
98
    if xregArgs > len(xregOrderC) {
99
        panic("too many arguments, only support at most 8 float arguments now")
100
    }
101

102
    ic, xc := iregArgs, xregArgs
103
    for i := 0; i < len(self.desc.Args); i++ {
104
        arg := self.desc.Args[i]
105
        if arg.IsFloat == floatKind64 {
106
            p.MOVSD(self.argv(i), xregOrderC[xregArgs - xc])
107
            xc -= 1 
108
        } else if arg.IsFloat == floatKind32 {
109
            p.MOVSS(self.argv(i), xregOrderC[xregArgs - xc])
110
            xc -= 1 
111
        } else {
112
            p.MOVQ(self.argv(i), iregOrderC[iregArgs - ic])
113
            ic -= 1
114
        }
115
    }
116
}
117

118
func (self *Frame) emitStackCheck(p *Program, to *Label, maxStack uintptr) {
119
    // get the current goroutine
120
    switch runtime.GOOS {
121
        case "linux"  : p.MOVQ(Abs(-8), R14).FS()
122
        case "darwin" : p.MOVQ(Abs(0x30), R14).GS()
123
        case "windows": break // windows always stores G pointer at R14 
124
        default       : panic("unsupported operating system")
125
    }
126
    
127
    // check the stack guard
128
    p.LEAQ(Ptr(RSP, -int32(self.Size() + uint32(maxStack))), RAX)
129
    p.CMPQ(Ptr(R14, _G_stackguard0), RAX)
130
    p.JBE(to)
131
}
132

133
func (self *Frame) StackCheckTextSize() uint32 {
134
    p := DefaultArch.CreateProgram()
135

136
    // get the current goroutine
137
    switch runtime.GOOS {
138
        case "linux"  : p.MOVQ(Abs(-8), R14).FS()
139
        case "darwin" : p.MOVQ(Abs(0x30), R14).GS()
140
        case "windows": break // windows always stores G pointer at R14 
141
        default       : panic("unsupported operating system")
142
    }
143
    
144
    // check the stack guard
145
    p.LEAQ(Ptr(RSP, -int32(self.Size())), RAX)
146
    p.CMPQ(Ptr(R14, _G_stackguard0), RAX)
147
    l := CreateLabel("")
148
    p.Link(l)
149
    p.JBE(l)
150

151
    return uint32(len(p.Assemble(0)))
152
}
153

154
func (self *Frame) emitExchangeRets(p *Program) {
155
    if len(self.desc.Rets) > 1 {
156
        panic("too many results, only support one result now")
157
    }    
158
    // store result
159
    if len(self.desc.Rets) ==1 {
160
        if self.desc.Rets[0].IsFloat == floatKind64 {
161
            p.MOVSD(xregOrderC[0], self.retv(0))
162
        } else if self.desc.Rets[0].IsFloat == floatKind32 {
163
            p.MOVSS(xregOrderC[0], self.retv(0))
164
        } else {
165
            p.MOVQ(RAX, self.retv(0))
166
        }
167
    }
168
}
169

170
func (self *Frame) emitRestoreRegs(p *Program) {
171
    // load reserved registers
172
    for i, r := range ReservedRegs(self.ccall) {
173
        switch r.(type) {
174
        case Register64:
175
            p.MOVQ(self.resv(i), r)
176
        case XMMRegister:
177
            p.MOVSD(self.resv(i), r)
178
        default:
179
            panic(fmt.Sprintf("unsupported register type %t to reserve", r))
180
        }
181
    }
182
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.