libgo, compiler: Upgrade libgo to Go 1.4, except for runtime.
[official-gcc.git] / libgo / go / runtime / print1.go
blob8f8268873b21ede2e671f453179651a74e396b81
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package runtime
7 import "unsafe"
9 // The compiler knows that a print of a value of this type
10 // should use printhex instead of printuint (decimal).
11 type hex uint64
13 func bytes(s string) (ret []byte) {
14 rp := (*slice)(unsafe.Pointer(&ret))
15 sp := (*_string)(noescape(unsafe.Pointer(&s)))
16 rp.array = sp.str
17 rp.len = uint(sp.len)
18 rp.cap = uint(sp.len)
19 return
22 // printf is only called from C code. It has no type information for the args,
23 // but C stacks are ignored by the garbage collector anyway, so having
24 // type information would not add anything.
25 //go:nosplit
26 func printf(s *byte) {
27 vprintf(gostringnocopy(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
30 // sprintf is only called from C code. It has no type information for the args,
31 // but C stacks are ignored by the garbage collector anyway, so having
32 // type information would not add anything.
33 //go:nosplit
34 func snprintf(dst *byte, n int32, s *byte) {
35 buf := (*[1 << 30]byte)(unsafe.Pointer(dst))[0:n:n]
37 gp := getg()
38 gp.writebuf = buf[0:0 : n-1] // leave room for NUL, this is called from C
39 vprintf(gostringnocopy(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
40 buf[len(gp.writebuf)] = '\x00'
41 gp.writebuf = nil
44 //var debuglock mutex
46 // write to goroutine-local buffer if diverting output,
47 // or else standard error.
48 func gwrite(b []byte) {
49 if len(b) == 0 {
50 return
52 gp := getg()
53 if gp == nil || gp.writebuf == nil {
54 write(2, unsafe.Pointer(&b[0]), int32(len(b)))
55 return
58 n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
59 gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
62 func prints(s *byte) {
63 b := (*[1 << 30]byte)(unsafe.Pointer(s))
64 for i := 0; ; i++ {
65 if b[i] == 0 {
66 gwrite(b[:i])
67 return
72 func printsp() {
73 print(" ")
76 func printnl() {
77 print("\n")
80 // Very simple printf. Only for debugging prints.
81 // Do not add to this without checking with Rob.
82 func vprintf(str string, arg unsafe.Pointer) {
83 //lock(&debuglock);
85 s := bytes(str)
86 start := 0
87 i := 0
88 for ; i < len(s); i++ {
89 if s[i] != '%' {
90 continue
92 if i > start {
93 gwrite(s[start:i])
95 if i++; i >= len(s) {
96 break
98 var siz uintptr
99 switch s[i] {
100 case 't', 'c':
101 siz = 1
102 case 'd', 'x': // 32-bit
103 arg = roundup(arg, 4)
104 siz = 4
105 case 'D', 'U', 'X', 'f': // 64-bit
106 arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
107 siz = 8
108 case 'C':
109 arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
110 siz = 16
111 case 'p', 's': // pointer-sized
112 arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
113 siz = unsafe.Sizeof(uintptr(0))
114 case 'S': // pointer-aligned but bigger
115 arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
116 siz = unsafe.Sizeof(string(""))
117 case 'a': // pointer-aligned but bigger
118 arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
119 siz = unsafe.Sizeof([]byte{})
120 case 'i', 'e': // pointer-aligned but bigger
121 arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
122 siz = unsafe.Sizeof(interface{}(nil))
124 switch s[i] {
125 case 'a':
126 printslice(*(*[]byte)(arg))
127 case 'c':
128 printbyte(*(*byte)(arg))
129 case 'd':
130 printint(int64(*(*int32)(arg)))
131 case 'D':
132 printint(int64(*(*int64)(arg)))
133 case 'e':
134 printeface(*(*interface{})(arg))
135 case 'f':
136 printfloat(*(*float64)(arg))
137 case 'C':
138 printcomplex(*(*complex128)(arg))
139 case 'i':
140 printiface(*(*fInterface)(arg))
141 case 'p':
142 printpointer(*(*unsafe.Pointer)(arg))
143 case 's':
144 prints(*(**byte)(arg))
145 case 'S':
146 printstring(*(*string)(arg))
147 case 't':
148 printbool(*(*bool)(arg))
149 case 'U':
150 printuint(*(*uint64)(arg))
151 case 'x':
152 printhex(uint64(*(*uint32)(arg)))
153 case 'X':
154 printhex(*(*uint64)(arg))
156 arg = add(arg, siz)
157 start = i + 1
159 if start < i {
160 gwrite(s[start:i])
163 //unlock(&debuglock);
166 func printpc(p unsafe.Pointer) {
167 print("PC=", hex(uintptr(p)))
170 func printbool(v bool) {
171 if v {
172 print("true")
173 } else {
174 print("false")
178 func printbyte(c byte) {
179 gwrite((*[1]byte)(unsafe.Pointer(&c))[:])
182 func printfloat(v float64) {
183 switch {
184 case v != v:
185 print("NaN")
186 return
187 case v+v == v && v > 0:
188 print("+Inf")
189 return
190 case v+v == v && v < 0:
191 print("-Inf")
192 return
195 const n = 7 // digits printed
196 var buf [n + 7]byte
197 buf[0] = '+'
198 e := 0 // exp
199 if v == 0 {
200 if 1/v < 0 {
201 buf[0] = '-'
203 } else {
204 if v < 0 {
205 v = -v
206 buf[0] = '-'
209 // normalize
210 for v >= 10 {
212 v /= 10
214 for v < 1 {
216 v *= 10
219 // round
220 h := 5.0
221 for i := 0; i < n; i++ {
222 h /= 10
224 v += h
225 if v >= 10 {
227 v /= 10
231 // format +d.dddd+edd
232 for i := 0; i < n; i++ {
233 s := int(v)
234 buf[i+2] = byte(s + '0')
235 v -= float64(s)
236 v *= 10
238 buf[1] = buf[2]
239 buf[2] = '.'
241 buf[n+2] = 'e'
242 buf[n+3] = '+'
243 if e < 0 {
244 e = -e
245 buf[n+3] = '-'
248 buf[n+4] = byte(e/100) + '0'
249 buf[n+5] = byte(e/10)%10 + '0'
250 buf[n+6] = byte(e%10) + '0'
251 gwrite(buf[:])
254 func printcomplex(c complex128) {
255 print("(", real(c), imag(c), "i)")
258 func printuint(v uint64) {
259 var buf [100]byte
260 i := len(buf)
261 for i--; i > 0; i-- {
262 buf[i] = byte(v%10 + '0')
263 if v < 10 {
264 break
266 v /= 10
268 gwrite(buf[i:])
271 func printint(v int64) {
272 if v < 0 {
273 print("-")
274 v = -v
276 printuint(uint64(v))
279 func printhex(v uint64) {
280 const dig = "0123456789abcdef"
281 var buf [100]byte
282 i := len(buf)
283 for i--; i > 0; i-- {
284 buf[i] = dig[v%16]
285 if v < 16 {
286 break
288 v /= 16
291 buf[i] = 'x'
293 buf[i] = '0'
294 gwrite(buf[i:])
297 func printpointer(p unsafe.Pointer) {
298 printhex(uint64(uintptr(p)))
301 func printstring(s string) {
302 if uintptr(len(s)) > maxstring {
303 gwrite(bytes("[string too long]"))
304 return
306 gwrite(bytes(s))
309 func printslice(s []byte) {
310 sp := (*slice)(unsafe.Pointer(&s))
311 print("[", len(s), "/", cap(s), "]")
312 printpointer(unsafe.Pointer(sp.array))
315 func printeface(e interface{}) {
316 ep := (*eface)(unsafe.Pointer(&e))
317 print("(", ep._type, ",", ep.data, ")")
320 func printiface(i fInterface) {
321 ip := (*iface)(unsafe.Pointer(&i))
322 print("(", ip.tab, ",", ip.data, ")")