~ubuntu-branches/ubuntu/jaunty/spim/jaunty

« back to all changes in this revision

Viewing changes to inst.c

  • Committer: Bazaar Package Importer
  • Author(s): Fernando Sanchez
  • Date: 2001-01-24 14:05:34 UTC
  • Revision ID: james.westby@ubuntu.com-20010124140534-3le9wmofforjjcd8
Tags: upstream-6.3
ImportĀ upstreamĀ versionĀ 6.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* SPIM S20 MIPS simulator.
 
2
   Code to build assembly instructions and resolve symbolic labels.
 
3
 
 
4
   Copyright (C) 1990-2000 by James Larus (larus@cs.wisc.edu).
 
5
   ALL RIGHTS RESERVED.
 
6
 
 
7
   SPIM is distributed under the following conditions:
 
8
 
 
9
     You may make copies of SPIM for your own use and modify those copies.
 
10
 
 
11
     All copies of SPIM must retain my name and copyright notice.
 
12
 
 
13
     You may not sell SPIM or distributed SPIM in conjunction with a
 
14
     commerical product or service without the expressed written consent of
 
15
     James Larus.
 
16
 
 
17
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 
18
   IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 
19
   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
20
   PURPOSE. */
 
21
 
 
22
 
 
23
/* $Header: /Software/SPIM/src/inst.c 10    12/24/00 1:37p Larus $
 
24
*/
 
25
 
 
26
#include <stdio.h>
 
27
#include <string.h>
 
28
 
 
29
#include "spim.h"
 
30
#include "spim-utils.h"
 
31
#include "inst.h"
 
32
#include "mem.h"
 
33
#include "reg.h"
 
34
#include "sym-tbl.h"
 
35
#include "parser.h"
 
36
#include "scanner.h"
 
37
#include "y.tab.h"
 
38
#include "data.h"
 
39
 
 
40
 
 
41
/* Local functions: */
 
42
 
 
43
#ifdef __STDC__
 
44
static int compare_pair_value (inst_info *p1, inst_info *p2);
 
45
static void i_type_inst_full_word (int opcode, int rt, int rs, imm_expr *expr,
 
46
                                   int value_known, int32 value);
 
47
static void inst_cmp (instruction *inst1, instruction *inst2);
 
48
static instruction *make_r_type_inst (int opcode, int rd, int rs, int rt);
 
49
static instruction *mk_i_inst (uint32 value, int opcode, int rs,
 
50
                               int rt, int offset);
 
51
static instruction *mk_j_inst (uint32, int opcode, int target);
 
52
static instruction *mk_r_inst (uint32, int opcode, int rs,
 
53
                               int rt, int rd, int shamt);
 
54
static char* print_imm_expr (char *buf, unsigned int length, imm_expr *expr,
 
55
                             int base_reg);
 
56
static void produce_immediate (imm_expr *expr, int rt, int value_known, int32 value);
 
57
static void sort_name_table (void);
 
58
#else
 
59
static int compare_pair_value ();
 
60
static void i_type_inst_f ();
 
61
static void i_type_inst_full_word ();
 
62
static void inst_cmp ();
 
63
static instruction * make_r_type_inst ();
 
64
static instruction *mk_i_inst ();
 
65
static instruction *mk_j_inst ();
 
66
static instruction *mk_r_inst ();
 
67
static char* print_imm_expr ();
 
68
static void produce_immediate ();
 
69
static void sort_name_table ();
 
70
#endif
 
71
 
 
72
 
 
73
/* Local variables: */
 
74
 
 
75
/* Non-zero means store instructions in kernel, not user, text segment */
 
76
 
 
77
static int in_kernel = 0;
 
78
 
 
79
/* Instruction used as breakpoint by SPIM: */
 
80
 
 
81
static instruction *break_inst = NULL;
 
82
 
 
83
 
 
84
/* Locations for next instruction in user and kernel text segments */
 
85
 
 
86
static mem_addr next_text_pc;
 
87
 
 
88
static mem_addr next_k_text_pc;
 
89
 
 
90
 
 
91
#define INST_PC (in_kernel ? next_k_text_pc : next_text_pc)
 
92
#define BUMP_INST_PC(DELTA) {if (in_kernel) \
 
93
                               next_k_text_pc += DELTA; \
 
94
                               else next_text_pc += DELTA;}
 
95
 
 
96
 
 
97
 
 
98
/* Set ADDRESS at which the next instruction is stored. */
 
99
 
 
100
#ifdef __STDC__
 
101
void
 
102
text_begins_at_point (mem_addr addr)
 
103
#else
 
104
void
 
105
text_begins_at_point (addr)
 
106
     mem_addr addr;
 
107
#endif
 
108
{
 
109
  next_text_pc = addr;
 
110
}
 
111
 
 
112
 
 
113
#ifdef __STDC__
 
114
void
 
115
k_text_begins_at_point (mem_addr addr)
 
116
#else
 
117
void
 
118
k_text_begins_at_point (addr)
 
119
     mem_addr addr;
 
120
#endif
 
121
{
 
122
  next_k_text_pc = addr;
 
123
}
 
124
 
 
125
 
 
126
/* Set the location (in user or kernel text space) for the next instruction. */
 
127
 
 
128
#ifdef __STDC__
 
129
void
 
130
set_text_pc (mem_addr addr)
 
131
#else
 
132
void
 
133
set_text_pc (addr)
 
134
     mem_addr addr;
 
135
#endif
 
136
{
 
137
  if (in_kernel)
 
138
    next_k_text_pc = addr;
 
139
  else
 
140
    next_text_pc = addr;
 
141
}
 
142
 
 
143
 
 
144
/* Return address for next instruction, in appropriate text segment. */
 
145
 
 
146
#ifdef __STDC__
 
147
mem_addr
 
148
current_text_pc (void)
 
149
#else
 
150
mem_addr
 
151
current_text_pc ()
 
152
#endif
 
153
{
 
154
  return (INST_PC);
 
155
}
 
156
 
 
157
 
 
158
/* Increment the current text segement PC. */
 
159
 
 
160
#ifdef __STDC__
 
161
void
 
162
increment_text_pc (int delta)
 
163
#else
 
164
void
 
165
increment_text_pc (delta)
 
166
     int delta;
 
167
#endif
 
168
{
 
169
  BUMP_INST_PC (delta);
 
170
}
 
171
 
 
172
 
 
173
/* If FLAG is non-zero, next instruction goes to kernel text segment,
 
174
   otherwise it goes to user segment. */
 
175
 
 
176
#ifdef __STDC__
 
177
void
 
178
user_kernel_text_segment (int to_kernel)
 
179
#else
 
180
void
 
181
user_kernel_text_segment (to_kernel)
 
182
     int to_kernel;
 
183
#endif
 
184
{
 
185
  in_kernel = to_kernel;
 
186
}
 
187
 
 
188
 
 
189
/* Store an INSTRUCTION in memory at the next location. */
 
190
 
 
191
#ifdef __STDC__
 
192
void
 
193
store_instruction (instruction *inst)
 
194
#else
 
195
void
 
196
store_instruction (inst)
 
197
     instruction *inst;
 
198
#endif
 
199
{
 
200
  if (data_dir)
 
201
    {
 
202
      store_word (inst_encode (inst));
 
203
      free_inst (inst);
 
204
    }
 
205
  else if (text_dir)
 
206
    {
 
207
      exception_occurred = 0;
 
208
      SET_MEM_INST (INST_PC, inst);
 
209
      if (exception_occurred)
 
210
        error ("Invalid address (0x%08x) for instruction\n", INST_PC);
 
211
      else
 
212
        BUMP_INST_PC (BYTES_PER_WORD);
 
213
      if (inst != NULL)
 
214
        {
 
215
          SET_SOURCE (inst, source_line ());
 
216
          if (ENCODING (inst) == 0)
 
217
            SET_ENCODING (inst, inst_encode (inst));
 
218
        }
 
219
    }
 
220
}
 
221
 
 
222
 
 
223
 
 
224
#ifdef __STDC__
 
225
void
 
226
i_type_inst_free (int opcode, int rt, int rs, imm_expr *expr)
 
227
#else
 
228
void
 
229
i_type_inst_free (opcode, rt, rs, expr)
 
230
     int opcode, rt, rs;
 
231
     imm_expr *expr;
 
232
#endif
 
233
{
 
234
  i_type_inst (opcode, rt, rs, expr);
 
235
  free (expr);
 
236
}
 
237
 
 
238
 
 
239
/* Produce an immediate instruction with the OPCODE, RT, RS, and IMM
 
240
   fields.  NB, because the immediate value may not fit in the field,
 
241
   this routine may produce more than one instruction.  On the bare
 
242
   machine, we resolve symbolic address, but they better produce values
 
243
   that fit into instruction's immediate field. */
 
244
 
 
245
#ifdef __STDC__
 
246
void
 
247
i_type_inst (int opcode, int rt, int rs, imm_expr *expr)
 
248
#else
 
249
void
 
250
i_type_inst (opcode, rt, rs, expr)
 
251
     int opcode, rt, rs;
 
252
     imm_expr *expr;
 
253
#endif
 
254
{
 
255
  instruction *inst = (instruction *) zmalloc (sizeof (instruction));
 
256
 
 
257
  SET_OPCODE (inst, opcode);
 
258
  SET_RS (inst, rs);
 
259
  SET_RT (inst, rt);
 
260
  SET_EXPR (inst, copy_imm_expr (expr));
 
261
  if (expr->symbol == NULL || SYMBOL_IS_DEFINED (expr->symbol))
 
262
    {
 
263
      /* Evaluate the instruction's expression. */
 
264
      int32 value = eval_imm_expr (expr);
 
265
 
 
266
      if (!bare_machine
 
267
          && (((opcode == Y_ADDI_OP
 
268
                || opcode == Y_ADDIU_OP
 
269
                || opcode == Y_SLTI_OP
 
270
                || opcode == Y_SLTIU_OP)
 
271
               ? ((value & 0xffff8000) != 0
 
272
                  && (value & 0xffff8000) != 0xffff8000)
 
273
               : (value & 0xffff0000) != 0)))
 
274
        {
 
275
          free_inst (inst);
 
276
          i_type_inst_full_word (opcode, rt, rs, expr, 1, value);
 
277
          return;
 
278
        }
 
279
      else
 
280
        resolve_a_label (expr->symbol, inst);
 
281
    }
 
282
  else if (bare_machine || expr->bits != 0)
 
283
    /* Don't know expression's value, but only needed upper/lower 16-bits
 
284
       anyways. */
 
285
    record_inst_uses_symbol (inst, expr->symbol);
 
286
  else
 
287
    {
 
288
      /* Don't know the expressions's value and want all of its bits,
 
289
         so assume that it will not produce a small result and generate
 
290
         sequence for 32 bit value. */
 
291
      free_inst (inst);
 
292
 
 
293
      i_type_inst_full_word (opcode, rt, rs, expr, 0, 0);
 
294
      return;
 
295
    }
 
296
 
 
297
  store_instruction (inst);
 
298
}
 
299
 
 
300
 
 
301
/* The immediate value for an instruction will (or may) not fit in 16 bits.
 
302
   Build the value from its piece with separate instructions. */
 
303
 
 
304
#ifdef __STDC__
 
305
static void
 
306
i_type_inst_full_word (int opcode, int rt, int rs, imm_expr *expr,
 
307
                       int value_known, int32 value)
 
308
#else
 
309
static void
 
310
i_type_inst_full_word (opcode, rt, rs, expr, value_known, value)
 
311
     int opcode, rt, rs;
 
312
     imm_expr *expr;
 
313
     int value_known;
 
314
     int32 value;
 
315
#endif
 
316
{
 
317
  if (opcode_is_load_store (opcode))
 
318
    {
 
319
      int offset;
 
320
 
 
321
      if (expr->symbol != NULL
 
322
          && expr->symbol->gp_flag
 
323
          && rs == 0
 
324
          && IMM_MIN <= (offset = expr->symbol->addr + expr->offset)
 
325
          && offset <= IMM_MAX)
 
326
        {
 
327
          i_type_inst_free (opcode, rt, REG_GP, make_imm_expr (offset, NULL, 0));
 
328
        }
 
329
      else if (value_known)
 
330
        {
 
331
          int low, high;
 
332
 
 
333
          high = (value >> 16) & 0xffff;
 
334
          low = value & 0xffff;
 
335
 
 
336
          if (high != 0 &&
 
337
              !(high == 0xffff && (low & 0x8000)))
 
338
            {
 
339
              /* Some of high 16 bits are non-zero */
 
340
              if (low & 0x8000)
 
341
                {
 
342
                  /* Adjust high 16, since load sign-extends low 16*/
 
343
                  high += 1;
 
344
                }
 
345
 
 
346
              i_type_inst_free (Y_LUI_OP, 1, 0, const_imm_expr (high));
 
347
              if (rs != 0)      /* Base register */
 
348
                {
 
349
                r_type_inst (Y_ADDU_OP, 1, 1, rs);
 
350
                }
 
351
              i_type_inst_free (opcode, rt, 1, const_imm_expr (low));
 
352
            }
 
353
          else
 
354
            {
 
355
              /* Special case, sign-extension of low 16 bits sets high to 0xffff */
 
356
              i_type_inst_free (opcode, rt, rs, const_imm_expr (low));
 
357
            }
 
358
        }
 
359
      else
 
360
        {
 
361
          /* Use $at */
 
362
          /* Need to adjust if lower bits are negative */
 
363
          i_type_inst_free (Y_LUI_OP, 1, 0, upper_bits_of_expr (expr));
 
364
          if (rs != 0)          /* Base register */
 
365
            {
 
366
            r_type_inst (Y_ADDU_OP, 1, 1, rs);
 
367
            }
 
368
          i_type_inst_free (opcode, rt, 1, lower_bits_of_expr (expr));
 
369
        }
 
370
    }
 
371
  else if (opcode_is_branch (opcode))
 
372
    {
 
373
      /* This only allows branches +/- 32K, which is not correct! */
 
374
      i_type_inst_free (opcode, rt, rs, lower_bits_of_expr (expr));
 
375
    }
 
376
  else
 
377
    /* Computation instruction */
 
378
    {
 
379
      int offset;
 
380
 
 
381
      if (expr->symbol != NULL
 
382
          && expr->symbol->gp_flag && rs == 0
 
383
          && IMM_MIN <= (offset = expr->symbol->addr + expr->offset)
 
384
          && offset <= IMM_MAX)
 
385
        {
 
386
        i_type_inst_free ((opcode == Y_LUI_OP ? Y_ADDIU_OP : opcode),
 
387
                          rt, REG_GP, make_imm_expr (offset, NULL, 0));
 
388
        }
 
389
      else
 
390
        {
 
391
          /* Use $at */
 
392
          if ((opcode == Y_ORI_OP
 
393
               || opcode == Y_ADDI_OP
 
394
               || opcode == Y_ADDIU_OP
 
395
               || opcode == Y_LUI_OP)
 
396
              && rs == 0)
 
397
            {
 
398
              produce_immediate(expr, rt, value_known, value);
 
399
            }
 
400
          else
 
401
            {
 
402
              produce_immediate(expr, 1, value_known, value);
 
403
              r_type_inst (imm_op_to_op (opcode), rt, rs, 1);
 
404
            }
 
405
        }
 
406
    }
 
407
}
 
408
 
 
409
 
 
410
#ifdef __STDC__
 
411
static void
 
412
produce_immediate (imm_expr *expr, int rt, int value_known, int32 value)
 
413
#else
 
414
static void
 
415
produce_immediate (expr, rt, value_known, value)
 
416
     imm_expr *expr;
 
417
     int rt;
 
418
     int value_known;
 
419
     int32 value;
 
420
#endif
 
421
{
 
422
  if (value_known && (value & 0xffff) == 0)
 
423
    {
 
424
      i_type_inst_free (Y_LUI_OP, rt, 0, upper_bits_of_expr (expr));
 
425
    }
 
426
  else if (value_known && (value & 0xffff0000) == 0)
 
427
    {
 
428
      i_type_inst_free (Y_ORI_OP, rt, 0, lower_bits_of_expr (expr));
 
429
    }
 
430
  else
 
431
    {
 
432
      i_type_inst_free (Y_LUI_OP, 1, 0, upper_bits_of_expr (expr));
 
433
      i_type_inst_free (Y_ORI_OP, rt, 1, lower_bits_of_expr(expr));
 
434
    }
 
435
}
 
436
 
 
437
 
 
438
/* Return a jump-type instruction with the given OPCODE and TARGET
 
439
   fields. NB, even the immediate value may not fit in the field, this
 
440
   routine will not produce more than one instruction. */
 
441
 
 
442
#ifdef __STDC__
 
443
void
 
444
j_type_inst (int opcode, imm_expr *target)
 
445
#else
 
446
void
 
447
j_type_inst (opcode, target)
 
448
     int opcode;
 
449
     imm_expr *target;
 
450
#endif
 
451
{
 
452
  instruction *inst = (instruction *) zmalloc (sizeof (instruction));
 
453
 
 
454
  SET_OPCODE(inst, opcode);
 
455
  target->offset = 0;           /* Not PC relative */
 
456
  target->pc_relative = 0;
 
457
  SET_EXPR (inst, copy_imm_expr (target));
 
458
  if (target->symbol == NULL || SYMBOL_IS_DEFINED (target->symbol))
 
459
    resolve_a_label (target->symbol, inst);
 
460
  else
 
461
    record_inst_uses_symbol (inst, target->symbol);
 
462
  store_instruction (inst);
 
463
}
 
464
 
 
465
 
 
466
/* Return a register-type instruction with the given OPCODE, RD, RS, and RT
 
467
   fields. */
 
468
 
 
469
#ifdef __STDC__
 
470
static instruction *
 
471
make_r_type_inst (int opcode, int rd, int rs, int rt)
 
472
#else
 
473
static instruction *
 
474
make_r_type_inst (opcode, rd, rs, rt)
 
475
     int opcode, rd, rs, rt;
 
476
#endif
 
477
{
 
478
  instruction *inst = (instruction *) zmalloc (sizeof (instruction));
 
479
 
 
480
  SET_OPCODE(inst, opcode);
 
481
  SET_RS(inst, rs);
 
482
  SET_RT(inst, rt);
 
483
  SET_RD(inst, rd);
 
484
  SHAMT(inst) = 0;
 
485
  return (inst);
 
486
}
 
487
 
 
488
 
 
489
/* Return a register-type instruction with the given OPCODE, RD, RS, and RT
 
490
   fields. */
 
491
 
 
492
#ifdef __STDC__
 
493
void
 
494
r_type_inst (int opcode, int rd, int rs, int rt)
 
495
#else
 
496
void
 
497
r_type_inst (opcode, rd, rs, rt)
 
498
     int opcode, rd, rs, rt;
 
499
#endif
 
500
{
 
501
  store_instruction (make_r_type_inst (opcode, rd, rs, rt));
 
502
}
 
503
 
 
504
 
 
505
/* Return a register-shift instruction with the given OPCODE, RD, RT, and
 
506
   SHAMT fields.*/
 
507
 
 
508
#ifdef __STDC__
 
509
void
 
510
r_sh_type_inst (int opcode, int rd, int rt, int shamt)
 
511
#else
 
512
void
 
513
r_sh_type_inst (opcode, rd, rt, shamt)
 
514
     int opcode, rd, rt, shamt;
 
515
#endif
 
516
{
 
517
  instruction *inst = make_r_type_inst (opcode, rd, 0, rt);
 
518
 
 
519
  SET_SHAMT(inst, shamt & 0x1f);
 
520
  store_instruction (inst);
 
521
}
 
522
 
 
523
 
 
524
/* Return a floating-point compare instruction with the given OPCODE,
 
525
   FS, and FT fields.*/
 
526
 
 
527
#ifdef __STDC__
 
528
void
 
529
r_cond_type_inst (int opcode, int rs, int rt)
 
530
#else
 
531
void
 
532
r_cond_type_inst (opcode, rs, rt)
 
533
     int opcode, rs, rt;
 
534
#endif
 
535
{
 
536
  instruction *inst = make_r_type_inst (opcode, 0, rs, rt);
 
537
 
 
538
  switch (opcode)
 
539
    {
 
540
    case Y_C_EQ_D_OP:
 
541
    case Y_C_EQ_S_OP:
 
542
      {
 
543
        COND(inst) = COND_EQ;
 
544
        break;
 
545
      }
 
546
 
 
547
    case Y_C_LE_D_OP:
 
548
    case Y_C_LE_S_OP:
 
549
      {
 
550
        COND(inst) = COND_IN | COND_LT | COND_EQ;
 
551
        break;
 
552
      }
 
553
 
 
554
    case Y_C_LT_D_OP:
 
555
    case Y_C_LT_S_OP:
 
556
      {
 
557
        COND(inst) = COND_IN | COND_LT;
 
558
        break;
 
559
      }
 
560
 
 
561
    case Y_C_NGE_D_OP:
 
562
    case Y_C_NGE_S_OP:
 
563
      {
 
564
        COND(inst) = COND_IN | COND_LT | COND_UN;
 
565
        break;
 
566
      }
 
567
 
 
568
    case Y_C_NGLE_D_OP:
 
569
    case Y_C_NGLE_S_OP:
 
570
      {
 
571
        COND(inst) = COND_IN | COND_UN;
 
572
        break;
 
573
      }
 
574
 
 
575
    case Y_C_NGL_D_OP:
 
576
    case Y_C_NGL_S_OP:
 
577
      {
 
578
        COND(inst) = COND_IN | COND_EQ | COND_UN;
 
579
        break;
 
580
      }
 
581
 
 
582
    case Y_C_NGT_D_OP:
 
583
    case Y_C_NGT_S_OP:
 
584
      {
 
585
        COND(inst) = COND_IN | COND_LT | COND_EQ | COND_UN;
 
586
        break;
 
587
      }
 
588
 
 
589
    case Y_C_OLT_D_OP:
 
590
    case Y_C_OLT_S_OP:
 
591
      {
 
592
        COND(inst) = COND_LT;
 
593
        break;
 
594
      }
 
595
 
 
596
    case Y_C_OLE_D_OP:
 
597
    case Y_C_OLE_S_OP:
 
598
      {
 
599
        COND(inst) = COND_LT | COND_EQ;
 
600
        break;
 
601
      }
 
602
 
 
603
    case Y_C_SEQ_D_OP:
 
604
    case Y_C_SEQ_S_OP:
 
605
      {
 
606
        COND(inst) = COND_IN | COND_EQ;
 
607
        break;
 
608
      }
 
609
 
 
610
    case Y_C_SF_D_OP:
 
611
    case Y_C_SF_S_OP:
 
612
      {
 
613
        COND(inst) = COND_IN;
 
614
        break;
 
615
      }
 
616
 
 
617
    case Y_C_F_D_OP:
 
618
    case Y_C_F_S_OP:
 
619
      {
 
620
        COND(inst) = 0;
 
621
        break;
 
622
      }
 
623
 
 
624
    case Y_C_UEQ_D_OP:
 
625
    case Y_C_UEQ_S_OP:
 
626
      {
 
627
        COND(inst) = COND_EQ | COND_UN;
 
628
        break;
 
629
      }
 
630
 
 
631
    case Y_C_ULT_D_OP:
 
632
    case Y_C_ULT_S_OP:
 
633
      {
 
634
        COND(inst) = COND_LT | COND_UN;
 
635
        break;
 
636
      }
 
637
 
 
638
    case Y_C_ULE_D_OP:
 
639
    case Y_C_ULE_S_OP:
 
640
      {
 
641
        COND(inst) = COND_LT | COND_EQ | COND_UN;
 
642
        break;
 
643
      }
 
644
 
 
645
    case Y_C_UN_D_OP:
 
646
    case Y_C_UN_S_OP:
 
647
      {
 
648
        COND(inst) = COND_UN;
 
649
        break;
 
650
      }
 
651
    }
 
652
  store_instruction (inst);
 
653
}
 
654
 
 
655
 
 
656
/* Make and return a deep copy of INST. */
 
657
 
 
658
#ifdef __STDC__
 
659
instruction *
 
660
copy_inst (instruction *inst)
 
661
#else
 
662
instruction *
 
663
copy_inst (inst)
 
664
instruction *inst;
 
665
#endif
 
666
{
 
667
  instruction *new_inst = (instruction *) xmalloc (sizeof (instruction));
 
668
 
 
669
  *new_inst = *inst;
 
670
  /*memcpy ((void*)new_inst, (void*)inst , sizeof (instruction));*/
 
671
  SET_EXPR (new_inst, copy_imm_expr (EXPR (inst)));
 
672
  return (new_inst);
 
673
}
 
674
 
 
675
 
 
676
#ifdef __STDC__
 
677
void
 
678
free_inst (instruction *inst)
 
679
#else
 
680
void
 
681
free_inst (inst)
 
682
instruction *inst;
 
683
#endif
 
684
{
 
685
  if (inst != break_inst)
 
686
    /* Don't free the breakpoint insructions since we only have one. */
 
687
    {
 
688
      if (EXPR (inst))
 
689
        free (EXPR (inst));
 
690
      free (inst);
 
691
    }
 
692
}
 
693
 
 
694
 
 
695
 
 
696
/* Maintain a table mapping from opcode to instruction name and
 
697
   instruction type.
 
698
 
 
699
   Table must be sorted before first use since its entries are
 
700
   alphabetical on name, not ordered by opcode. */
 
701
 
 
702
static int sorted_name_table = 0;       /* Non-zero => table sorted */
 
703
 
 
704
 
 
705
/* Map from opcode -> name/type. */
 
706
 
 
707
static inst_info name_tbl [] = {
 
708
#undef OP
 
709
#define OP(NAME, OPCODE, TYPE, R_OPCODE) {NAME, OPCODE, TYPE},
 
710
#include "op.h"
 
711
};
 
712
 
 
713
 
 
714
/* Compare the VALUE1 field of two INST_INFO entries in the format
 
715
   required by qsort. */
 
716
 
 
717
#ifdef __STDC__
 
718
static int
 
719
compare_pair_value (inst_info *p1, inst_info *p2)
 
720
#else
 
721
static int
 
722
compare_pair_value (p1, p2)
 
723
     inst_info *p1, *p2;
 
724
#endif
 
725
{
 
726
  if (p1->value1 < p2->value1)
 
727
    return (-1);
 
728
  else if (p1->value1 > p2->value1)
 
729
    return (1);
 
730
  else
 
731
    return (0);
 
732
}
 
733
 
 
734
 
 
735
/* Sort the opcode table on their key (the opcode value). */
 
736
 
 
737
#ifdef __STDC__
 
738
static void
 
739
sort_name_table (void)
 
740
#else
 
741
static void
 
742
sort_name_table ()
 
743
#endif
 
744
{
 
745
  qsort (name_tbl,
 
746
         sizeof (name_tbl) / sizeof (inst_info),
 
747
         sizeof (inst_info),
 
748
         (QSORT_FUNC) compare_pair_value);
 
749
  sorted_name_table = 1;
 
750
}
 
751
 
 
752
 
 
753
/* Print the instruction stored at the memory ADDRESS. */
 
754
 
 
755
#ifdef __STDC__
 
756
void
 
757
print_inst (mem_addr addr)
 
758
#else
 
759
void
 
760
print_inst (addr)
 
761
     mem_addr addr;
 
762
#endif
 
763
{
 
764
  instruction *inst;
 
765
  char buf [1024];
 
766
 
 
767
  exception_occurred = 0;
 
768
  READ_MEM_INST (inst, addr);
 
769
 
 
770
  if (exception_occurred)
 
771
    {
 
772
      error ("Can't print instruction not in text segment (0x%08x)\n", addr);
 
773
      return;
 
774
    }
 
775
  print_inst_internal (buf, sizeof(buf), inst, addr);
 
776
  write_output (message_out, buf);
 
777
}
 
778
 
 
779
 
 
780
#ifdef __STDC__
 
781
int
 
782
print_inst_internal (char *buf, int length, instruction *inst, mem_addr addr)
 
783
#else
 
784
int
 
785
print_inst_internal (buf, length, inst, addr)
 
786
     char *buf;
 
787
     int length;
 
788
     instruction *inst;
 
789
     mem_addr addr;
 
790
#endif
 
791
{
 
792
  char *bp = buf;
 
793
  inst_info *entry;
 
794
 
 
795
  if (!sorted_name_table)
 
796
    sort_name_table ();
 
797
 
 
798
  sprintf (buf, "[0x%08x]\t", addr);
 
799
  buf += strlen (buf);
 
800
  if (inst == NULL)
 
801
    {
 
802
      sprintf (buf, "<none>\n");
 
803
      buf += strlen (buf);
 
804
      return (buf - bp);
 
805
    }
 
806
  entry = map_int_to_inst_info (name_tbl,
 
807
                                sizeof (name_tbl) / sizeof (inst_info),
 
808
                                OPCODE (inst));
 
809
  if (entry == NULL)
 
810
    {
 
811
      sprintf (buf, "<unknown instruction %d>\n", OPCODE (inst));
 
812
      buf += strlen (buf);
 
813
      return (buf - bp);
 
814
    }
 
815
  sprintf (buf, "0x%08x  %s", ENCODING (inst), entry->name);
 
816
  buf += strlen (buf);
 
817
  switch (entry->value2)
 
818
    {
 
819
    case B0_TYPE_INST:
 
820
      sprintf (buf, " %d", IDISP (inst));
 
821
      buf += strlen (buf);
 
822
      break;
 
823
 
 
824
    case B1_TYPE_INST:
 
825
      sprintf (buf, " $%d %d", RS (inst), IDISP (inst));
 
826
      buf += strlen (buf);
 
827
      break;
 
828
 
 
829
    case I1t_TYPE_INST:
 
830
      sprintf (buf, " $%d, %d", RT (inst), IMM (inst));
 
831
      buf += strlen (buf);
 
832
      break;
 
833
 
 
834
    case I2_TYPE_INST:
 
835
      sprintf (buf, " $%d, $%d, %d", RT (inst), RS (inst), IMM (inst));
 
836
      buf += strlen (buf);
 
837
      break;
 
838
 
 
839
    case B2_TYPE_INST:
 
840
      sprintf (buf, " $%d, $%d, %d", RS (inst), RT (inst), IDISP (inst));
 
841
      buf += strlen (buf);
 
842
      break;
 
843
 
 
844
    case I2a_TYPE_INST:
 
845
      sprintf (buf, " $%d, %d($%d)", RT (inst), IMM (inst), BASE (inst));
 
846
      buf += strlen (buf);
 
847
      break;
 
848
 
 
849
    case R1s_TYPE_INST:
 
850
      sprintf (buf, " $%d", RS (inst));
 
851
      buf += strlen (buf);
 
852
      break;
 
853
 
 
854
    case R1d_TYPE_INST:
 
855
      sprintf (buf, " $%d", RD (inst));
 
856
      buf += strlen (buf);
 
857
      break;
 
858
 
 
859
    case R2td_TYPE_INST:
 
860
      sprintf (buf, " $%d, $%d", RT (inst), RD (inst));
 
861
      buf += strlen (buf);
 
862
      break;
 
863
 
 
864
    case R2st_TYPE_INST:
 
865
      sprintf (buf, " $%d, $%d", RS (inst), RT (inst));
 
866
      buf += strlen (buf);
 
867
      break;
 
868
 
 
869
    case R2ds_TYPE_INST:
 
870
      sprintf (buf, " $%d, $%d", RD (inst), RS (inst));
 
871
      buf += strlen (buf);
 
872
      break;
 
873
 
 
874
    case R2sh_TYPE_INST:
 
875
      if (ENCODING (inst) == 0)
 
876
        {
 
877
          buf -= 3;             /* zap sll */
 
878
          sprintf (buf, "nop");
 
879
        }
 
880
      else
 
881
        sprintf (buf, " $%d, $%d, %d", RD (inst), RT (inst), SHAMT (inst));
 
882
      buf += strlen (buf);
 
883
      break;
 
884
 
 
885
    case R3_TYPE_INST:
 
886
      sprintf (buf, " $%d, $%d, $%d", RD (inst), RS (inst), RT (inst));
 
887
      buf += strlen (buf);
 
888
      break;
 
889
 
 
890
    case R3sh_TYPE_INST:
 
891
      sprintf (buf, " $%d, $%d, $%d", RD (inst), RT (inst), RS (inst));
 
892
      buf += strlen (buf);
 
893
      break;
 
894
 
 
895
    case FP_I2a_TYPE_INST:
 
896
      sprintf (buf, " $f%d, %d($%d)", FT (inst), IMM (inst), BASE (inst));
 
897
      buf += strlen (buf);
 
898
      break;
 
899
 
 
900
    case FP_R2ds_TYPE_INST:
 
901
      sprintf (buf, " $f%d, $f%d", FD (inst), FS (inst));
 
902
      buf += strlen (buf);
 
903
      break;
 
904
 
 
905
    case FP_CMP_TYPE_INST:
 
906
      sprintf (buf, " $f%d, $f%d", FS (inst), FT (inst));
 
907
      buf += strlen (buf);
 
908
      break;
 
909
 
 
910
    case FP_R3_TYPE_INST:
 
911
      sprintf (buf, " $f%d, $f%d, $f%d", FD (inst), FS (inst), FT (inst));
 
912
      buf += strlen (buf);
 
913
      break;
 
914
 
 
915
    case FP_MOV_TYPE_INST:
 
916
      sprintf (buf, " $f%d, $f%d", FD (inst), FS (inst));
 
917
      buf += strlen (buf);
 
918
      break;
 
919
 
 
920
    case J_TYPE_INST:
 
921
      sprintf (buf, " 0x%08x", TARGET (inst) << 2);
 
922
      buf += strlen (buf);
 
923
      break;
 
924
 
 
925
    case CP_TYPE_INST:
 
926
      sprintf (buf, " $%d, $%d", RT (inst), RD (inst));
 
927
      buf += strlen (buf);
 
928
      break;
 
929
 
 
930
    case NOARG_TYPE_INST:
 
931
      break;
 
932
 
 
933
    case ASM_DIR:
 
934
    case PSEUDO_OP:
 
935
    default:
 
936
      fatal_error ("Unknown instruction type in print_inst\n");
 
937
    }
 
938
 
 
939
  if (EXPR (inst) != NULL && EXPR (inst)->symbol != NULL)
 
940
    {
 
941
      sprintf (buf, " [");
 
942
      buf += strlen (buf);
 
943
      if (opcode_is_load_store (OPCODE (inst)))
 
944
        buf = print_imm_expr (buf, length - (buf - bp) - 2,
 
945
                              EXPR (inst), BASE (inst));
 
946
      else
 
947
        buf = print_imm_expr (buf, length - (buf - bp) - 2, EXPR (inst), -1);
 
948
      sprintf (buf, "]");
 
949
      buf += strlen (buf);
 
950
    }
 
951
 
 
952
  if (SOURCE (inst) != NULL && 10 < length - (buf - bp))
 
953
    {
 
954
      /* Comment is source line text of current line. */
 
955
      int gap_length = 57 - (buf - bp);
 
956
      int n = strlen (SOURCE (inst));
 
957
      int remaining;
 
958
 
 
959
      for ( ; 0 < gap_length; gap_length -= 1)
 
960
        {
 
961
          sprintf (buf, " ");
 
962
          buf += 1;
 
963
        }
 
964
 
 
965
      strcpy (buf, "; ");
 
966
      buf += strlen (buf);
 
967
 
 
968
      remaining = length - (buf - bp);
 
969
      if (n < remaining - 2)
 
970
        {
 
971
          strncpy (buf, SOURCE (inst), n + 1);
 
972
          buf += n;
 
973
        }
 
974
      else
 
975
        {
 
976
          strncpy (buf, SOURCE (inst), remaining - 3);
 
977
          strncpy (buf + remaining - 3, "...", 3);
 
978
          buf += remaining;
 
979
        }
 
980
    }
 
981
 
 
982
  sprintf (buf, "\n");
 
983
  buf += strlen (buf);
 
984
  return (buf - bp);
 
985
}
 
986
 
 
987
 
 
988
 
 
989
/* Return non-zero if an INSTRUCTION is a conditional branch. */
 
990
 
 
991
#ifdef __STDC__
 
992
int
 
993
opcode_is_branch (int opcode)
 
994
#else
 
995
int
 
996
opcode_is_branch (opcode)
 
997
     int opcode;
 
998
#endif
 
999
{
 
1000
  switch (opcode)
 
1001
    {
 
1002
    case Y_BEQ_OP:
 
1003
    case Y_BEQZ_POP:
 
1004
    case Y_BGE_POP:
 
1005
    case Y_BGEU_POP:
 
1006
    case Y_BGEZ_OP:
 
1007
    case Y_BGEZAL_OP:
 
1008
    case Y_BGT_POP:
 
1009
    case Y_BGTU_POP:
 
1010
    case Y_BGTZ_OP:
 
1011
    case Y_BLE_POP:
 
1012
    case Y_BLEU_POP:
 
1013
    case Y_BLEZ_OP:
 
1014
    case Y_BLT_POP:
 
1015
    case Y_BLTU_POP:
 
1016
    case Y_BLTZ_OP:
 
1017
    case Y_BLTZAL_OP:
 
1018
    case Y_BNE_OP:
 
1019
    case Y_BNEZ_POP:
 
1020
    case Y_BC1F_OP:
 
1021
    case Y_BC1T_OP:
 
1022
      return (1);
 
1023
 
 
1024
    default:
 
1025
      return (0);
 
1026
    }
 
1027
}
 
1028
 
 
1029
 
 
1030
/* Return non-zero if an INSTRUCTION is an conditional branch (jump). */
 
1031
 
 
1032
#ifdef __STDC__
 
1033
int
 
1034
opcode_is_jump (int opcode)
 
1035
#else
 
1036
int
 
1037
opcode_is_jump (opcode)
 
1038
     int opcode;
 
1039
#endif
 
1040
{
 
1041
  switch (opcode)
 
1042
    {
 
1043
    case Y_J_OP:
 
1044
    case Y_JAL_OP:
 
1045
      return (1);
 
1046
 
 
1047
    default:
 
1048
      return (0);
 
1049
    }
 
1050
}
 
1051
 
 
1052
/* Return non-zero if an INSTRUCTION is a load or store. */
 
1053
 
 
1054
#ifdef __STDC__
 
1055
int
 
1056
opcode_is_load_store (int opcode)
 
1057
#else
 
1058
int
 
1059
opcode_is_load_store (opcode)
 
1060
     int opcode;
 
1061
#endif
 
1062
{
 
1063
  switch (opcode)
 
1064
    {
 
1065
    case Y_LB_OP: return (1);
 
1066
    case Y_LBU_OP: return (1);
 
1067
    case Y_LH_OP: return (1);
 
1068
    case Y_LHU_OP: return (1);
 
1069
    case Y_LW_OP: return (1);
 
1070
    case Y_LWC0_OP: return (1);
 
1071
    case Y_LWC1_OP: return (1);
 
1072
    case Y_LWC2_OP: return (1);
 
1073
    case Y_LWC3_OP: return (1);
 
1074
    case Y_LWL_OP: return (1);
 
1075
    case Y_LWR_OP: return (1);
 
1076
    case Y_SB_OP: return (1);
 
1077
    case Y_SH_OP: return (1);
 
1078
    case Y_SW_OP: return (1);
 
1079
    case Y_SWC0_OP: return (1);
 
1080
    case Y_SWC1_OP: return (1);
 
1081
    case Y_SWC2_OP: return (1);
 
1082
    case Y_SWC3_OP: return (1);
 
1083
    case Y_SWL_OP: return (1);
 
1084
    case Y_SWR_OP: return (1);
 
1085
    case Y_L_D_POP: return (1);
 
1086
    case Y_L_S_POP: return (1);
 
1087
    case Y_S_D_POP: return (1);
 
1088
    case Y_S_S_POP: return (1);
 
1089
    default: return (0);
 
1090
    }
 
1091
}
 
1092
 
 
1093
 
 
1094
/* Return non-zero if a breakpoint is set at ADDR. */
 
1095
 
 
1096
#ifdef __STDC__
 
1097
int
 
1098
inst_is_breakpoint (mem_addr addr)
 
1099
#else
 
1100
int
 
1101
inst_is_breakpoint (addr)
 
1102
     mem_addr addr;
 
1103
#endif
 
1104
{
 
1105
  instruction *old_inst;
 
1106
 
 
1107
  if (break_inst == NULL)
 
1108
    break_inst = make_r_type_inst (Y_BREAK_OP, 1, 0, 0);
 
1109
 
 
1110
  READ_MEM_INST (old_inst, addr);
 
1111
  return (old_inst == break_inst);
 
1112
}
 
1113
 
 
1114
 
 
1115
/* Set a breakpoint at ADDR and return the old instruction.  If the
 
1116
   breakpoint cannot be set, return NULL. */
 
1117
 
 
1118
#ifdef __STDC__
 
1119
instruction *
 
1120
set_breakpoint (mem_addr addr)
 
1121
#else
 
1122
instruction *
 
1123
set_breakpoint (addr)
 
1124
     mem_addr addr;
 
1125
#endif
 
1126
{
 
1127
  instruction *old_inst;
 
1128
 
 
1129
  if (break_inst == NULL)
 
1130
    break_inst = make_r_type_inst (Y_BREAK_OP, 1, 0, 0);
 
1131
 
 
1132
  exception_occurred = 0;
 
1133
  READ_MEM_INST (old_inst, addr);
 
1134
  if (old_inst == break_inst)
 
1135
    return (NULL);
 
1136
  SET_MEM_INST (addr, break_inst);
 
1137
  if (exception_occurred)
 
1138
    return (NULL);
 
1139
  else
 
1140
    return (old_inst);
 
1141
}
 
1142
 
 
1143
 
 
1144
 
 
1145
/* An immediate expression has the form: SYMBOL +/- IOFFSET, where either
 
1146
   part may be omitted. */
 
1147
 
 
1148
/* Make and return a new immediate expression */
 
1149
 
 
1150
#ifdef __STDC__
 
1151
imm_expr *
 
1152
make_imm_expr (int offs, char *sym, int pc_rel)
 
1153
#else
 
1154
imm_expr *
 
1155
make_imm_expr (offs, sym, pc_rel)
 
1156
     int offs;
 
1157
     char *sym;
 
1158
     int pc_rel;
 
1159
#endif
 
1160
{
 
1161
  imm_expr *expr = (imm_expr *) xmalloc (sizeof (imm_expr));
 
1162
 
 
1163
  expr->offset = offs;
 
1164
  expr->bits = 0;
 
1165
  expr->pc_relative = (short)pc_rel;
 
1166
  if (sym != NULL)
 
1167
    expr->symbol = lookup_label (sym);
 
1168
  else
 
1169
    expr->symbol = NULL;
 
1170
  return (expr);
 
1171
}
 
1172
 
 
1173
 
 
1174
/* Return a shallow copy of the EXPRESSION. */
 
1175
 
 
1176
#ifdef __STDC__
 
1177
imm_expr *
 
1178
copy_imm_expr (imm_expr *old_expr)
 
1179
#else
 
1180
imm_expr *
 
1181
copy_imm_expr (old_expr)
 
1182
     imm_expr *old_expr;
 
1183
#endif
 
1184
{
 
1185
  imm_expr *expr = (imm_expr *) xmalloc (sizeof (imm_expr));
 
1186
 
 
1187
  *expr = *old_expr;
 
1188
  /*memcpy ((void*)expr, (void*)old_expr, sizeof (imm_expr));*/
 
1189
  return (expr);
 
1190
}
 
1191
 
 
1192
 
 
1193
/* Return a shallow copy of an EXPRESSION that only uses the upper
 
1194
   sixteen bits of the expression's value. */
 
1195
 
 
1196
#ifdef __STDC__
 
1197
imm_expr *
 
1198
upper_bits_of_expr (imm_expr *old_expr)
 
1199
#else
 
1200
imm_expr *
 
1201
upper_bits_of_expr (old_expr)
 
1202
     imm_expr *old_expr;
 
1203
#endif
 
1204
{
 
1205
  imm_expr *expr = copy_imm_expr (old_expr);
 
1206
 
 
1207
  expr->bits = 1;
 
1208
  return (expr);
 
1209
}
 
1210
 
 
1211
 
 
1212
/* Return a shallow copy of the EXPRESSION that only uses the lower
 
1213
   sixteen bits of the expression's value. */
 
1214
 
 
1215
#ifdef __STDC__
 
1216
imm_expr *
 
1217
lower_bits_of_expr (imm_expr *old_expr)
 
1218
#else
 
1219
imm_expr *
 
1220
lower_bits_of_expr (old_expr)
 
1221
     imm_expr *old_expr;
 
1222
#endif
 
1223
{
 
1224
  imm_expr *expr = copy_imm_expr (old_expr);
 
1225
 
 
1226
  expr->bits = -1;
 
1227
  return (expr);
 
1228
}
 
1229
 
 
1230
 
 
1231
/* Return an instruction expression for a constant VALUE. */
 
1232
 
 
1233
#ifdef __STDC__
 
1234
imm_expr *
 
1235
const_imm_expr (int32 value)
 
1236
#else
 
1237
imm_expr *
 
1238
const_imm_expr (value)
 
1239
     int32 value;
 
1240
#endif
 
1241
{
 
1242
  return (make_imm_expr (value, NULL, 0));
 
1243
}
 
1244
 
 
1245
 
 
1246
/* Return a shallow copy of the EXPRESSION with the offset field
 
1247
   incremented by the given amount. */
 
1248
 
 
1249
#ifdef __STDC__
 
1250
imm_expr *
 
1251
incr_expr_offset (imm_expr *expr, int32 value)
 
1252
#else
 
1253
imm_expr *
 
1254
incr_expr_offset (expr, value)
 
1255
     imm_expr *expr;
 
1256
     int32 value;
 
1257
#endif
 
1258
{
 
1259
  imm_expr *new_expr = copy_imm_expr (expr);
 
1260
 
 
1261
  new_expr->offset += value;
 
1262
  return (new_expr);
 
1263
}
 
1264
 
 
1265
 
 
1266
/* Return the value of the EXPRESSION. */
 
1267
 
 
1268
#ifdef __STDC__
 
1269
int32
 
1270
eval_imm_expr (imm_expr *expr)
 
1271
#else
 
1272
int32
 
1273
eval_imm_expr (expr)
 
1274
     imm_expr *expr;
 
1275
#endif
 
1276
{
 
1277
  int32 value;
 
1278
 
 
1279
  if (expr->symbol == NULL)
 
1280
    value = expr->offset;
 
1281
  else if (SYMBOL_IS_DEFINED (expr->symbol))
 
1282
    {
 
1283
      value = expr->offset + expr->symbol->addr;
 
1284
      if (expr->symbol->gp_flag) /* Addr is offset from $gp */
 
1285
        value += gp_midpoint;
 
1286
    }
 
1287
  else
 
1288
    {
 
1289
      error ("Evaluated undefined symbol: %s\n", expr->symbol->name);
 
1290
      value = 0;
 
1291
    }
 
1292
  if (expr->bits > 0)
 
1293
    return ((value >> 16) & 0xffff);  /* Use upper bits of result */
 
1294
  else if (expr->bits < 0)
 
1295
    return (value & 0xffff);          /* Use lower bits */
 
1296
  else
 
1297
    return (value);
 
1298
}
 
1299
 
 
1300
 
 
1301
/* Print the EXPRESSION. */
 
1302
 
 
1303
#ifdef __STDC__
 
1304
static char*
 
1305
print_imm_expr (char *buf, unsigned int length, imm_expr *expr, int base_reg)
 
1306
#else
 
1307
static char*
 
1308
print_imm_expr (buf, length, expr, base_reg)
 
1309
     char *buf;
 
1310
     int length;
 
1311
     imm_expr *expr;
 
1312
     int base_reg;
 
1313
#endif
 
1314
{
 
1315
  char lbuf[100];
 
1316
  char* lbp = lbuf;
 
1317
 
 
1318
  if (expr->symbol != NULL)
 
1319
    {
 
1320
      unsigned int n = strlen (expr->symbol->name);
 
1321
      if (n < length)
 
1322
        {
 
1323
          strncpy (buf, expr->symbol->name, length);
 
1324
          buf += n;
 
1325
          length -= n;
 
1326
        }
 
1327
      else
 
1328
        {
 
1329
          strncpy (buf, expr->symbol->name, length - 3);
 
1330
          strncpy (buf + length - 3, "...", 3);
 
1331
          buf += length;
 
1332
          length = 0;
 
1333
        }
 
1334
    }
 
1335
 
 
1336
  *lbp = '\0';
 
1337
  if (expr->pc_relative)
 
1338
    sprintf (lbp, "-0x%08x", -expr->offset);
 
1339
  else if (expr->offset < -10)
 
1340
    sprintf (lbp, "-%d (-0x%08x)", -expr->offset, -expr->offset);
 
1341
  else if (expr->offset > 10)
 
1342
    sprintf (lbp, "+%d (0x%08x)", expr->offset, expr->offset);
 
1343
  lbp += strlen(lbp);
 
1344
 
 
1345
  if (base_reg != -1 && expr->symbol != NULL &&
 
1346
      (expr->offset > 10 || expr->offset < -10))
 
1347
    {
 
1348
      if (expr->offset == 0 && base_reg != 0)
 
1349
        sprintf (lbp, "+0");
 
1350
      if (expr->offset != 0 || base_reg != 0)
 
1351
        sprintf (lbp, "($%d)", base_reg);
 
1352
    }
 
1353
  lbp += strlen (lbp);
 
1354
 
 
1355
  if (length <= 0)
 
1356
    ;
 
1357
  else if (strlen (lbuf) < length)
 
1358
    {
 
1359
      strncpy (buf, lbuf, length);
 
1360
      buf += strlen (buf);
 
1361
    }
 
1362
  else
 
1363
    {
 
1364
      strncpy (buf, lbuf, length - 3);
 
1365
      strncpy (buf + length - 3, "...", 3);
 
1366
      buf += length;
 
1367
    }
 
1368
 
 
1369
  return (buf);
 
1370
}
 
1371
 
 
1372
 
 
1373
/* Return non-zero if the EXPRESSION is a constant 0. */
 
1374
 
 
1375
#ifdef __STDC__
 
1376
int
 
1377
zero_imm (imm_expr *expr)
 
1378
#else
 
1379
int
 
1380
zero_imm (expr)
 
1381
     imm_expr *expr;
 
1382
#endif
 
1383
{
 
1384
  return (expr->offset == 0 && expr->symbol == NULL);
 
1385
}
 
1386
 
 
1387
 
 
1388
 
 
1389
/* Return an address expression of the form SYMBOL +/- IOFFSET (REGISTER).
 
1390
   Any of the three parts may be omitted. */
 
1391
 
 
1392
#ifdef __STDC__
 
1393
addr_expr *
 
1394
make_addr_expr (int offs, char *sym, int reg_no)
 
1395
#else
 
1396
addr_expr *
 
1397
make_addr_expr (offs, sym, reg_no)
 
1398
     int offs;
 
1399
     char *sym;
 
1400
     int reg_no;
 
1401
#endif
 
1402
{
 
1403
  addr_expr *expr = (addr_expr *) xmalloc (sizeof (addr_expr));
 
1404
  label *lab;
 
1405
 
 
1406
  if (reg_no == 0 && sym != NULL && (lab = lookup_label (sym))->gp_flag)
 
1407
    {
 
1408
      expr->reg_no = REG_GP;
 
1409
      expr->imm = make_imm_expr (offs + lab->addr - gp_midpoint, NULL, 0);
 
1410
    }
 
1411
  else
 
1412
    {
 
1413
      expr->reg_no = (unsigned char)reg_no;
 
1414
      expr->imm = make_imm_expr (offs, (sym ? str_copy (sym) : sym), 0);
 
1415
    }
 
1416
  return (expr);
 
1417
}
 
1418
 
 
1419
 
 
1420
#ifdef __STDC__
 
1421
imm_expr *
 
1422
addr_expr_imm (addr_expr *expr)
 
1423
#else
 
1424
imm_expr *
 
1425
addr_expr_imm (expr)
 
1426
addr_expr *expr;
 
1427
#endif
 
1428
{
 
1429
  return (expr->imm);
 
1430
}
 
1431
 
 
1432
 
 
1433
#ifdef __STDC__
 
1434
int
 
1435
addr_expr_reg (addr_expr *expr)
 
1436
#else
 
1437
int
 
1438
addr_expr_reg (expr)
 
1439
addr_expr *expr;
 
1440
#endif
 
1441
{
 
1442
  return (expr->reg_no);
 
1443
}
 
1444
 
 
1445
 
 
1446
 
 
1447
/* Map between a SPIM instruction and the binary representation of the
 
1448
   instruction. */
 
1449
 
 
1450
 
 
1451
/* Maintain a table mapping from internal opcode (i_opcode) to actual
 
1452
   opcode (a_opcode).  Table must be sorted before first use since its
 
1453
   entries are alphabetical on name, not ordered by opcode. */
 
1454
 
 
1455
static int sorted_i_opcode_table = 0; /* Non-zero => table sorted */
 
1456
 
 
1457
 
 
1458
/* Map from internal opcode -> real opcode */
 
1459
 
 
1460
static inst_info i_opcode_tbl [] = {
 
1461
#undef OP
 
1462
#define OP(NAME, I_OPCODE, TYPE, A_OPCODE) {NAME, I_OPCODE, (int)A_OPCODE},
 
1463
#include "op.h"
 
1464
};
 
1465
 
 
1466
 
 
1467
/* Sort the opcode table on their key (the interal opcode value). */
 
1468
 
 
1469
#ifdef __STDC__
 
1470
static void
 
1471
sort_i_opcode_table (void)
 
1472
#else
 
1473
static void
 
1474
sort_i_opcode_table ()
 
1475
#endif
 
1476
{
 
1477
  qsort (i_opcode_tbl,
 
1478
         sizeof (i_opcode_tbl) / sizeof (inst_info),
 
1479
         sizeof (inst_info),
 
1480
         (QSORT_FUNC) compare_pair_value);
 
1481
  sorted_i_opcode_table = 1;
 
1482
}
 
1483
 
 
1484
 
 
1485
#define REGS(R,O) (((R) & 0x1f) << O)
 
1486
 
 
1487
 
 
1488
#ifdef __STDC__
 
1489
int32
 
1490
inst_encode (instruction *inst)
 
1491
#else
 
1492
int32
 
1493
inst_encode (inst)
 
1494
     instruction *inst;
 
1495
#endif
 
1496
{
 
1497
  int32 a_opcode = 0;
 
1498
  inst_info *entry;
 
1499
 
 
1500
  if (inst == NULL)
 
1501
    return (0);
 
1502
  if (!sorted_i_opcode_table)
 
1503
    sort_i_opcode_table ();
 
1504
  if (!sorted_name_table)
 
1505
    sort_name_table ();
 
1506
 
 
1507
  entry = map_int_to_inst_info (i_opcode_tbl,
 
1508
                                sizeof (i_opcode_tbl) / sizeof (inst_info),
 
1509
                                OPCODE (inst));
 
1510
  if (entry == NULL)
 
1511
    return 0;
 
1512
 
 
1513
  a_opcode = entry->value2;
 
1514
  entry = map_int_to_inst_info (name_tbl,
 
1515
                                sizeof (name_tbl) / sizeof (inst_info),
 
1516
                                OPCODE (inst));
 
1517
 
 
1518
  switch (entry->value2)
 
1519
    {
 
1520
    case B0_TYPE_INST:
 
1521
      return (a_opcode
 
1522
              | (IOFFSET (inst) & 0xffff));
 
1523
 
 
1524
    case B1_TYPE_INST:
 
1525
      return (a_opcode
 
1526
              | REGS (RS (inst), 21)
 
1527
              | (IOFFSET (inst) & 0xffff));
 
1528
 
 
1529
    case I1t_TYPE_INST:
 
1530
      return (a_opcode
 
1531
              | REGS (RS (inst), 21)
 
1532
              | REGS (RT (inst), 16)
 
1533
              | (IMM (inst) & 0xffff));
 
1534
 
 
1535
    case I2_TYPE_INST:
 
1536
    case B2_TYPE_INST:
 
1537
      return (a_opcode
 
1538
              | REGS (RS (inst), 21)
 
1539
              | REGS (RT (inst), 16)
 
1540
              | (IMM (inst) & 0xffff));
 
1541
 
 
1542
    case I2a_TYPE_INST:
 
1543
      return (a_opcode
 
1544
              | REGS (BASE (inst), 21)
 
1545
              | REGS (RT (inst), 16)
 
1546
              | (IOFFSET (inst) & 0xffff));
 
1547
 
 
1548
    case R1s_TYPE_INST:
 
1549
      return (a_opcode
 
1550
              | REGS (RS (inst), 21));
 
1551
 
 
1552
    case R1d_TYPE_INST:
 
1553
      return (a_opcode
 
1554
              | REGS (RD (inst), 11));
 
1555
 
 
1556
    case R2td_TYPE_INST:
 
1557
      return (a_opcode
 
1558
              | REGS (RT (inst), 16)
 
1559
              | REGS (RD (inst), 11));
 
1560
 
 
1561
    case R2st_TYPE_INST:
 
1562
      return (a_opcode
 
1563
              | REGS (RS (inst), 21)
 
1564
              | REGS (RT (inst), 16));
 
1565
 
 
1566
    case R2ds_TYPE_INST:
 
1567
      return (a_opcode
 
1568
              | REGS (RS (inst), 21)
 
1569
              | REGS (RD (inst), 11));
 
1570
 
 
1571
    case R2sh_TYPE_INST:
 
1572
      return (a_opcode
 
1573
              | REGS (RT (inst), 16)
 
1574
              | REGS (RD (inst), 11)
 
1575
              | REGS (SHAMT (inst), 6));
 
1576
 
 
1577
    case R3_TYPE_INST:
 
1578
      return (a_opcode
 
1579
              | REGS (RS (inst), 21)
 
1580
              | REGS (RT (inst), 16)
 
1581
              | REGS (RD (inst), 11));
 
1582
 
 
1583
    case R3sh_TYPE_INST:
 
1584
      return (a_opcode
 
1585
              | REGS (RS (inst), 21)
 
1586
              | REGS (RT (inst), 16)
 
1587
              | REGS (RD (inst), 11));
 
1588
 
 
1589
    case FP_I2a_TYPE_INST:
 
1590
      return (a_opcode
 
1591
              | REGS (BASE (inst), 21)
 
1592
              | REGS (RT (inst), 16)
 
1593
              | (IOFFSET (inst) & 0xffff));
 
1594
 
 
1595
    case FP_R2ds_TYPE_INST:
 
1596
      return (a_opcode
 
1597
              | REGS (FS (inst), 11)
 
1598
              | REGS (FD (inst), 6));
 
1599
 
 
1600
    case FP_CMP_TYPE_INST:
 
1601
      return (a_opcode
 
1602
              | REGS (FT (inst), 16)
 
1603
              | REGS (FS (inst), 11)
 
1604
              | (COND (inst) & 0xf));
 
1605
 
 
1606
    case FP_R3_TYPE_INST:
 
1607
      return (a_opcode
 
1608
              | REGS (FT (inst), 16)
 
1609
              | REGS (FS (inst), 11)
 
1610
              | REGS (FD (inst), 6));
 
1611
 
 
1612
    case FP_MOV_TYPE_INST:
 
1613
      return (a_opcode
 
1614
              | REGS (FS (inst), 11)
 
1615
              | REGS (FD (inst), 6));
 
1616
 
 
1617
    case J_TYPE_INST:
 
1618
      return (a_opcode
 
1619
              | TARGET (inst));
 
1620
 
 
1621
    case CP_TYPE_INST:
 
1622
      return (a_opcode
 
1623
              | REGS (RT (inst), 16)
 
1624
              | REGS (RD (inst), 11));
 
1625
 
 
1626
    case NOARG_TYPE_INST:
 
1627
      return (a_opcode);
 
1628
 
 
1629
    case ASM_DIR:
 
1630
    case PSEUDO_OP:
 
1631
    default:
 
1632
      fatal_error ("Unknown instruction type in inst_encoding\n");
 
1633
      return (0);               /* Not reached */
 
1634
    }
 
1635
}
 
1636
 
 
1637
 
 
1638
/* Maintain a table mapping from actual opcode to interal opcode.
 
1639
   Table must be sorted before first use since its entries are
 
1640
   alphabetical on name, not ordered by opcode. */
 
1641
 
 
1642
static int sorted_a_opcode_table = 0; /* Non-zero => table sorted */
 
1643
 
 
1644
 
 
1645
/* Map from internal opcode -> real opcode */
 
1646
 
 
1647
static inst_info a_opcode_tbl [] = {
 
1648
#undef OP
 
1649
#define OP(NAME, I_OPCODE, TYPE, A_OPCODE) {NAME, (int)A_OPCODE, (int)I_OPCODE},
 
1650
#include "op.h"
 
1651
};
 
1652
 
 
1653
 
 
1654
/* Sort the opcode table on their key (the interal opcode value). */
 
1655
 
 
1656
#ifdef __STDC__
 
1657
static void
 
1658
sort_a_opcode_table (void)
 
1659
#else
 
1660
static void
 
1661
sort_a_opcode_table ()
 
1662
#endif
 
1663
{
 
1664
  qsort (a_opcode_tbl,
 
1665
         sizeof (a_opcode_tbl) / sizeof (inst_info),
 
1666
         sizeof (inst_info),
 
1667
         (QSORT_FUNC) compare_pair_value);
 
1668
  sorted_a_opcode_table = 1;
 
1669
}
 
1670
 
 
1671
 
 
1672
#define REG(V,O) ((V) >> O) & 0x1f
 
1673
 
 
1674
 
 
1675
#ifdef __STDC__
 
1676
instruction *
 
1677
  inst_decode (uint32 value)
 
1678
#else
 
1679
instruction *
 
1680
  inst_decode (value)
 
1681
uint32 value;
 
1682
#endif
 
1683
{
 
1684
  int32 a_opcode = value & 0xfc000000;
 
1685
  inst_info *entry;
 
1686
  int32 i_opcode;
 
1687
 
 
1688
  if (a_opcode == 0)            /* SPECIAL */
 
1689
    a_opcode |= (value & 0x3f);
 
1690
  else if (a_opcode == 0x04000000) /* BCOND */
 
1691
    a_opcode |= (value & 0x001f0000);
 
1692
  else if (a_opcode == 0x40000000) /* COP0 */
 
1693
    a_opcode |= (value & 0x03e00000) | (value & 0x1f);
 
1694
  else if (a_opcode == 0x44000000) /* COP1 */
 
1695
    {
 
1696
      a_opcode |= (value & 0x03e00000);
 
1697
      if ((value & 0xff000000) == 0x45000000)
 
1698
        a_opcode |= (value & 0x00010000); /* BC1f/t */
 
1699
      else
 
1700
        a_opcode |= (value & 0x3f);
 
1701
    }
 
1702
  else if (a_opcode == 0x48000000 /* COPz */
 
1703
           || a_opcode == 0x4c000000)
 
1704
    a_opcode |= (value & 0x03e00000);
 
1705
 
 
1706
 
 
1707
  if (!sorted_a_opcode_table)
 
1708
    sort_a_opcode_table ();
 
1709
  if (!sorted_name_table)
 
1710
    sort_name_table ();
 
1711
 
 
1712
  entry = map_int_to_inst_info (a_opcode_tbl,
 
1713
                                sizeof (a_opcode_tbl) / sizeof (inst_info),
 
1714
                                a_opcode);
 
1715
  if (entry == NULL)
 
1716
    return (mk_r_inst (value, 0, 0, 0, 0, 0)); /* Invalid inst */
 
1717
 
 
1718
  i_opcode = entry->value2;
 
1719
 
 
1720
  switch (map_int_to_inst_info (name_tbl,
 
1721
                                sizeof (name_tbl) / sizeof (inst_info),
 
1722
                                i_opcode)->value2)
 
1723
    {
 
1724
    case B0_TYPE_INST:
 
1725
      return (mk_i_inst (value, i_opcode, 0, 0, value & 0xffff));
 
1726
 
 
1727
    case B1_TYPE_INST:
 
1728
      return (mk_i_inst (value, i_opcode, REG (value, 21), 0, value & 0xffff));
 
1729
 
 
1730
    case I1t_TYPE_INST:
 
1731
      return (mk_i_inst (value, i_opcode, REG (value, 21), REG (value, 16),
 
1732
                         value & 0xffff));
 
1733
 
 
1734
    case I2_TYPE_INST:
 
1735
    case B2_TYPE_INST:
 
1736
      return (mk_i_inst (value, i_opcode, REG (value, 21), REG (value, 16),
 
1737
                         value & 0xffff));
 
1738
 
 
1739
    case I2a_TYPE_INST:
 
1740
      return (mk_i_inst (value, i_opcode, REG (value, 21), REG (value, 16),
 
1741
                         value & 0xffff));
 
1742
 
 
1743
    case R1s_TYPE_INST:
 
1744
      return (mk_r_inst (value, i_opcode, REG (value, 21), 0, 0, 0));
 
1745
 
 
1746
    case R1d_TYPE_INST:
 
1747
      return (mk_r_inst (value, i_opcode, 0, 0, REG (value, 11), 0));
 
1748
 
 
1749
    case R2td_TYPE_INST:
 
1750
      return (mk_r_inst (value, i_opcode, 0, REG (value, 16), REG (value, 11),
 
1751
                         0));
 
1752
 
 
1753
    case R2st_TYPE_INST:
 
1754
      return (mk_r_inst (value, i_opcode, REG (value, 21), REG (value, 16),
 
1755
                         0, 0));
 
1756
 
 
1757
    case R2ds_TYPE_INST:
 
1758
      return (mk_r_inst (value, i_opcode, REG (value, 21), 0, REG (value, 11),
 
1759
                         0));
 
1760
 
 
1761
    case R2sh_TYPE_INST:
 
1762
      return (mk_r_inst (value, i_opcode, 0, REG (value, 16), REG (value, 11),
 
1763
                         REG (value, 6)));
 
1764
 
 
1765
    case R3_TYPE_INST:
 
1766
      return (mk_r_inst (value, i_opcode, REG (value, 21), REG (value, 16),
 
1767
                         REG (value, 11), 0));
 
1768
 
 
1769
    case R3sh_TYPE_INST:
 
1770
      return (mk_r_inst (value, i_opcode, REG (value, 21), REG (value, 16),
 
1771
                         REG (value, 11), 0));
 
1772
 
 
1773
    case FP_I2a_TYPE_INST:
 
1774
      return (mk_i_inst (value, i_opcode, REG (value, 21), REG (value, 16),
 
1775
                         value & 0xffff));
 
1776
 
 
1777
    case FP_R2ds_TYPE_INST:
 
1778
      return (mk_r_inst (value, i_opcode, REG (value, 11), 0, REG (value, 6),
 
1779
                         0));
 
1780
 
 
1781
    case FP_CMP_TYPE_INST:
 
1782
      {
 
1783
        instruction *inst = mk_r_inst (value, i_opcode, REG (value, 11),
 
1784
                                       REG (value, 16), 0, 0);
 
1785
        SET_COND (inst, value & 0xf);
 
1786
        return (inst);
 
1787
      }
 
1788
 
 
1789
    case FP_R3_TYPE_INST:
 
1790
      return (mk_r_inst (value, i_opcode, REG (value, 11), REG (value, 16),
 
1791
                         REG (value, 6), 0));
 
1792
 
 
1793
    case FP_MOV_TYPE_INST:
 
1794
      return (mk_r_inst (value, i_opcode, REG (value, 11), 0, REG (value, 6),
 
1795
                         0));
 
1796
 
 
1797
    case J_TYPE_INST:
 
1798
      return (mk_j_inst (value, i_opcode, value & 0x2ffffff));
 
1799
 
 
1800
    case CP_TYPE_INST:
 
1801
      return (mk_r_inst (value, i_opcode, 0, REG (value, 16), REG (value, 11),
 
1802
                         0));
 
1803
 
 
1804
    case NOARG_TYPE_INST:
 
1805
      return (mk_r_inst (value, i_opcode, 0, 0, 0, 0));
 
1806
 
 
1807
    case ASM_DIR:
 
1808
    case PSEUDO_OP:
 
1809
    default:
 
1810
      return (mk_r_inst (value, 0, 0, 0, 0, 0)); /* Invalid inst */
 
1811
    }
 
1812
}
 
1813
 
 
1814
 
 
1815
#ifdef __STDC__
 
1816
static instruction *
 
1817
mk_r_inst (uint32 value, int opcode, int rs, int rt, int rd, int shamt)
 
1818
#else
 
1819
static instruction *
 
1820
mk_r_inst (value, opcode, rs, rt, rd, shamt)
 
1821
     uint32 value;
 
1822
     int opcode, rs, rt, rd, shamt;
 
1823
#endif
 
1824
{
 
1825
  instruction *inst = (instruction *) zmalloc (sizeof (instruction));
 
1826
 
 
1827
  SET_OPCODE (inst, opcode);
 
1828
  SET_RS (inst, rs);
 
1829
  SET_RT (inst, rt);
 
1830
  SET_RD (inst, rd);
 
1831
  SET_SHAMT (inst, shamt);
 
1832
  SET_ENCODING (inst, value);
 
1833
  SET_EXPR (inst, NULL);
 
1834
  return (inst);
 
1835
}
 
1836
 
 
1837
 
 
1838
#ifdef __STDC__
 
1839
static instruction *
 
1840
mk_i_inst (uint32 value, int opcode, int rs, int rt, int offset)
 
1841
#else
 
1842
static instruction *
 
1843
mk_i_inst (value, opcode, rs, rt, offset)
 
1844
     uint32 value;
 
1845
     int opcode, rs, rt, offset;
 
1846
#endif
 
1847
{
 
1848
  instruction *inst = (instruction *) zmalloc (sizeof (instruction));
 
1849
 
 
1850
  SET_OPCODE (inst, opcode);
 
1851
  SET_RS (inst, rs);
 
1852
  SET_RT (inst, rt);
 
1853
  SET_IOFFSET (inst, offset);
 
1854
  SET_ENCODING (inst, value);
 
1855
  SET_EXPR (inst, NULL);
 
1856
  return (inst);
 
1857
}
 
1858
 
 
1859
#ifdef __STDC__
 
1860
static instruction *
 
1861
mk_j_inst (uint32 value, int opcode, int target)
 
1862
#else
 
1863
static instruction *
 
1864
mk_j_inst (value, opcode, target)
 
1865
     uint32 value;
 
1866
     int opcode, target;
 
1867
#endif
 
1868
{
 
1869
  instruction *inst = (instruction *) zmalloc (sizeof (instruction));
 
1870
 
 
1871
  SET_OPCODE (inst, opcode);
 
1872
  SET_TARGET (inst, target);
 
1873
  SET_ENCODING (inst, value);
 
1874
  SET_EXPR (inst, NULL);
 
1875
  return (inst);
 
1876
}
 
1877
 
 
1878
 
 
1879
/* Code to test encode/decode of instructions. */
 
1880
 
 
1881
#ifdef __STDC__
 
1882
void
 
1883
test_assembly (instruction *inst)
 
1884
#else
 
1885
void
 
1886
test_assembly (inst)
 
1887
     instruction *inst;
 
1888
#endif
 
1889
{
 
1890
  instruction *new_inst = inst_decode (inst_encode (inst));
 
1891
 
 
1892
  inst_cmp (inst, new_inst);
 
1893
  free_inst (new_inst);
 
1894
}
 
1895
 
 
1896
 
 
1897
#ifdef __STDC__
 
1898
static void
 
1899
inst_cmp (instruction *inst1, instruction *inst2)
 
1900
#else
 
1901
static void
 
1902
inst_cmp (inst1, inst2)
 
1903
     instruction *inst1, *inst2;
 
1904
#endif
 
1905
{
 
1906
  char buf[1024];
 
1907
 
 
1908
  if (memcmp (inst1, inst2, sizeof (instruction) - 4) != 0)
 
1909
    {
 
1910
      printf ("=================== Not Equal ===================\n");
 
1911
      print_inst_internal (buf, sizeof(buf), inst1, 0);
 
1912
      printf ("%s\n", buf);
 
1913
      print_inst_internal (buf, sizeof(buf), inst2, 0);
 
1914
      printf ("%s\n", buf);
 
1915
      printf ("=================== Not Equal ===================\n");
 
1916
    }
 
1917
}