2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 #define RCSID5 "$Id: mach5.c,v 0.3 1994/06/24 13:09:58 ceriel Exp $"
8 * NS 16032 special routines
11 clrmode() { /* clear the current mode */
12 mode_ptr->m_ndisp = 0 ;
17 case 'b' : return 0x1C ;
18 case 'w' : return 0x1D ;
19 case 'd' : return 0x1E ;
20 case 'q' : return 0x1F ;
22 serror("illegal size indicator") ;
29 serror("bad operands");
33 serror("immediate operand not allowed") ;
35 /* Create the output formats */
37 assert ( id_t1(id)==T_INT ) ;
38 emit1( id_g1(id) | 0xC | (id_op(id)<<4) | ((sval&1)<<7 ) ) ;
39 emit1( (sval>>1) | (mode1.m_mode<<3) ) ;
43 assert ( id_t1(id)==T_INT ) ;
44 emit1( id_g1(id) | 0x7C | ((id_op(id)&1)<<7) ) ;
45 emit1( (id_op(id)>>1) | (mode1.m_mode<<3) ) ;
49 assert ( id_t1(id)==T_INT && id_t2(id)==T_INT );
50 emit1( id_g2(id) | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ;
51 emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
55 assert ( id_t1(id)==T_INT ) ;
57 emit1( id_g1(id) | (id_op(id)<<2) | ((sval&1)<<7 ) ) ;
62 assert ( id_t1(id)==T_INT && id_t2(id)==T_INT );
64 emit1( i_type | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ;
65 emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
69 assert ( id_t1(id)==T_INT ) ;
70 emit1( 0x2E | ((id_op(id)&3)<<6) ) ;
71 emit1( id_g1(id) | (id_op(id)&04) | (reg<<3) | ((mode2.m_mode&03)<<6) ) ;
72 emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
75 form9(id,i_type,f_type) {
77 emit1( i_type | (f_type<<2) | (id_op(id)<<3) | ((mode2.m_mode&03)<<6) ) ;
78 emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
82 assert ( id_t1(id)==T_FL && id_t2(id)==T_FL && id_g1(id)==id_g2(id) );
84 emit1( id_g1(id) | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ;
85 emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
89 assert ( id_t1(id)==T_INT ) ;
91 emit1( id_g1(id) | (id_op(id)<<2) | ((reg&1)<<7 ) ) ;
92 emit1( (reg>>1) | (mode1.m_mode<<3) ) ;
96 assert ( id_t1(id)==T_INT ) ;
97 emit1(0x16 /* + slave<<5 */ ) ;
98 emit1( id_g1(id) | (id_op(id)<<2) | ((reg&1)<<7 ) ) ;
99 emit1( (reg>>1) | (mode1.m_mode<<3) ) ;
102 frm15_1(id,i_type,s_type) {
103 emit1(0x16 /* + slave<<5 */ ) ;
104 emit1( i_type | (s_type<<2) | (id_op(id)<<3) | ((mode2.m_mode&03)<<6) ) ;
105 emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
109 assert(id_t1(id)==T_SLAVE&& id_t2(id)==T_SLAVE&& id_g1(id)==id_g2(id) );
110 emit1(0x16 /* + slave<<5 */ ) ;
111 emit1( id_g1(id) | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ;
112 emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
116 if ( (mode1.m_mode&0x1C)==0x1C ) {
117 emit1(mode1.m_index) ;
119 if ( mode1.m_mode==0x14 ) { /* Immediate */
120 RELOMOVE(relonami, mode1.m_rel1);
121 imm(id_g1(id),&mode1.m_expr1) ;
123 if ( mode1.m_ndisp >0 ) {
124 RELOMOVE(relonami, mode1.m_rel1);
125 disp(&mode1.m_expr1, mode1.m_mode == 0x1B ? RELPC : 0) ;
126 if ( mode1.m_ndisp >1 ) {
127 RELOMOVE(relonami, mode1.m_rel2);
128 disp(&mode1.m_expr2, 0) ;
134 if ( (mode1.m_mode&0x1C)==0x1C ) {
135 emit1(mode1.m_index) ;
137 if ( (mode2.m_mode&0x1C)==0x1C ) {
138 emit1(mode2.m_index) ;
140 if ( mode1.m_mode==0x14 ) { /* Immediate */
141 RELOMOVE(relonami, mode1.m_rel1);
142 imm(id_g1(id),&mode1.m_expr1) ;
144 if ( mode1.m_ndisp >0 ) {
145 RELOMOVE(relonami, mode1.m_rel1);
146 disp(&mode1.m_expr1, mode1.m_mode == 0x1B ? RELPC : 0) ;
147 if ( mode1.m_ndisp >1 ) {
148 RELOMOVE(relonami, mode1.m_rel2);
149 disp(&mode1.m_expr2, 0) ;
152 if ( mode2.m_mode==0x14 ) { /* Immediate */
153 RELOMOVE(relonami, mode2.m_rel1);
154 imm(id_g2(id),&mode2.m_expr1) ;
156 if ( mode2.m_ndisp >0 ) {
157 RELOMOVE(relonami, mode2.m_rel1);
158 disp(&mode2.m_expr1, mode2.m_mode == 0x1B ? RELPC : 0) ;
159 if ( mode2.m_ndisp >1 ) {
160 RELOMOVE(relonami, mode2.m_rel2);
161 disp(&mode2.m_expr2, 0) ;
166 disp(expr, relpc) register expr_t *expr ; {
170 if (DOTTYP >= 0x2 && DOTTYP<=0x7F &&
172 (pass==PASS_1 ? expr->typ==S_ABS : expr->typ!=S_VAR ) ) {
174 expr->typ == S_ABS) {
176 /* All non-text displacements are quad-sized.
177 The algorithm currently used for minimizing the size
178 (See CACM article) might generate assertion failures if
179 any displacement it is trying to minimize increases during
180 the assembly process. The only way to avoid increases
181 like that is to fix the sizes of all displacements in
183 If the framework included enough information one
184 might detect in the first pass (0) whether the value
185 of the expression depends on any symbols whose value
186 might alter later on in the assembly process. In that case
187 one could determine the right size in the first pass in
190 if ( fitd_b(expr->val) ) {
193 if ( fitd_w(expr->val) ) sm2=1 ;
196 sm1=small(sm1,1) ; sm2=small(sm2,2) ;
198 newrelo(expr->typ, RELO4|RELBR|RELWR|relpc);
200 if ( sm1 ) putdisp(expr->val,1) ;
201 else if ( sm2 ) putdisp(expr->val,2) ;
202 else putdisp(expr->val,4) ;
205 putdisp(val,size) valu_t val ; {
208 emit1( ((int)val)&0x7F ) ;
211 emit1( ( (((int)val)>>8)&0x3F ) | 0x80 ) ;
212 emit1( ((int)val)&0xFF ) ;
215 emit1( (((int)(val>>24)) | 0xC0) & 0xFF ) ;
216 emit1( ((int)(val>>16)) & 0xFF ) ;
217 emit1( (((int)val)>>8) & 0xFF ) ;
218 emit1( ((int)val)&0xFF ) ;
223 dot_adjust(expr) register expr_t *expr ; {
224 expr->val -= DOTVAL ;
225 if ( pass==PASS_2 ) {
226 if ( (expr->typ&S_DOT) == 0 && expr->val>0 ) {
227 expr->val -= DOTGAIN;
230 if ( (expr->typ & ~S_DOT) == DOTTYP ) {
237 /* The idea of the following is:
238 * Give the assembler programmer a warning if he tries to store
239 * an immediate value in a field which is too small to fit in.
243 /* check if value fits in type */
245 case I_DOUBLE : return fit32(val);
246 case I_WORD : return fit16(val);
247 case I_BYTE : return fit8(val);
251 imm(i_type,expr) register expr_t *expr ; {
252 /* emit value of immediate expression , after check on FIT */
253 if (!testsize(i_type,(int)expr->val))
254 warning("immediate operand too large");
258 newrelo(expr->typ, RELO4|RELBR|RELWR);
260 emit1( ((int)(expr->val>>24)) & 0xFF ) ;
261 emit1( ((int)(expr->val>>16)) & 0xFF ) ;
262 emit1( (((int)expr->val)>>8) & 0xFF ) ;
263 emit1( ((int)expr->val) & 0xFF ) ;
267 newrelo(expr->typ, RELO2|RELBR);
269 emit1( (((int)expr->val)>>8) & 0xFF ) ;
270 emit1( ((int)expr->val) & 0xFF ) ;
274 newrelo(expr->typ, RELO1);
276 emit1( ((int)expr->val) & 0xFF ) ;
281 reg_list(list,reverse) {
282 register rev_list, i ;
287 for ( i=0 ; i<8 ; i++ ) {
288 if ( list & (1<<i) ) {
289 rev_list |= 1<<(7-i) ;
296 case 'i' : return 1 ;
297 case 'f' : return 2 ;
298 case 'm' : return 4 ;
299 case 'c' : return 8 ;
301 serror("illegal cpu option %c",indic) ;
308 case 'b' : return SO_BACKW ;
309 case 'u' : return SO_UNTIL ;
310 case 'w' : return SO_WHILE ;
312 serror("illegal string option %c",indic) ;