1
2
3
4
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
71 for i := 0; i < ft.NumIn(); i++ {
72 sp, fn.Args = salloc(fn.Args, sp, ft.In(i))
73 }
74
75
76 for i := 0; i < ft.NumOut(); i++ {
77 sp, fn.Rets = salloc(fn.Rets, sp, ft.Out(i))
78 }
79
80
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
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
124 default : panic("unsupported operating system")
125 }
126
127
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
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
141 default : panic("unsupported operating system")
142 }
143
144
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
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
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 }
View as plain text