s390.c: Rename cfun_set_fpr_bit to cfun_set_fpr_save and cfun_fpr_bit_p to cfun_fpr_s...
[gcc.git] / libgo / runtime / print.c
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.
4
5 #include <stdarg.h>
6 #include "runtime.h"
7 #include "array.h"
8
9 //static Lock debuglock;
10
11 static void go_vprintf(const char*, va_list);
12
13 // write to goroutine-local buffer if diverting output,
14 // or else standard error.
15 static void
16 gwrite(const void *v, int32 n)
17 {
18 G* g = runtime_g();
19
20 if(g == nil || g->writebuf == nil) {
21 // Avoid -D_FORTIFY_SOURCE problems.
22 int rv __attribute__((unused));
23
24 rv = runtime_write(2, v, n);
25 return;
26 }
27
28 if(g->writenbuf == 0)
29 return;
30
31 if(n > g->writenbuf)
32 n = g->writenbuf;
33 runtime_memmove(g->writebuf, v, n);
34 g->writebuf += n;
35 g->writenbuf -= n;
36 }
37
38 void
39 runtime_dump(byte *p, int32 n)
40 {
41 int32 i;
42
43 for(i=0; i<n; i++) {
44 runtime_printpointer((byte*)(uintptr)(p[i]>>4));
45 runtime_printpointer((byte*)(uintptr)(p[i]&0xf));
46 if((i&15) == 15)
47 runtime_prints("\n");
48 else
49 runtime_prints(" ");
50 }
51 if(n & 15)
52 runtime_prints("\n");
53 }
54
55 void
56 runtime_prints(const char *s)
57 {
58 gwrite(s, runtime_findnull((const byte*)s));
59 }
60
61 void
62 runtime_printf(const char *s, ...)
63 {
64 va_list va;
65
66 va_start(va, s);
67 go_vprintf(s, va);
68 va_end(va);
69 }
70
71 // Very simple printf. Only for debugging prints.
72 // Do not add to this without checking with Rob.
73 static void
74 go_vprintf(const char *s, va_list va)
75 {
76 const char *p, *lp;
77
78 //runtime_lock(&debuglock);
79
80 lp = p = s;
81 for(; *p; p++) {
82 if(*p != '%')
83 continue;
84 if(p > lp)
85 gwrite(lp, p-lp);
86 p++;
87 switch(*p) {
88 case 'a':
89 runtime_printslice(va_arg(va, Slice));
90 break;
91 case 'd':
92 runtime_printint(va_arg(va, int32));
93 break;
94 case 'D':
95 runtime_printint(va_arg(va, int64));
96 break;
97 case 'e':
98 runtime_printeface(va_arg(va, Eface));
99 break;
100 case 'f':
101 runtime_printfloat(va_arg(va, float64));
102 break;
103 case 'C':
104 runtime_printcomplex(va_arg(va, __complex double));
105 break;
106 case 'i':
107 runtime_printiface(va_arg(va, Iface));
108 break;
109 case 'p':
110 runtime_printpointer(va_arg(va, void*));
111 break;
112 case 's':
113 runtime_prints(va_arg(va, char*));
114 break;
115 case 'S':
116 runtime_printstring(va_arg(va, String));
117 break;
118 case 't':
119 runtime_printbool(va_arg(va, int));
120 break;
121 case 'U':
122 runtime_printuint(va_arg(va, uint64));
123 break;
124 case 'x':
125 runtime_printhex(va_arg(va, uint32));
126 break;
127 case 'X':
128 runtime_printhex(va_arg(va, uint64));
129 break;
130 }
131 lp = p+1;
132 }
133 if(p > lp)
134 gwrite(lp, p-lp);
135
136 //runtime_unlock(&debuglock);
137 }
138
139 void
140 runtime_printpc(void *p __attribute__ ((unused)))
141 {
142 runtime_prints("PC=");
143 runtime_printhex((uint64)(uintptr)runtime_getcallerpc(p));
144 }
145
146 void
147 runtime_printbool(_Bool v)
148 {
149 if(v) {
150 gwrite("true", 4);
151 return;
152 }
153 gwrite("false", 5);
154 }
155
156 void
157 runtime_printfloat(double v)
158 {
159 byte buf[20];
160 int32 e, s, i, n;
161 float64 h;
162
163 if(ISNAN(v)) {
164 gwrite("NaN", 3);
165 return;
166 }
167 i = __builtin_isinf_sign(v);
168 if(i > 0) {
169 gwrite("+Inf", 4);
170 return;
171 }
172 if(i < 0) {
173 gwrite("-Inf", 4);
174 return;
175 }
176
177 n = 7; // digits printed
178 e = 0; // exp
179 s = 0; // sign
180 if(v != 0) {
181 // sign
182 if(v < 0) {
183 v = -v;
184 s = 1;
185 }
186
187 // normalize
188 while(v >= 10) {
189 e++;
190 v /= 10;
191 }
192 while(v < 1) {
193 e--;
194 v *= 10;
195 }
196
197 // round
198 h = 5;
199 for(i=0; i<n; i++)
200 h /= 10;
201
202 v += h;
203 if(v >= 10) {
204 e++;
205 v /= 10;
206 }
207 }
208
209 // format +d.dddd+edd
210 buf[0] = '+';
211 if(s)
212 buf[0] = '-';
213 for(i=0; i<n; i++) {
214 s = v;
215 buf[i+2] = s+'0';
216 v -= s;
217 v *= 10.;
218 }
219 buf[1] = buf[2];
220 buf[2] = '.';
221
222 buf[n+2] = 'e';
223 buf[n+3] = '+';
224 if(e < 0) {
225 e = -e;
226 buf[n+3] = '-';
227 }
228
229 buf[n+4] = (e/100) + '0';
230 buf[n+5] = (e/10)%10 + '0';
231 buf[n+6] = (e%10) + '0';
232 gwrite(buf, n+7);
233 }
234
235 void
236 runtime_printcomplex(__complex double v)
237 {
238 gwrite("(", 1);
239 runtime_printfloat(__builtin_creal(v));
240 runtime_printfloat(__builtin_cimag(v));
241 gwrite("i)", 2);
242 }
243
244 void
245 runtime_printuint(uint64 v)
246 {
247 byte buf[100];
248 int32 i;
249
250 for(i=nelem(buf)-1; i>0; i--) {
251 buf[i] = v%10 + '0';
252 if(v < 10)
253 break;
254 v = v/10;
255 }
256 gwrite(buf+i, nelem(buf)-i);
257 }
258
259 void
260 runtime_printint(int64 v)
261 {
262 if(v < 0) {
263 gwrite("-", 1);
264 v = -v;
265 }
266 runtime_printuint(v);
267 }
268
269 void
270 runtime_printhex(uint64 v)
271 {
272 static const char *dig = "0123456789abcdef";
273 byte buf[100];
274 int32 i;
275
276 i=nelem(buf);
277 for(; v>0; v/=16)
278 buf[--i] = dig[v%16];
279 if(i == nelem(buf))
280 buf[--i] = '0';
281 buf[--i] = 'x';
282 buf[--i] = '0';
283 gwrite(buf+i, nelem(buf)-i);
284 }
285
286 void
287 runtime_printpointer(void *p)
288 {
289 runtime_printhex((uint64)(uintptr)p);
290 }
291
292 void
293 runtime_printstring(String v)
294 {
295 // extern uint32 runtime_maxstring;
296
297 // if(v.len > runtime_maxstring) {
298 // gwrite("[string too long]", 17);
299 // return;
300 // }
301 if(v.len > 0)
302 gwrite(v.str, v.len);
303 }
304
305 void
306 __go_print_space(void)
307 {
308 gwrite(" ", 1);
309 }
310
311 void
312 __go_print_nl(void)
313 {
314 gwrite("\n", 1);
315 }