Project

General

Profile

Download (13.1 KB) Statistics
| Branch: | Tag: | Revision:
1 d93979b7 Arnaud Dieumegard
2
-- Copyright (C) 1996 Morgan Kaufmann Publishers, Inc
3
4
-- This file is part of VESTs (Vhdl tESTs).
5
6
-- VESTs is free software; you can redistribute it and/or modify it
7
-- under the terms of the GNU General Public License as published by the
8
-- Free Software Foundation; either version 2 of the License, or (at
9
-- your option) any later version. 
10
11
-- VESTs is distributed in the hope that it will be useful, but WITHOUT
12
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
-- FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
-- for more details. 
15
16
-- You should have received a copy of the GNU General Public License
17
-- along with VESTs; if not, write to the Free Software Foundation,
18
-- Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19
20
-- ---------------------------------------------------------------------
21
--
22
-- $Id: ch_15_dlxi-b.vhd,v 1.3 2001-10-26 16:29:35 paw Exp $
23
-- $Revision: 1.3 $
24
--
25
-- ---------------------------------------------------------------------
26
27
library bv_utilities;
28
29
package body dlx_instr is
30
31
  use bv_utilities.bv_arithmetic.all;
32
33
  constant opcode_names : opcode_name_array
34
    := ( "SPECIAL ",   "FPARITH ",   "J       ",   "JAL     ",
35
         "BEQZ    ",   "BNEZ    ",   "BFPT    ",   "BFPF    ",
36
         "ADDI    ",    "ADDUI   ",   "SUBI    ",   "SUBUI   ",
37
         "ANDI    ",   "ORI     ",   "XORI    ",   "LHI     ",
38
         "RFE     ",   "TRAP    ",   "JR      ",   "JALR    ",
39
         "SLLI    ",   "UNDEF_15",   "SRLI    ",   "SRAI    ",
40
         "SEQI    ",   "SNEI    ",   "SLTI    ",   "SGTI    ",
41
         "SLEI    ",   "SGEI    ",   "UNDEF_1E",   "UNDEF_1F",
42
         "LB      ",   "LH      ",   "UNDEF_22",   "LW      ",
43
         "LBU     ",   "LHU     ",   "LF      ",   "LD      ",
44
         "SB      ",   "SH      ",   "UNDEF_2A",   "SW      ",
45
         "UNDEF_2C",   "UNDEF_2D",   "SF      ",   "SD      ",
46
         "SEQUI   ",   "SNEUI   ",   "SLTUI   ",   "SGTUI   ",
47
         "SLEUI   ",   "SGEUI   ",   "UNDEF_36",   "UNDEF_37",
48
         "UNDEF_38",   "UNDEF_39",   "UNDEF_3A",   "UNDEF_3B",
49
         "UNDEF_3C",   "UNDEF_3D",   "UNDEF_3E",   "UNDEF_3F" );
50
51
  constant sp_func_names : sp_func_name_array
52
    := ( "NOP     ",   "UNDEF_01",   "UNDEF_02",   "UNDEF_03",
53
         "SLL     ",   "UNDEF_05",   "SRL     ",   "SRA     ",
54
         "UNDEF_08",   "UNDEF_09",   "UNDEF_0A",   "UNDEF_0B",
55
         "UNDEF_0C",   "UNDEF_0D",   "UNDEF_0E",   "UNDEF_0F",
56
         "SEQU    ",   "SNEU    ",   "SLTU    ",   "SGTU    ",
57
         "SLEU    ",   "SGEU    ",   "UNDEF_16",   "UNDEF_17",
58
         "UNDEF_18",   "UNDEF_19",   "UNDEF_1A",   "UNDEF_1B",
59
         "UNDEF_1C",   "UNDEF_1D",   "UNDEF_1E",   "UNDEF_1F",
60
         "ADD     ",   "ADDU    ",   "SUB     ",   "SUBU    ",
61
         "AND     ",   "OR      ",   "XOR     ",   "UNDEF_27",
62
         "SEQ     ",   "SNE     ",   "SLT     ",   "SGT     ",
63
         "SLE     ",   "SGE     ",   "UNDEF_2E",   "UNDEF_2F",
64
         "MOVI2S  ",   "MOVS2I  ",   "MOVF    ",   "MOVD    ",
65
         "MOVFP2I ",   "MOVI2FP ",   "UNDEF_36",   "UNDEF_37",
66
         "UNDEF_38",   "UNDEF_39",   "UNDEF_3A",   "UNDEF_3B",
67
         "UNDEF_3C",   "UNDEF_3D",   "UNDEF_3E",   "UNDEF_3F" );
68
69
  constant fp_func_names : fp_func_name_array
70
    := ( "ADDF    ",   "SUBF    ",   "MULTF   ",   "DIVF    ",
71
         "ADDD    ",   "SUBD    ",   "MULTD   ",   "DIVD    ",
72
         "CVTF2D  ",   "CVTF2I  ",   "CVTD2F  ",   "CVTD2I  ",
73
         "CVTI2F  ",   "CVTI2D  ",   "MULT    ",   "DIV     ",
74
         "EQF     ",   "NEF     ",   "LTF     ",   "GTF     ",
75
         "LEF     ",   "GEF     ",   "MULTU   ",   "DIVU    ",
76
         "EQD     ",   "NED     ",   "LTD     ",   "GTD     ",
77
         "LED     ",   "GED     ",   "UNDEF_1E",   "UNDEF_1F" );
78
79
80
  procedure disassemble ( instr : dlx_bv_word;
81
			  disassembled_instr : out string;  len : out positive ) is
82
83
    alias norm_disassembled_instr : string(1 to disassembled_instr'length)
84
      is disassembled_instr;
85
86
    alias instr_opcode : dlx_opcode is instr(0 to 5);
87
    alias instr_sp_func : dlx_sp_func is instr(26 to 31);
88
    alias instr_fp_func : dlx_fp_func is instr(27 to 31);
89
    alias instr_rs1 : dlx_reg_addr is instr(6 to 10);
90
    alias instr_rs2 : dlx_reg_addr is instr(11 to 15);
91
    alias instr_Itype_rd : dlx_reg_addr is instr(11 to 15);
92
    alias instr_Rtype_rd : dlx_reg_addr is instr(16 to 20);
93
    alias instr_immed16 : dlx_immed16 is instr(16 to 31);
94
    alias instr_immed26 : dlx_immed26 is instr(6 to 31);
95
96
    variable instr_opcode_num : dlx_opcode_num;
97
    variable instr_sp_func_num : dlx_sp_func_num;
98
    variable instr_fp_func_num : dlx_fp_func_num;
99
    variable rs1 : reg_index;
100
    variable rs2 : reg_index;
101
    variable Itype_rd : reg_index;
102
    variable Rtype_rd : reg_index;
103
    variable result : string(1 to 40)	-- long enough for longest instruction
104
		:= (others => ' ');
105
    variable index : positive range 1 to 41 := 1;  -- position for next char in result
106
107
    procedure disassemble_reg ( reg : reg_index;  reg_prefix : character ) is
108
    begin
109
      result(index) := reg_prefix;
110
      index := index + 1;
111
      if reg < 10 then
112
        result(index to index) := integer'image(reg);
113
        index := index + 1;
114
      else
115
        result(index to index + 1) := integer'image(reg);
116
        index := index + 2;
117
      end if;
118
    end procedure disassemble_reg;
119
120
    procedure disassemble_special_reg ( reg : reg_index ) is
121
    begin
122
      case reg is
123
        when 0 =>
124
          result(index to index + 2) := "IAR";
125
          index := index + 3;
126
        when 1 =>
127
          result(index to index + 2) := "FSR";
128
          index := index + 3;
129
        when others =>
130
          disassemble_reg(reg, 'S');
131
      end case;
132
    end procedure disassemble_special_reg;
133
134
    procedure disassemble_integer ( int : integer ) is
135
      constant int_image_length : natural := integer'image(int)'length;
136
    begin
137
      result(index to index + int_image_length - 1) := integer'image(int);
138
      index := index + int_image_length;
139
    end procedure disassemble_integer;
140
141
  begin
142
    instr_opcode_num := bv_to_natural(instr_opcode);
143
    instr_sp_func_num := bv_to_natural(instr_sp_func);
144
    instr_fp_func_num := bv_to_natural(instr_fp_func);
145
    rs1 := bv_to_natural(instr_rs1);
146
    rs2 := bv_to_natural(instr_rs2);
147
    Itype_rd := bv_to_natural(instr_Itype_rd);
148
    Rtype_rd := bv_to_natural(instr_Rtype_rd);
149
    if (instr_opcode /= op_special) and (instr_opcode /= op_fparith) then
150
      result(index to index + instr_name'length - 1) := opcode_names(instr_opcode_num);
151
      index := index + instr_name'length + 1;  -- include space after opcode name
152
    end if;
153
    case instr_opcode is
154
      when op_special =>
155
	result(index to index + instr_name'length - 1) := sp_func_names(instr_sp_func_num);
156
        index := index + instr_name'length + 1;  -- include space after function name
157
        case instr_sp_func is
158
          when sp_func_nop =>
159
            null;
160
          when sp_func_sll | sp_func_srl | sp_func_sra
161
            | sp_func_sequ | sp_func_sneu | sp_func_sltu
162
            | sp_func_sgtu | sp_func_sleu | sp_func_sgeu
163
            | sp_func_add | sp_func_addu | sp_func_sub | sp_func_subu
164
            | sp_func_and | sp_func_or | sp_func_xor
165
            | sp_func_seq | sp_func_sne | sp_func_slt
166
            | sp_func_sgt | sp_func_sle | sp_func_sge =>
167
	    disassemble_reg(Rtype_rd, 'R');
168
	    result(index) := ',';
169
	    index := index + 2;  -- include space after comma
170
	    disassemble_reg(rs1, 'R');
171
	    result(index) := ',';
172
	    index := index + 2;  -- include space after comma
173
	    disassemble_reg(rs2, 'R');
174
          when sp_func_movi2s =>
175
	    disassemble_special_reg(Rtype_rd);
176
	    result(index) := ',';
177
	    index := index + 2;  -- include space after comma
178
	    disassemble_reg(rs1, 'R');
179
          when sp_func_movs2i =>
180
	    disassemble_reg(Rtype_rd, 'R');
181
	    result(index) := ',';
182
	    index := index + 2;  -- include space after comma
183
	    disassemble_special_reg(rs1);
184
          when sp_func_movf | sp_func_movd =>
185
	    disassemble_reg(Rtype_rd, 'F');
186
	    result(index) := ',';
187
	    index := index + 2;  -- include space after comma
188
	    disassemble_reg(rs1, 'F');
189
          when sp_func_movfp2i =>
190
	    disassemble_reg(Rtype_rd, 'R');
191
	    result(index) := ',';
192
	    index := index + 2;  -- include space after comma
193
	    disassemble_reg(rs1, 'F');
194
          when sp_func_movi2fp =>
195
	    disassemble_reg(Rtype_rd, 'F');
196
	    result(index) := ',';
197
	    index := index + 2;  -- include space after comma
198
	    disassemble_reg(rs1, 'R');
199
          when others =>
200
            null;
201
        end case;
202
      when op_fparith =>
203
	result(index to index + instr_name'length - 1) := fp_func_names(instr_fp_func_num);
204
        index := index + instr_name'length + 1;  -- include space after function name
205
        case instr_fp_func is
206
          when fp_func_addf | fp_func_subf | fp_func_multf | fp_func_divf
207
            | fp_func_addd | fp_func_subd | fp_func_multd | fp_func_divd
208
            | fp_func_mult | fp_func_div | fp_func_multu | fp_func_divu =>
209
	    disassemble_reg(Rtype_rd, 'F');
210
	    result(index) := ',';
211
	    index := index + 2;  -- include space after comma
212
	    disassemble_reg(rs1, 'F');
213
	    result(index) := ',';
214
	    index := index + 2;  -- include space after comma
215
	    disassemble_reg(rs2, 'F');
216
          when fp_func_cvtf2d | fp_func_cvtd2f =>
217
	    disassemble_reg(Rtype_rd, 'F');
218
	    result(index) := ',';
219
	    index := index + 2;  -- include space after comma
220
	    disassemble_reg(rs1, 'F');
221
          when fp_func_cvtf2i | fp_func_cvtd2i =>
222
	    disassemble_reg(Rtype_rd, 'R');
223
	    result(index) := ',';
224
	    index := index + 2;  -- include space after comma
225
	    disassemble_reg(rs1, 'F');
226
          when fp_func_cvti2f | fp_func_cvti2d =>
227
	    disassemble_reg(Rtype_rd, 'F');
228
	    result(index) := ',';
229
	    index := index + 2;  -- include space after comma
230
	    disassemble_reg(rs1, 'R');
231
          when fp_func_eqf | fp_func_nef | fp_func_ltf
232
            | fp_func_gtf | fp_func_lef | fp_func_gef
233
            | fp_func_eqd | fp_func_ned | fp_func_ltd
234
            | fp_func_gtd | fp_func_led | fp_func_ged =>
235
	    disassemble_reg(rs1, 'F');
236
	    result(index) := ',';
237
	    index := index + 2;  -- include space after comma
238
	    disassemble_reg(rs2, 'F');
239
          when others =>
240
            null;
241
        end case;
242
      when op_j  | op_jal =>
243
        disassemble_integer(bv_to_integer(instr_immed26));
244
      when op_beqz | op_bnez =>
245
	disassemble_reg(rs1, 'R');
246
	result(index) := ',';
247
	index := index + 2;  -- include space after comma
248
	disassemble_integer(bv_to_integer(instr_immed16));
249
      when op_bfpt | op_bfpf =>
250
	disassemble_integer(bv_to_integer(instr_immed16));
251
      when op_slli | op_srli | op_srai =>
252
	disassemble_reg(Itype_rd, 'R');
253
	result(index) := ',';
254
	index := index + 2;  -- include space after comma
255
	disassemble_reg(rs1, 'R');
256
	result(index) := ',';
257
	index := index + 2;  -- include space after comma
258
	disassemble_integer(bv_to_natural(instr_immed16(11 to 15)));
259
      when op_addi | op_subi
260
        | op_seqi | op_snei | op_slti | op_sgti | op_slei | op_sgei =>
261
	disassemble_reg(Itype_rd, 'R');
262
	result(index) := ',';
263
	index := index + 2;  -- include space after comma
264
	disassemble_reg(rs1, 'R');
265
	result(index) := ',';
266
	index := index + 2;  -- include space after comma
267
	disassemble_integer(bv_to_integer(instr_immed16));
268
      when op_addui | op_subui | op_andi | op_ori | op_xori
269
        | op_sequi | op_sneui | op_sltui | op_sgtui | op_sleui | op_sgeui =>
270
	disassemble_reg(Itype_rd, 'R');
271
	result(index) := ',';
272
	index := index + 2;  -- include space after comma
273
	disassemble_reg(rs1, 'R');
274
	result(index) := ',';
275
	index := index + 2;  -- include space after comma
276
	disassemble_integer(bv_to_natural(instr_immed16));
277
      when op_lhi =>
278
	disassemble_reg(Itype_rd, 'R');
279
	result(index) := ',';
280
	index := index + 2;  -- include space after comma
281
	disassemble_integer(bv_to_natural(instr_immed16));
282
      when op_rfe =>
283
        null;
284
      when op_trap =>
285
	disassemble_integer(bv_to_natural(instr_immed26));
286
      when op_jr | op_jalr =>
287
	disassemble_reg(rs1, 'R');
288
      when op_lb | op_lh | op_lw | op_lbu | op_lhu | op_lf | op_ld =>
289
	disassemble_reg(Itype_rd, 'R');
290
	result(index) := ',';
291
	index := index + 2;  -- include space after comma
292
	disassemble_integer(bv_to_integer(instr_immed16));
293
        result(index) := '(';
294
                           index := index + 1;
295
                           disassemble_reg(rs1, 'R');
296
                           result(index) := ')';
297
	index := index + 1;
298
      when op_sb | op_sh | op_sw | op_sf | op_sd =>
299
	disassemble_integer(bv_to_integer(instr_immed16));
300
        result(index) := '(';
301
                           index := index + 1;
302
                           disassemble_reg(rs1, 'R');
303
                           result(index) := ')';
304
	index := index + 1;
305
	result(index) := ',';
306
	index := index + 2;  -- include space after comma
307
	disassemble_reg(Itype_rd, 'R');
308
      when others =>
309
        null;  -- remaining opcodes have no operands to disassemble
310
    end case;
311
    if index > norm_disassembled_instr'length then
312
      index := norm_disassembled_instr'length;  -- limit to out parameter length
313
    else
314
      index := index - 1;  -- index points to last result character
315
    end if;
316
    norm_disassembled_instr(1 to index) := result(1 to index);
317
    len := index;
318
  end procedure disassemble;
319
320
end package body dlx_instr;