Files
ldc/backend/debug.c
Alexey Prokhin caad8cde58 Squashed 'dmd2/' content from commit 10017d5
git-subtree-dir: dmd2
git-subtree-split: 10017d50eaaff4ecdc37a0153b6c37ea0b004c81
2012-04-05 11:10:48 +04:00

416 lines
10 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright (C) 1985-1998 by Symantec
// Copyright (C) 2000-2009 by Digital Mars
// All Rights Reserved
// http://www.digitalmars.com
// Written by Walter Bright
/*
* This source file is made available for personal use
* only. The license is in /dmd/src/dmd/backendlicense.txt
* or /dm/src/dmd/backendlicense.txt
* For any other uses, please contact Digital Mars.
*/
#ifdef DEBUG
#if !SPP
#include <stdio.h>
#include <time.h>
#include "cc.h"
#include "oper.h"
#include "type.h"
#include "el.h"
#include "token.h"
#include "global.h"
#include "vec.h"
#include "go.h"
#include "code.h"
#include "debtab.c"
static char __file__[] = __FILE__; /* for tassert.h */
#include "tassert.h"
#define ferr(p) dbg_printf("%s",(p))
/*******************************
* Write out storage class.
*/
char *str_class(enum SC c)
{ static char sc[SCMAX][10] =
{
#define X(a,b) #a,
ENUMSCMAC
#undef X
};
static char buffer[9 + 3];
(void) assert(arraysize(sc) == SCMAX);
if ((unsigned) c < (unsigned) SCMAX)
sprintf(buffer,"SC%s",sc[(int) c]);
else
sprintf(buffer,"SC%u",(unsigned)c);
return buffer;
}
void WRclass(enum SC c)
{
dbg_printf("%11s ",str_class(c));
}
/***************************
* Write out oper numbers.
*/
void WROP(unsigned oper)
{
if (oper >= OPMAX)
{ dbg_printf("op = x%x, OPMAX = %d\n",oper,OPMAX);
assert(0);
}
ferr(debtab[oper]);
ferr(" ");
}
/*******************************
* Write TYxxxx
*/
void WRTYxx(tym_t t)
{
#if TX86
if (t & mTYnear)
dbg_printf("mTYnear|");
#if TARGET_SEGMENTED
if (t & mTYfar)
dbg_printf("mTYfar|");
if (t & mTYcs)
dbg_printf("mTYcs|");
#endif
#endif
if (t & mTYconst)
dbg_printf("mTYconst|");
if (t & mTYvolatile)
dbg_printf("mTYvolatile|");
#if !MARS && (linux || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun&&__SVR4)
if (t & mTYtransu)
dbg_printf("mTYtransu|");
#endif
t = tybasic(t);
if (t >= TYMAX)
{ dbg_printf("TY %lx\n",(long)t);
assert(0);
}
dbg_printf("TY%s ",tystring[tybasic(t)]);
}
void WRBC(unsigned bc)
{ static char bcs[][7] =
{"unde ","goto ","true ","ret ","retexp",
"exit ","asm ","switch","ifthen","jmptab",
"try ","catch ","jump ",
"_try ","_filte","_final","_ret ","_excep",
"jcatch",
"jplace",
};
assert(sizeof(bcs) / sizeof(bcs[0]) == BCMAX);
assert(bc < BCMAX);
dbg_printf("BC%s",bcs[bc]);
}
/************************
* Write arglst
*/
void WRarglst(list_t a)
{ int n = 1;
if (!a) dbg_printf("0 args\n");
while (a)
{ const char* c = (const char*)list_ptr(a);
dbg_printf("arg %d: '%s'\n", n, c ? c : "NULL");
a = a->next;
n++;
}
}
/***************************
* Write out equation elem.
*/
void WReqn(elem *e)
{ static int nest;
if (!e)
return;
if (OTunary(e->Eoper))
{
WROP(e->Eoper);
if (OTbinary(e->E1->Eoper))
{ nest++;
ferr("(");
WReqn(e->E1);
ferr(")");
nest--;
}
else
WReqn(e->E1);
}
else if (e->Eoper == OPcomma && !nest)
{ WReqn(e->E1);
dbg_printf(";\n\t");
WReqn(e->E2);
}
else if (OTbinary(e->Eoper))
{
if (OTbinary(e->E1->Eoper))
{ nest++;
ferr("(");
WReqn(e->E1);
ferr(")");
nest--;
}
else
WReqn(e->E1);
ferr(" ");
WROP(e->Eoper);
if (e->Eoper == OPstreq)
dbg_printf("%ld",(long)type_size(e->ET));
ferr(" ");
if (OTbinary(e->E2->Eoper))
{ nest++;
ferr("(");
WReqn(e->E2);
ferr(")");
nest--;
}
else
WReqn(e->E2);
}
else
{
switch (e->Eoper)
{ case OPconst:
switch (tybasic(e->Ety))
{
case TYfloat:
dbg_printf("%g <float> ",e->EV.Vfloat);
break;
case TYdouble:
dbg_printf("%g ",e->EV.Vdouble);
break;
case TYldouble:
dbg_printf("%Lg ",e->EV.Vldouble);
break;
case TYcent:
case TYucent:
dbg_printf("%lld+%lld ", e->EV.Vcent.msw, e->EV.Vcent.lsw);
break;
default:
dbg_printf("%lld ",el_tolong(e));
break;
}
break;
case OPrelconst:
ferr("#");
/* FALL-THROUGH */
case OPvar:
dbg_printf("%s",e->EV.sp.Vsym->Sident);
if (e->EV.sp.Vsym->Ssymnum != -1)
dbg_printf("(%d)",e->EV.sp.Vsym->Ssymnum);
if (e->Eoffset != 0)
{
if (sizeof(e->Eoffset) == 8)
dbg_printf(".x%llx", e->Eoffset);
else
dbg_printf(".%ld",(long)e->Eoffset);
}
break;
case OPasm:
case OPstring:
dbg_printf("\"%s\"",e->EV.ss.Vstring);
if (e->EV.ss.Voffset)
dbg_printf("+%ld",(long)e->EV.ss.Voffset);
break;
case OPmark:
case OPgot:
case OPframeptr:
case OPhalt:
WROP(e->Eoper);
break;
case OPstrthis:
break;
default:
WROP(e->Eoper);
assert(0);
}
}
}
void WRblocklist(list_t bl)
{
for (; bl; bl = list_next(bl))
{ register block *b = list_block(bl);
if (b && b->Bweight)
dbg_printf("B%d (%p) ",b->Bdfoidx,b);
else
dbg_printf("%p ",b);
}
ferr("\n");
}
void WRdefnod()
{ register int i;
for (i = 0; i < deftop; i++)
{ dbg_printf("defnod[%d] in B%d = (",defnod[i].DNblock->Bdfoidx,i);
WReqn(defnod[i].DNelem);
dbg_printf(");\n");
}
}
void WRFL(enum FL fl)
{ static char fls[FLMAX][7] =
{"unde ","const ","oper ","func ","data ",
"reg ",
"pseudo",
"auto ","para ","extrn ","tmp ",
"code ","block ","udata ","cs ","swit ",
"fltrg ","offst ","datsg ",
"ctor ","dtor ","regsav","asm ",
#if TX86
"ndp ",
#endif
#if TARGET_SEGMENTED
"farda ","csdat ",
#endif
"local ","tlsdat",
"bprel ","frameh","blocko","alloca",
"stack ","dsym ",
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
"got ","gotoff",
#endif
};
if ((unsigned)fl >= (unsigned)FLMAX)
dbg_printf("FL%d",fl);
else
dbg_printf("FL%s",fls[fl]);
}
/***********************
* Write out block.
*/
void WRblock(block *b)
{
if (OPTIMIZER)
{
if (b && b->Bweight)
dbg_printf("B%d: (%p), weight=%d",b->Bdfoidx,b,b->Bweight);
else
dbg_printf("block %p",b);
if (!b)
{ ferr("\n");
return;
}
dbg_printf(" flags=x%x weight=%d",b->Bflags,b->Bweight);
#if 0
dbg_printf("\tfile %p, line %d",b->Bfilptr,b->Blinnum);
#endif
dbg_printf(" ");
WRBC(b->BC);
dbg_printf(" Btry=%p Bindex=%d",b->Btry,b->Bindex);
#if SCPP
if (b->BC == BCtry)
dbg_printf(" catchvar = %p",b->catchvar);
#endif
dbg_printf("\n");
dbg_printf("\tBpred: "); WRblocklist(b->Bpred);
dbg_printf("\tBsucc: "); WRblocklist(b->Bsucc);
if (b->Belem)
{ if (debugf) /* if full output */
elem_print(b->Belem);
else
{ ferr("\t");
WReqn(b->Belem);
dbg_printf(";\n");
}
}
if (b->Bcode)
b->Bcode->print();
ferr("\n");
}
else
{
targ_llong *pu;
int ncases;
list_t bl;
assert(b);
dbg_printf("********* Basic Block %p ************\n",b);
if (b->Belem) elem_print(b->Belem);
dbg_printf("block: ");
WRBC(b->BC);
dbg_printf(" Btry=%p Bindex=%d",b->Btry,b->Bindex);
dbg_printf("\n");
dbg_printf("\tBpred:\n");
for (bl = b->Bpred; bl; bl = list_next(bl))
dbg_printf("\t%p\n",list_block(bl));
bl = b->Bsucc;
switch (b->BC)
{
case BCswitch:
pu = b->BS.Bswitch;
assert(pu);
ncases = *pu;
dbg_printf("\tncases = %d\n",ncases);
dbg_printf("\tdefault: %p\n",list_block(bl));
while (ncases--)
{ bl = list_next(bl);
dbg_printf("\tcase %lld: %p\n",*++pu,list_block(bl));
}
break;
case BCiftrue:
case BCgoto:
case BCasm:
#if SCPP
case BCtry:
case BCcatch:
#endif
case BCjcatch:
case BC_try:
case BC_filter:
case BC_finally:
case BC_ret:
case BC_except:
Lsucc:
dbg_printf("\tBsucc:\n");
for ( ; bl; bl = list_next(bl))
dbg_printf("\t%p\n",list_block(bl));
break;
case BCret:
case BCretexp:
case BCexit:
break;
default:
assert(0);
}
}
}
void WRfunc()
{
block *b;
dbg_printf("func: '%s'\n",funcsym_p->Sident);
for (b = startblock; b; b = b->Bnext)
WRblock(b);
}
#endif /* DEBUG */
#endif /* !SPP */