2008-06-30 12:50:36 -06:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "runtime.h"
|
2010-03-30 11:53:16 -06:00
|
|
|
#include "type.h"
|
2008-06-30 12:50:36 -06:00
|
|
|
|
2009-10-12 11:26:38 -06:00
|
|
|
//static Lock debuglock;
|
2008-06-30 12:50:36 -06:00
|
|
|
|
2010-01-27 16:37:08 -07:00
|
|
|
static void vprintf(int8*, byte*);
|
|
|
|
|
2008-06-30 12:50:36 -06:00
|
|
|
void
|
|
|
|
dump(byte *p, int32 n)
|
|
|
|
{
|
|
|
|
int32 i;
|
|
|
|
|
|
|
|
for(i=0; i<n; i++) {
|
2010-01-25 19:52:55 -07:00
|
|
|
·printpointer((byte*)(p[i]>>4));
|
|
|
|
·printpointer((byte*)(p[i]&0xf));
|
2008-06-30 12:50:36 -06:00
|
|
|
if((i&15) == 15)
|
|
|
|
prints("\n");
|
|
|
|
else
|
|
|
|
prints(" ");
|
|
|
|
}
|
|
|
|
if(n & 15)
|
|
|
|
prints("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
prints(int8 *s)
|
|
|
|
{
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, s, findnull((byte*)s));
|
2008-06-30 12:50:36 -06:00
|
|
|
}
|
|
|
|
|
2010-01-27 16:37:08 -07:00
|
|
|
#pragma textflag 7
|
2008-11-25 17:48:10 -07:00
|
|
|
void
|
|
|
|
printf(int8 *s, ...)
|
2010-01-27 16:37:08 -07:00
|
|
|
{
|
|
|
|
byte *arg;
|
|
|
|
|
|
|
|
arg = (byte*)(&s+1);
|
|
|
|
vprintf(s, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
static byte*
|
|
|
|
vrnd(byte *p, int32 x)
|
|
|
|
{
|
|
|
|
if((uint32)(uintptr)p&(x-1))
|
|
|
|
p += x - ((uint32)(uintptr)p&(x-1));
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Very simple printf. Only for debugging prints.
|
|
|
|
// Do not add to this without checking with Rob.
|
|
|
|
static void
|
|
|
|
vprintf(int8 *s, byte *arg)
|
2008-11-25 17:48:10 -07:00
|
|
|
{
|
|
|
|
int8 *p, *lp;
|
2010-01-27 16:37:08 -07:00
|
|
|
byte *narg;
|
2008-11-25 17:48:10 -07:00
|
|
|
|
2009-10-12 11:26:38 -06:00
|
|
|
// lock(&debuglock);
|
2009-10-09 17:45:20 -06:00
|
|
|
|
2008-11-25 17:48:10 -07:00
|
|
|
lp = p = s;
|
|
|
|
for(; *p; p++) {
|
|
|
|
if(*p != '%')
|
|
|
|
continue;
|
|
|
|
if(p > lp)
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, lp, p-lp);
|
2008-11-25 17:48:10 -07:00
|
|
|
p++;
|
2009-03-30 01:01:07 -06:00
|
|
|
narg = nil;
|
|
|
|
switch(*p) {
|
2010-01-27 16:37:08 -07:00
|
|
|
case 't':
|
|
|
|
narg = arg + 1;
|
|
|
|
break;
|
2009-03-30 01:01:07 -06:00
|
|
|
case 'd': // 32-bit
|
|
|
|
case 'x':
|
2010-01-27 16:37:08 -07:00
|
|
|
arg = vrnd(arg, 4);
|
2009-03-30 01:01:07 -06:00
|
|
|
narg = arg + 4;
|
|
|
|
break;
|
|
|
|
case 'D': // 64-bit
|
2010-01-27 16:37:08 -07:00
|
|
|
case 'U':
|
2009-03-30 01:01:07 -06:00
|
|
|
case 'X':
|
2010-01-27 16:37:08 -07:00
|
|
|
case 'f':
|
|
|
|
arg = vrnd(arg, sizeof(uintptr));
|
2009-03-30 01:01:07 -06:00
|
|
|
narg = arg + 8;
|
|
|
|
break;
|
2010-03-05 21:16:04 -07:00
|
|
|
case 'C':
|
|
|
|
arg = vrnd(arg, sizeof(uintptr));
|
|
|
|
narg = arg + 16;
|
|
|
|
break;
|
2009-03-30 01:01:07 -06:00
|
|
|
case 'p': // pointer-sized
|
|
|
|
case 's':
|
2010-01-27 16:37:08 -07:00
|
|
|
arg = vrnd(arg, sizeof(uintptr));
|
2009-03-30 01:01:07 -06:00
|
|
|
narg = arg + sizeof(uintptr);
|
|
|
|
break;
|
2009-04-15 19:52:28 -06:00
|
|
|
case 'S': // pointer-aligned but bigger
|
2010-01-27 16:37:08 -07:00
|
|
|
arg = vrnd(arg, sizeof(uintptr));
|
2009-04-15 19:52:28 -06:00
|
|
|
narg = arg + sizeof(String);
|
|
|
|
break;
|
2010-01-27 16:37:08 -07:00
|
|
|
case 'a': // pointer-aligned but bigger
|
|
|
|
arg = vrnd(arg, sizeof(uintptr));
|
|
|
|
narg = arg + sizeof(Slice);
|
|
|
|
break;
|
|
|
|
case 'i': // pointer-aligned but bigger
|
|
|
|
case 'e':
|
|
|
|
arg = vrnd(arg, sizeof(uintptr));
|
|
|
|
narg = arg + sizeof(Eface);
|
|
|
|
break;
|
2009-03-30 01:01:07 -06:00
|
|
|
}
|
2008-11-25 17:48:10 -07:00
|
|
|
switch(*p) {
|
2010-01-27 16:37:08 -07:00
|
|
|
case 'a':
|
|
|
|
·printslice(*(Slice*)arg);
|
|
|
|
break;
|
2008-11-25 17:48:10 -07:00
|
|
|
case 'd':
|
2010-01-25 19:52:55 -07:00
|
|
|
·printint(*(int32*)arg);
|
2008-11-25 17:48:10 -07:00
|
|
|
break;
|
|
|
|
case 'D':
|
2010-01-25 19:52:55 -07:00
|
|
|
·printint(*(int64*)arg);
|
2008-11-25 17:48:10 -07:00
|
|
|
break;
|
2010-01-27 16:37:08 -07:00
|
|
|
case 'e':
|
|
|
|
·printeface(*(Eface*)arg);
|
2008-11-25 17:48:10 -07:00
|
|
|
break;
|
2010-01-27 16:37:08 -07:00
|
|
|
case 'f':
|
|
|
|
·printfloat(*(float64*)arg);
|
|
|
|
break;
|
2010-02-19 21:42:50 -07:00
|
|
|
case 'C':
|
|
|
|
·printcomplex(*(Complex128*)arg);
|
|
|
|
break;
|
2010-01-27 16:37:08 -07:00
|
|
|
case 'i':
|
|
|
|
·printiface(*(Iface*)arg);
|
2008-11-25 17:48:10 -07:00
|
|
|
break;
|
|
|
|
case 'p':
|
2010-01-25 19:52:55 -07:00
|
|
|
·printpointer(*(void**)arg);
|
2008-11-25 17:48:10 -07:00
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
prints(*(int8**)arg);
|
|
|
|
break;
|
|
|
|
case 'S':
|
2010-01-25 19:52:55 -07:00
|
|
|
·printstring(*(String*)arg);
|
2008-11-25 17:48:10 -07:00
|
|
|
break;
|
2010-01-27 16:37:08 -07:00
|
|
|
case 't':
|
|
|
|
·printbool(*(bool*)arg);
|
|
|
|
break;
|
|
|
|
case 'U':
|
|
|
|
·printuint(*(uint64*)arg);
|
|
|
|
break;
|
|
|
|
case 'x':
|
|
|
|
·printhex(*(uint32*)arg);
|
|
|
|
break;
|
|
|
|
case 'X':
|
|
|
|
·printhex(*(uint64*)arg);
|
|
|
|
break;
|
|
|
|
case '!':
|
2010-03-30 11:53:16 -06:00
|
|
|
panic(-1);
|
2008-11-25 17:48:10 -07:00
|
|
|
}
|
2009-03-30 01:01:07 -06:00
|
|
|
arg = narg;
|
2008-11-25 17:48:10 -07:00
|
|
|
lp = p+1;
|
|
|
|
}
|
|
|
|
if(p > lp)
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, lp, p-lp);
|
2009-10-09 17:45:20 -06:00
|
|
|
|
2009-10-12 11:26:38 -06:00
|
|
|
// unlock(&debuglock);
|
2008-11-25 17:48:10 -07:00
|
|
|
}
|
|
|
|
|
2010-03-04 16:34:25 -07:00
|
|
|
#pragma textflag 7
|
2010-01-27 16:37:08 -07:00
|
|
|
void
|
|
|
|
·printf(String s, ...)
|
|
|
|
{
|
|
|
|
// Can assume s has terminating NUL because only
|
|
|
|
// the Go compiler generates calls to ·printf, using
|
|
|
|
// string constants, and all the string constants have NULs.
|
|
|
|
vprintf((int8*)s.str, (byte*)(&s+1));
|
|
|
|
}
|
2008-11-25 17:48:10 -07:00
|
|
|
|
2008-06-30 12:50:36 -06:00
|
|
|
void
|
2010-01-25 19:52:55 -07:00
|
|
|
·printpc(void *p)
|
2008-06-30 12:50:36 -06:00
|
|
|
{
|
2008-11-25 17:48:10 -07:00
|
|
|
prints("PC=");
|
2010-01-25 19:52:55 -07:00
|
|
|
·printhex((uint64)·getcallerpc(p));
|
2008-06-30 12:50:36 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-01-25 19:52:55 -07:00
|
|
|
·printbool(bool v)
|
2008-06-30 12:50:36 -06:00
|
|
|
{
|
|
|
|
if(v) {
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, (byte*)"true", 4);
|
2008-06-30 12:50:36 -06:00
|
|
|
return;
|
|
|
|
}
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, (byte*)"false", 5);
|
2008-06-30 12:50:36 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-01-25 19:52:55 -07:00
|
|
|
·printfloat(float64 v)
|
2008-06-30 12:50:36 -06:00
|
|
|
{
|
2008-07-04 19:01:35 -06:00
|
|
|
byte buf[20];
|
|
|
|
int32 e, s, i, n;
|
|
|
|
float64 h;
|
|
|
|
|
2008-11-10 15:54:10 -07:00
|
|
|
if(isNaN(v)) {
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, "NaN", 3);
|
2008-11-10 15:54:10 -07:00
|
|
|
return;
|
|
|
|
}
|
2010-06-01 15:08:15 -06:00
|
|
|
if(isInf(v, 1)) {
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, "+Inf", 4);
|
2008-11-10 15:54:10 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(isInf(v, -1)) {
|
2010-06-01 15:08:15 -06:00
|
|
|
write(fd, "-Inf", 4);
|
2008-11-10 15:54:10 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-09-27 14:33:50 -06:00
|
|
|
n = 7; // digits printed
|
2008-07-04 19:01:35 -06:00
|
|
|
e = 0; // exp
|
|
|
|
s = 0; // sign
|
|
|
|
if(v != 0) {
|
|
|
|
// sign
|
|
|
|
if(v < 0) {
|
|
|
|
v = -v;
|
|
|
|
s = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// normalize
|
|
|
|
while(v >= 10) {
|
|
|
|
e++;
|
|
|
|
v /= 10;
|
|
|
|
}
|
|
|
|
while(v < 1) {
|
|
|
|
e--;
|
|
|
|
v *= 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
// round
|
|
|
|
h = 5;
|
|
|
|
for(i=0; i<n; i++)
|
|
|
|
h /= 10;
|
|
|
|
v += h;
|
|
|
|
if(v >= 10) {
|
|
|
|
e++;
|
|
|
|
v /= 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// format +d.dddd+edd
|
|
|
|
buf[0] = '+';
|
|
|
|
if(s)
|
|
|
|
buf[0] = '-';
|
|
|
|
for(i=0; i<n; i++) {
|
|
|
|
s = v;
|
|
|
|
buf[i+2] = s+'0';
|
|
|
|
v -= s;
|
|
|
|
v *= 10.;
|
|
|
|
}
|
|
|
|
buf[1] = buf[2];
|
|
|
|
buf[2] = '.';
|
|
|
|
|
2008-09-14 17:57:55 -06:00
|
|
|
buf[n+2] = 'e';
|
|
|
|
buf[n+3] = '+';
|
2008-07-04 19:01:35 -06:00
|
|
|
if(e < 0) {
|
|
|
|
e = -e;
|
2008-09-14 17:57:55 -06:00
|
|
|
buf[n+3] = '-';
|
2008-07-04 19:01:35 -06:00
|
|
|
}
|
2008-09-14 17:57:55 -06:00
|
|
|
|
2008-11-10 15:54:10 -07:00
|
|
|
buf[n+4] = (e/100) + '0';
|
|
|
|
buf[n+5] = (e/10)%10 + '0';
|
|
|
|
buf[n+6] = (e%10) + '0';
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, buf, n+7);
|
2008-06-30 12:50:36 -06:00
|
|
|
}
|
|
|
|
|
2010-02-19 21:42:50 -07:00
|
|
|
void
|
|
|
|
·printcomplex(Complex128 v)
|
|
|
|
{
|
|
|
|
write(fd, "(", 1);
|
|
|
|
·printfloat(v.real);
|
|
|
|
·printfloat(v.imag);
|
|
|
|
write(fd, "i)", 2);
|
|
|
|
}
|
|
|
|
|
2008-06-30 12:50:36 -06:00
|
|
|
void
|
2010-01-25 19:52:55 -07:00
|
|
|
·printuint(uint64 v)
|
2008-06-30 12:50:36 -06:00
|
|
|
{
|
|
|
|
byte buf[100];
|
2008-11-10 15:54:10 -07:00
|
|
|
int32 i;
|
2008-06-30 12:50:36 -06:00
|
|
|
|
|
|
|
for(i=nelem(buf)-1; i>0; i--) {
|
|
|
|
buf[i] = v%10 + '0';
|
|
|
|
if(v < 10)
|
|
|
|
break;
|
|
|
|
v = v/10;
|
|
|
|
}
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, buf+i, nelem(buf)-i);
|
2008-06-30 12:50:36 -06:00
|
|
|
}
|
|
|
|
|
2008-11-10 15:54:10 -07:00
|
|
|
void
|
2010-01-25 19:52:55 -07:00
|
|
|
·printint(int64 v)
|
2008-11-10 15:54:10 -07:00
|
|
|
{
|
|
|
|
if(v < 0) {
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, "-", 1);
|
2008-11-10 15:54:10 -07:00
|
|
|
v = -v;
|
|
|
|
}
|
2010-01-25 19:52:55 -07:00
|
|
|
·printuint(v);
|
2008-11-10 15:54:10 -07:00
|
|
|
}
|
|
|
|
|
2008-06-30 12:50:36 -06:00
|
|
|
void
|
2010-01-25 19:52:55 -07:00
|
|
|
·printhex(uint64 v)
|
2008-06-30 12:50:36 -06:00
|
|
|
{
|
2008-11-25 17:48:10 -07:00
|
|
|
static int8 *dig = "0123456789abcdef";
|
2008-06-30 12:50:36 -06:00
|
|
|
byte buf[100];
|
|
|
|
int32 i;
|
|
|
|
|
2008-11-25 17:48:10 -07:00
|
|
|
i=nelem(buf);
|
|
|
|
for(; v>0; v/=16)
|
|
|
|
buf[--i] = dig[v%16];
|
|
|
|
if(i == nelem(buf))
|
|
|
|
buf[--i] = '0';
|
|
|
|
buf[--i] = 'x';
|
|
|
|
buf[--i] = '0';
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, buf+i, nelem(buf)-i);
|
2008-06-30 12:50:36 -06:00
|
|
|
}
|
|
|
|
|
2008-11-25 17:48:10 -07:00
|
|
|
void
|
2010-01-25 19:52:55 -07:00
|
|
|
·printpointer(void *p)
|
2008-11-25 17:48:10 -07:00
|
|
|
{
|
2010-01-25 19:52:55 -07:00
|
|
|
·printhex((uint64)p);
|
2008-11-25 17:48:10 -07:00
|
|
|
}
|
|
|
|
|
2008-06-30 12:50:36 -06:00
|
|
|
void
|
2010-01-25 19:52:55 -07:00
|
|
|
·printstring(String v)
|
2008-06-30 12:50:36 -06:00
|
|
|
{
|
2009-01-29 18:38:58 -07:00
|
|
|
extern int32 maxstring;
|
|
|
|
|
2009-04-09 19:16:21 -06:00
|
|
|
if(v.len > maxstring) {
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, "[invalid string]", 16);
|
2009-04-09 19:16:21 -06:00
|
|
|
return;
|
2009-01-29 18:38:58 -07:00
|
|
|
}
|
2009-04-09 19:16:21 -06:00
|
|
|
if(v.len > 0)
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, v.str, v.len);
|
2008-06-30 12:50:36 -06:00
|
|
|
}
|
2008-10-02 15:38:07 -06:00
|
|
|
|
|
|
|
void
|
2010-01-25 19:52:55 -07:00
|
|
|
·printsp(void)
|
2008-10-02 15:38:07 -06:00
|
|
|
{
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, " ", 1);
|
2008-10-02 15:38:07 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-01-25 19:52:55 -07:00
|
|
|
·printnl(void)
|
2008-10-02 15:38:07 -06:00
|
|
|
{
|
2009-10-13 23:48:03 -06:00
|
|
|
write(fd, "\n", 1);
|
2008-10-02 15:38:07 -06:00
|
|
|
}
|