|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)instruction.c 1.1 86/02/03 Copyr 1985 Sun Micro";
3: #endif
4:
5: /*
6: * Copyright (c) 1985 by Sun Microsystems, Inc.
7: */
8:
9: #include "as.h"
10: #if C2
11: #include "c2.h"
12: #endif
13:
14: extern char *malloc();
15: struct oper *newoperand();
16: struct oper operands[OPERANDS_MAX];
17: int numops, code_length;
18:
19: #if C2
20: NODE first = { OP_FIRST, SUBOP_OTHER, &first, &first };
21:
22: /* does this branch read the c or v bit of the condition code? */
23: char read_cc_cv[]={ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0 };
24: static struct ins_bkt * moveq = NULL;
25: #endif
26:
27: instruction( ip )
28: register struct ins_bkt *ip;
29: {
30: #if C2
31: register NODE *np;
32: #endif
33: register i;
34:
35: if ((ip->xflags_i&I20) && !ext_instruction_set)
36: PROG_ERROR( E_OPCODE );
37: i = 0;
38: if (ip->noper_i != numops && ip->noper_i <= OPERANDS_MAX){
39: if ( (ip->touchop_i&TOUCH1(TOUCHMASK)) == TOUCH1(SPEC(2)) && numops==1 && ip->subop_i == SUBOP_W )
40: /* shifts are a special case...*/
41: i = 0;
42: else if ( (ip->touchop_i&TOUCH1(TOUCHMASK)) == TOUCH1(SPEC(6)) && numops==0 )
43: /* so is rts */
44: i = 0;
45: else
46: i = (E_NUMOPS);
47: } else switch (ip->noper_i){
48: default: i = 0; break;
49: case 1:
50: i = operand_ok( ip, &operands[0], (struct oper *)NULL, (struct oper *)NULL); break;
51: case 2:
52: i = operand_ok( ip, &operands[0], &operands[1], (struct oper *)NULL);break;
53: case 3:
54: i = operand_ok( ip, &operands[0], &operands[1], &operands[2] );break;
55: }
56: if (i)
57: PROG_ERROR(i);
58: if (ip->align_i & dot) /* don't want instructions on odd bounds */
59: PROG_ERROR(E_ODDADDR);
60: #if AS
61: if (ISINSTRUC( ip->op_i ) )
62: code_length = 2; /* all instructions at least this long */
63: #endif
64: (ip->routine_i)(ip, numops);
65: #if AS
66: if (code_length) {
67: put_words(code,code_length); /* output text */
68: bc = code_length; /* increment LC */
69: }
70: #endif
71: }
72:
73:
74: static unsigned
75: op_to_bits( op )
76: register struct oper *op;
77: {
78: /* return the address-mode bits for operand *op */
79: register unsigned s;
80: static unsigned bits[] = {
81: 0,
82: AM_REG, AM_DEFER, AM_POSTINC, AM_PREDEC, AM_DISPL,
83: AM_INDEX, AM_ABSS, AM_ABSL, AM_IMMED, AM_NORMAL,
84: AM_REGPAIR, -1, -1, -1, -1,
85: AM_REGLIST,AM_FREGLIST,AM_FCREGLIST
86: };
87: switch ( s = bits[(int)op->type_o]){
88: case AM_REG:
89: s = reg_access[op->value_o]; break;
90: case AM_DISPL:
91: if (op->reg_o == PCREG) s = AM_PCDISPL; break;
92: case AM_INDEX:
93: if (op->reg_o == PCREG) s = AM_PCINDEX; break;
94: }
95: return s;
96: }
97:
98: int
99: operand_ok( ip, op1, op2, op3 )
100: struct ins_bkt *ip;
101: struct oper *op1, *op2, *op3;
102: {
103: /*
104: * this routine answers the eternal question:
105: * are operands *op1 and *op2 ok to use as the operands of instruction *ip?
106: * it does it by looking at the optype_i bit fields in the instruction
107: * description.
108: */
109: register i;
110: register unsigned opbits1, opbits2, opbits3;
111: register noperands = ip->noper_i;
112:
113: op1->access_o = opbits1 = op_to_bits( op1 );
114: if (op2)
115: op2->access_o = opbits2 = op_to_bits( op2 );
116: else
117: opbits2 = 0;
118: if (op3)
119: op3->access_o = opbits3 = op_to_bits( op3 );
120: else
121: opbits3 = 0;
122: switch (ip->touchop_i&TOUCH2(TOUCHMASK)){
123: case TOUCH2(SPEC(2)):
124: /* special hackery for shifts */
125: if (opbits1 == AM_IMMED && ((i=op1->value_o)<1 || i>8 || op1->sym_o))
126: return E_CONSTANT;
127: break;
128: }
129: switch (ip->touchop_i&TOUCH1(TOUCHMASK)){
130: case TOUCH1(SPEC(0)):
131: case TOUCH1(SPEC(1)):
132: /* special hackery for bit ops */
133: if (opbits1 == AM_IMMED){
134: i = op1->value_o;
135: if (op1->sym_o) return E_CONSTANT;
136: if (opbits2 == AM_DREG){
137: if (i < 0 || i > 31 ) return E_CONSTANT;
138: } else
139: if (i < 0 || i > 7 ) return E_CONSTANT;
140: }
141: break;
142: }
143: switch (noperands){
144: case 0: return 0;
145: case 1:
146: for (i=0; i<N_OPTYPES; i+=1)
147: if (opbits1&ip->optype_i[i]) return 0;
148: break;
149: case 2:
150: for (i=0; i<N_OPTYPES; i+=2)
151: if ((opbits1&ip->optype_i[i]) && (opbits2&ip->optype_i[i+1]) ) return 0;
152: break;
153: case 3:
154: for (i=0; i<N_OPTYPES; i+=3)
155: if ((opbits1&ip->optype_i[i]) && (opbits2&ip->optype_i[i+1]) && (opbits3&ip->optype_i[i+2]) ) return 0;
156: break;
157: }
158: return E_OPERAND;
159: }
160:
161:
162: /* table used to determine node type. */
163: /*
164: * we would really like this table to be subscripted by the enumerated type
165: * opcode_t, but C cannot hack that. Order here is VERY IMPORTANT,
166: * and this table must change if the opcode order or number changes!!
167: */
168: char opcodetypes[] = {
169: 0, 0, 0, /* FIRST, COMMENT, LABEL */
170: PSEUDOCODE, PSEUDOCODE, /* LONG, WORD */
171: PSEUDOCODE, PSEUDONOCODE, /* BYTE,TEXT */
172: PSEUDONOCODE, PSEUDONOCODE, /* DATA, DATA1 */
173: PSEUDONOCODE, PSEUDONOCODE, /* DATA2, BSS */
174: PSEUDONOCODE, /* PROC */
175: PSEUDONOCODE, PSEUDONOCODE, /* GLOBL, COMM */
176: PSEUDOCODE, PSEUDOCODE, /* EVEN, ALIGN */
177: PSEUDOCODE, PSEUDOCODE, /* ASCIZ, ASCII */
178: PSEUDOCODE, PSEUDOCODE, /* FLOAT, DOUBLE */
179: PSEUDONOCODE, /* STABS */
180: PSEUDONOCODE, PSEUDONOCODE, /* STABD, STABN */
181: PSEUDOCODE, PSEUDONOCODE, /* SKIP, LCOMM */
182: PSEUDONOCODE, /* CPID */
183: INSTRTYPE, INSTRTYPE, /* CSWITCH, FSWITCH */
184: INSTRTYPE, INSTRTYPE, /* BRANCH, MOVE */
185: INSTRTYPE, INSTRTYPE, /* MOVEM, EXIT */
186: INSTRTYPE, INSTRTYPE, /* DBRA, CALL */
187: INSTRTYPE, INSTRTYPE, /* JUMP, DJMP */
188: INSTRTYPE, INSTRTYPE, /* LINK, CMP */
189: INSTRTYPE, INSTRTYPE, /* PEA, ADD */
190: INSTRTYPE, INSTRTYPE, /* AND, EXT */
191: INSTRTYPE, INSTRTYPE, /* OR, TST */
192: INSTRTYPE, INSTRTYPE, /* ASL, ASR */
193: INSTRTYPE, INSTRTYPE, /* SUB, UNLK */
194: INSTRTYPE, INSTRTYPE, /* LEA, CLR */
195: INSTRTYPE, INSTRTYPE, /* BOP, EOR */
196: INSTRTYPE, /* OTHER */
197: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.