comparison keiko/trace.c @ 0:bfdcc3820b32

Basis
author Mike Spivey <mike@cs.ox.ac.uk>
date Thu, 05 Oct 2017 08:04:15 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:bfdcc3820b32
1 /*
2 * trace.c
3 *
4 * This file is part of the Oxford Oberon-2 compiler
5 * Copyright (c) 2006--2016 J. M. Spivey
6 * All rights reserved
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #define TRACE
32 #include "obx.h"
33 #include "keiko.h"
34
35 struct _opcode {
36 const char *i_name; /* Name */
37 const char *i_patt; /* Argument template */
38 int i_arg; /* Argument packed in opcode */
39 int i_len; /* Total length in bytes */
40 };
41
42 #define __o1__(op, inst, patt, arg, len) { #inst, patt, arg, len },
43 struct _opcode optable[256] = { __OPCODES__(__o1__) };
44
45 char *fmt_inst(uchar *pc) {
46 uchar *args = pc;
47 struct _opcode *ip = &optable[*pc++];
48 static char buf[80];
49 char *s = buf;
50
51 if (ip->i_name == NULL) {
52 strcpy(buf, "UNKNOWN");
53 return buf;
54 }
55
56 s += sprintf(s, "%s", ip->i_name);
57
58 for (const char *p = ip->i_patt; *p != '\0'; p++) {
59 switch (*p) {
60 case '1': case 'K':
61 s += sprintf(s, " %d", get1(pc)); pc++; break;
62 case '2': case 'L':
63 s += sprintf(s, " %d", get2(pc)); pc += 2; break;
64 case 'R':
65 s += sprintf(s, " %ld", (long) (get2(pc)+(args-imem)));
66 pc += 2; break;
67 case 'S':
68 s += sprintf(s, " %ld", (long) (get1(pc)+(args-imem)));
69 pc += 1; break;
70 case 'N':
71 s += sprintf(s, " %d", ip->i_arg); break;
72 default:
73 s += sprintf(s, " ?%c?", *p);
74 }
75 }
76
77 return buf;
78 }
79
80 void dump(void) {
81 for (int k = 0; k < nprocs; k++) {
82 proc p = proctab[k];
83 value *cp = p->p_addr;
84 uchar *pc, *limit;
85
86 if (! interpreted(cp)) continue;
87
88 pc = pointer(cp[CP_CODE]); limit = pc + cp[CP_SIZE].i;
89
90 printf("Procedure %s:\n", proctab[k]->p_name);
91 while (pc < limit) {
92 int op = *pc;
93 uchar *pc1 = pc + optable[op].i_len;
94
95 printf("%6ld: %-30s", (long) (pc-imem), fmt_inst(pc));
96 while (pc < pc1) printf(" %d", *pc++);
97 printf("\n");
98
99 if (op == K_JCASE_1) {
100 int n = pc[-1];
101 for (int i = 0; i < n; i++) {
102 printf("%6ld: CASEL %-22ld %d %d\n",
103 (long) (pc-imem), (long) (get2(pc)+(pc-imem)),
104 pc[0], pc[1]);
105 pc += 2;
106 }
107 }
108 }
109 }
110 }
111
112 const char *prim_name(value *p) {
113 if (pointer(p[1]) != NULL) return (char *) pointer(p[1]);
114 return "(unknown)";
115 }