1
/* SPIM S20 MIPS simulator.
2
Code to build assembly instructions and resolve symbolic labels.
4
Copyright (C) 1990-2000 by James Larus (larus@cs.wisc.edu).
7
SPIM is distributed under the following conditions:
9
You may make copies of SPIM for your own use and modify those copies.
11
All copies of SPIM must retain my name and copyright notice.
13
You may not sell SPIM or distributed SPIM in conjunction with a
14
commerical product or service without the expressed written consent of
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
23
/* $Header: /Software/SPIM/src/inst.c 10 12/24/00 1:37p Larus $
30
#include "spim-utils.h"
41
/* Local functions: */
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,
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,
56
static void produce_immediate (imm_expr *expr, int rt, int value_known, int32 value);
57
static void sort_name_table (void);
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 ();
73
/* Local variables: */
75
/* Non-zero means store instructions in kernel, not user, text segment */
77
static int in_kernel = 0;
79
/* Instruction used as breakpoint by SPIM: */
81
static instruction *break_inst = NULL;
84
/* Locations for next instruction in user and kernel text segments */
86
static mem_addr next_text_pc;
88
static mem_addr next_k_text_pc;
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;}
98
/* Set ADDRESS at which the next instruction is stored. */
102
text_begins_at_point (mem_addr addr)
105
text_begins_at_point (addr)
115
k_text_begins_at_point (mem_addr addr)
118
k_text_begins_at_point (addr)
122
next_k_text_pc = addr;
126
/* Set the location (in user or kernel text space) for the next instruction. */
130
set_text_pc (mem_addr addr)
138
next_k_text_pc = addr;
144
/* Return address for next instruction, in appropriate text segment. */
148
current_text_pc (void)
158
/* Increment the current text segement PC. */
162
increment_text_pc (int delta)
165
increment_text_pc (delta)
169
BUMP_INST_PC (delta);
173
/* If FLAG is non-zero, next instruction goes to kernel text segment,
174
otherwise it goes to user segment. */
178
user_kernel_text_segment (int to_kernel)
181
user_kernel_text_segment (to_kernel)
185
in_kernel = to_kernel;
189
/* Store an INSTRUCTION in memory at the next location. */
193
store_instruction (instruction *inst)
196
store_instruction (inst)
202
store_word (inst_encode (inst));
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);
212
BUMP_INST_PC (BYTES_PER_WORD);
215
SET_SOURCE (inst, source_line ());
216
if (ENCODING (inst) == 0)
217
SET_ENCODING (inst, inst_encode (inst));
226
i_type_inst_free (int opcode, int rt, int rs, imm_expr *expr)
229
i_type_inst_free (opcode, rt, rs, expr)
234
i_type_inst (opcode, rt, rs, expr);
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. */
247
i_type_inst (int opcode, int rt, int rs, imm_expr *expr)
250
i_type_inst (opcode, rt, rs, expr)
255
instruction *inst = (instruction *) zmalloc (sizeof (instruction));
257
SET_OPCODE (inst, opcode);
260
SET_EXPR (inst, copy_imm_expr (expr));
261
if (expr->symbol == NULL || SYMBOL_IS_DEFINED (expr->symbol))
263
/* Evaluate the instruction's expression. */
264
int32 value = eval_imm_expr (expr);
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)))
276
i_type_inst_full_word (opcode, rt, rs, expr, 1, value);
280
resolve_a_label (expr->symbol, inst);
282
else if (bare_machine || expr->bits != 0)
283
/* Don't know expression's value, but only needed upper/lower 16-bits
285
record_inst_uses_symbol (inst, expr->symbol);
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. */
293
i_type_inst_full_word (opcode, rt, rs, expr, 0, 0);
297
store_instruction (inst);
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. */
306
i_type_inst_full_word (int opcode, int rt, int rs, imm_expr *expr,
307
int value_known, int32 value)
310
i_type_inst_full_word (opcode, rt, rs, expr, value_known, value)
317
if (opcode_is_load_store (opcode))
321
if (expr->symbol != NULL
322
&& expr->symbol->gp_flag
324
&& IMM_MIN <= (offset = expr->symbol->addr + expr->offset)
325
&& offset <= IMM_MAX)
327
i_type_inst_free (opcode, rt, REG_GP, make_imm_expr (offset, NULL, 0));
329
else if (value_known)
333
high = (value >> 16) & 0xffff;
334
low = value & 0xffff;
337
!(high == 0xffff && (low & 0x8000)))
339
/* Some of high 16 bits are non-zero */
342
/* Adjust high 16, since load sign-extends low 16*/
346
i_type_inst_free (Y_LUI_OP, 1, 0, const_imm_expr (high));
347
if (rs != 0) /* Base register */
349
r_type_inst (Y_ADDU_OP, 1, 1, rs);
351
i_type_inst_free (opcode, rt, 1, const_imm_expr (low));
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));
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 */
366
r_type_inst (Y_ADDU_OP, 1, 1, rs);
368
i_type_inst_free (opcode, rt, 1, lower_bits_of_expr (expr));
371
else if (opcode_is_branch (opcode))
373
/* This only allows branches +/- 32K, which is not correct! */
374
i_type_inst_free (opcode, rt, rs, lower_bits_of_expr (expr));
377
/* Computation instruction */
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)
386
i_type_inst_free ((opcode == Y_LUI_OP ? Y_ADDIU_OP : opcode),
387
rt, REG_GP, make_imm_expr (offset, NULL, 0));
392
if ((opcode == Y_ORI_OP
393
|| opcode == Y_ADDI_OP
394
|| opcode == Y_ADDIU_OP
395
|| opcode == Y_LUI_OP)
398
produce_immediate(expr, rt, value_known, value);
402
produce_immediate(expr, 1, value_known, value);
403
r_type_inst (imm_op_to_op (opcode), rt, rs, 1);
412
produce_immediate (imm_expr *expr, int rt, int value_known, int32 value)
415
produce_immediate (expr, rt, value_known, value)
422
if (value_known && (value & 0xffff) == 0)
424
i_type_inst_free (Y_LUI_OP, rt, 0, upper_bits_of_expr (expr));
426
else if (value_known && (value & 0xffff0000) == 0)
428
i_type_inst_free (Y_ORI_OP, rt, 0, lower_bits_of_expr (expr));
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));
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. */
444
j_type_inst (int opcode, imm_expr *target)
447
j_type_inst (opcode, target)
452
instruction *inst = (instruction *) zmalloc (sizeof (instruction));
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);
461
record_inst_uses_symbol (inst, target->symbol);
462
store_instruction (inst);
466
/* Return a register-type instruction with the given OPCODE, RD, RS, and RT
471
make_r_type_inst (int opcode, int rd, int rs, int rt)
474
make_r_type_inst (opcode, rd, rs, rt)
475
int opcode, rd, rs, rt;
478
instruction *inst = (instruction *) zmalloc (sizeof (instruction));
480
SET_OPCODE(inst, opcode);
489
/* Return a register-type instruction with the given OPCODE, RD, RS, and RT
494
r_type_inst (int opcode, int rd, int rs, int rt)
497
r_type_inst (opcode, rd, rs, rt)
498
int opcode, rd, rs, rt;
501
store_instruction (make_r_type_inst (opcode, rd, rs, rt));
505
/* Return a register-shift instruction with the given OPCODE, RD, RT, and
510
r_sh_type_inst (int opcode, int rd, int rt, int shamt)
513
r_sh_type_inst (opcode, rd, rt, shamt)
514
int opcode, rd, rt, shamt;
517
instruction *inst = make_r_type_inst (opcode, rd, 0, rt);
519
SET_SHAMT(inst, shamt & 0x1f);
520
store_instruction (inst);
524
/* Return a floating-point compare instruction with the given OPCODE,
529
r_cond_type_inst (int opcode, int rs, int rt)
532
r_cond_type_inst (opcode, rs, rt)
536
instruction *inst = make_r_type_inst (opcode, 0, rs, rt);
543
COND(inst) = COND_EQ;
550
COND(inst) = COND_IN | COND_LT | COND_EQ;
557
COND(inst) = COND_IN | COND_LT;
564
COND(inst) = COND_IN | COND_LT | COND_UN;
571
COND(inst) = COND_IN | COND_UN;
578
COND(inst) = COND_IN | COND_EQ | COND_UN;
585
COND(inst) = COND_IN | COND_LT | COND_EQ | COND_UN;
592
COND(inst) = COND_LT;
599
COND(inst) = COND_LT | COND_EQ;
606
COND(inst) = COND_IN | COND_EQ;
613
COND(inst) = COND_IN;
627
COND(inst) = COND_EQ | COND_UN;
634
COND(inst) = COND_LT | COND_UN;
641
COND(inst) = COND_LT | COND_EQ | COND_UN;
648
COND(inst) = COND_UN;
652
store_instruction (inst);
656
/* Make and return a deep copy of INST. */
660
copy_inst (instruction *inst)
667
instruction *new_inst = (instruction *) xmalloc (sizeof (instruction));
670
/*memcpy ((void*)new_inst, (void*)inst , sizeof (instruction));*/
671
SET_EXPR (new_inst, copy_imm_expr (EXPR (inst)));
678
free_inst (instruction *inst)
685
if (inst != break_inst)
686
/* Don't free the breakpoint insructions since we only have one. */
696
/* Maintain a table mapping from opcode to instruction name and
699
Table must be sorted before first use since its entries are
700
alphabetical on name, not ordered by opcode. */
702
static int sorted_name_table = 0; /* Non-zero => table sorted */
705
/* Map from opcode -> name/type. */
707
static inst_info name_tbl [] = {
709
#define OP(NAME, OPCODE, TYPE, R_OPCODE) {NAME, OPCODE, TYPE},
714
/* Compare the VALUE1 field of two INST_INFO entries in the format
715
required by qsort. */
719
compare_pair_value (inst_info *p1, inst_info *p2)
722
compare_pair_value (p1, p2)
726
if (p1->value1 < p2->value1)
728
else if (p1->value1 > p2->value1)
735
/* Sort the opcode table on their key (the opcode value). */
739
sort_name_table (void)
746
sizeof (name_tbl) / sizeof (inst_info),
748
(QSORT_FUNC) compare_pair_value);
749
sorted_name_table = 1;
753
/* Print the instruction stored at the memory ADDRESS. */
757
print_inst (mem_addr addr)
767
exception_occurred = 0;
768
READ_MEM_INST (inst, addr);
770
if (exception_occurred)
772
error ("Can't print instruction not in text segment (0x%08x)\n", addr);
775
print_inst_internal (buf, sizeof(buf), inst, addr);
776
write_output (message_out, buf);
782
print_inst_internal (char *buf, int length, instruction *inst, mem_addr addr)
785
print_inst_internal (buf, length, inst, addr)
795
if (!sorted_name_table)
798
sprintf (buf, "[0x%08x]\t", addr);
802
sprintf (buf, "<none>\n");
806
entry = map_int_to_inst_info (name_tbl,
807
sizeof (name_tbl) / sizeof (inst_info),
811
sprintf (buf, "<unknown instruction %d>\n", OPCODE (inst));
815
sprintf (buf, "0x%08x %s", ENCODING (inst), entry->name);
817
switch (entry->value2)
820
sprintf (buf, " %d", IDISP (inst));
825
sprintf (buf, " $%d %d", RS (inst), IDISP (inst));
830
sprintf (buf, " $%d, %d", RT (inst), IMM (inst));
835
sprintf (buf, " $%d, $%d, %d", RT (inst), RS (inst), IMM (inst));
840
sprintf (buf, " $%d, $%d, %d", RS (inst), RT (inst), IDISP (inst));
845
sprintf (buf, " $%d, %d($%d)", RT (inst), IMM (inst), BASE (inst));
850
sprintf (buf, " $%d", RS (inst));
855
sprintf (buf, " $%d", RD (inst));
860
sprintf (buf, " $%d, $%d", RT (inst), RD (inst));
865
sprintf (buf, " $%d, $%d", RS (inst), RT (inst));
870
sprintf (buf, " $%d, $%d", RD (inst), RS (inst));
875
if (ENCODING (inst) == 0)
877
buf -= 3; /* zap sll */
878
sprintf (buf, "nop");
881
sprintf (buf, " $%d, $%d, %d", RD (inst), RT (inst), SHAMT (inst));
886
sprintf (buf, " $%d, $%d, $%d", RD (inst), RS (inst), RT (inst));
891
sprintf (buf, " $%d, $%d, $%d", RD (inst), RT (inst), RS (inst));
895
case FP_I2a_TYPE_INST:
896
sprintf (buf, " $f%d, %d($%d)", FT (inst), IMM (inst), BASE (inst));
900
case FP_R2ds_TYPE_INST:
901
sprintf (buf, " $f%d, $f%d", FD (inst), FS (inst));
905
case FP_CMP_TYPE_INST:
906
sprintf (buf, " $f%d, $f%d", FS (inst), FT (inst));
910
case FP_R3_TYPE_INST:
911
sprintf (buf, " $f%d, $f%d, $f%d", FD (inst), FS (inst), FT (inst));
915
case FP_MOV_TYPE_INST:
916
sprintf (buf, " $f%d, $f%d", FD (inst), FS (inst));
921
sprintf (buf, " 0x%08x", TARGET (inst) << 2);
926
sprintf (buf, " $%d, $%d", RT (inst), RD (inst));
930
case NOARG_TYPE_INST:
936
fatal_error ("Unknown instruction type in print_inst\n");
939
if (EXPR (inst) != NULL && EXPR (inst)->symbol != NULL)
943
if (opcode_is_load_store (OPCODE (inst)))
944
buf = print_imm_expr (buf, length - (buf - bp) - 2,
945
EXPR (inst), BASE (inst));
947
buf = print_imm_expr (buf, length - (buf - bp) - 2, EXPR (inst), -1);
952
if (SOURCE (inst) != NULL && 10 < length - (buf - bp))
954
/* Comment is source line text of current line. */
955
int gap_length = 57 - (buf - bp);
956
int n = strlen (SOURCE (inst));
959
for ( ; 0 < gap_length; gap_length -= 1)
968
remaining = length - (buf - bp);
969
if (n < remaining - 2)
971
strncpy (buf, SOURCE (inst), n + 1);
976
strncpy (buf, SOURCE (inst), remaining - 3);
977
strncpy (buf + remaining - 3, "...", 3);
989
/* Return non-zero if an INSTRUCTION is a conditional branch. */
993
opcode_is_branch (int opcode)
996
opcode_is_branch (opcode)
1030
/* Return non-zero if an INSTRUCTION is an conditional branch (jump). */
1034
opcode_is_jump (int opcode)
1037
opcode_is_jump (opcode)
1052
/* Return non-zero if an INSTRUCTION is a load or store. */
1056
opcode_is_load_store (int opcode)
1059
opcode_is_load_store (opcode)
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);
1094
/* Return non-zero if a breakpoint is set at ADDR. */
1098
inst_is_breakpoint (mem_addr addr)
1101
inst_is_breakpoint (addr)
1105
instruction *old_inst;
1107
if (break_inst == NULL)
1108
break_inst = make_r_type_inst (Y_BREAK_OP, 1, 0, 0);
1110
READ_MEM_INST (old_inst, addr);
1111
return (old_inst == break_inst);
1115
/* Set a breakpoint at ADDR and return the old instruction. If the
1116
breakpoint cannot be set, return NULL. */
1120
set_breakpoint (mem_addr addr)
1123
set_breakpoint (addr)
1127
instruction *old_inst;
1129
if (break_inst == NULL)
1130
break_inst = make_r_type_inst (Y_BREAK_OP, 1, 0, 0);
1132
exception_occurred = 0;
1133
READ_MEM_INST (old_inst, addr);
1134
if (old_inst == break_inst)
1136
SET_MEM_INST (addr, break_inst);
1137
if (exception_occurred)
1145
/* An immediate expression has the form: SYMBOL +/- IOFFSET, where either
1146
part may be omitted. */
1148
/* Make and return a new immediate expression */
1152
make_imm_expr (int offs, char *sym, int pc_rel)
1155
make_imm_expr (offs, sym, pc_rel)
1161
imm_expr *expr = (imm_expr *) xmalloc (sizeof (imm_expr));
1163
expr->offset = offs;
1165
expr->pc_relative = (short)pc_rel;
1167
expr->symbol = lookup_label (sym);
1169
expr->symbol = NULL;
1174
/* Return a shallow copy of the EXPRESSION. */
1178
copy_imm_expr (imm_expr *old_expr)
1181
copy_imm_expr (old_expr)
1185
imm_expr *expr = (imm_expr *) xmalloc (sizeof (imm_expr));
1188
/*memcpy ((void*)expr, (void*)old_expr, sizeof (imm_expr));*/
1193
/* Return a shallow copy of an EXPRESSION that only uses the upper
1194
sixteen bits of the expression's value. */
1198
upper_bits_of_expr (imm_expr *old_expr)
1201
upper_bits_of_expr (old_expr)
1205
imm_expr *expr = copy_imm_expr (old_expr);
1212
/* Return a shallow copy of the EXPRESSION that only uses the lower
1213
sixteen bits of the expression's value. */
1217
lower_bits_of_expr (imm_expr *old_expr)
1220
lower_bits_of_expr (old_expr)
1224
imm_expr *expr = copy_imm_expr (old_expr);
1231
/* Return an instruction expression for a constant VALUE. */
1235
const_imm_expr (int32 value)
1238
const_imm_expr (value)
1242
return (make_imm_expr (value, NULL, 0));
1246
/* Return a shallow copy of the EXPRESSION with the offset field
1247
incremented by the given amount. */
1251
incr_expr_offset (imm_expr *expr, int32 value)
1254
incr_expr_offset (expr, value)
1259
imm_expr *new_expr = copy_imm_expr (expr);
1261
new_expr->offset += value;
1266
/* Return the value of the EXPRESSION. */
1270
eval_imm_expr (imm_expr *expr)
1273
eval_imm_expr (expr)
1279
if (expr->symbol == NULL)
1280
value = expr->offset;
1281
else if (SYMBOL_IS_DEFINED (expr->symbol))
1283
value = expr->offset + expr->symbol->addr;
1284
if (expr->symbol->gp_flag) /* Addr is offset from $gp */
1285
value += gp_midpoint;
1289
error ("Evaluated undefined symbol: %s\n", expr->symbol->name);
1293
return ((value >> 16) & 0xffff); /* Use upper bits of result */
1294
else if (expr->bits < 0)
1295
return (value & 0xffff); /* Use lower bits */
1301
/* Print the EXPRESSION. */
1305
print_imm_expr (char *buf, unsigned int length, imm_expr *expr, int base_reg)
1308
print_imm_expr (buf, length, expr, base_reg)
1318
if (expr->symbol != NULL)
1320
unsigned int n = strlen (expr->symbol->name);
1323
strncpy (buf, expr->symbol->name, length);
1329
strncpy (buf, expr->symbol->name, length - 3);
1330
strncpy (buf + length - 3, "...", 3);
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);
1345
if (base_reg != -1 && expr->symbol != NULL &&
1346
(expr->offset > 10 || expr->offset < -10))
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);
1353
lbp += strlen (lbp);
1357
else if (strlen (lbuf) < length)
1359
strncpy (buf, lbuf, length);
1360
buf += strlen (buf);
1364
strncpy (buf, lbuf, length - 3);
1365
strncpy (buf + length - 3, "...", 3);
1373
/* Return non-zero if the EXPRESSION is a constant 0. */
1377
zero_imm (imm_expr *expr)
1384
return (expr->offset == 0 && expr->symbol == NULL);
1389
/* Return an address expression of the form SYMBOL +/- IOFFSET (REGISTER).
1390
Any of the three parts may be omitted. */
1394
make_addr_expr (int offs, char *sym, int reg_no)
1397
make_addr_expr (offs, sym, reg_no)
1403
addr_expr *expr = (addr_expr *) xmalloc (sizeof (addr_expr));
1406
if (reg_no == 0 && sym != NULL && (lab = lookup_label (sym))->gp_flag)
1408
expr->reg_no = REG_GP;
1409
expr->imm = make_imm_expr (offs + lab->addr - gp_midpoint, NULL, 0);
1413
expr->reg_no = (unsigned char)reg_no;
1414
expr->imm = make_imm_expr (offs, (sym ? str_copy (sym) : sym), 0);
1422
addr_expr_imm (addr_expr *expr)
1425
addr_expr_imm (expr)
1435
addr_expr_reg (addr_expr *expr)
1438
addr_expr_reg (expr)
1442
return (expr->reg_no);
1447
/* Map between a SPIM instruction and the binary representation of the
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. */
1455
static int sorted_i_opcode_table = 0; /* Non-zero => table sorted */
1458
/* Map from internal opcode -> real opcode */
1460
static inst_info i_opcode_tbl [] = {
1462
#define OP(NAME, I_OPCODE, TYPE, A_OPCODE) {NAME, I_OPCODE, (int)A_OPCODE},
1467
/* Sort the opcode table on their key (the interal opcode value). */
1471
sort_i_opcode_table (void)
1474
sort_i_opcode_table ()
1477
qsort (i_opcode_tbl,
1478
sizeof (i_opcode_tbl) / sizeof (inst_info),
1480
(QSORT_FUNC) compare_pair_value);
1481
sorted_i_opcode_table = 1;
1485
#define REGS(R,O) (((R) & 0x1f) << O)
1490
inst_encode (instruction *inst)
1502
if (!sorted_i_opcode_table)
1503
sort_i_opcode_table ();
1504
if (!sorted_name_table)
1507
entry = map_int_to_inst_info (i_opcode_tbl,
1508
sizeof (i_opcode_tbl) / sizeof (inst_info),
1513
a_opcode = entry->value2;
1514
entry = map_int_to_inst_info (name_tbl,
1515
sizeof (name_tbl) / sizeof (inst_info),
1518
switch (entry->value2)
1522
| (IOFFSET (inst) & 0xffff));
1526
| REGS (RS (inst), 21)
1527
| (IOFFSET (inst) & 0xffff));
1531
| REGS (RS (inst), 21)
1532
| REGS (RT (inst), 16)
1533
| (IMM (inst) & 0xffff));
1538
| REGS (RS (inst), 21)
1539
| REGS (RT (inst), 16)
1540
| (IMM (inst) & 0xffff));
1544
| REGS (BASE (inst), 21)
1545
| REGS (RT (inst), 16)
1546
| (IOFFSET (inst) & 0xffff));
1550
| REGS (RS (inst), 21));
1554
| REGS (RD (inst), 11));
1556
case R2td_TYPE_INST:
1558
| REGS (RT (inst), 16)
1559
| REGS (RD (inst), 11));
1561
case R2st_TYPE_INST:
1563
| REGS (RS (inst), 21)
1564
| REGS (RT (inst), 16));
1566
case R2ds_TYPE_INST:
1568
| REGS (RS (inst), 21)
1569
| REGS (RD (inst), 11));
1571
case R2sh_TYPE_INST:
1573
| REGS (RT (inst), 16)
1574
| REGS (RD (inst), 11)
1575
| REGS (SHAMT (inst), 6));
1579
| REGS (RS (inst), 21)
1580
| REGS (RT (inst), 16)
1581
| REGS (RD (inst), 11));
1583
case R3sh_TYPE_INST:
1585
| REGS (RS (inst), 21)
1586
| REGS (RT (inst), 16)
1587
| REGS (RD (inst), 11));
1589
case FP_I2a_TYPE_INST:
1591
| REGS (BASE (inst), 21)
1592
| REGS (RT (inst), 16)
1593
| (IOFFSET (inst) & 0xffff));
1595
case FP_R2ds_TYPE_INST:
1597
| REGS (FS (inst), 11)
1598
| REGS (FD (inst), 6));
1600
case FP_CMP_TYPE_INST:
1602
| REGS (FT (inst), 16)
1603
| REGS (FS (inst), 11)
1604
| (COND (inst) & 0xf));
1606
case FP_R3_TYPE_INST:
1608
| REGS (FT (inst), 16)
1609
| REGS (FS (inst), 11)
1610
| REGS (FD (inst), 6));
1612
case FP_MOV_TYPE_INST:
1614
| REGS (FS (inst), 11)
1615
| REGS (FD (inst), 6));
1623
| REGS (RT (inst), 16)
1624
| REGS (RD (inst), 11));
1626
case NOARG_TYPE_INST:
1632
fatal_error ("Unknown instruction type in inst_encoding\n");
1633
return (0); /* Not reached */
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. */
1642
static int sorted_a_opcode_table = 0; /* Non-zero => table sorted */
1645
/* Map from internal opcode -> real opcode */
1647
static inst_info a_opcode_tbl [] = {
1649
#define OP(NAME, I_OPCODE, TYPE, A_OPCODE) {NAME, (int)A_OPCODE, (int)I_OPCODE},
1654
/* Sort the opcode table on their key (the interal opcode value). */
1658
sort_a_opcode_table (void)
1661
sort_a_opcode_table ()
1664
qsort (a_opcode_tbl,
1665
sizeof (a_opcode_tbl) / sizeof (inst_info),
1667
(QSORT_FUNC) compare_pair_value);
1668
sorted_a_opcode_table = 1;
1672
#define REG(V,O) ((V) >> O) & 0x1f
1677
inst_decode (uint32 value)
1684
int32 a_opcode = value & 0xfc000000;
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 */
1696
a_opcode |= (value & 0x03e00000);
1697
if ((value & 0xff000000) == 0x45000000)
1698
a_opcode |= (value & 0x00010000); /* BC1f/t */
1700
a_opcode |= (value & 0x3f);
1702
else if (a_opcode == 0x48000000 /* COPz */
1703
|| a_opcode == 0x4c000000)
1704
a_opcode |= (value & 0x03e00000);
1707
if (!sorted_a_opcode_table)
1708
sort_a_opcode_table ();
1709
if (!sorted_name_table)
1712
entry = map_int_to_inst_info (a_opcode_tbl,
1713
sizeof (a_opcode_tbl) / sizeof (inst_info),
1716
return (mk_r_inst (value, 0, 0, 0, 0, 0)); /* Invalid inst */
1718
i_opcode = entry->value2;
1720
switch (map_int_to_inst_info (name_tbl,
1721
sizeof (name_tbl) / sizeof (inst_info),
1725
return (mk_i_inst (value, i_opcode, 0, 0, value & 0xffff));
1728
return (mk_i_inst (value, i_opcode, REG (value, 21), 0, value & 0xffff));
1731
return (mk_i_inst (value, i_opcode, REG (value, 21), REG (value, 16),
1736
return (mk_i_inst (value, i_opcode, REG (value, 21), REG (value, 16),
1740
return (mk_i_inst (value, i_opcode, REG (value, 21), REG (value, 16),
1744
return (mk_r_inst (value, i_opcode, REG (value, 21), 0, 0, 0));
1747
return (mk_r_inst (value, i_opcode, 0, 0, REG (value, 11), 0));
1749
case R2td_TYPE_INST:
1750
return (mk_r_inst (value, i_opcode, 0, REG (value, 16), REG (value, 11),
1753
case R2st_TYPE_INST:
1754
return (mk_r_inst (value, i_opcode, REG (value, 21), REG (value, 16),
1757
case R2ds_TYPE_INST:
1758
return (mk_r_inst (value, i_opcode, REG (value, 21), 0, REG (value, 11),
1761
case R2sh_TYPE_INST:
1762
return (mk_r_inst (value, i_opcode, 0, REG (value, 16), REG (value, 11),
1766
return (mk_r_inst (value, i_opcode, REG (value, 21), REG (value, 16),
1767
REG (value, 11), 0));
1769
case R3sh_TYPE_INST:
1770
return (mk_r_inst (value, i_opcode, REG (value, 21), REG (value, 16),
1771
REG (value, 11), 0));
1773
case FP_I2a_TYPE_INST:
1774
return (mk_i_inst (value, i_opcode, REG (value, 21), REG (value, 16),
1777
case FP_R2ds_TYPE_INST:
1778
return (mk_r_inst (value, i_opcode, REG (value, 11), 0, REG (value, 6),
1781
case FP_CMP_TYPE_INST:
1783
instruction *inst = mk_r_inst (value, i_opcode, REG (value, 11),
1784
REG (value, 16), 0, 0);
1785
SET_COND (inst, value & 0xf);
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));
1793
case FP_MOV_TYPE_INST:
1794
return (mk_r_inst (value, i_opcode, REG (value, 11), 0, REG (value, 6),
1798
return (mk_j_inst (value, i_opcode, value & 0x2ffffff));
1801
return (mk_r_inst (value, i_opcode, 0, REG (value, 16), REG (value, 11),
1804
case NOARG_TYPE_INST:
1805
return (mk_r_inst (value, i_opcode, 0, 0, 0, 0));
1810
return (mk_r_inst (value, 0, 0, 0, 0, 0)); /* Invalid inst */
1816
static instruction *
1817
mk_r_inst (uint32 value, int opcode, int rs, int rt, int rd, int shamt)
1819
static instruction *
1820
mk_r_inst (value, opcode, rs, rt, rd, shamt)
1822
int opcode, rs, rt, rd, shamt;
1825
instruction *inst = (instruction *) zmalloc (sizeof (instruction));
1827
SET_OPCODE (inst, opcode);
1831
SET_SHAMT (inst, shamt);
1832
SET_ENCODING (inst, value);
1833
SET_EXPR (inst, NULL);
1839
static instruction *
1840
mk_i_inst (uint32 value, int opcode, int rs, int rt, int offset)
1842
static instruction *
1843
mk_i_inst (value, opcode, rs, rt, offset)
1845
int opcode, rs, rt, offset;
1848
instruction *inst = (instruction *) zmalloc (sizeof (instruction));
1850
SET_OPCODE (inst, opcode);
1853
SET_IOFFSET (inst, offset);
1854
SET_ENCODING (inst, value);
1855
SET_EXPR (inst, NULL);
1860
static instruction *
1861
mk_j_inst (uint32 value, int opcode, int target)
1863
static instruction *
1864
mk_j_inst (value, opcode, target)
1869
instruction *inst = (instruction *) zmalloc (sizeof (instruction));
1871
SET_OPCODE (inst, opcode);
1872
SET_TARGET (inst, target);
1873
SET_ENCODING (inst, value);
1874
SET_EXPR (inst, NULL);
1879
/* Code to test encode/decode of instructions. */
1883
test_assembly (instruction *inst)
1886
test_assembly (inst)
1890
instruction *new_inst = inst_decode (inst_encode (inst));
1892
inst_cmp (inst, new_inst);
1893
free_inst (new_inst);
1899
inst_cmp (instruction *inst1, instruction *inst2)
1902
inst_cmp (inst1, inst2)
1903
instruction *inst1, *inst2;
1908
if (memcmp (inst1, inst2, sizeof (instruction) - 4) != 0)
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");