OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [sim/] [disasm.c] - Blame information for rev 300

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 hellwig
/*
2
 * disasm.c -- disassembler
3
 */
4
 
5
 
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
 
10
#include "common.h"
11
#include "console.h"
12
#include "error.h"
13
#include "instr.h"
14
#include "disasm.h"
15
 
16
 
17
static char instrBuffer[100];
18
 
19
 
20
static void disasmN(char *opName, Word immed) {
21
  if (immed == 0) {
22
    sprintf(instrBuffer, "%-7s", opName);
23
  } else {
24
    sprintf(instrBuffer, "%-7s %08X", opName, immed);
25
  }
26
}
27
 
28
 
29
static void disasmRH(char *opName, int r1, Half immed) {
30
  sprintf(instrBuffer, "%-7s $%d,%04X", opName, r1, immed);
31
}
32
 
33
 
34
static void disasmRHH(char *opName, int r1, Half immed) {
35
  sprintf(instrBuffer, "%-7s $%d,%08X", opName, r1, (Word) immed << 16);
36
}
37
 
38
 
39
static void disasmRRH(char *opName, int r1, int r2, Half immed) {
40
  sprintf(instrBuffer, "%-7s $%d,$%d,%04X", opName, r1, r2, immed);
41
}
42
 
43
 
44
static void disasmRRS(char *opName, int r1, int r2, Half immed) {
45
  sprintf(instrBuffer, "%-7s $%d,$%d,%s%04X", opName, r1, r2,
46
          SIGN(16) & immed ? "-" : "+",
47
          SIGN(16) & immed ? -SEXT16(immed) : SEXT16(immed));
48
}
49
 
50
 
51
static void disasmRRR(char *opName, int r1, int r2, int r3) {
52
  sprintf(instrBuffer, "%-7s $%d,$%d,$%d", opName, r1, r2, r3);
53
}
54
 
55
 
56
static void disasmRRB(char *opName, int r1, int r2, Half offset, Word locus) {
57
  sprintf(instrBuffer, "%-7s $%d,$%d,%08X", opName,
58
          r1, r2, (locus + 4) + (SEXT16(offset) << 2));
59
}
60
 
61
 
62
static void disasmJ(char *opName, Word offset, Word locus) {
63
  sprintf(instrBuffer, "%-7s %08X", opName,
64
          (locus + 4) + (SEXT26(offset) << 2));
65
}
66
 
67
 
68
static void disasmJR(char *opName, int r1) {
69
  sprintf(instrBuffer, "%-7s $%d", opName, r1);
70
}
71
 
72
 
73
char *disasm(Word instr, Word locus) {
74
  Byte opcode;
75
  Instr *ip;
76
 
77
  opcode = (instr >> 26) & 0x3F;
78
  ip = instrCodeTbl[opcode];
79
  if (ip == NULL) {
80
    disasmN("???", 0);
81
  } else {
82
    switch (ip->format) {
83
      case FORMAT_N:
84
        disasmN(ip->name, instr & 0x03FFFFFF);
85
        break;
86
      case FORMAT_RH:
87
        disasmRH(ip->name, (instr >> 16) & 0x1F, instr & 0x0000FFFF);
88
        break;
89
      case FORMAT_RHH:
90
        disasmRHH(ip->name, (instr >> 16) & 0x1F, instr & 0x0000FFFF);
91
        break;
92
      case FORMAT_RRH:
93
        disasmRRH(ip->name, (instr >> 16) & 0x1F,
94
                  (instr >> 21) & 0x1F, instr & 0x0000FFFF);
95
        break;
96
      case FORMAT_RRS:
97
        disasmRRS(ip->name, (instr >> 16) & 0x1F,
98
                  (instr >> 21) & 0x1F, instr & 0x0000FFFF);
99
        break;
100
      case FORMAT_RRR:
101
        disasmRRR(ip->name, (instr >> 11) & 0x1F,
102
                  (instr >> 21) & 0x1F, (instr >> 16) & 0x1F);
103
        break;
104
      case FORMAT_RRX:
105
        if ((opcode & 1) == 0) {
106
          /* the FORMAT_RRR variant */
107
          disasmRRR(ip->name, (instr >> 11) & 0x1F,
108
                    (instr >> 21) & 0x1F, (instr >> 16) & 0x1F);
109
        } else {
110
          /* the FORMAT_RRH variant */
111
          disasmRRH(ip->name, (instr >> 16) & 0x1F,
112
                    (instr >> 21) & 0x1F, instr & 0x0000FFFF);
113
        }
114
        break;
115
      case FORMAT_RRY:
116
        if ((opcode & 1) == 0) {
117
          /* the FORMAT_RRR variant */
118
          disasmRRR(ip->name, (instr >> 11) & 0x1F,
119
                    (instr >> 21) & 0x1F, (instr >> 16) & 0x1F);
120
        } else {
121
          /* the FORMAT_RRS variant */
122
          disasmRRS(ip->name, (instr >> 16) & 0x1F,
123
                    (instr >> 21) & 0x1F, instr & 0x0000FFFF);
124
        }
125
        break;
126
      case FORMAT_RRB:
127
        disasmRRB(ip->name, (instr >> 21) & 0x1F,
128
                  (instr >> 16) & 0x1F, instr & 0x0000FFFF, locus);
129
        break;
130
      case FORMAT_J:
131
        disasmJ(ip->name, instr & 0x03FFFFFF, locus);
132
        break;
133
      case FORMAT_JR:
134
        disasmJR(ip->name, (instr >> 21) & 0x1F);
135
        break;
136
      default:
137
        error("illegal entry in instruction table");
138
    }
139
  }
140
  return instrBuffer;
141
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.