This is for PR 628.
[deliverable/binutils-gdb.git] / gas / config / tc-m68kmote.c
1 /* tc-m68kmote.c All the m68020 specific stuff in one convenient, huge,
2 slow to compile, easy to find file.
3 Copyright (C) 1987, 1991, 1992 Free Software Foundation, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #define MRI
22 #include <ctype.h>
23
24 #include "as.h"
25 #include "bfd.h"
26 #include "obstack.h"
27
28 /* note that this file includes real declarations and thus can only be included by one source file per executable. */
29 #include "opcode/m68k.h"
30 #ifdef TE_SUN
31 /* This variable contains the value to write out at the beginning of
32 the a.out file. The 2<<16 means that this is a 68020 file instead
33 of an old-style 68000 file */
34
35 long omagic = 2<<16|OMAGIC; /* Magic byte for header file */
36 #else
37 long omagic = OMAGIC;
38 #endif
39
40 /* This array holds the chars that always start a comment. If the
41 pre-processor is disabled, these aren't very useful */
42 const char comment_chars[] = "|";
43
44 /* This array holds the chars that only start a comment at the beginning of
45 a line. If the line seems to have the form '# 123 filename'
46 .line and .file directives will appear in the pre-processed output */
47 /* Note that input_file.c hand checks for '#' at the beginning of the
48 first line of the input file. This is because the compiler outputs
49 #NO_APP at the beginning of its output. */
50 /* Also note that comments like this one will always work. */
51 #ifdef MRI
52 const char line_comment_chars[] = "*";
53 #else
54 const char line_comment_chars[] = "#";
55 #endif
56
57 #define NO_RELOC 0
58
59 /* Chars that can be used to separate mant from exp in floating point nums */
60 const char EXP_CHARS[] = "eE";
61
62 /* Chars that mean this number is a floating point constant */
63 /* As in 0f12.456 */
64 /* or 0d1.2345e12 */
65
66 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
67
68 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
69 changed in read.c . Ideally it shouldn't have to know about it at all,
70 but nothing is ideal around here.
71 */
72
73 int md_reloc_size = 8; /* Size of relocation record */
74
75 /* Its an arbitrary name: This means I don't approve of it */
76 /* See flames below */
77 static struct obstack robyn;
78
79 #define TAB(x,y) (((x)<<2)+(y))
80 #define TABTYPE(xy) ((xy) >> 2)
81 #define BYTE 0
82 #define SHORT 1
83 #define LONG 2
84 #define SZ_UNDEF 3
85
86 #define BRANCH 1
87 #define FBRANCH 2
88 #define PCREL 3
89 #define BCC68000 4
90 #define DBCC 5
91 #define PCLEA 6
92
93 /* Operands we can parse: (And associated modes)
94
95 numb: 8 bit num
96 numw: 16 bit num
97 numl: 32 bit num
98 dreg: data reg 0-7
99 reg: address or data register
100 areg: address register
101 apc: address register, PC, ZPC or empty string
102 num: 16 or 32 bit num
103 num2: like num
104 sz: w or l if omitted, l assumed
105 scale: 1 2 4 or 8 if omitted, 1 assumed
106
107 7.4 IMMED #num --> NUM
108 0.? DREG dreg --> dreg
109 1.? AREG areg --> areg
110 2.? AINDR areg@ --> *(areg)
111 3.? AINC areg@+ --> *(areg++)
112 4.? ADEC areg@- --> *(--areg)
113 5.? AOFF apc@(numw) --> *(apc+numw) -- empty string and ZPC not allowed here
114 6.? AINDX apc@(num,reg:sz:scale) --> *(apc+num+reg*scale)
115 6.? AINDX apc@(reg:sz:scale) --> same, with num=0
116 6.? APODX apc@(num)@(num2,reg:sz:scale) --> *(*(apc+num)+num2+reg*scale)
117 6.? APODX apc@(num)@(reg:sz:scale) --> same, with num2=0
118 6.? AMIND apc@(num)@(num2) --> *(*(apc+num)+num2) (previous mode without an index reg)
119 6.? APRDX apc@(num,reg:sz:scale)@(num2) --> *(*(apc+num+reg*scale)+num2)
120 6.? APRDX apc@(reg:sz:scale)@(num2) --> same, with num=0
121 7.0 ABSL num:sz --> *(num)
122 num --> *(num) (sz L assumed)
123 *** MSCR otherreg --> Magic
124 With -l option
125 5.? AOFF apc@(num) --> *(apc+num) -- empty string and ZPC not allowed here still
126 ?.? DINDR dreg@ --> (dreg) -- cas2 only
127
128 examples:
129 #foo #0x35 #12
130 d2
131 a4
132 a3@
133 a5@+
134 a6@-
135 a2@(12) pc@(14)
136 a1@(5,d2:w:1) @(45,d6:l:4)
137 pc@(a2) @(d4)
138 etc . . .
139
140
141 #name@(numw) -->turn into PC rel mode
142 apc@(num8,reg:sz:scale) --> *(apc+num8+reg*scale)
143
144 */
145
146 enum operand_type {
147 IMMED = 1,
148 DREG,
149 AREG,
150 AINDR,
151 ADEC,
152 AINC,
153 AOFF,
154 AINDX,
155 APODX,
156 AMIND,
157 APRDX,
158 ABSL,
159 MSCR,
160 REGLST,
161 DINDR
162 };
163
164
165 struct m68k_exp {
166 char *e_beg;
167 char *e_end;
168 expressionS e_exp;
169 short e_siz; /* 0== default 1==short/byte 2==word 3==long */
170 };
171
172 /* DATA and ADDR have to be contiguous, so that reg-DATA gives 0-7==data reg,
173 8-15==addr reg for operands that take both types */
174
175 enum _register {
176 DATA = 1, /* 1- 8 == data registers 0-7 */
177 DATA0 = DATA,
178 DATA1,
179 DATA2,
180 DATA3,
181 DATA4,
182 DATA5,
183 DATA6,
184 DATA7,
185
186 ADDR,
187 ADDR0 = ADDR,
188 ADDR1,
189 ADDR2,
190 ADDR3,
191 ADDR4,
192 ADDR5,
193 ADDR6,
194 ADDR7,
195
196 /* Note that COPNUM==processor #1 -- COPNUM+7==#8, which stores as 000 */
197 /* I think. . . */
198
199 SP = ADDR7,
200
201 FPREG, /* Eight FP registers */
202 FP0 = FPREG,
203 FP1,
204 FP2,
205 FP3,
206 FP4,
207 FP5,
208 FP6,
209 FP7,
210 COPNUM = (FPREG+8), /* Co-processor #1-#8 */
211 COP0 = COPNUM,
212 COP1,
213 COP2,
214 COP3,
215 COP4,
216 COP5,
217 COP6,
218 COP7,
219 PC, /* Program counter */
220 ZPC, /* Hack for Program space, but 0 addressing */
221 SR, /* Status Reg */
222 CCR, /* Condition code Reg */
223
224 /* These have to be in order for the movec instruction to work. */
225 USP, /* User Stack Pointer */
226 ISP, /* Interrupt stack pointer */
227 SFC,
228 DFC,
229 CACR,
230 VBR,
231 CAAR,
232 MSP,
233 ITT0,
234 ITT1,
235 DTT0,
236 DTT1,
237 MMUSR,
238 TC,
239 SRP,
240 URP,
241 /* end of movec ordering constraints */
242
243 FPI,
244 FPS,
245 FPC,
246
247 DRP,
248 CRP,
249 CAL,
250 VAL,
251 SCC,
252 AC,
253 BAD,
254 BAD0 = BAD,
255 BAD1,
256 BAD2,
257 BAD3,
258 BAD4,
259 BAD5,
260 BAD6,
261 BAD7,
262 BAC,
263 BAC0 = BAC,
264 BAC1,
265 BAC2,
266 BAC3,
267 BAC4,
268 BAC5,
269 BAC6,
270 BAC7,
271 PSR,
272 PCSR,
273
274 IC, /* instruction cache token */
275 DC, /* data cache token */
276 NC, /* no cache token */
277 BC, /* both caches token */
278
279 };
280
281 /* Internal form of an operand. */
282 struct m68k_op {
283 char *error; /* Couldn't parse it */
284 enum operand_type mode; /* What mode this instruction is in. */
285 enum _register reg; /* Base register */
286 struct m68k_exp *con1;
287 int ireg; /* Index register */
288 int isiz; /* 0==unspec 1==byte(?) 2==short 3==long */
289 int imul; /* Multipy ireg by this (1,2,4,or 8) */
290 struct m68k_exp *con2;
291 };
292
293 /* internal form of a 68020 instruction */
294 struct m68k_it {
295 char *error;
296 char *args; /* list of opcode info */
297 int numargs;
298
299 int numo; /* Number of shorts in opcode */
300 short opcode[11];
301
302 struct m68k_op operands[6];
303
304 int nexp; /* number of exprs in use */
305 struct m68k_exp exprs[4];
306
307 int nfrag; /* Number of frags we have to produce */
308 struct {
309 int fragoff; /* Where in the current opcode[] the frag ends */
310 symbolS *fadd;
311 long foff;
312 int fragty;
313 } fragb[4];
314
315 int nrel; /* Num of reloc strucs in use */
316 struct {
317 int n;
318 symbolS *add,
319 *sub;
320 long off;
321 char wid;
322 char pcrel;
323 } reloc[5]; /* Five is enough??? */
324 };
325
326 #define cpu_of_arch(x) ((x) & m68000up)
327 #define float_of_arch(x) ((x) & mfloat)
328 #define mmu_of_arch(x) ((x) & mmmu)
329
330 static struct m68k_it the_ins; /* the instruction being assembled */
331
332 /* Macros for adding things to the m68k_it struct */
333
334 #define addword(w) the_ins.opcode[the_ins.numo++]=(w)
335
336 /* Like addword, but goes BEFORE general operands */
337 #define insop(w) {int z;\
338 for(z=the_ins.numo;z>opcode->m_codenum;--z)\
339 the_ins.opcode[z]=the_ins.opcode[z-1];\
340 for(z=0;z<the_ins.nrel;z++)\
341 the_ins.reloc[z].n+=2;\
342 the_ins.opcode[opcode->m_codenum]=w;\
343 the_ins.numo++;\
344 }
345
346
347 #define add_exp(beg,end) (\
348 the_ins.exprs[the_ins.nexp].e_beg=beg,\
349 the_ins.exprs[the_ins.nexp].e_end=end,\
350 &the_ins.exprs[the_ins.nexp++]\
351 )
352
353
354 /* The numo+1 kludge is so we can hit the low order byte of the prev word. Blecch*/
355 #define add_fix(width,exp,pc_rel) {\
356 the_ins.reloc[the_ins.nrel].n= ((width)=='B') ? (the_ins.numo*2-1) : \
357 (((width)=='b') ? ((the_ins.numo-1)*2) : (the_ins.numo*2));\
358 the_ins.reloc[the_ins.nrel].add=adds((exp));\
359 the_ins.reloc[the_ins.nrel].sub=subs((exp));\
360 the_ins.reloc[the_ins.nrel].off=offs((exp));\
361 the_ins.reloc[the_ins.nrel].wid=width;\
362 the_ins.reloc[the_ins.nrel++].pcrel=pc_rel;\
363 }
364
365 #define add_frag(add,off,type) {\
366 the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;\
367 the_ins.fragb[the_ins.nfrag].fadd=add;\
368 the_ins.fragb[the_ins.nfrag].foff=off;\
369 the_ins.fragb[the_ins.nfrag++].fragty=type;\
370 }
371
372 #define isvar(exp) ((exp) && (adds(exp) || subs(exp)))
373
374 #define seg(exp) ((exp)->e_exp.X_seg)
375 #define adds(exp) ((exp)->e_exp.X_add_symbol)
376 #define subs(exp) ((exp)->e_exp.X_subtract_symbol)
377 #define offs(exp) ((exp)->e_exp.X_add_number)
378
379
380 struct m68k_incant {
381 char *m_operands;
382 unsigned long m_opcode;
383 short m_opnum;
384 short m_codenum;
385 enum m68k_architecture m_arch;
386 struct m68k_incant *m_next;
387 };
388
389 #define getone(x) ((((x)->m_opcode)>>16)&0xffff)
390 #define gettwo(x) (((x)->m_opcode)&0xffff)
391
392
393 #if __STDC__ == 1
394
395 static char *crack_operand(char *str, struct m68k_op *opP);
396 static int get_num(struct m68k_exp *exp, int ok);
397 static int get_regs(int i, char *str, struct m68k_op *opP);
398 static int reverse_16_bits(int in);
399 static int reverse_8_bits(int in);
400 static int try_index(char **s, struct m68k_op *opP);
401 static void install_gen_operand(int mode, int val);
402 static void install_operand(int mode, int val);
403 static void s_bss(void);
404 static void s_data1(void);
405 static void s_data2(void);
406 static void s_even(void);
407 static void s_proc(void);
408
409 #else /* not __STDC__ */
410
411 static char *crack_operand();
412 static int get_num();
413 static int get_regs();
414 static int reverse_16_bits();
415 static int reverse_8_bits();
416 static int try_index();
417 static void install_gen_operand();
418 static void install_operand();
419 static void s_bss();
420 static void s_data1();
421 static void s_data2();
422 static void s_even();
423 static void s_proc();
424
425 #endif /* not __STDC__ */
426
427 static enum m68k_architecture current_architecture = _m68k_undef;
428
429 /* BCC68000 is for patching in an extra jmp instruction for long offsets
430 on the 68000. The 68000 doesn't support long branches with branchs */
431
432 /* This table desribes how you change sizes for the various types of variable
433 size expressions. This version only supports two kinds. */
434
435 /* Note that calls to frag_var need to specify the maximum expansion needed */
436 /* This is currently 10 bytes for DBCC */
437
438 /* The fields are:
439 How far Forward this mode will reach:
440 How far Backward this mode will reach:
441 How many bytes this mode will add to the size of the frag
442 Which mode to go to if the offset won't fit in this one
443 */
444 const relax_typeS
445 md_relax_table[] = {
446 { 1, 1, 0, 0 }, /* First entries aren't used */
447 { 1, 1, 0, 0 }, /* For no good reason except */
448 { 1, 1, 0, 0 }, /* that the VAX doesn't either */
449 { 1, 1, 0, 0 },
450
451 { (127), (-128), 0, TAB(BRANCH,SHORT)},
452 { (32767), (-32768), 2, TAB(BRANCH,LONG) },
453 { 0, 0, 4, 0 },
454 { 1, 1, 0, 0 },
455
456 { 1, 1, 0, 0 }, /* FBRANCH doesn't come BYTE */
457 { (32767), (-32768), 2, TAB(FBRANCH,LONG)},
458 { 0, 0, 4, 0 },
459 { 1, 1, 0, 0 },
460
461 { 1, 1, 0, 0 }, /* PCREL doesn't come BYTE */
462 { (32767), (-32768), 2, TAB(PCREL,LONG)},
463 { 0, 0, 4, 0 },
464 { 1, 1, 0, 0 },
465
466 { (127), (-128), 0, TAB(BCC68000,SHORT)},
467 { (32767), (-32768), 2, TAB(BCC68000,LONG) },
468 { 0, 0, 6, 0 }, /* jmp long space */
469 { 1, 1, 0, 0 },
470
471 { 1, 1, 0, 0 }, /* DBCC doesn't come BYTE */
472 { (32767), (-32768), 2, TAB(DBCC,LONG) },
473 { 0, 0, 10, 0 }, /* bra/jmp long space */
474 { 1, 1, 0, 0 },
475
476 { 1, 1, 0, 0 }, /* PCLEA doesn't come BYTE */
477 { 32767, -32768, 2, TAB(PCLEA,LONG) },
478 { 0, 0, 6, 0 },
479 { 1, 1, 0, 0 },
480
481 };
482
483 /* These are the machine dependent pseudo-ops. These are included so
484 the assembler can work on the output from the SUN C compiler, which
485 generates these.
486 */
487
488 /* This table describes all the machine specific pseudo-ops the assembler
489 has to support. The fields are:
490 pseudo-op name without dot
491 function to call to execute this pseudo-op
492 Integer arg to pass to the function
493 */
494 #ifdef MRI
495
496 void cons();
497 void s_sect();
498 void float_cons();
499 void s_align_bytes();
500 void s_chip();
501 void s_ds();
502 void s_dcb();
503 void s_dc();
504 const pseudo_typeS md_pseudo_table[] = {
505 { "xdef", s_globl, 0 },
506 { "sect", s_sect, 0 },
507 { "dc", s_dc, 2 },
508 { "dc.d", float_cons, 'd' },
509 { "dc.s", float_cons, 'f' },
510 { "dc.l", s_dc, 4 },
511 { "dc.w", s_dc, 2 },
512 { "dc.b", s_dc, 1 },
513 { "comline", s_ds, 1 },
514 { "ds.b", s_ds, 1 },
515 { "ds.w", s_ds, 2 },
516 { "ds", s_ds, 2 },
517 { "ds.l", s_ds, 4 },
518 { "ds.d", s_ds, 8 },
519 { "ds.s", s_ds, 4 },
520 { "dcb", s_dcb, 2 },
521 { "dcb.b", s_dcb, 1 },
522 { "dcb.w", s_dcb, 2 },
523 { "dcb.l", s_dcb, 4 },
524 { "xcom", s_comm, 0 },
525 { "align", s_align_bytes, 0 },
526 { "chip", s_chip, 0 },
527 { 0, 0, 0 }
528 };
529 #else
530
531 const pseudo_typeS md_pseudo_table[] = {
532 { "data1", s_data1, 0 },
533 { "data2", s_data2, 0 },
534 { "bss", s_bss, 0 },
535 { "even", s_even, 0 },
536 { "skip", s_space, 0 },
537 { "proc", s_proc, 0 },
538 { 0, 0, 0 }
539 }
540
541
542
543
544 #endif
545
546 /* #define isbyte(x) ((x)>=-128 && (x)<=127) */
547 /* #define isword(x) ((x)>=-32768 && (x)<=32767) */
548
549 #define issbyte(x) ((x)>=-128 && (x)<=127)
550 #define isubyte(x) ((x)>=0 && (x)<=255)
551 #define issword(x) ((x)>=-32768 && (x)<=32767)
552 #define isuword(x) ((x)>=0 && (x)<=65535)
553
554 #define isbyte(x) ((x)>=-128 && (x)<=255)
555 #define isword(x) ((x)>=-32768 && (x)<=65535)
556 #define islong(x) (1)
557
558 extern char *input_line_pointer;
559
560 enum {
561 FAIL = 0,
562 OK = 1,
563 };
564
565 /* JF these tables here are for speed at the expense of size */
566 /* You can replace them with the #if 0 versions if you really
567 need space and don't mind it running a bit slower */
568
569 static char mklower_table[256];
570 #define mklower(c) (mklower_table[(unsigned char)(c)])
571 static char notend_table[256];
572 static char alt_notend_table[256];
573 #define notend(s) ( !(notend_table[(unsigned char)(*s)] || (*s==':' &&\
574 alt_notend_table[(unsigned char)(s[1])])))
575
576 #if 0
577 #define mklower(c) (isupper(c) ? tolower(c) : c)
578 #endif
579
580 #define ISSPACE(x) ((x) == ' ' || (x) == '\t')
581 #ifdef MRI
582 #define MULTIPLIER '*'
583 #define SIZER '.'
584 #else
585 #define MULTIPLIER ':'
586 #define SIZER ':'
587 #endif
588
589
590 /* JF modified this to handle cases where the first part of a symbol name
591 looks like a register */
592
593 /*
594 * m68k_reg_parse() := if it looks like a register, return it's token &
595 * advance the pointer.
596 */
597
598 enum _register m68k_reg_parse(ccp)
599 register char **ccp;
600 {
601 #ifndef MAX_REG_NAME_LEN
602 #define MAX_REG_NAME_LEN (6)
603 #endif /* MAX_REG_NAME_LEN */
604 register char c[MAX_REG_NAME_LEN];
605 char *p, *q;
606 register int n = 0,
607 ret = FAIL;
608
609 c[0] = mklower(ccp[0][0]);
610 #ifdef REGISTER_PREFIX
611 if (c[0] != REGISTER_PREFIX) {
612 return(FAIL);
613 } /* need prefix */
614 #endif
615
616 for (p = c, q = ccp[0]; p < c + MAX_REG_NAME_LEN; ++p, ++q)
617 {
618 if (*q == 0)
619 {
620 *p = 0;
621 break;
622 }
623 else
624 *p = mklower(*q);
625 } /* downcase */
626
627 switch(c[0]) {
628 case 'a':
629 if(c[1]>='0' && c[1]<='7') {
630 n=2;
631 ret=ADDR+c[1]-'0';
632 }
633 #ifndef NO_68851
634 else if (c[1] == 'c') {
635 n = 2;
636 ret = AC;
637 }
638 #endif
639 break;
640 #ifndef NO_68851
641 case 'b':
642 if (c[1] == 'a') {
643 if (c[2] == 'd') {
644 if (c[3] >= '0' && c[3] <= '7') {
645 n = 4;
646 ret = BAD + c[3] - '0';
647 }
648 } /* BAD */
649 if (c[2] == 'c') {
650 if (c[3] >= '0' && c[3] <= '7') {
651 n = 4;
652 ret = BAC + c[3] - '0';
653 }
654 } /* BAC */
655 } else if (c[1] == 'c') {
656 n = 2;
657 ret = BC;
658 } /* BC */
659 break;
660 #endif
661 case 'c':
662 #ifndef NO_68851
663 if (c[1] == 'a' && c[2] == 'l') {
664 n = 3;
665 ret = CAL;
666 } else
667 #endif
668 /* This supports both CCR and CC as the ccr reg. */
669 if(c[1]=='c' && c[2]=='r') {
670 n=3;
671 ret = CCR;
672 } else if(c[1]=='c') {
673 n=2;
674 ret = CCR;
675 } else if(c[1]=='a' && (c[2]=='a' || c[2]=='c') && c[3]=='r') {
676 n=4;
677 ret = c[2]=='a' ? CAAR : CACR;
678 }
679 #ifndef NO_68851
680 else if (c[1] == 'r' && c[2] == 'p') {
681 n = 3;
682 ret = (CRP);
683 }
684 #endif
685 break;
686 case 'd':
687 if (c[1] >= '0' && c[1] <= '7') {
688 n = 2;
689 ret = DATA + c[1] - '0';
690 } else if (c[1] == 'f' && c[2] == 'c') {
691 n = 3;
692 ret = DFC;
693 } else if (c[1] == 'c') {
694 n = 2;
695 ret = DC;
696 } else if (c[1] == 't' && c[2] == 't') {
697 if ('0' <= c[3] && c[3] <= '1') {
698 n = 4;
699 ret = DTT0 + (c[3] - '0');
700 } /* DTT[01] */
701 }
702 #ifndef NO_68851
703 else if (c[1] == 'r' && c[2] == 'p') {
704 n = 3;
705 ret = (DRP);
706 }
707 #endif
708 break;
709 case 'f':
710 if(c[1]=='p') {
711 if(c[2]>='0' && c[2]<='7') {
712 n=3;
713 ret = FPREG+c[2]-'0';
714 if(c[3]==':')
715 ccp[0][3]=',';
716 } else if(c[2]=='i') {
717 n=3;
718 ret = FPI;
719 } else if(c[2]=='s') {
720 n= (c[3] == 'r' ? 4 : 3);
721 ret = FPS;
722 } else if(c[2]=='c') {
723 n= (c[3] == 'r' ? 4 : 3);
724 ret = FPC;
725 } else if (!isalpha(c[2]) && !isdigit(c[2])) {
726 n = 2;
727 ret = ADDR + 6;
728 }
729
730
731 }
732 break;
733 case 'i':
734 if (c[1] == 's' && c[2] == 'p') {
735 n = 3;
736 ret = ISP;
737 } else if (c[1] == 'c') {
738 n = 2;
739 ret = IC;
740 } else if (c[1] == 't' && c[2] == 't') {
741 if ('0' <= c[3] && c[3] <= '1') {
742 n = 4;
743 ret = ITT0 + (c[3] - '0');
744 } /* ITT[01] */
745 }
746 break;
747 case 'm':
748 if (c[1] == 's' && c[2] == 'p') {
749 n = 3;
750 ret = MSP;
751 } else if (c[1] == 'm' && c[2] == 'u' && c[3] == 's' && c[4] == 'r') {
752 n = 5;
753 ret = MMUSR;
754 }
755 break;
756 case 'n':
757 if (c[1] == 'c') {
758 n = 2;
759 ret = NC;
760 }
761 break;
762 case 'p':
763 if(c[1]=='c') {
764 #ifndef NO_68851
765 if(c[2] == 's' && c[3]=='r') {
766 n=4;
767 ret = (PCSR);
768 } else
769 #endif
770 {
771 n=2;
772 ret = PC;
773 }
774 }
775 #ifndef NO_68851
776 else if (c[1] == 's' && c[2] == 'r') {
777 n = 3;
778 ret = (PSR);
779 }
780 #endif
781 break;
782 case 's':
783 #ifndef NO_68851
784 if (c[1] == 'c' && c[2] == 'c') {
785 n = 3;
786 ret = (SCC);
787 } else
788 #endif
789 if (c[1] == 'r') {
790 if (c[2] == 'p') {
791 n = 3;
792 ret = SRP;
793 } else {
794 n = 2;
795 ret = SR;
796 } /* srp else sr */
797 } else if (c[1] == 'p') {
798 n = 2;
799 ret = SP;
800 } else if (c[1] == 'f' && c[2] == 'c') {
801 n = 3;
802 ret = SFC;
803 }
804 break;
805 case 't':
806 if (c[1] == 'c') {
807 n = 2;
808 ret = TC;
809 }
810 break;
811 case 'u':
812 if (c[1] == 's' && c[2] == 'p') {
813 n=3;
814 ret = USP;
815 } else if (c[1] == 'r' && c[2] == 'p') {
816 n = 3;
817 ret = URP;
818 }
819 break;
820 case 'v':
821 #ifndef NO_68851
822 if (c[1] == 'a' && c[2] == 'l') {
823 n = 3;
824 ret = (VAL);
825 } else
826 #endif
827 if(c[1]=='b' && c[2]=='r') {
828 n=3;
829 ret = VBR;
830 }
831 break;
832 case 'z':
833 if(c[1]=='p' && c[2]=='c') {
834 n=3;
835 ret = ZPC;
836 }
837 break;
838 default:
839 break;
840 }
841 if(n) {
842 #ifdef REGISTER_PREFIX
843 n++;
844 #endif
845 if(isalnum(ccp[0][n]) || ccp[0][n]=='_')
846 ret=FAIL;
847 else
848 ccp[0]+=n;
849 } else
850 ret = FAIL;
851 return ret;
852 }
853
854 #define SKIP_WHITE() { str++; if(ISSPACE(*str)) str++;}
855
856 #ifdef MRI
857
858
859 /* Parse an operand from the text *str into the operand struct *opP. */
860 int
861 m68k_ip_op(str,opP)
862 char *str;
863 register struct m68k_op *opP;
864 {
865 char *strend;
866 long i;
867 char *parse_index();
868
869 /* Skip leading blank */
870 if(ISSPACE(*str))
871 str++;
872 if(!*str) {
873 opP->error="Missing operand";
874 return FAIL;
875 }
876 /* *strend = last character of string */
877 for(strend=str;*strend;strend++)
878 ;
879 --strend;
880
881 /* Logic of the parsing switch(*str):
882 case opP->mode =
883 ---- -----------
884 #anything IMMED 1
885 REG AREG or DREG or MSCR 3 or 2 or 13
886 REG- or REG/ REGLST 14
887 (REG) AINDR 4
888 (REG)+ AINC 6
889 (REG,INDX) AINDX 8
890 (EXPR,REG) AOFF 7
891 (EXPR,REG,INDX) AINDX 8
892 -(REG) ADEC 5
893 EXP2(REG) AOFF 7
894 EXP2(REG,INDX) AINDX 8
895 EXP2 ABSL 12
896
897 REG means truth(m68k_reg_parse(&str))
898 INDX means truth(try_index(&str,opP))
899 EXPR means not REG
900 EXP2 means not REG and not '(' and not '-('
901 */
902
903 if(*str=='#') {
904 /* "#<expression>" Immediate mode */
905 str++;
906 opP->con1=add_exp(str,strend);
907 opP->mode=IMMED;
908 return OK;
909 }
910
911 i=m68k_reg_parse(&str);
912 if (i!=FAIL) {
913 if(*str=='\0') {
914 /* "Rn" Register Direct mode */
915 opP->reg=i;
916 if(i>=DATA+0 && i<=DATA+7)
917 opP->mode=DREG;
918 else if(i>=ADDR+0 && i<=ADDR+7)
919 opP->mode=AREG;
920 else
921 opP->mode=MSCR;
922 return OK;
923 }
924 else if(*str=='/' || *str=='-') {
925 /* "Rm-Rn/Ro-Rp" Register list for MOVEM instruction */
926 opP->mode=REGLST;
927 return get_regs(i,str,opP);
928 }
929 else {
930 opP->error="Junk after register name";
931 return FAIL;
932 }
933 }
934
935 if(*str=='(') {
936 str++;
937 i=m68k_reg_parse(&str);
938 if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL
939 && (*str != ')' || str[1] != '\0' || i<DATA+0 || i>DATA+7)) {
940 /* Can't indirect off non address regs,
941 but (dx) is OK for cas2. */
942 opP->error="Invalid indirect register";
943 return FAIL;
944 }
945 if(i!=FAIL) {
946 opP->reg=i;
947 if(*str==')') {
948 str++;
949 if(*str=='\0') {
950 /* "(An)" Address Register Indirect mode
951 or "(Dn)" for cas2 instruction. */
952 if (i < DATA + 0 || i > DATA + 7)
953 opP->mode=AINDR;
954 else
955 opP->mode=DINDR;
956 return OK;
957 }
958 if(*str=='+') {
959 if(str[1]=='\0') {
960 /* "(An)+" Register Indirect w Postincrement */
961 opP->mode=AINC;
962 return OK;
963 }
964 }
965 opP->error="Junk after indirect";
966 return FAIL;
967 }
968 if(*str==',') {
969 str++;
970 i=try_index(&str,opP);
971 if(i==FAIL) return FAIL;
972 /* "(An,Rn)" Register Indirect with Index mode*/
973 opP->mode=AINDX;
974 return OK;
975 }
976 else {
977 opP->error="Bad indirect syntax";
978 return FAIL;
979 }
980 }
981 else {
982 /* "(EXPR,..." , a displacement */
983 char *stmp;
984 char *index();
985
986 if(stmp=index(str,',')) {
987 opP->con1=add_exp(str,stmp-1);
988 str=stmp;
989 SKIP_WHITE();
990 i=m68k_reg_parse(&str);
991 if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC) {
992 /* Can't indirect off non address regs */
993 opP->error="Invalid indirect register";
994 return FAIL;
995 }
996 if(i!=FAIL) {
997 opP->reg=i;
998 if(*str==')') {
999 /* "(d,An)" Register Indirect w Displacement */
1000 opP->mode=AOFF;
1001 return OK;
1002 }
1003 if(*str==',') {
1004 str++;
1005 i=try_index(&str,opP);
1006 if(i==FAIL) return FAIL;
1007 /* "(d,An,Rn)" Register Indirect with Index */
1008 opP->mode=AINDX;
1009 return OK;
1010 }
1011 else {
1012 opP->error="Bad indirect syntax";
1013 return FAIL;
1014 }
1015 }
1016 else {
1017 opP->error="Invalid register";
1018 return FAIL;
1019 }
1020 }
1021 else {
1022 opP->error="Missing register for indirect";
1023 return FAIL;
1024 }
1025 }
1026 }
1027
1028 if(*str=='-') {
1029 if(str[1]=='(') {
1030 str = str+2;
1031 i=m68k_reg_parse(&str);
1032 if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL) {
1033 /* Can't indirect off non address regs */
1034 opP->error="Invalid indirect register";
1035 return FAIL;
1036 }
1037 if(i!=FAIL) {
1038 opP->reg=i;
1039 if(*str==')') {
1040 str++;
1041 if(*str=='\0') {
1042 /* "-(An)" Register Indirect with Predecrement */
1043 opP->mode=ADEC;
1044 return OK;
1045 }
1046 opP->error="Junk after indirect";
1047 return FAIL;
1048 }
1049 opP->error="Bad indirect syntax";
1050 return FAIL;
1051 }
1052 opP->error="Invalid register";
1053 return FAIL;
1054 }
1055 /* if '-' but not "-(', do nothing */
1056 }
1057
1058 /* whether *str=='-' or not */
1059 {
1060 /* "EXP2" or "EXP2(REG..." */
1061 char *stmp;
1062 char *index();
1063 if(stmp=index(str,'(')) {
1064 opP->con1=add_exp(str,stmp-1);
1065 str=stmp+1;
1066 i=m68k_reg_parse(&str);
1067 if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC) {
1068 /* Can't indirect off non address regs */
1069 opP->error="Invalid indirect register";
1070 return FAIL;
1071 }
1072 if(i!=FAIL) {
1073 opP->reg=i;
1074 if(*str==')') {
1075 /* "d(An)" Register Indirect w Displacement */
1076 opP->mode=AOFF;
1077 return OK;
1078 }
1079 if(*str==',') {
1080 str++;
1081 i=try_index(&str,opP);
1082 if(i==FAIL) return FAIL;
1083 /* "d(An,Rn)" Register Indirect with Index */
1084 opP->mode=AINDX;
1085 return OK;
1086 }
1087 else {
1088 opP->error="Bad indirect syntax";
1089 return FAIL;
1090 }
1091 }
1092 else {
1093 opP->error="Invalid register";
1094 return FAIL;
1095 }
1096 }
1097 else {
1098 /* "EXP2" Absolute */
1099 opP->mode=ABSL;
1100 if(strend[-1]=='.') { /* mode ==foo.[wl] */
1101 switch(*strend) {
1102 case 'w':
1103 case 'W':
1104 opP->isiz=2;
1105 break;
1106 case 'l':
1107 case 'L':
1108 opP->isiz=3;
1109 break;
1110 default:
1111 opP->error="Size spec not .W or .L";
1112 return FAIL;
1113 }
1114 strend-=2;
1115 }
1116 else opP->isiz=0;
1117
1118
1119 opP->con1=add_exp(str,strend);
1120 return OK;
1121 }
1122 }
1123 }
1124 /* end of m68k_ip_op () */
1125 #else
1126 /*
1127 * m68k_ip_op := '#' + <anything>
1128 * | <register> + range_sep + get_regs
1129 * ;
1130 *
1131 * range_sep := '/' | '-' ;
1132 *
1133 * SKIP_WHITE := <empty> | ' ' ;
1134 *
1135 */
1136
1137 int
1138 m68k_ip_op(str,opP)
1139 char *str;
1140 register struct m68k_op *opP;
1141 {
1142 char *strend;
1143 long i;
1144 char *parse_index();
1145
1146 if (ISSPACE(*str)) {
1147 str++;
1148 } /* Find the beginning of the string */
1149
1150 if(!*str) {
1151 opP->error="Missing operand";
1152 return FAIL;
1153 } /* Out of gas */
1154
1155 for(strend = str; *strend; strend++) ;;
1156
1157 --strend;
1158
1159 if(*str=='#') {
1160 str++;
1161 opP->con1=add_exp(str,strend);
1162 opP->mode=IMMED;
1163 return OK;
1164 } /* Guess what: A constant. Shar and enjoy */
1165
1166 i = m68k_reg_parse(&str);
1167
1168 /* is a register, is exactly a register, and is followed by '@' */
1169
1170 if((i==FAIL || *str!='\0') && *str!='@') {
1171 char *stmp;
1172
1173 if(i!=FAIL && (*str=='/' || *str=='-')) {
1174 opP->mode=REGLST;
1175 return(get_regs(i,str,opP));
1176 }
1177 if ((stmp=strchr(str,'@')) != '\0') {
1178 opP->con1=add_exp(str,stmp-1);
1179 if(stmp==strend) {
1180 opP->mode=AINDX;
1181 return(OK);
1182 }
1183
1184 if ((current_architecture & m68020up) == 0) {
1185 return(FAIL);
1186 } /* if target is not a '20 or better */
1187
1188 stmp++;
1189 if(*stmp++!='(' || *strend--!=')') {
1190 opP->error="Malformed operand";
1191 return(FAIL);
1192 }
1193 i=try_index(&stmp,opP);
1194 opP->con2=add_exp(stmp,strend);
1195
1196 if (i == FAIL) {
1197 opP->mode=AMIND;
1198 } else {
1199 opP->mode=APODX;
1200 }
1201 return(OK);
1202 } /* if there's an '@' */
1203 opP->mode = ABSL;
1204 opP->con1 = add_exp(str,strend);
1205 return(OK);
1206 } /* not a register, not exactly a register, or no '@' */
1207
1208 opP->reg=i;
1209
1210 if (*str=='\0') {
1211 if(i>=DATA+0 && i<=DATA+7)
1212 opP->mode=DREG;
1213 else if(i>=ADDR+0 && i<=ADDR+7)
1214 opP->mode=AREG;
1215 else
1216 opP->mode=MSCR;
1217 return OK;
1218 }
1219
1220 /* Can't indirect off non address regs, but Dx@ is OK for cas2 */
1221 if((i<ADDR+0 || i>ADDR+7) && i!=PC && i!=ZPC && i!=FAIL
1222 && (str[1] != '\0' || i<DATA+0 || i>DATA+7)) {
1223 opP->error="Invalid indirect register";
1224 return FAIL;
1225 }
1226 know(*str == '@');
1227
1228 str++;
1229 switch(*str) {
1230 case '\0':
1231 if (i < DATA + 0 || i > DATA + 7)
1232 opP->mode=AINDR;
1233 else
1234 opP->mode=DINDR;
1235 return OK;
1236 case '-':
1237 opP->mode=ADEC;
1238 return OK;
1239 case '+':
1240 opP->mode=AINC;
1241 return OK;
1242 case '(':
1243 str++;
1244 break;
1245 default:
1246 opP->error="Junk after indirect";
1247 return FAIL;
1248 }
1249 /* Some kind of indexing involved. Lets find out how bad it is */
1250 i=try_index(&str,opP);
1251 /* Didn't start with an index reg, maybe its offset or offset,reg */
1252 if(i==FAIL) {
1253 char *beg_str;
1254
1255 beg_str=str;
1256 for(i=1;i;) {
1257 switch(*str++) {
1258 case '\0':
1259 opP->error="Missing )";
1260 return FAIL;
1261 case ',': i=0; break;
1262 case '(': i++; break;
1263 case ')': --i; break;
1264 }
1265 }
1266 /* if(str[-3]==':') {
1267 int siz;
1268
1269 switch(str[-2]) {
1270 case 'b':
1271 case 'B':
1272 siz=1;
1273 break;
1274 case 'w':
1275 case 'W':
1276 siz=2;
1277 break;
1278 case 'l':
1279 case 'L':
1280 siz=3;
1281 break;
1282 default:
1283 opP->error="Specified size isn't :w or :l";
1284 return FAIL;
1285 }
1286 opP->con1=add_exp(beg_str,str-4);
1287 opP->con1->e_siz=siz;
1288 } else */
1289 opP->con1=add_exp(beg_str,str-2);
1290 /* Should be offset,reg */
1291 if(str[-1]==',') {
1292 i=try_index(&str,opP);
1293 if(i==FAIL) {
1294 opP->error="Malformed index reg";
1295 return FAIL;
1296 }
1297 }
1298 }
1299 /* We've now got offset) offset,reg) or reg) */
1300
1301 if (*str == '\0') {
1302 /* Th-the-thats all folks */
1303 if (opP->reg == FAIL) opP->mode = AINDX; /* Other form of indirect */
1304 else if(opP->ireg == FAIL) opP->mode = AOFF;
1305 else opP->mode = AINDX;
1306 return(OK);
1307 }
1308 /* Next thing had better be another @ */
1309 if(*str!='@' || str[1]!='(') {
1310 opP->error = "junk after indirect";
1311 return(FAIL);
1312 }
1313
1314 if ((current_architecture & m68020up) == 0) {
1315 return(FAIL);
1316 } /* if target is not a '20 or better */
1317
1318 str+=2;
1319
1320 if(opP->ireg != FAIL) {
1321 opP->mode = APRDX;
1322
1323 i = try_index(&str, opP);
1324 if (i != FAIL) {
1325 opP->error = "Two index registers! not allowed!";
1326 return(FAIL);
1327 }
1328 } else {
1329 i = try_index(&str, opP);
1330 }
1331
1332 if (i == FAIL) {
1333 char *beg_str;
1334
1335 beg_str = str;
1336
1337 for (i = 1; i; ) {
1338 switch(*str++) {
1339 case '\0':
1340 opP->error="Missing )";
1341 return(FAIL);
1342 case ',': i=0; break;
1343 case '(': i++; break;
1344 case ')': --i; break;
1345 }
1346 }
1347
1348 opP->con2=add_exp(beg_str,str-2);
1349
1350 if (str[-1] == ',') {
1351 if (opP->ireg != FAIL) {
1352 opP->error = "Can't have two index regs";
1353 return(FAIL);
1354 }
1355
1356 i = try_index(&str, opP);
1357
1358 if (i == FAIL) {
1359 opP->error = "malformed index reg";
1360 return(FAIL);
1361 }
1362
1363 opP->mode = APODX;
1364 } else if (opP->ireg != FAIL) {
1365 opP->mode = APRDX;
1366 } else {
1367 opP->mode = AMIND;
1368 }
1369 } else {
1370 opP->mode = APODX;
1371 }
1372
1373 if(*str!='\0') {
1374 opP->error="Junk after indirect";
1375 return FAIL;
1376 }
1377 return(OK);
1378 } /* m68k_ip_op() */
1379 #endif
1380 /*
1381 *
1382 * try_index := data_or_address_register + ')' + SKIP_W
1383 * | data_or_address_register + ':' + SKIP_W + size_spec + SKIP_W + multiplier + ')' + SKIP_W
1384 *
1385 * multiplier := <empty>
1386 * | ':' + multiplier_number
1387 * ;
1388 *
1389 * multiplier_number := '1' | '2' | '4' | '8' ;
1390 *
1391 * size_spec := 'l' | 'L' | 'w' | 'W' ;
1392 *
1393 * SKIP_W := <empty> | ' ' ;
1394 *
1395 */
1396
1397 static int try_index(s,opP)
1398 char **s;
1399 struct m68k_op *opP;
1400 {
1401 register int i;
1402 char *ss;
1403 #define SKIP_W() { ss++; if (ISSPACE(*ss)) ss++;}
1404
1405 ss= *s;
1406 /* SKIP_W(); */
1407 i=m68k_reg_parse(&ss);
1408 if(!(i>=DATA+0 && i<=ADDR+7)) { /* if i is not DATA or ADDR reg */
1409 *s=ss;
1410 return FAIL;
1411 }
1412 opP->ireg=i;
1413 /* SKIP_W(); */
1414 if(*ss==')') {
1415 opP->isiz=0;
1416 opP->imul=1;
1417 SKIP_W();
1418 *s=ss;
1419 return OK;
1420 }
1421 if(*ss!=SIZER)
1422 {
1423 opP->error="Missing : in index register";
1424 *s=ss;
1425 return FAIL;
1426 }
1427 SKIP_W();
1428 switch(*ss) {
1429 case 'w':
1430 case 'W':
1431 opP->isiz=2;
1432 break;
1433 case 'l':
1434 case 'L':
1435 opP->isiz=3;
1436 break;
1437 default:
1438 opP->error="Index register size spec not :w or :l";
1439 *s=ss;
1440 return FAIL;
1441 }
1442 SKIP_W();
1443 if(*ss==MULTIPLIER)
1444 {
1445 SKIP_W();
1446 switch(*ss) {
1447 case '1':
1448 case '2':
1449 case '4':
1450 case '8':
1451 opP->imul= *ss-'0';
1452 break;
1453 default:
1454 opP->error="index multiplier not 1, 2, 4 or 8";
1455 *s=ss;
1456 return FAIL;
1457 }
1458 SKIP_W();
1459 } else opP->imul=1;
1460 if(*ss!=')') {
1461 opP->error="Missing )";
1462 *s=ss;
1463 return FAIL;
1464 }
1465 SKIP_W();
1466 *s=ss;
1467 return OK;
1468 } /* try_index() */
1469
1470 #ifdef TEST1 /* TEST1 tests m68k_ip_op(), which parses operands */
1471 main()
1472 {
1473 char buf[128];
1474 struct m68k_op thark;
1475
1476 for(;;) {
1477 if(!gets(buf))
1478 break;
1479 memset(&thark, '\0', sizeof(thark));
1480 if(!m68k_ip_op(buf,&thark)) printf("FAIL:");
1481 if(thark.error)
1482 printf("op1 error %s in %s\n",thark.error,buf);
1483 printf("mode %d, reg %d, ",thark.mode,thark.reg);
1484 if(thark.b_const)
1485 printf("Constant: '%.*s',",1+thark.e_const-thark.b_const,thark.b_const);
1486 printf("ireg %d, isiz %d, imul %d ",thark.ireg,thark.isiz,thark.imul);
1487 if(thark.b_iadd)
1488 printf("Iadd: '%.*s'",1+thark.e_iadd-thark.b_iadd,thark.b_iadd);
1489 printf("\n");
1490 }
1491 exit(0);
1492 }
1493
1494 #endif
1495
1496
1497 static struct hash_control* op_hash = NULL; /* handle of the OPCODE hash table
1498 NULL means any use before m68k_ip_begin()
1499 will crash */
1500
1501 \f
1502 /*
1503 * m 6 8 k _ i p ( )
1504 *
1505 * This converts a string into a 68k instruction.
1506 * The string must be a bare single instruction in sun format
1507 * with RMS-style 68020 indirects
1508 * (example: )
1509 *
1510 * It provides some error messages: at most one fatal error message (which
1511 * stops the scan) and at most one warning message for each operand.
1512 * The 68k instruction is returned in exploded form, since we have no
1513 * knowledge of how you parse (or evaluate) your expressions.
1514 * We do however strip off and decode addressing modes and operation
1515 * mnemonic.
1516 *
1517 * This function's value is a string. If it is not "" then an internal
1518 * logic error was found: read this code to assign meaning to the string.
1519 * No argument string should generate such an error string:
1520 * it means a bug in our code, not in the user's text.
1521 *
1522 * You MUST have called m68k_ip_begin() once and m86_ip_end() never before using
1523 * this function.
1524 */
1525
1526 /* JF this function no longer returns a useful value. Sorry */
1527 void m68k_ip (instring)
1528 char *instring;
1529 {
1530 register char *p;
1531 register struct m68k_op *opP;
1532 register struct m68k_incant *opcode, prev_opcode;
1533 register char *s;
1534 register int tmpreg = 0,
1535 baseo = 0,
1536 outro = 0,
1537 nextword;
1538 int siz1,
1539 siz2;
1540 char c;
1541 int losing;
1542 int opsfound;
1543 char *crack_operand();
1544
1545 LITTLENUM_TYPE words[6];
1546 LITTLENUM_TYPE *wordp;
1547
1548 if (ISSPACE(*instring))
1549 instring++; /* skip leading whitespace */
1550
1551 /* Scan up to end of operation-code, which MUST end in end-of-string
1552 or exactly 1 space. */
1553 for (p = instring; *p != '\0'; p++)
1554 if (ISSPACE(*p))
1555 break;
1556
1557
1558 if (p == instring) {
1559 the_ins.error = "No operator";
1560 the_ins.opcode[0] = NULL;
1561 /* the_ins.numo=1; */
1562 return;
1563 }
1564
1565 /* p now points to the end of the opcode name, probably whitespace.
1566 make sure the name is null terminated by clobbering the whitespace,
1567 look it up in the hash table, then fix it back. */
1568 c = *p;
1569 *p = '\0';
1570 #ifdef MRI
1571 /* Copy from input line to our private buffer, and drop any dots */
1572 {
1573 char our_copy[100];
1574 char *dst = our_copy;
1575 char *src = instring;
1576 while (*src)
1577 {
1578 if (*src != '.')
1579 *dst++ = *src;
1580 src++;
1581 }
1582 *dst = 0;
1583
1584
1585 opcode = (struct m68k_incant *)hash_find (op_hash, our_copy);
1586
1587 /* If no match, try again with a w suffix */
1588 if (!opcode)
1589 {
1590 *dst++ = 'w';
1591 *dst = 0;
1592 opcode = (struct m68k_incant *)hash_find (op_hash, our_copy);
1593 }
1594
1595
1596
1597 }
1598
1599 #else
1600 opcode = (struct m68k_incant *)hash_find (op_hash, instring);
1601 #endif
1602 *p = c;
1603
1604 if (opcode == NULL) {
1605 the_ins.error = "Unknown opcode";
1606 the_ins.opcode[0] = NULL;
1607 /* the_ins.numo=1; */
1608 return;
1609 }
1610
1611 /* found a legitimate opcode, start matching operands */
1612 while (ISSPACE(*p)) ++p;
1613
1614 for(opP = &the_ins.operands[0]; *p; opP++) {
1615
1616 p = crack_operand(p, opP);
1617
1618 if (opP->error) {
1619 the_ins.error=opP->error;
1620 return;
1621 }
1622 }
1623
1624 opsfound = opP - &the_ins.operands[0];
1625
1626 /* This ugly hack is to support the floating pt opcodes in their standard form */
1627 /* Essentially, we fake a first enty of type COP#1 */
1628 if (opcode->m_operands[0]=='I') {
1629 int n;
1630
1631 for(n=opsfound;n>0;--n)
1632 the_ins.operands[n]=the_ins.operands[n-1];
1633
1634 /* memcpy((char *)(&the_ins.operands[1]), (char *)(&the_ins.operands[0]), opsfound*sizeof(the_ins.operands[0])); */
1635 memset((char *)(&the_ins.operands[0]), '\0', sizeof(the_ins.operands[0]));
1636 the_ins.operands[0].mode=MSCR;
1637 the_ins.operands[0].reg=COPNUM; /* COP #1 */
1638 opsfound++;
1639 }
1640
1641 /* We've got the operands. Find an opcode that'll accept them */
1642 for (losing = 0; ; ) {
1643 /* if we didn't get the right number of ops,
1644 or we have no common model with this pattern
1645 then reject this pattern. */
1646
1647 if (opsfound != opcode->m_opnum
1648 || ((opcode->m_arch & current_architecture) == 0)) {
1649
1650 ++losing;
1651
1652 } else {
1653 for (s=opcode->m_operands, opP = &the_ins.operands[0]; *s && !losing; s += 2, opP++) {
1654 /* Warning: this switch is huge! */
1655 /* I've tried to organize the cases into this order:
1656 non-alpha first, then alpha by letter. lower-case goes directly
1657 before uppercase counterpart. */
1658 /* Code with multiple case ...: gets sorted by the lowest case ...
1659 it belongs to. I hope this makes sense. */
1660 switch(*s) {
1661 case '!':
1662 if (opP->mode == MSCR || opP->mode == IMMED
1663 || opP->mode == DREG || opP->mode == AREG
1664 || opP->mode == AINC || opP->mode == ADEC
1665 || opP->mode == REGLST)
1666 losing++;
1667 break;
1668
1669 case '#':
1670 if(opP->mode!=IMMED)
1671 losing++;
1672 else {
1673 long t;
1674
1675 t=get_num(opP->con1,80);
1676 if(s[1]=='b' && !isbyte(t))
1677 losing++;
1678 else if(s[1]=='w' && !isword(t))
1679 losing++;
1680 }
1681 break;
1682
1683 case '^':
1684 case 'T':
1685 if(opP->mode!=IMMED)
1686 losing++;
1687 break;
1688
1689 case '$':
1690 if(opP->mode==MSCR || opP->mode==AREG ||
1691 opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST)
1692 losing++;
1693 break;
1694
1695 case '%':
1696 if(opP->mode==MSCR || opP->reg==PC ||
1697 opP->reg==ZPC || opP->mode==REGLST)
1698 losing++;
1699 break;
1700
1701
1702 case '&':
1703 if(opP->mode==MSCR || opP->mode==DREG ||
1704 opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC ||
1705 opP->mode==AINC || opP->mode==ADEC || opP->mode==REGLST)
1706 losing++;
1707 break;
1708
1709 case '*':
1710 if(opP->mode==MSCR || opP->mode==REGLST)
1711 losing++;
1712 break;
1713
1714 case '+':
1715 if(opP->mode!=AINC)
1716 losing++;
1717 break;
1718
1719 case '-':
1720 if(opP->mode!=ADEC)
1721 losing++;
1722 break;
1723
1724 case '/':
1725 if(opP->mode==MSCR || opP->mode==AREG ||
1726 opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->mode==REGLST)
1727 losing++;
1728 break;
1729
1730 case ';':
1731 if(opP->mode==MSCR || opP->mode==AREG || opP->mode==REGLST)
1732 losing++;
1733 break;
1734
1735 case '?':
1736 if(opP->mode==MSCR || opP->mode==AREG ||
1737 opP->mode==AINC || opP->mode==ADEC || opP->mode==IMMED || opP->reg==PC ||
1738 opP->reg==ZPC || opP->mode==REGLST)
1739 losing++;
1740 break;
1741
1742 case '@':
1743 if(opP->mode==MSCR || opP->mode==AREG ||
1744 opP->mode==IMMED || opP->mode==REGLST)
1745 losing++;
1746 break;
1747
1748 case '~': /* For now! (JF FOO is this right?) */
1749 if(opP->mode==MSCR || opP->mode==DREG ||
1750 opP->mode==AREG || opP->mode==IMMED || opP->reg==PC || opP->reg==ZPC || opP->mode==REGLST)
1751 losing++;
1752 break;
1753
1754 case 'A':
1755 if(opP->mode!=AREG)
1756 losing++;
1757 break;
1758 case 'a':
1759 if (opP->mode != AINDR) {
1760 ++losing;
1761 } /* if not address register indirect */
1762 break;
1763 case 'B': /* FOO */
1764 if(opP->mode!=ABSL || (flagseen['S'] && instring[0] == 'j'
1765 && instring[1] == 'b'
1766 && instring[2] == 's'
1767 && instring[3] == 'r'))
1768 losing++;
1769 break;
1770
1771 case 'C':
1772 if(opP->mode!=MSCR || opP->reg!=CCR)
1773 losing++;
1774 break;
1775
1776 case 'd': /* FOO This mode is a KLUDGE!! */
1777 if(opP->mode!=AOFF && (opP->mode!=ABSL ||
1778 opP->con1->e_beg[0]!='(' || opP->con1->e_end[0]!=')'))
1779 losing++;
1780 break;
1781
1782 case 'D':
1783 if(opP->mode!=DREG)
1784 losing++;
1785 break;
1786
1787 case 'F':
1788 if(opP->mode!=MSCR || opP->reg<(FPREG+0) || opP->reg>(FPREG+7))
1789 losing++;
1790 break;
1791
1792 case 'I':
1793 if(opP->mode!=MSCR || opP->reg<COPNUM ||
1794 opP->reg>=COPNUM+7)
1795 losing++;
1796 break;
1797
1798 case 'J':
1799 if (opP->mode != MSCR
1800 || opP->reg < USP
1801 || opP->reg > URP
1802 || cpu_of_arch(current_architecture) < m68010 /* before 68010 had none */
1803 || (cpu_of_arch(current_architecture) < m68020
1804 && opP->reg != SFC
1805 && opP->reg != DFC
1806 && opP->reg != USP
1807 && opP->reg != VBR) /* 68010's had only these */
1808 || (cpu_of_arch(current_architecture) < m68040
1809 && opP->reg != SFC
1810 && opP->reg != DFC
1811 && opP->reg != USP
1812 && opP->reg != VBR
1813 && opP->reg != CACR
1814 && opP->reg != CAAR
1815 && opP->reg != MSP
1816 && opP->reg != ISP) /* 680[23]0's have only these */
1817 || (cpu_of_arch(current_architecture) == m68040 /* 68040 has all but this */
1818 && opP->reg == CAAR)) {
1819 losing++;
1820 } /* doesn't cut it */
1821 break;
1822
1823 case 'k':
1824 if(opP->mode!=IMMED)
1825 losing++;
1826 break;
1827
1828 case 'l':
1829 case 'L':
1830 if(opP->mode==DREG || opP->mode==AREG || opP->mode==FPREG) {
1831 if(s[1]=='8')
1832 losing++;
1833 else {
1834 opP->mode=REGLST;
1835 opP->reg=1<<(opP->reg-DATA);
1836 }
1837 } else if(opP->mode!=REGLST) {
1838 losing++;
1839 } else if(s[1]=='8' && opP->reg&0x0FFffFF)
1840 losing++;
1841 else if(s[1]=='3' && opP->reg&0x7000000)
1842 losing++;
1843 break;
1844
1845 case 'M':
1846 if(opP->mode!=IMMED)
1847 losing++;
1848 else {
1849 long t;
1850
1851 t=get_num(opP->con1,80);
1852 if(!issbyte(t) || isvar(opP->con1))
1853 losing++;
1854 }
1855 break;
1856
1857 case 'O':
1858 if(opP->mode!=DREG && opP->mode!=IMMED)
1859 losing++;
1860 break;
1861
1862 case 'Q':
1863 if(opP->mode!=IMMED)
1864 losing++;
1865 else {
1866 long t;
1867
1868 t=get_num(opP->con1,80);
1869 if(t<1 || t>8 || isvar(opP->con1))
1870 losing++;
1871 }
1872 break;
1873
1874 case 'R':
1875 if(opP->mode!=DREG && opP->mode!=AREG)
1876 losing++;
1877 break;
1878
1879 case 'r':
1880 if(opP->mode!=AINDR && opP->mode!=DINDR)
1881 losing++;
1882 break;
1883
1884 case 's':
1885 if(opP->mode!=MSCR || !(opP->reg==FPI || opP->reg==FPS || opP->reg==FPC))
1886 losing++;
1887 break;
1888
1889 case 'S':
1890 if(opP->mode!=MSCR || opP->reg!=SR)
1891 losing++;
1892 break;
1893
1894 case 'U':
1895 if(opP->mode!=MSCR || opP->reg!=USP)
1896 losing++;
1897 break;
1898
1899 /* JF these are out of order. We could put them
1900 in order if we were willing to put up with
1901 bunches of #ifdef m68851s in the code */
1902 #ifndef NO_68851
1903 /* Memory addressing mode used by pflushr */
1904 case '|':
1905 if(opP->mode==MSCR || opP->mode==DREG ||
1906 opP->mode==AREG || opP->mode==REGLST)
1907 losing++;
1908 break;
1909
1910 case 'f':
1911 if (opP->mode != MSCR || (opP->reg != SFC && opP->reg != DFC))
1912 losing++;
1913 break;
1914
1915 case 'P':
1916 if (opP->mode != MSCR || (opP->reg != TC && opP->reg != CAL &&
1917 opP->reg != VAL && opP->reg != SCC && opP->reg != AC))
1918 losing++;
1919 break;
1920
1921 case 'V':
1922 if (opP->reg != VAL)
1923 losing++;
1924 break;
1925
1926 case 'W':
1927 if (opP->mode != MSCR || (opP->reg != DRP && opP->reg != SRP &&
1928 opP->reg != CRP))
1929 losing++;
1930 break;
1931
1932 case 'X':
1933 if (opP->mode != MSCR ||
1934 (!(opP->reg >= BAD && opP->reg <= BAD+7) &&
1935 !(opP->reg >= BAC && opP->reg <= BAC+7)))
1936 losing++;
1937 break;
1938
1939 case 'Y':
1940 if (opP->reg != PSR)
1941 losing++;
1942 break;
1943
1944 case 'Z':
1945 if (opP->reg != PCSR)
1946 losing++;
1947 break;
1948 #endif
1949 case 'c':
1950 if (opP->reg != NC
1951 && opP->reg != IC
1952 && opP->reg != DC
1953 && opP->reg != BC) {
1954 losing++;
1955 } /* not a cache specifier. */
1956 break;
1957
1958 case '_':
1959 if (opP->mode != ABSL) {
1960 ++losing;
1961 } /* not absolute */
1962 break;
1963
1964 default:
1965 as_fatal("Internal error: Operand mode %c unknown in line %s of file \"%s\"",
1966 *s, __LINE__, __FILE__);
1967 } /* switch on type of operand */
1968
1969 if (losing) break;
1970 } /* for each operand */
1971 } /* if immediately wrong */
1972
1973 if (!losing) {
1974 break;
1975 } /* got it. */
1976
1977
1978 if (!opcode->m_next)
1979 {
1980 if ((opcode->m_arch & current_architecture) == 0)
1981 {
1982 the_ins.error = "Opcode not available on architecture specified";
1983 addword(0);
1984
1985 }
1986 else
1987 {
1988 the_ins.error = "instruction/operands mismatch";
1989 }
1990
1991 return;
1992 } /* Fell off the end */
1993 opcode = opcode->m_next;
1994 losing = 0;
1995 }
1996
1997 /* now assemble it */
1998
1999 the_ins.args=opcode->m_operands;
2000 the_ins.numargs=opcode->m_opnum;
2001 the_ins.numo=opcode->m_codenum;
2002 the_ins.opcode[0]=getone(opcode);
2003 the_ins.opcode[1]=gettwo(opcode);
2004
2005 for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++) {
2006 /* This switch is a doozy.
2007 Watch the first step; its a big one! */
2008 switch(s[0]) {
2009
2010 case '*':
2011 case '~':
2012 case '%':
2013 case ';':
2014 case '@':
2015 case '!':
2016 case '&':
2017 case '$':
2018 case '?':
2019 case '/':
2020 #ifndef NO_68851
2021 case '|':
2022 #endif
2023 switch(opP->mode) {
2024 case IMMED:
2025 tmpreg=0x3c; /* 7.4 */
2026 if (strchr("bwl",s[1])) nextword=get_num(opP->con1,80);
2027 else nextword=nextword=get_num(opP->con1,0);
2028 if(isvar(opP->con1))
2029 add_fix(s[1],opP->con1,0);
2030 switch(s[1]) {
2031 case 'b':
2032 if(!isbyte(nextword))
2033 opP->error="operand out of range";
2034 addword(nextword);
2035 baseo=0;
2036 break;
2037 case 'w':
2038 if(!isword(nextword))
2039 opP->error="operand out of range";
2040 addword(nextword);
2041 baseo=0;
2042 break;
2043 case 'l':
2044 addword(nextword>>16);
2045 addword(nextword);
2046 baseo=0;
2047 break;
2048
2049 case 'f':
2050 baseo=2;
2051 outro=8;
2052 break;
2053 case 'F':
2054 baseo=4;
2055 outro=11;
2056 break;
2057 case 'x':
2058 baseo=6;
2059 outro=15;
2060 break;
2061 case 'p':
2062 baseo=6;
2063 outro= -1;
2064 break;
2065 default:
2066 as_fatal("Internal error: Can't decode %c%c in line %s of file \"%s\"",
2067 *s, s[1], __LINE__, __FILE__);
2068 }
2069 if(!baseo)
2070 break;
2071
2072 /* We gotta put out some float */
2073 if(seg(opP->con1)!=SEG_BIG) {
2074 int_to_gen(nextword);
2075 gen_to_words(words,baseo,(long int)outro);
2076 for(wordp=words;baseo--;wordp++)
2077 addword(*wordp);
2078 break;
2079 } /* Its BIG */
2080 if(offs(opP->con1)>0) {
2081 as_warn("Bignum assumed to be binary bit-pattern");
2082 if(offs(opP->con1)>baseo) {
2083 as_warn("Bignum too big for %c format; truncated",s[1]);
2084 offs(opP->con1)=baseo;
2085 }
2086 baseo-=offs(opP->con1);
2087 for(wordp=generic_bignum+offs(opP->con1)-1;offs(opP->con1)--;--wordp)
2088 addword(*wordp);
2089 while(baseo--)
2090 addword(0);
2091 break;
2092 }
2093 gen_to_words(words,baseo,(long)outro);
2094 for (wordp=words;baseo--;wordp++)
2095 addword(*wordp);
2096 break;
2097 case DREG:
2098 tmpreg=opP->reg-DATA; /* 0.dreg */
2099 break;
2100 case AREG:
2101 tmpreg=0x08+opP->reg-ADDR; /* 1.areg */
2102 break;
2103 case AINDR:
2104 tmpreg=0x10+opP->reg-ADDR; /* 2.areg */
2105 break;
2106 case ADEC:
2107 tmpreg=0x20+opP->reg-ADDR; /* 4.areg */
2108 break;
2109 case AINC:
2110 tmpreg=0x18+opP->reg-ADDR; /* 3.areg */
2111 break;
2112 case AOFF:
2113
2114 nextword=get_num(opP->con1,80);
2115 /* Force into index mode. Hope this works */
2116
2117 /* We do the first bit for 32-bit displacements,
2118 and the second bit for 16 bit ones. It is
2119 possible that we should make the default be
2120 WORD instead of LONG, but I think that'd
2121 break GCC, so we put up with a little
2122 inefficiency for the sake of working output.
2123 */
2124
2125 if( !issword(nextword)
2126 || ( isvar(opP->con1)
2127 && ( ( opP->con1->e_siz==0
2128 && flagseen['l']==0)
2129 || opP->con1->e_siz==3))) {
2130
2131 if(opP->reg==PC)
2132 tmpreg=0x3B; /* 7.3 */
2133 else
2134 tmpreg=0x30+opP->reg-ADDR; /* 6.areg */
2135 if(isvar(opP->con1)) {
2136 if(opP->reg==PC) {
2137 add_frag(adds(opP->con1),
2138 offs(opP->con1),
2139 TAB(PCLEA,SZ_UNDEF));
2140 break;
2141 } else {
2142 addword(0x0170);
2143 add_fix('l',opP->con1,1);
2144 }
2145 } else
2146 addword(0x0170);
2147 addword(nextword>>16);
2148 } else {
2149 if(opP->reg==PC)
2150 tmpreg=0x3A; /* 7.2 */
2151 else
2152 tmpreg=0x28+opP->reg-ADDR; /* 5.areg */
2153
2154 if(isvar(opP->con1)) {
2155 if(opP->reg==PC) {
2156 add_fix('w',opP->con1,1);
2157 } else
2158 add_fix('w',opP->con1,0);
2159 }
2160 }
2161 addword(nextword);
2162 break;
2163
2164 case APODX:
2165 case AMIND:
2166 case APRDX:
2167 know(current_architecture & m68020up);
2168 /* intentional fall-through */
2169 case AINDX:
2170 nextword=0;
2171 baseo=get_num(opP->con1,80);
2172 outro=get_num(opP->con2,80);
2173 /* Figure out the 'addressing mode' */
2174 /* Also turn on the BASE_DISABLE bit, if needed */
2175 if(opP->reg==PC || opP->reg==ZPC) {
2176 tmpreg=0x3b; /* 7.3 */
2177 if(opP->reg==ZPC)
2178 nextword|=0x80;
2179 } else if(opP->reg==FAIL) {
2180 nextword|=0x80;
2181 tmpreg=0x30; /* 6.garbage */
2182 } else tmpreg=0x30+opP->reg-ADDR; /* 6.areg */
2183
2184 siz1= (opP->con1) ? opP->con1->e_siz : 0;
2185 siz2= (opP->con2) ? opP->con2->e_siz : 0;
2186
2187 /* Index register stuff */
2188 if(opP->ireg>=DATA+0 && opP->ireg<=ADDR+7) {
2189 nextword|=(opP->ireg-DATA)<<12;
2190
2191 if(opP->isiz==0 || opP->isiz==3)
2192 nextword|=0x800;
2193 switch(opP->imul) {
2194 case 1: break;
2195 case 2: nextword|=0x200; break;
2196 case 4: nextword|=0x400; break;
2197 case 8: nextword|=0x600; break;
2198 default: as_fatal("failed sanity check.");
2199 }
2200 /* IF its simple,
2201 GET US OUT OF HERE! */
2202
2203 /* Must be INDEX, with an index
2204 register. Address register
2205 cannot be ZERO-PC, and either
2206 :b was forced, or we know
2207 it will fit */
2208 if( opP->mode==AINDX
2209 && opP->reg!=FAIL
2210 && opP->reg!=ZPC
2211 && ( siz1==1
2212 || ( issbyte(baseo)
2213 && !isvar(opP->con1)))) {
2214 nextword +=baseo&0xff;
2215 addword(nextword);
2216 if(isvar(opP->con1))
2217 add_fix('B',opP->con1,0);
2218 break;
2219 }
2220 } else
2221 nextword|=0x40; /* No index reg */
2222
2223 /* It aint simple */
2224 nextword|=0x100;
2225 /* If the guy specified a width, we assume that
2226 it is wide enough. Maybe it isn't. If so, we lose
2227 */
2228 switch(siz1) {
2229 case 0:
2230 if(isvar(opP->con1) || !issword(baseo)) {
2231 siz1=3;
2232 nextword|=0x30;
2233 } else if(baseo==0)
2234 nextword|=0x10;
2235 else {
2236 nextword|=0x20;
2237 siz1=2;
2238 }
2239 break;
2240 case 1:
2241 as_warn("Byte dispacement won't work. Defaulting to :w");
2242 case 2:
2243 nextword|=0x20;
2244 break;
2245 case 3:
2246 nextword|=0x30;
2247 break;
2248 }
2249
2250 /* Figure out innner displacement stuff */
2251 if(opP->mode!=AINDX) {
2252 switch(siz2) {
2253 case 0:
2254 if(isvar(opP->con2) || !issword(outro)) {
2255 siz2=3;
2256 nextword|=0x3;
2257 } else if(outro==0)
2258 nextword|=0x1;
2259 else {
2260 nextword|=0x2;
2261 siz2=2;
2262 }
2263 break;
2264 case 1:
2265 as_warn("Byte dispacement won't work. Defaulting to :w");
2266 case 2:
2267 nextword|=0x2;
2268 break;
2269 case 3:
2270 nextword|=0x3;
2271 break;
2272 }
2273 if(opP->mode==APODX) nextword|=0x04;
2274 else if(opP->mode==AMIND) nextword|=0x40;
2275 }
2276 addword(nextword);
2277
2278 if(isvar(opP->con1)) {
2279 if(opP->reg==PC || opP->reg==ZPC) {
2280 add_fix(siz1==3 ? 'l' : 'w',opP->con1,1);
2281 opP->con1->e_exp.X_add_number+=6;
2282 } else
2283 add_fix(siz1==3 ? 'l' : 'w',opP->con1,0);
2284 }
2285 if(siz1==3)
2286 addword(baseo>>16);
2287 if(siz1)
2288 addword(baseo);
2289
2290 if(isvar(opP->con2)) {
2291 if(opP->reg==PC || opP->reg==ZPC) {
2292 add_fix(siz2==3 ? 'l' : 'w',opP->con2,1);
2293 opP->con1->e_exp.X_add_number+=6;
2294 } else
2295 add_fix(siz2==3 ? 'l' : 'w',opP->con2,0);
2296 }
2297 if(siz2==3)
2298 addword(outro>>16);
2299 if(siz2)
2300 addword(outro);
2301
2302 break;
2303
2304 case ABSL:
2305 nextword=get_num(opP->con1,80);
2306 switch(opP->con1->e_siz) {
2307 default:
2308 as_warn("Unknown size for absolute reference");
2309 case 0:
2310 if(!isvar(opP->con1) && issword(offs(opP->con1))) {
2311 tmpreg=0x38; /* 7.0 */
2312 addword(nextword);
2313 break;
2314 }
2315 /* Don't generate pc relative code
2316 on 68010 and 68000 */
2317 if(isvar(opP->con1)
2318 && !subs(opP->con1)
2319 && seg(opP->con1) == SEG_TEXT
2320 && now_seg == SEG_TEXT
2321 && cpu_of_arch(current_architecture) < m68020
2322 && !flagseen['S']
2323 && !strchr("~%&$?", s[0])) {
2324 tmpreg=0x3A; /* 7.2 */
2325 add_frag(adds(opP->con1),
2326 offs(opP->con1),
2327 TAB(PCREL,SZ_UNDEF));
2328 break;
2329 }
2330 case 3: /* Fall through into long */
2331 if(isvar(opP->con1))
2332 add_fix('l',opP->con1,0);
2333
2334 tmpreg=0x39; /* 7.1 mode */
2335 addword(nextword>>16);
2336 addword(nextword);
2337 break;
2338
2339 case 2: /* Word */
2340 if(isvar(opP->con1))
2341 add_fix('w',opP->con1,0);
2342
2343 tmpreg=0x38; /* 7.0 mode */
2344 addword(nextword);
2345 break;
2346 }
2347 break;
2348 case DINDR:
2349 as_bad("invalid indirect register");
2350 break;
2351 case MSCR:
2352 default:
2353 as_bad("unknown/incorrect operand");
2354 /* abort(); */
2355 }
2356 install_gen_operand(s[1],tmpreg);
2357 break;
2358
2359 case '#':
2360 case '^':
2361 switch(s[1]) { /* JF: I hate floating point! */
2362 case 'j':
2363 tmpreg=70;
2364 break;
2365 case '8':
2366 tmpreg=20;
2367 break;
2368 case 'C':
2369 tmpreg=50;
2370 break;
2371 case '3':
2372 default:
2373 tmpreg=80;
2374 break;
2375 }
2376 tmpreg=get_num(opP->con1,tmpreg);
2377 if(isvar(opP->con1))
2378 add_fix(s[1],opP->con1,0);
2379 switch(s[1]) {
2380 case 'b': /* Danger: These do no check for
2381 certain types of overflow.
2382 user beware! */
2383 if(!isbyte(tmpreg))
2384 opP->error="out of range";
2385 insop(tmpreg);
2386 if(isvar(opP->con1))
2387 the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;
2388 break;
2389 case 'w':
2390 if(!isword(tmpreg))
2391 opP->error="out of range";
2392 insop(tmpreg);
2393 if(isvar(opP->con1))
2394 the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;
2395 break;
2396 case 'l':
2397 insop(tmpreg); /* Because of the way insop works, we put these two out backwards */
2398 insop(tmpreg>>16);
2399 if(isvar(opP->con1))
2400 the_ins.reloc[the_ins.nrel-1].n=(opcode->m_codenum)*2;
2401 break;
2402 case '3':
2403 tmpreg&=0xFF;
2404 case '8':
2405 case 'C':
2406 install_operand(s[1],tmpreg);
2407 break;
2408 default:
2409 as_fatal("Internal error: Unknown mode #%c in line %s of file \"%s\"", s[1], __LINE__, __FILE__);
2410 }
2411 break;
2412
2413 case '+':
2414 case '-':
2415 case 'A':
2416 case 'a':
2417 install_operand(s[1],opP->reg-ADDR);
2418 break;
2419
2420 case 'B':
2421 tmpreg=get_num(opP->con1,80);
2422 switch(s[1]) {
2423 case 'B':
2424 /* Needs no offsetting */
2425 add_fix('B',opP->con1,1);
2426 break;
2427 case 'W':
2428 /* Offset the displacement to be relative to byte disp location */
2429 opP->con1->e_exp.X_add_number+=2;
2430 add_fix('w',opP->con1,1);
2431 addword(0);
2432 break;
2433 case 'L':
2434 long_branch:
2435 if (cpu_of_arch(current_architecture) < m68020) /* 68000 or 010 */
2436 as_warn("Can't use long branches on 68000/68010");
2437 the_ins.opcode[the_ins.numo-1]|=0xff;
2438 /* Offset the displacement to be relative to byte disp location */
2439 opP->con1->e_exp.X_add_number+=4;
2440 add_fix('l',opP->con1,1);
2441 addword(0);
2442 addword(0);
2443 break;
2444 case 'g':
2445 if(subs(opP->con1)) /* We can't relax it */
2446 goto long_branch;
2447
2448 /* This could either be a symbol, or an
2449 absolute address. No matter, the
2450 frag hacking will finger it out.
2451 Not quite: it can't switch from
2452 BRANCH to BCC68000 for the case
2453 where opnd is absolute (it needs
2454 to use the 68000 hack since no
2455 conditional abs jumps). */
2456 if (((cpu_of_arch(current_architecture) < m68020) || (0==adds(opP->con1)))
2457 && (the_ins.opcode[0] >= 0x6200)
2458 && (the_ins.opcode[0] <= 0x6f00)) {
2459 add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF));
2460 } else {
2461 add_frag(adds(opP->con1),offs(opP->con1),TAB(BRANCH,SZ_UNDEF));
2462 }
2463 break;
2464 case 'w':
2465 if(isvar(opP->con1)) {
2466 /* check for DBcc instruction */
2467 if ((the_ins.opcode[0] & 0xf0f8) ==0x50c8) {
2468 /* size varies if patch */
2469 /* needed for long form */
2470 add_frag(adds(opP->con1),offs(opP->con1),TAB(DBCC,SZ_UNDEF));
2471 break;
2472 }
2473
2474 /* Don't ask! */
2475 opP->con1->e_exp.X_add_number+=2;
2476 add_fix('w',opP->con1,1);
2477 }
2478 addword(0);
2479 break;
2480 case 'C': /* Fixed size LONG coproc branches */
2481 the_ins.opcode[the_ins.numo-1]|=0x40;
2482 /* Offset the displacement to be relative to byte disp location */
2483 /* Coproc branches don't have a byte disp option, but they are
2484 compatible with the ordinary branches, which do... */
2485 opP->con1->e_exp.X_add_number+=4;
2486 add_fix('l',opP->con1,1);
2487 addword(0);
2488 addword(0);
2489 break;
2490 case 'c': /* Var size Coprocesssor branches */
2491 if(subs(opP->con1)) {
2492 add_fix('l',opP->con1,1);
2493 add_frag((symbolS *)0,(long)0,TAB(FBRANCH,LONG));
2494 } else if(adds(opP->con1)) {
2495 add_frag(adds(opP->con1),offs(opP->con1),TAB(FBRANCH,SZ_UNDEF));
2496 } else {
2497 /* add_frag((symbolS *)0,offs(opP->con1),TAB(FBRANCH,SHORT)); */
2498 the_ins.opcode[the_ins.numo-1]|=0x40;
2499 add_fix('l',opP->con1,1);
2500 addword(0);
2501 addword(4);
2502 }
2503 break;
2504 default:
2505 as_fatal("Internal error: operand type B%c unknown in line %s of file \"%s\"",
2506 s[1], __LINE__, __FILE__);
2507 }
2508 break;
2509
2510 case 'C': /* Ignore it */
2511 break;
2512
2513 case 'd': /* JF this is a kludge */
2514 if(opP->mode==AOFF) {
2515 install_operand('s',opP->reg-ADDR);
2516 } else {
2517 char *tmpP;
2518
2519 tmpP=opP->con1->e_end-2;
2520 opP->con1->e_beg++;
2521 opP->con1->e_end-=4; /* point to the , */
2522 baseo=m68k_reg_parse(&tmpP);
2523 if(baseo<ADDR+0 || baseo>ADDR+7) {
2524 as_bad("Unknown address reg, using A0");
2525 baseo=0;
2526 } else baseo-=ADDR;
2527 install_operand('s',baseo);
2528 }
2529 tmpreg=get_num(opP->con1,80);
2530 if(!issword(tmpreg)) {
2531 as_warn("Expression out of range, using 0");
2532 tmpreg=0;
2533 }
2534 addword(tmpreg);
2535 break;
2536
2537 case 'D':
2538 install_operand(s[1],opP->reg-DATA);
2539 break;
2540
2541 case 'F':
2542 install_operand(s[1],opP->reg-FPREG);
2543 break;
2544
2545 case 'I':
2546 tmpreg=1+opP->reg-COPNUM;
2547 if(tmpreg==8)
2548 tmpreg=0;
2549 install_operand(s[1],tmpreg);
2550 break;
2551
2552 case 'J': /* JF foo */
2553 switch(opP->reg) {
2554 case SFC: tmpreg=0x000; break;
2555 case DFC: tmpreg=0x001; break;
2556 case CACR: tmpreg=0x002; break;
2557 case TC: tmpreg=0x003; break;
2558 case ITT0: tmpreg=0x004; break;
2559 case ITT1: tmpreg=0x005; break;
2560 case DTT0: tmpreg=0x006; break;
2561 case DTT1: tmpreg=0x007; break;
2562
2563 case USP: tmpreg=0x800; break;
2564 case VBR: tmpreg=0x801; break;
2565 case CAAR: tmpreg=0x802; break;
2566 case MSP: tmpreg=0x803; break;
2567 case ISP: tmpreg=0x804; break;
2568 case MMUSR: tmpreg=0x805; break;
2569 case URP: tmpreg=0x806; break;
2570 case SRP: tmpreg=0x807; break;
2571 default:
2572 as_fatal("failed sanity check.");
2573 }
2574 install_operand(s[1],tmpreg);
2575 break;
2576
2577 case 'k':
2578 tmpreg=get_num(opP->con1,55);
2579 install_operand(s[1],tmpreg&0x7f);
2580 break;
2581
2582 case 'l':
2583 tmpreg=opP->reg;
2584 if(s[1]=='w') {
2585 if(tmpreg&0x7FF0000)
2586 as_bad("Floating point register in register list");
2587 insop(reverse_16_bits(tmpreg));
2588 } else {
2589 if(tmpreg&0x700FFFF)
2590 as_bad("Wrong register in floating-point reglist");
2591 install_operand(s[1],reverse_8_bits(tmpreg>>16));
2592 }
2593 break;
2594
2595 case 'L':
2596 tmpreg=opP->reg;
2597 if(s[1]=='w') {
2598 if(tmpreg&0x7FF0000)
2599 as_bad("Floating point register in register list");
2600 insop(tmpreg);
2601 } else if(s[1]=='8') {
2602 if(tmpreg&0x0FFFFFF)
2603 as_bad("incorrect register in reglist");
2604 install_operand(s[1],tmpreg>>24);
2605 } else {
2606 if(tmpreg&0x700FFFF)
2607 as_bad("wrong register in floating-point reglist");
2608 else
2609 install_operand(s[1],tmpreg>>16);
2610 }
2611 break;
2612
2613 case 'M':
2614 install_operand(s[1],get_num(opP->con1,60));
2615 break;
2616
2617 case 'O':
2618 tmpreg= (opP->mode==DREG)
2619 ? 0x20+opP->reg-DATA
2620 : (get_num(opP->con1,40)&0x1F);
2621 install_operand(s[1],tmpreg);
2622 break;
2623
2624 case 'Q':
2625 tmpreg=get_num(opP->con1,10);
2626 if(tmpreg==8)
2627 tmpreg=0;
2628 install_operand(s[1],tmpreg);
2629 break;
2630
2631 case 'R':
2632 case 'r':
2633 /* This depends on the fact that ADDR registers are
2634 eight more than their corresponding DATA regs, so
2635 the result will have the ADDR_REG bit set */
2636 install_operand(s[1],opP->reg-DATA);
2637 break;
2638
2639 case 's':
2640 if(opP->reg==FPI) tmpreg=0x1;
2641 else if(opP->reg==FPS) tmpreg=0x2;
2642 else if(opP->reg==FPC) tmpreg=0x4;
2643 else as_fatal("failed sanity check.");
2644 install_operand(s[1],tmpreg);
2645 break;
2646
2647 case 'S': /* Ignore it */
2648 break;
2649
2650 case 'T':
2651 install_operand(s[1],get_num(opP->con1,30));
2652 break;
2653
2654 case 'U': /* Ignore it */
2655 break;
2656
2657 case 'c':
2658 switch (opP->reg) {
2659 case NC: tmpreg = 0; break;
2660 case DC: tmpreg = 1; break;
2661 case IC: tmpreg = 2; break;
2662 case BC: tmpreg = 3; break;
2663 default:
2664 as_fatal("failed sanity check");
2665 } /* switch on cache token */
2666 install_operand(s[1], tmpreg);
2667 break;
2668 #ifndef NO_68851
2669 /* JF: These are out of order, I fear. */
2670 case 'f':
2671 switch (opP->reg) {
2672 case SFC:
2673 tmpreg=0;
2674 break;
2675 case DFC:
2676 tmpreg=1;
2677 break;
2678 default:
2679 as_fatal("failed sanity check.");
2680 }
2681 install_operand(s[1],tmpreg);
2682 break;
2683
2684 case 'P':
2685 switch(opP->reg) {
2686 case TC:
2687 tmpreg=0;
2688 break;
2689 case CAL:
2690 tmpreg=4;
2691 break;
2692 case VAL:
2693 tmpreg=5;
2694 break;
2695 case SCC:
2696 tmpreg=6;
2697 break;
2698 case AC:
2699 tmpreg=7;
2700 break;
2701 default:
2702 as_fatal("failed sanity check.");
2703 }
2704 install_operand(s[1],tmpreg);
2705 break;
2706
2707 case 'V':
2708 if (opP->reg == VAL)
2709 break;
2710 as_fatal("failed sanity check.");
2711
2712 case 'W':
2713 switch(opP->reg) {
2714
2715 case DRP:
2716 tmpreg=1;
2717 break;
2718 case SRP:
2719 tmpreg=2;
2720 break;
2721 case CRP:
2722 tmpreg=3;
2723 break;
2724 default:
2725 as_fatal("failed sanity check.");
2726 }
2727 install_operand(s[1],tmpreg);
2728 break;
2729
2730 case 'X':
2731 switch (opP->reg) {
2732 case BAD: case BAD+1: case BAD+2: case BAD+3:
2733 case BAD+4: case BAD+5: case BAD+6: case BAD+7:
2734 tmpreg = (4 << 10) | ((opP->reg - BAD) << 2);
2735 break;
2736
2737 case BAC: case BAC+1: case BAC+2: case BAC+3:
2738 case BAC+4: case BAC+5: case BAC+6: case BAC+7:
2739 tmpreg = (5 << 10) | ((opP->reg - BAC) << 2);
2740 break;
2741
2742 default:
2743 as_fatal("failed sanity check.");
2744 }
2745 install_operand(s[1], tmpreg);
2746 break;
2747 case 'Y':
2748 know(opP->reg == PSR);
2749 break;
2750 case 'Z':
2751 know(opP->reg == PCSR);
2752 break;
2753 #endif /* m68851 */
2754 case '_':
2755 tmpreg=get_num(opP->con1,80);
2756 install_operand(s[1], tmpreg);
2757 break;
2758 default:
2759 as_fatal("Internal error: Operand type %c unknown in line %s of file \"%s\"", s[0], __LINE__, __FILE__);
2760 }
2761 }
2762 /* By the time whe get here (FINALLY) the_ins contains the complete
2763 instruction, ready to be emitted. . . */
2764 } /* m68k_ip() */
2765
2766 /*
2767 * get_regs := '/' + ?
2768 * | '-' + <register>
2769 * | '-' + <register> + ?
2770 * | <empty>
2771 * ;
2772 *
2773
2774 * The idea here must be to scan in a set of registers but I don't
2775 * understand it. Looks awfully sloppy to me but I don't have any doc on
2776 * this format so...
2777
2778 *
2779 *
2780 */
2781
2782 static int get_regs(i,str,opP)
2783 int i;
2784 struct m68k_op *opP;
2785 char *str;
2786 {
2787 /* 26, 25, 24, 23-16, 15-8, 0-7 */
2788 /* Low order 24 bits encoded fpc,fps,fpi,fp7-fp0,a7-a0,d7-d0 */
2789 unsigned long cur_regs = 0;
2790 int reg1,
2791 reg2;
2792
2793 #define ADD_REG(x) { if(x==FPI) cur_regs|=(1<<24);\
2794 else if(x==FPS) cur_regs|=(1<<25);\
2795 else if(x==FPC) cur_regs|=(1<<26);\
2796 else cur_regs|=(1<<(x-1)); }
2797
2798 reg1=i;
2799 for(;;) {
2800 if(*str=='/') {
2801 ADD_REG(reg1);
2802 str++;
2803 } else if(*str=='-') {
2804 str++;
2805 reg2=m68k_reg_parse(&str);
2806 if(reg2<DATA || reg2>=FPREG+8 || reg1==FPI || reg1==FPS || reg1==FPC) {
2807 opP->error="unknown register in register list";
2808 return FAIL;
2809 }
2810 while(reg1<=reg2) {
2811 ADD_REG(reg1);
2812 reg1++;
2813 }
2814 if(*str=='\0')
2815 break;
2816 } else if(*str=='\0') {
2817 ADD_REG(reg1);
2818 break;
2819 } else {
2820 opP->error="unknow character in register list";
2821 return FAIL;
2822 }
2823 /* DJA -- Bug Fix. Did't handle d1-d2/a1 until the following instruction was added */
2824 if (*str=='/')
2825 str ++;
2826 reg1=m68k_reg_parse(&str);
2827 if((reg1<DATA || reg1>=FPREG+8) && !(reg1==FPI || reg1==FPS || reg1==FPC)) {
2828 opP->error="unknown register in register list";
2829 return FAIL;
2830 }
2831 }
2832 opP->reg=cur_regs;
2833 return OK;
2834 } /* get_regs() */
2835
2836 static int reverse_16_bits(in)
2837 int in;
2838 {
2839 int out=0;
2840 int n;
2841
2842 static int mask[16] = {
2843 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
2844 0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000
2845 };
2846 for(n=0;n<16;n++) {
2847 if(in&mask[n])
2848 out|=mask[15-n];
2849 }
2850 return out;
2851 } /* reverse_16_bits() */
2852
2853 static int reverse_8_bits(in)
2854 int in;
2855 {
2856 int out=0;
2857 int n;
2858
2859 static int mask[8] = {
2860 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
2861 };
2862
2863 for(n=0;n<8;n++) {
2864 if(in&mask[n])
2865 out|=mask[7-n];
2866 }
2867 return out;
2868 } /* reverse_8_bits() */
2869
2870 static void install_operand(mode,val)
2871 int mode;
2872 int val;
2873 {
2874 switch(mode) {
2875 case 's':
2876 the_ins.opcode[0]|=val & 0xFF; /* JF FF is for M kludge */
2877 break;
2878 case 'd':
2879 the_ins.opcode[0]|=val<<9;
2880 break;
2881 case '1':
2882 the_ins.opcode[1]|=val<<12;
2883 break;
2884 case '2':
2885 the_ins.opcode[1]|=val<<6;
2886 break;
2887 case '3':
2888 the_ins.opcode[1]|=val;
2889 break;
2890 case '4':
2891 the_ins.opcode[2]|=val<<12;
2892 break;
2893 case '5':
2894 the_ins.opcode[2]|=val<<6;
2895 break;
2896 case '6':
2897 /* DANGER! This is a hack to force cas2l and cas2w cmds
2898 to be three words long! */
2899 the_ins.numo++;
2900 the_ins.opcode[2]|=val;
2901 break;
2902 case '7':
2903 the_ins.opcode[1]|=val<<7;
2904 break;
2905 case '8':
2906 the_ins.opcode[1]|=val<<10;
2907 break;
2908 #ifndef NO_68851
2909 case '9':
2910 the_ins.opcode[1]|=val<<5;
2911 break;
2912 #endif
2913
2914 case 't':
2915 the_ins.opcode[1]|=(val<<10)|(val<<7);
2916 break;
2917 case 'D':
2918 the_ins.opcode[1]|=(val<<12)|val;
2919 break;
2920 case 'g':
2921 the_ins.opcode[0]|=val=0xff;
2922 break;
2923 case 'i':
2924 the_ins.opcode[0]|=val<<9;
2925 break;
2926 case 'C':
2927 the_ins.opcode[1]|=val;
2928 break;
2929 case 'j':
2930 the_ins.opcode[1]|=val;
2931 the_ins.numo++; /* What a hack */
2932 break;
2933 case 'k':
2934 the_ins.opcode[1]|=val<<4;
2935 break;
2936 case 'b':
2937 case 'w':
2938 case 'l':
2939 break;
2940 case 'e':
2941 the_ins.opcode[0] |= (val << 6);
2942 break;
2943 case 'L':
2944 the_ins.opcode[1] = (val >> 16);
2945 the_ins.opcode[2] = val & 0xffff;
2946 break;
2947 case 'c':
2948 default:
2949 as_fatal("failed sanity check.");
2950 }
2951 } /* install_operand() */
2952
2953 static void install_gen_operand(mode,val)
2954 int mode;
2955 int val;
2956 {
2957 switch(mode) {
2958 case 's':
2959 the_ins.opcode[0]|=val;
2960 break;
2961 case 'd':
2962 /* This is a kludge!!! */
2963 the_ins.opcode[0]|=(val&0x07)<<9|(val&0x38)<<3;
2964 break;
2965 case 'b':
2966 case 'w':
2967 case 'l':
2968 case 'f':
2969 case 'F':
2970 case 'x':
2971 case 'p':
2972 the_ins.opcode[0]|=val;
2973 break;
2974 /* more stuff goes here */
2975 default:
2976 as_fatal("failed sanity check.");
2977 }
2978 } /* install_gen_operand() */
2979
2980 /*
2981 * verify that we have some number of paren pairs, do m68k_ip_op(), and
2982 * then deal with the bitfield hack.
2983 */
2984
2985 static char *crack_operand(str,opP)
2986 register char *str;
2987 register struct m68k_op *opP;
2988 {
2989 register int parens;
2990 register int c;
2991 register char *beg_str;
2992
2993 if(!str) {
2994 return str;
2995 }
2996 beg_str=str;
2997 for(parens=0;*str && (parens>0 || notend(str));str++) {
2998 if(*str=='(') parens++;
2999 else if(*str==')') {
3000 if(!parens) { /* ERROR */
3001 opP->error="Extra )";
3002 return str;
3003 }
3004 --parens;
3005 }
3006 }
3007 if(!*str && parens) { /* ERROR */
3008 opP->error="Missing )";
3009 return str;
3010 }
3011 c= *str;
3012 *str='\0';
3013 if(m68k_ip_op(beg_str,opP)==FAIL) {
3014 *str=c;
3015 return str;
3016 }
3017 *str=c;
3018
3019 if(c=='}')
3020 c= *++str; /* JF bitfield hack */
3021
3022 if(c) {
3023 c= *++str;
3024 if(!c)
3025 as_bad("Missing operand");
3026 }
3027 return str;
3028 }
3029
3030 /* See the comment up above where the #define notend(... is */
3031 #if 0
3032 notend(s)
3033 char *s;
3034 {
3035 if(*s==',') return 0;
3036 if(*s=='{' || *s=='}')
3037 return 0;
3038 if(*s!=':') return 1;
3039 /* This kludge here is for the division cmd, which is a kludge */
3040 if(index("aAdD#(",s[1])) return 0;
3041 return 1;
3042 }
3043 #endif
3044
3045
3046 int done_pseudo(str)
3047 char *str;
3048 {
3049 extern struct hash_control * po_hash;
3050 char *ptr = str;
3051 char *null_ptr;
3052 pseudo_typeS * pop;
3053
3054 char c;
3055
3056 is_end_of_line[0] = 1;
3057 /* Skip over name of pseudo, change to lower case */
3058 while (isalpha(*ptr) || *ptr == '.')
3059 {
3060 if (isupper(*ptr)) {
3061 *ptr = tolower(*ptr);
3062 }
3063 ptr++;
3064 }
3065 null_ptr = ptr;
3066 c = *null_ptr;
3067 *null_ptr = 0;
3068
3069
3070 pop = (pseudo_typeS *)hash_find(po_hash, str);
3071
3072 *null_ptr = c;
3073 if (pop != (pseudo_typeS *)NULL)
3074 {
3075 input_line_pointer = null_ptr+1;
3076 SKIP_WHITESPACE();
3077 /* Now we point to first non-blank char after pseudo op */
3078 (*pop->poc_handler)(pop->poc_val);
3079 input_line_pointer--;
3080
3081 return 1;
3082
3083 }
3084 /* Just put back the char where the null was put and return as if nothing had happened */
3085
3086 *null_ptr = c;
3087 return 0;
3088
3089 }
3090
3091
3092 /* This is the guts of the machine-dependent assembler. STR points to a
3093 machine dependent instruction. This function is supposed to emit
3094 the frags/bytes it assembles to.
3095 */
3096 void
3097 md_assemble(str)
3098 char *str;
3099 {
3100 char *er;
3101 short *fromP;
3102 char *toP = NULL;
3103 int m,n = 0;
3104 char *to_beg_P;
3105 int shorts_this_frag;
3106
3107 /* if (done_pseudo(str)) return ;*/
3108
3109
3110
3111 if (current_architecture == 0) {
3112 current_architecture = (m68020
3113 #ifndef NO_68881
3114 | m68881
3115 #endif
3116 #ifndef NO_68851
3117 | m68851
3118 #endif
3119 );
3120 } /* default current_architecture */
3121
3122 memset((char *)(&the_ins), '\0', sizeof(the_ins)); /* JF for paranoia sake */
3123
3124 m68k_ip(str);
3125 er=the_ins.error;
3126 if(!er) {
3127 for(n=the_ins.numargs;n;--n)
3128 if(the_ins.operands[n].error) {
3129 er=the_ins.operands[n].error;
3130 break;
3131 }
3132 }
3133 if(er) {
3134 as_bad("\"%s\" -- Statement '%s' ignored",er,str);
3135 return;
3136 }
3137
3138 if(the_ins.nfrag==0) { /* No frag hacking involved; just put it out */
3139 toP=frag_more(2*the_ins.numo);
3140 fromP= &the_ins.opcode[0];
3141 for(m=the_ins.numo;m;--m) {
3142 md_number_to_chars(toP,(long)(*fromP),2);
3143 toP+=2;
3144 fromP++;
3145 }
3146 /* put out symbol-dependent info */
3147 for(m=0;m<the_ins.nrel;m++) {
3148 switch(the_ins.reloc[m].wid) {
3149 case 'B':
3150 n=1;
3151 break;
3152 case 'b':
3153 n=1;
3154 break;
3155 case '3':
3156 n=2;
3157 break;
3158 case 'w':
3159 n=2;
3160 break;
3161 case 'l':
3162 n=4;
3163 break;
3164 default:
3165 as_fatal("Don't know how to figure width of %c in md_assemble()",the_ins.reloc[m].wid);
3166 }
3167
3168 fix_new(frag_now,
3169 (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n,
3170 n,
3171 the_ins.reloc[m].add,
3172 the_ins.reloc[m].sub,
3173 the_ins.reloc[m].off,
3174 the_ins.reloc[m].pcrel,
3175 NO_RELOC);
3176 }
3177 return;
3178 }
3179
3180 /* There's some frag hacking */
3181 for(n=0,fromP= &the_ins.opcode[0];n<the_ins.nfrag;n++) {
3182 int wid;
3183
3184 if(n==0) wid=2*the_ins.fragb[n].fragoff;
3185 else wid=2*(the_ins.numo-the_ins.fragb[n-1].fragoff);
3186 toP=frag_more(wid);
3187 to_beg_P=toP;
3188 shorts_this_frag=0;
3189 for(m=wid/2;m;--m) {
3190 md_number_to_chars(toP,(long)(*fromP),2);
3191 toP+=2;
3192 fromP++;
3193 shorts_this_frag++;
3194 }
3195 for(m=0;m<the_ins.nrel;m++) {
3196 if((the_ins.reloc[m].n)>= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */) {
3197 the_ins.reloc[m].n-= 2*shorts_this_frag /* 2*the_ins.fragb[n].fragoff */;
3198 break;
3199 }
3200 wid=the_ins.reloc[m].wid;
3201 if(wid==0)
3202 continue;
3203 the_ins.reloc[m].wid=0;
3204 wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000;
3205
3206 fix_new(frag_now,
3207 (toP-frag_now->fr_literal)-the_ins.numo*2+the_ins.reloc[m].n,
3208 wid,
3209 the_ins.reloc[m].add,
3210 the_ins.reloc[m].sub,
3211 the_ins.reloc[m].off,
3212 the_ins.reloc[m].pcrel,
3213 NO_RELOC);
3214 }
3215 /* know(the_ins.fragb[n].fadd); */
3216 (void)frag_var(rs_machine_dependent,10,0,(relax_substateT)(the_ins.fragb[n].fragty),
3217 the_ins.fragb[n].fadd,the_ins.fragb[n].foff,to_beg_P);
3218 }
3219 n=(the_ins.numo-the_ins.fragb[n-1].fragoff);
3220 shorts_this_frag=0;
3221 if(n) {
3222 toP=frag_more(n*sizeof(short));
3223 while(n--) {
3224 md_number_to_chars(toP,(long)(*fromP),2);
3225 toP+=2;
3226 fromP++;
3227 shorts_this_frag++;
3228 }
3229 }
3230 for(m=0;m<the_ins.nrel;m++) {
3231 int wid;
3232
3233 wid=the_ins.reloc[m].wid;
3234 if(wid==0)
3235 continue;
3236 the_ins.reloc[m].wid=0;
3237 wid = (wid=='b') ? 1 : (wid=='w') ? 2 : (wid=='l') ? 4 : 4000;
3238
3239 fix_new(frag_now,
3240 (the_ins.reloc[m].n + toP-frag_now->fr_literal)- /* the_ins.numo */ shorts_this_frag*2,
3241 wid,
3242 the_ins.reloc[m].add,
3243 the_ins.reloc[m].sub,
3244 the_ins.reloc[m].off,
3245 the_ins.reloc[m].pcrel,
3246 NO_RELOC);
3247 }
3248 }
3249
3250 /* This function is called once, at assembler startup time. This should
3251 set up all the tables, etc that the MD part of the assembler needs
3252 */
3253 void
3254 md_begin()
3255 {
3256 /*
3257 * md_begin -- set up hash tables with 68000 instructions.
3258 * similar to what the vax assembler does. ---phr
3259 */
3260 /* RMS claims the thing to do is take the m68k-opcode.h table, and make
3261 a copy of it at runtime, adding in the information we want but isn't
3262 there. I think it'd be better to have an awk script hack the table
3263 at compile time. Or even just xstr the table and use it as-is. But
3264 my lord ghod hath spoken, so we do it this way. Excuse the ugly var
3265 names. */
3266
3267 register const struct m68k_opcode *ins;
3268 register struct m68k_incant *hack,
3269 *slak;
3270 register char *retval = 0; /* empty string, or error msg text */
3271 register unsigned int i;
3272 register char c;
3273
3274 if ((op_hash = hash_new()) == NULL)
3275 as_fatal("Virtual memory exhausted");
3276
3277 obstack_begin(&robyn,4000);
3278 for (ins = m68k_opcodes; ins < endop; ins++) {
3279 hack=slak=(struct m68k_incant *)obstack_alloc(&robyn,sizeof(struct m68k_incant));
3280 do {
3281 /* we *could* ignore insns that don't match our
3282 arch here but just leaving them out of the
3283 hash. */
3284 slak->m_operands=ins->args;
3285 slak->m_opnum=strlen(slak->m_operands)/2;
3286 slak->m_arch = ins->arch;
3287 slak->m_opcode=ins->opcode;
3288 /* This is kludgey */
3289 slak->m_codenum=((ins->match)&0xffffL) ? 2 : 1;
3290 if((ins+1)!=endop && !strcmp(ins->name,(ins+1)->name)) {
3291 slak->m_next=(struct m68k_incant *) obstack_alloc(&robyn,sizeof(struct m68k_incant));
3292 ins++;
3293 } else
3294 slak->m_next=0;
3295 slak=slak->m_next;
3296 } while(slak);
3297
3298 retval = hash_insert (op_hash, ins->name,(char *)hack);
3299 /* Didn't his mommy tell him about null pointers? */
3300 if(retval && *retval)
3301 as_fatal("Internal Error: Can't hash %s: %s",ins->name,retval);
3302 }
3303
3304 for (i = 0; i < sizeof(mklower_table) ; i++)
3305 mklower_table[i] = (isupper(c = (char) i)) ? tolower(c) : c;
3306
3307 for (i = 0 ; i < sizeof(notend_table) ; i++) {
3308 notend_table[i] = 0;
3309 alt_notend_table[i] = 0;
3310 }
3311 notend_table[','] = 1;
3312 notend_table['{'] = 1;
3313 notend_table['}'] = 1;
3314 alt_notend_table['a'] = 1;
3315 alt_notend_table['A'] = 1;
3316 alt_notend_table['d'] = 1;
3317 alt_notend_table['D'] = 1;
3318 alt_notend_table['#'] = 1;
3319 alt_notend_table['f'] = 1;
3320 alt_notend_table['F'] = 1;
3321 alt_notend_table['('] = 1;
3322
3323 #ifdef REGISTER_PREFIX
3324 alt_notend_table[REGISTER_PREFIX] = 1;
3325 #endif
3326
3327
3328 }
3329
3330 #if 0
3331 #define notend(s) ((*s == ',' || *s == '}' || *s == '{' \
3332 || (*s == ':' && strchr("aAdD#(", s[1]))) \
3333 ? 0 : 1)
3334 #endif
3335
3336 /* This funciton is called once, before the assembler exits. It is
3337 supposed to do any final cleanup for this part of the assembler.
3338 */
3339 void
3340 md_end()
3341 {
3342 }
3343
3344 /* Equal to MAX_PRECISION in atof-ieee.c */
3345 #define MAX_LITTLENUMS 6
3346
3347 /* Turn a string in str into a floating point constant of type
3348 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
3349 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
3350 */
3351 char *
3352 md_atof(type,litP,sizeP)
3353 char type;
3354 char *litP;
3355 int *sizeP;
3356 {
3357 int prec;
3358 LITTLENUM_TYPE words[MAX_LITTLENUMS];
3359 LITTLENUM_TYPE *wordP;
3360 char *t;
3361 char *atof_ieee();
3362
3363 switch(type) {
3364 case 'f':
3365 case 'F':
3366 case 's':
3367 case 'S':
3368 prec = 2;
3369 break;
3370
3371 case 'd':
3372 case 'D':
3373 case 'r':
3374 case 'R':
3375 prec = 4;
3376 break;
3377
3378 case 'x':
3379 case 'X':
3380 prec = 6;
3381 break;
3382
3383 case 'p':
3384 case 'P':
3385 prec = 6;
3386 break;
3387
3388 default:
3389 *sizeP=0;
3390 return "Bad call to MD_ATOF()";
3391 }
3392 t=atof_ieee(input_line_pointer,type,words);
3393 if(t)
3394 input_line_pointer=t;
3395
3396 *sizeP=prec * sizeof(LITTLENUM_TYPE);
3397 for(wordP=words;prec--;) {
3398 md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
3399 litP+=sizeof(LITTLENUM_TYPE);
3400 }
3401 return ""; /* Someone should teach Dean about null pointers */
3402 }
3403
3404 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
3405 for use in the a.out file, and stores them in the array pointed to by buf.
3406 This knows about the endian-ness of the target machine and does
3407 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
3408 2 (short) and 4 (long) Floating numbers are put out as a series of
3409 LITTLENUMS (shorts, here at least)
3410 */
3411 void
3412 md_number_to_chars(buf,val,n)
3413 char *buf;
3414 long val;
3415 int n;
3416 {
3417 switch(n) {
3418 case 1:
3419 *buf++=val;
3420 break;
3421 case 2:
3422 *buf++=(val>>8);
3423 *buf++=val;
3424 break;
3425 case 4:
3426 *buf++=(val>>24);
3427 *buf++=(val>>16);
3428 *buf++=(val>>8);
3429 *buf++=val;
3430 break;
3431 default:
3432 as_fatal("failed sanity check.");
3433 }
3434 }
3435
3436 void
3437 md_apply_fix(fixP, val)
3438 fixS *fixP;
3439 long val;
3440 {
3441 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
3442
3443 switch(fixP->fx_size) {
3444 case 1:
3445 *buf++=val;
3446 break;
3447 case 2:
3448 *buf++=(val>>8);
3449 *buf++=val;
3450 break;
3451 case 4:
3452 *buf++=(val>>24);
3453 *buf++=(val>>16);
3454 *buf++=(val>>8);
3455 *buf++=val;
3456 break;
3457 default:
3458 BAD_CASE (fixP->fx_size);
3459 }
3460 }
3461
3462
3463 /* *fragP has been relaxed to its final size, and now needs to have
3464 the bytes inside it modified to conform to the new size There is UGLY
3465 MAGIC here. ..
3466 */
3467 void
3468 md_convert_frag(headers, fragP)
3469 object_headers *headers;
3470 register fragS *fragP;
3471 {
3472 long disp;
3473 long ext = 0;
3474
3475 /* Address in object code of the displacement. */
3476 register int object_address = fragP -> fr_fix + fragP -> fr_address;
3477
3478 #ifdef IBM_COMPILER_SUX
3479 /* This is wrong but it convinces the native rs6000 compiler to
3480 generate the code we want. */
3481 register char *buffer_address = fragP -> fr_literal;
3482 buffer_address += fragP -> fr_fix;
3483 #else /* IBM_COMPILER_SUX */
3484 /* Address in gas core of the place to store the displacement. */
3485 register char *buffer_address = fragP->fr_fix + fragP->fr_literal;
3486 #endif /* IBM_COMPILER_SUX */
3487
3488 /* No longer true: know(fragP->fr_symbol); */
3489
3490 /* The displacement of the address, from current location. */
3491 disp = fragP->fr_symbol ? S_GET_VALUE(fragP->fr_symbol) : 0;
3492 disp = (disp + fragP->fr_offset) - object_address;
3493
3494 switch(fragP->fr_subtype) {
3495 case TAB(BCC68000,BYTE):
3496 case TAB(BRANCH,BYTE):
3497 know(issbyte(disp));
3498 if(disp==0)
3499 as_bad("short branch with zero offset: use :w");
3500 fragP->fr_opcode[1]=disp;
3501 ext=0;
3502 break;
3503 case TAB(DBCC,SHORT):
3504 know(issword(disp));
3505 ext=2;
3506 break;
3507 case TAB(BCC68000,SHORT):
3508 case TAB(BRANCH,SHORT):
3509 know(issword(disp));
3510 fragP->fr_opcode[1]=0x00;
3511 ext=2;
3512 break;
3513 case TAB(BRANCH,LONG):
3514 if (cpu_of_arch(current_architecture) < m68020) {
3515 if (fragP->fr_opcode[0]==0x61) {
3516 fragP->fr_opcode[0]= 0x4E;
3517 fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */
3518 subseg_change(SEG_TEXT, 0);
3519
3520 fix_new(fragP,
3521 fragP->fr_fix,
3522 4,
3523 fragP->fr_symbol,
3524 0,
3525 fragP->fr_offset,
3526 0,
3527 NO_RELOC);
3528
3529 fragP->fr_fix+=4;
3530 ext=0;
3531 } else if (fragP->fr_opcode[0]==0x60) {
3532 fragP->fr_opcode[0]= 0x4E;
3533 fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */
3534 subseg_change(SEG_TEXT, 0);
3535 fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset,0,
3536 NO_RELOC);
3537 fragP->fr_fix+=4;
3538 ext=0;
3539 } else {
3540 as_bad("Long branch offset not supported.");
3541 }
3542 } else {
3543 fragP->fr_opcode[1]=0xff;
3544 ext=4;
3545 }
3546 break;
3547 case TAB(BCC68000,LONG):
3548 /* only Bcc 68000 instructions can come here */
3549 /* change bcc into b!cc/jmp absl long */
3550 fragP->fr_opcode[0] ^= 0x01; /* invert bcc */
3551 fragP->fr_opcode[1] = 0x6; /* branch offset = 6 */
3552
3553 /* JF: these used to be fr_opcode[2,3], but they may be in a
3554 different frag, in which case refering to them is a no-no.
3555 Only fr_opcode[0,1] are guaranteed to work. */
3556 *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */
3557 *buffer_address++ = 0xf9;
3558 fragP->fr_fix += 2; /* account for jmp instruction */
3559 subseg_change(SEG_TEXT,0);
3560 fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
3561 fragP->fr_offset,0,
3562 NO_RELOC);
3563 fragP->fr_fix += 4;
3564 ext=0;
3565 break;
3566 case TAB(DBCC,LONG):
3567 /* only DBcc 68000 instructions can come here */
3568 /* change dbcc into dbcc/jmp absl long */
3569 /* JF: these used to be fr_opcode[2-7], but that's wrong */
3570 *buffer_address++ = 0x00; /* branch offset = 4 */
3571 *buffer_address++ = 0x04;
3572 *buffer_address++ = 0x60; /* put in bra pc+6 */
3573 *buffer_address++ = 0x06;
3574 *buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */
3575 *buffer_address++ = 0xf9;
3576
3577 fragP->fr_fix += 6; /* account for bra/jmp instructions */
3578 subseg_change(SEG_TEXT,0);
3579 fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
3580 fragP->fr_offset,0,
3581 NO_RELOC);
3582 fragP->fr_fix += 4;
3583 ext=0;
3584 break;
3585 case TAB(FBRANCH,SHORT):
3586 know((fragP->fr_opcode[1]&0x40)==0);
3587 ext=2;
3588 break;
3589 case TAB(FBRANCH,LONG):
3590 fragP->fr_opcode[1]|=0x40; /* Turn on LONG bit */
3591 ext=4;
3592 break;
3593 case TAB(PCREL,SHORT):
3594 ext=2;
3595 break;
3596 case TAB(PCREL,LONG):
3597 /* The thing to do here is force it to ABSOLUTE LONG, since
3598 PCREL is really trying to shorten an ABSOLUTE address anyway */
3599 /* JF FOO This code has not been tested */
3600 subseg_change(SEG_TEXT,0);
3601 fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
3602 if((fragP->fr_opcode[1] & 0x3F) != 0x3A)
3603 as_bad("Internal error (long PC-relative operand) for insn 0x%04lx at 0x%lx",
3604 fragP->fr_opcode[0],fragP->fr_address);
3605 fragP->fr_opcode[1]&= ~0x3F;
3606 fragP->fr_opcode[1]|=0x39; /* Mode 7.1 */
3607 fragP->fr_fix+=4;
3608 /* md_number_to_chars(buffer_address,
3609 (long)(fragP->fr_symbol->sy_value + fragP->fr_offset),
3610 4); */
3611 ext=0;
3612 break;
3613 case TAB(PCLEA,SHORT):
3614 subseg_change(SEG_TEXT,0);
3615 fix_new(fragP,(int)(fragP->fr_fix),2,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset,1,
3616 NO_RELOC);
3617 fragP->fr_opcode[1] &= ~0x3F;
3618 fragP->fr_opcode[1] |= 0x3A;
3619 ext=2;
3620 break;
3621 case TAB(PCLEA,LONG):
3622 subseg_change(SEG_TEXT,0);
3623 fix_new(fragP,(int)(fragP->fr_fix)+2,4,fragP->fr_symbol,(symbolS *)0,fragP->fr_offset+2,1,
3624 NO_RELOC);
3625 *buffer_address++ = 0x01;
3626 *buffer_address++ = 0x70;
3627 fragP->fr_fix+=2;
3628 /* buffer_address+=2; */
3629 ext=4;
3630 break;
3631
3632 } /* switch on subtype */
3633
3634 if (ext) {
3635 md_number_to_chars(buffer_address, (long) disp, (int) ext);
3636 fragP->fr_fix += ext;
3637 /* H_SET_TEXT_SIZE(headers, H_GET_TEXT_SIZE(headers) + ext); */
3638 } /* if extending */
3639
3640 return;
3641 } /* md_convert_frag() */
3642
3643 /* Force truly undefined symbols to their maximum size, and generally set up
3644 the frag list to be relaxed
3645 */
3646 int md_estimate_size_before_relax(fragP, segment)
3647 register fragS *fragP;
3648 segT segment;
3649 {
3650 int old_fix;
3651 register char *buffer_address = fragP->fr_fix + fragP->fr_literal;
3652
3653 old_fix = fragP->fr_fix;
3654
3655 /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */
3656 switch(fragP->fr_subtype) {
3657
3658 case TAB(BRANCH,SZ_UNDEF): {
3659 if((fragP->fr_symbol != NULL) /* Not absolute */
3660 && S_GET_SEGMENT(fragP->fr_symbol) == segment) {
3661 fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE);
3662 break;
3663 } else if((fragP->fr_symbol == 0) || (cpu_of_arch(current_architecture) < m68020)) {
3664 /* On 68000, or for absolute value, switch to abs long */
3665 /* FIXME, we should check abs val, pick short or long */
3666 if(fragP->fr_opcode[0]==0x61) {
3667 fragP->fr_opcode[0]= 0x4E;
3668 fragP->fr_opcode[1]= 0xB9; /* JBSR with ABSL LONG offset */
3669 subseg_change(SEG_TEXT, 0);
3670 fix_new(fragP, fragP->fr_fix, 4,
3671 fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
3672 fragP->fr_fix+=4;
3673 frag_wane(fragP);
3674 } else if(fragP->fr_opcode[0]==0x60) {
3675 fragP->fr_opcode[0]= 0x4E;
3676 fragP->fr_opcode[1]= 0xF9; /* JMP with ABSL LONG offset */
3677 subseg_change(SEG_TEXT, 0);
3678 fix_new(fragP, fragP->fr_fix, 4,
3679 fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
3680 fragP->fr_fix+=4;
3681 frag_wane(fragP);
3682 } else {
3683 as_warn("Long branch offset to extern symbol not supported.");
3684 }
3685 } else { /* Symbol is still undefined. Make it simple */
3686 fix_new(fragP, (int)(fragP->fr_fix), 4, fragP->fr_symbol,
3687 (symbolS *)0, fragP->fr_offset+4, 1, NO_RELOC);
3688 fragP->fr_fix+=4;
3689 fragP->fr_opcode[1]=0xff;
3690 frag_wane(fragP);
3691 break;
3692 }
3693
3694 break;
3695 } /* case TAB(BRANCH,SZ_UNDEF) */
3696
3697 case TAB(FBRANCH,SZ_UNDEF): {
3698 if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) {
3699 fragP->fr_subtype = TAB(FBRANCH,SHORT);
3700 fragP->fr_var += 2;
3701 } else {
3702 fragP->fr_subtype = TAB(FBRANCH,LONG);
3703 fragP->fr_var += 4;
3704 }
3705 break;
3706 } /* TAB(FBRANCH,SZ_UNDEF) */
3707
3708 case TAB(PCREL,SZ_UNDEF): {
3709 if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) {
3710 fragP->fr_subtype = TAB(PCREL,SHORT);
3711 fragP->fr_var += 2;
3712 } else {
3713 fragP->fr_subtype = TAB(PCREL,LONG);
3714 fragP->fr_var += 4;
3715 }
3716 break;
3717 } /* TAB(PCREL,SZ_UNDEF) */
3718
3719 case TAB(BCC68000,SZ_UNDEF): {
3720 if((fragP->fr_symbol != NULL)
3721 && S_GET_SEGMENT(fragP->fr_symbol) == segment) {
3722 fragP->fr_subtype=TAB(BCC68000,BYTE);
3723 break;
3724 }
3725 /* only Bcc 68000 instructions can come here */
3726 /* change bcc into b!cc/jmp absl long */
3727 fragP->fr_opcode[0] ^= 0x01; /* invert bcc */
3728 if(flagseen['l']) {
3729 fragP->fr_opcode[1] = 0x04; /* branch offset = 6 */
3730 /* JF: these were fr_opcode[2,3] */
3731 buffer_address[0] = 0x4e; /* put in jmp long (0x4ef9) */
3732 buffer_address[1] = 0xf8;
3733 fragP->fr_fix += 2; /* account for jmp instruction */
3734 subseg_change(SEG_TEXT,0);
3735 fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0,
3736 fragP->fr_offset, 0, NO_RELOC);
3737 fragP->fr_fix += 2;
3738 } else {
3739 fragP->fr_opcode[1] = 0x06; /* branch offset = 6 */
3740 /* JF: these were fr_opcode[2,3] */
3741 buffer_address[2] = 0x4e; /* put in jmp long (0x4ef9) */
3742 buffer_address[3] = 0xf9;
3743 fragP->fr_fix += 2; /* account for jmp instruction */
3744 subseg_change(SEG_TEXT,0);
3745 fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
3746 fragP->fr_offset, 0, NO_RELOC);
3747 fragP->fr_fix += 4;
3748 }
3749 frag_wane(fragP);
3750 break;
3751 } /* case TAB(BCC68000,SZ_UNDEF) */
3752
3753 case TAB(DBCC,SZ_UNDEF): {
3754 if (fragP->fr_symbol != NULL && S_GET_SEGMENT(fragP->fr_symbol) == segment) {
3755 fragP->fr_subtype=TAB(DBCC,SHORT);
3756 fragP->fr_var+=2;
3757 break;
3758 }
3759 /* only DBcc 68000 instructions can come here */
3760 /* change dbcc into dbcc/jmp absl long */
3761 /* JF: these used to be fr_opcode[2-4], which is wrong. */
3762 buffer_address[0] = 0x00; /* branch offset = 4 */
3763 buffer_address[1] = 0x04;
3764 buffer_address[2] = 0x60; /* put in bra pc + ... */
3765
3766 if(flagseen['l']) {
3767 /* JF: these were fr_opcode[5-7] */
3768 buffer_address[3] = 0x04; /* plus 4 */
3769 buffer_address[4] = 0x4e;/* Put in Jump Word */
3770 buffer_address[5] = 0xf8;
3771 fragP->fr_fix += 6; /* account for bra/jmp instruction */
3772 subseg_change(SEG_TEXT,0);
3773 fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0,
3774 fragP->fr_offset, 0, NO_RELOC);
3775 fragP->fr_fix += 2;
3776 } else {
3777 /* JF: these were fr_opcode[5-7] */
3778 buffer_address[3] = 0x06; /* Plus 6 */
3779 buffer_address[4] = 0x4e; /* put in jmp long (0x4ef9) */
3780 buffer_address[5] = 0xf9;
3781 fragP->fr_fix += 6; /* account for bra/jmp instruction */
3782 subseg_change(SEG_TEXT,0);
3783 fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
3784 fragP->fr_offset, 0, NO_RELOC);
3785 fragP->fr_fix += 4;
3786 }
3787
3788 frag_wane(fragP);
3789 break;
3790 } /* case TAB(DBCC,SZ_UNDEF) */
3791
3792 case TAB(PCLEA,SZ_UNDEF): {
3793 if ((S_GET_SEGMENT(fragP->fr_symbol))==segment || flagseen['l']) {
3794 fragP->fr_subtype=TAB(PCLEA,SHORT);
3795 fragP->fr_var+=2;
3796 } else {
3797 fragP->fr_subtype=TAB(PCLEA,LONG);
3798 fragP->fr_var+=6;
3799 }
3800 break;
3801 } /* TAB(PCLEA,SZ_UNDEF) */
3802
3803 default:
3804 break;
3805
3806 } /* switch on subtype looking for SZ_UNDEF's. */
3807
3808 /* now that SZ_UNDEF are taken care of, check others */
3809 switch(fragP->fr_subtype) {
3810 case TAB(BCC68000,BYTE):
3811 case TAB(BRANCH,BYTE):
3812 /* We can't do a short jump to the next instruction,
3813 so we force word mode. */
3814 if (fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 &&
3815 fragP->fr_symbol->sy_frag==fragP->fr_next) {
3816 fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT);
3817 fragP->fr_var+=2;
3818 }
3819 break;
3820 default:
3821 break;
3822 }
3823 return fragP->fr_var + fragP->fr_fix - old_fix;
3824 }
3825
3826 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
3827 /* the bit-field entries in the relocation_info struct plays hell
3828 with the byte-order problems of cross-assembly. So as a hack,
3829 I added this mach. dependent ri twiddler. Ugly, but it gets
3830 you there. -KWK */
3831 /* on m68k: first 4 bytes are normal unsigned long, next three bytes
3832 are symbolnum, most sig. byte first. Last byte is broken up with
3833 bit 7 as pcrel, bits 6 & 5 as length, bit 4 as pcrel, and the lower
3834 nibble as nuthin. (on Sun 3 at least) */
3835 /* Translate the internal relocation information into target-specific
3836 format. */
3837 #ifdef comment
3838 void
3839 md_ri_to_chars(the_bytes, ri)
3840 char *the_bytes;
3841 struct reloc_info_generic *ri;
3842 {
3843 /* this is easy */
3844 md_number_to_chars(the_bytes, ri->r_address, 4);
3845 /* now the fun stuff */
3846 the_bytes[4] = (ri->r_symbolnum >> 16) & 0x0ff;
3847 the_bytes[5] = (ri->r_symbolnum >> 8) & 0x0ff;
3848 the_bytes[6] = ri->r_symbolnum & 0x0ff;
3849 the_bytes[7] = (((ri->r_pcrel << 7) & 0x80) | ((ri->r_length << 5) & 0x60) |
3850 ((ri->r_extern << 4) & 0x10));
3851 }
3852 #endif /* comment */
3853
3854 void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
3855 char *where;
3856 fixS *fixP;
3857 relax_addressT segment_address_in_file;
3858 {
3859 /*
3860 * In: length of relocation (or of address) in chars: 1, 2 or 4.
3861 * Out: GNU LD relocation length code: 0, 1, or 2.
3862 */
3863
3864 static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 };
3865
3866 long r_extern;
3867 long r_symbolnum;
3868
3869 /* this is easy */
3870 md_number_to_chars(where,
3871 fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
3872 4);
3873
3874 /* now the fun stuff */
3875 if (S_GET_TYPE(fixP->fx_addsy) == N_UNDF) {
3876 r_extern = 1;
3877 r_symbolnum = fixP->fx_addsy->sy_number;
3878 } else {
3879 r_extern = 0;
3880 r_symbolnum = S_GET_TYPE(fixP->fx_addsy);
3881 }
3882
3883 where[4] = (r_symbolnum >> 16) & 0x0ff;
3884 where[5] = (r_symbolnum >> 8) & 0x0ff;
3885 where[6] = r_symbolnum & 0x0ff;
3886 where[7] = (((fixP->fx_pcrel << 7) & 0x80) | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) |
3887 ((r_extern << 4) & 0x10));
3888
3889 return;
3890 } /* tc_aout_fix_to_chars() */
3891
3892 #endif /* OBJ_AOUT or OBJ_BOUT */
3893
3894 #ifndef WORKING_DOT_WORD
3895 const int md_short_jump_size = 4;
3896 const int md_long_jump_size = 6;
3897
3898 void
3899 md_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol)
3900 char *ptr;
3901 long from_addr,
3902 to_addr;
3903 fragS *frag;
3904 symbolS *to_symbol;
3905 {
3906 long offset;
3907
3908 offset = to_addr - (from_addr+2);
3909
3910 md_number_to_chars(ptr ,(long)0x6000,2);
3911 md_number_to_chars(ptr+2,(long)offset,2);
3912 }
3913
3914 void
3915 md_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol)
3916 char *ptr;
3917 long from_addr,
3918 to_addr;
3919 fragS *frag;
3920 symbolS *to_symbol;
3921 {
3922 long offset;
3923
3924 if (cpu_of_arch(current_architecture) < m68020) {
3925 offset=to_addr-S_GET_VALUE(to_symbol);
3926 md_number_to_chars(ptr ,(long)0x4EF9,2);
3927 md_number_to_chars(ptr+2,(long)offset,4);
3928 fix_new(frag,(ptr+2)-frag->fr_literal,4,to_symbol,(symbolS *)0,(long)0,0,
3929 NO_RELOC);
3930 } else {
3931 offset=to_addr - (from_addr+2);
3932 md_number_to_chars(ptr ,(long)0x60ff,2);
3933 md_number_to_chars(ptr+2,(long)offset,4);
3934 }
3935 }
3936
3937 #endif
3938 /* Different values of OK tell what its OK to return. Things that aren't OK are an error (what a shock, no?)
3939
3940 0: Everything is OK
3941 10: Absolute 1:8 only
3942 20: Absolute 0:7 only
3943 30: absolute 0:15 only
3944 40: Absolute 0:31 only
3945 50: absolute 0:127 only
3946 55: absolute -64:63 only
3947 60: absolute -128:127 only
3948 70: absolute 0:4095 only
3949 80: No bignums
3950
3951 */
3952
3953 static int get_num(exp,ok)
3954 struct m68k_exp *exp;
3955 int ok;
3956 {
3957 #ifdef TEST2
3958 long l = 0;
3959
3960 if(!exp->e_beg)
3961 return 0;
3962 if(*exp->e_beg=='0') {
3963 if(exp->e_beg[1]=='x')
3964 sscanf(exp->e_beg+2,"%x",&l);
3965 else
3966 sscanf(exp->e_beg+1,"%O",&l);
3967 return l;
3968 }
3969 return atol(exp->e_beg);
3970 #else
3971 char *save_in;
3972 char c_save;
3973
3974 if(!exp) {
3975 /* Can't do anything */
3976 return 0;
3977 }
3978 if(!exp->e_beg || !exp->e_end) {
3979 seg(exp)=SEG_ABSOLUTE;
3980 adds(exp)=0;
3981 subs(exp)=0;
3982 offs(exp)= (ok==10) ? 1 : 0;
3983 as_warn("Null expression defaults to %ld",offs(exp));
3984 return 0;
3985 }
3986
3987 exp->e_siz=0;
3988 if(/* ok!=80 && */exp->e_end[-1]==SIZER && (exp->e_end-exp->e_beg)>=2) {
3989 switch(exp->e_end[0]) {
3990 case 's':
3991 case 'S':
3992 case 'b':
3993 case 'B':
3994 exp->e_siz=1;
3995 break;
3996 case 'w':
3997 case 'W':
3998 exp->e_siz=2;
3999 break;
4000 case 'l':
4001 case 'L':
4002 exp->e_siz=3;
4003 break;
4004 default:
4005 as_bad("Unknown size for expression \"%c\"",exp->e_end[0]);
4006 }
4007 exp->e_end-=2;
4008 }
4009 c_save=exp->e_end[1];
4010 exp->e_end[1]='\0';
4011 save_in=input_line_pointer;
4012 input_line_pointer=exp->e_beg;
4013 switch(expression(&(exp->e_exp))) {
4014 case SEG_PASS1:
4015 seg(exp)=SEG_ABSOLUTE;
4016 adds(exp)=0;
4017 subs(exp)=0;
4018 offs(exp)= (ok==10) ? 1 : 0;
4019 as_warn("Unknown expression: '%s' defaulting to %d",exp->e_beg,offs(exp));
4020 break;
4021
4022 case SEG_ABSENT:
4023 /* Do the same thing the VAX asm does */
4024 seg(exp)=SEG_ABSOLUTE;
4025 adds(exp)=0;
4026 subs(exp)=0;
4027 offs(exp)=0;
4028 if(ok==10) {
4029 as_warn("expression out of range: defaulting to 1");
4030 offs(exp)=1;
4031 }
4032 break;
4033 case SEG_ABSOLUTE:
4034 switch(ok) {
4035 case 10:
4036 if(offs(exp)<1 || offs(exp)>8) {
4037 as_warn("expression out of range: defaulting to 1");
4038 offs(exp)=1;
4039 }
4040 break;
4041 case 20:
4042 if(offs(exp)<0 || offs(exp)>7)
4043 goto outrange;
4044 break;
4045 case 30:
4046 if(offs(exp)<0 || offs(exp)>15)
4047 goto outrange;
4048 break;
4049 case 40:
4050 if(offs(exp)<0 || offs(exp)>32)
4051 goto outrange;
4052 break;
4053 case 50:
4054 if(offs(exp)<0 || offs(exp)>127)
4055 goto outrange;
4056 break;
4057 case 55:
4058 if(offs(exp)<-64 || offs(exp)>63)
4059 goto outrange;
4060 break;
4061 case 60:
4062 if(offs(exp)<-128 || offs(exp)>127)
4063 goto outrange;
4064 break;
4065 case 70:
4066 if(offs(exp)<0 || offs(exp)>4095) {
4067 outrange:
4068 as_warn("expression out of range: defaulting to 0");
4069 offs(exp)=0;
4070 }
4071 break;
4072 default:
4073 break;
4074 }
4075 break;
4076 case SEG_TEXT:
4077 case SEG_DATA:
4078 case SEG_BSS:
4079 case SEG_UNKNOWN:
4080 case SEG_DIFFERENCE:
4081 if(ok>=10 && ok<=70) {
4082 seg(exp)=SEG_ABSOLUTE;
4083 adds(exp)=0;
4084 subs(exp)=0;
4085 offs(exp)= (ok==10) ? 1 : 0;
4086 as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp));
4087 }
4088 break;
4089 case SEG_BIG:
4090 if(ok==80 && offs(exp)<0) { /* HACK! Turn it into a long */
4091 LITTLENUM_TYPE words[6];
4092
4093 gen_to_words(words,2,8L);/* These numbers are magic! */
4094 seg(exp)=SEG_ABSOLUTE;
4095 adds(exp)=0;
4096 subs(exp)=0;
4097 offs(exp)=words[1]|(words[0]<<16);
4098 } else if(ok!=0) {
4099 seg(exp)=SEG_ABSOLUTE;
4100 adds(exp)=0;
4101 subs(exp)=0;
4102 offs(exp)= (ok==10) ? 1 : 0;
4103 as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp));
4104 }
4105 break;
4106 default:
4107 as_fatal("failed sanity check.");
4108 }
4109 if(input_line_pointer!=exp->e_end+1)
4110 as_bad("Ignoring junk after expression");
4111 exp->e_end[1]=c_save;
4112 input_line_pointer=save_in;
4113 if(exp->e_siz) {
4114 switch(exp->e_siz) {
4115 case 1:
4116 if(!isbyte(offs(exp)))
4117 as_warn("expression doesn't fit in BYTE");
4118 break;
4119 case 2:
4120 if(!isword(offs(exp)))
4121 as_warn("expression doesn't fit in WORD");
4122 break;
4123 }
4124 }
4125 return offs(exp);
4126 #endif
4127 } /* get_num() */
4128
4129 /* These are the back-ends for the various machine dependent pseudo-ops. */
4130 void demand_empty_rest_of_line(); /* Hate those extra verbose names */
4131
4132 static void s_data1() {
4133 subseg_new(SEG_DATA,1);
4134 demand_empty_rest_of_line();
4135 } /* s_data1() */
4136
4137 static void s_data2() {
4138 subseg_new(SEG_DATA,2);
4139 demand_empty_rest_of_line();
4140 } /* s_data2() */
4141
4142 static void s_bss() {
4143 /* We don't support putting frags in the BSS segment, but we
4144 can put them into initialized data for now... */
4145 subseg_new(SEG_DATA,255); /* FIXME-SOON */
4146 demand_empty_rest_of_line();
4147 } /* s_bss() */
4148
4149 static void s_even() {
4150 register int temp;
4151 register long temp_fill;
4152
4153 temp = 1; /* JF should be 2? */
4154 temp_fill = get_absolute_expression ();
4155 if ( ! need_pass_2 ) /* Never make frag if expect extra pass. */
4156 frag_align (temp, (int)temp_fill);
4157 demand_empty_rest_of_line();
4158 } /* s_even() */
4159
4160 static void s_proc() {
4161 demand_empty_rest_of_line();
4162 } /* s_proc() */
4163
4164 /* s_space is defined in read.c .skip is simply an alias to it. */
4165
4166 /*
4167 * md_parse_option
4168 * Invocation line includes a switch not recognized by the base assembler.
4169 * See if it's a processor-specific option. These are:
4170 *
4171 * -[A]m[c]68000, -[A]m[c]68008, -[A]m[c]68010, -[A]m[c]68020, -[A]m[c]68030, -[A]m[c]68040
4172 * -[A]m[c]68881, -[A]m[c]68882, -[A]m[c]68851
4173 * Select the architecture. Instructions or features not
4174 * supported by the selected architecture cause fatal
4175 * errors. More than one may be specified. The default is
4176 * -m68020 -m68851 -m68881. Note that -m68008 is a synonym
4177 * for -m68000, and -m68882 is a synonym for -m68881.
4178 *
4179 * MAYBE_FLOAT_TOO is defined below so that specifying a processor type
4180 * (e.g. m68020) also requests that float instructions be included. This
4181 * is the default setup, mostly to avoid hassling users. A better
4182 * rearrangement of this structure would be to add an option to DENY
4183 * floating point opcodes, for people who want to really know there's none
4184 * of that funny floaty stuff going on. FIXME-later.
4185 */
4186 #ifndef MAYBE_FLOAT_TOO
4187 #define MAYBE_FLOAT_TOO m68881
4188 #endif
4189
4190 int md_parse_option(argP,cntP,vecP)
4191 char **argP;
4192 int *cntP;
4193 char ***vecP;
4194 {
4195 switch(**argP) {
4196 case 'l': /* -l means keep external to 2 bit offset
4197 rather than 16 bit one */
4198 break;
4199
4200 case 'S': /* -S means that jbsr's always turn into jsr's. */
4201 break;
4202
4203 case 'A':
4204 (*argP)++;
4205 /* intentional fall-through */
4206 case 'm':
4207 (*argP)++;
4208
4209 if (**argP=='c') {
4210 (*argP)++;
4211 } /* allow an optional "c" */
4212
4213 if (!strcmp(*argP, "68000")
4214 || !strcmp(*argP, "68008")) {
4215 current_architecture |= m68000;
4216 } else if (!strcmp(*argP, "68010")) {
4217 #ifdef TE_SUN
4218 omagic= 1<<16|OMAGIC;
4219 #endif
4220 current_architecture |= m68010;
4221
4222 } else if (!strcmp(*argP, "68020")) {
4223 current_architecture |= m68020 | MAYBE_FLOAT_TOO;
4224
4225 } else if (!strcmp(*argP, "68030")) {
4226 current_architecture |= m68030 | MAYBE_FLOAT_TOO;
4227
4228 } else if (!strcmp(*argP, "68040")) {
4229 current_architecture |= m68040 | MAYBE_FLOAT_TOO;
4230
4231 #ifndef NO_68881
4232 } else if (!strcmp(*argP, "68881")) {
4233 current_architecture |= m68881;
4234
4235 } else if (!strcmp(*argP, "68882")) {
4236 current_architecture |= m68882;
4237
4238 #endif /* NO_68881 */
4239 #ifndef NO_68851
4240 } else if (!strcmp(*argP,"68851")) {
4241 current_architecture |= m68851;
4242
4243 #endif /* NO_68851 */
4244 } else {
4245 as_warn("Unknown architecture, \"%s\". option ignored", *argP);
4246 } /* switch on architecture */
4247
4248 while(**argP) (*argP)++;
4249
4250 break;
4251
4252 case 'p':
4253 if (!strcmp(*argP,"pic")) {
4254 (*argP) += 3;
4255 break; /* -pic, Position Independent Code */
4256 } else {
4257 return(0);
4258 } /* pic or not */
4259
4260 default:
4261 return 0;
4262 }
4263 return 1;
4264 }
4265
4266
4267 #ifdef TEST2
4268
4269 /* TEST2: Test md_assemble() */
4270 /* Warning, this routine probably doesn't work anymore */
4271
4272 main()
4273 {
4274 struct m68k_it the_ins;
4275 char buf[120];
4276 char *cp;
4277 int n;
4278
4279 m68k_ip_begin();
4280 for(;;) {
4281 if(!gets(buf) || !*buf)
4282 break;
4283 if(buf[0]=='|' || buf[1]=='.')
4284 continue;
4285 for(cp=buf;*cp;cp++)
4286 if(*cp=='\t')
4287 *cp=' ';
4288 if(is_label(buf))
4289 continue;
4290 memset(&the_ins, '\0', sizeof(the_ins));
4291 m68k_ip(&the_ins,buf);
4292 if(the_ins.error) {
4293 printf("Error %s in %s\n",the_ins.error,buf);
4294 } else {
4295 printf("Opcode(%d.%s): ",the_ins.numo,the_ins.args);
4296 for(n=0;n<the_ins.numo;n++)
4297 printf(" 0x%x",the_ins.opcode[n]&0xffff);
4298 printf(" ");
4299 print_the_insn(&the_ins.opcode[0],stdout);
4300 (void)putchar('\n');
4301 }
4302 for(n=0;n<strlen(the_ins.args)/2;n++) {
4303 if(the_ins.operands[n].error) {
4304 printf("op%d Error %s in %s\n",n,the_ins.operands[n].error,buf);
4305 continue;
4306 }
4307 printf("mode %d, reg %d, ",the_ins.operands[n].mode,the_ins.operands[n].reg);
4308 if(the_ins.operands[n].b_const)
4309 printf("Constant: '%.*s', ",1+the_ins.operands[n].e_const-the_ins.operands[n].b_const,the_ins.operands[n].b_const);
4310 printf("ireg %d, isiz %d, imul %d, ",the_ins.operands[n].ireg,the_ins.operands[n].isiz,the_ins.operands[n].imul);
4311 if(the_ins.operands[n].b_iadd)
4312 printf("Iadd: '%.*s',",1+the_ins.operands[n].e_iadd-the_ins.operands[n].b_iadd,the_ins.operands[n].b_iadd);
4313 (void)putchar('\n');
4314 }
4315 }
4316 m68k_ip_end();
4317 return 0;
4318 }
4319
4320 is_label(str)
4321 char *str;
4322 {
4323 while(ISSPACE(*str))
4324 str++;
4325 while(*str && !ISSPACE(*str))
4326 str++;
4327 if(str[-1]==':' || str[1]=='=')
4328 return 1;
4329 return 0;
4330 }
4331
4332 #endif
4333
4334 /* Possible states for relaxation:
4335
4336 0 0 branch offset byte (bra, etc)
4337 0 1 word
4338 0 2 long
4339
4340 1 0 indexed offsets byte a0@(32,d4:w:1) etc
4341 1 1 word
4342 1 2 long
4343
4344 2 0 two-offset index word-word a0@(32,d4)@(45) etc
4345 2 1 word-long
4346 2 2 long-word
4347 2 3 long-long
4348
4349 */
4350
4351
4352
4353 #ifdef DONTDEF
4354 abort()
4355 {
4356 printf("ABORT!\n");
4357 exit(12);
4358 }
4359
4360 print_frags()
4361 {
4362 fragS *fragP;
4363 extern fragS *text_frag_root;
4364
4365 for(fragP=text_frag_root;fragP;fragP=fragP->fr_next) {
4366 printf("addr %lu next 0x%x fix %ld var %ld symbol 0x%x offset %ld\n",
4367 fragP->fr_address,fragP->fr_next,fragP->fr_fix,fragP->fr_var,fragP->fr_symbol,fragP->fr_offset);
4368 printf("opcode 0x%x type %d subtype %d\n\n",fragP->fr_opcode,fragP->fr_type,fragP->fr_subtype);
4369 }
4370 fflush(stdout);
4371 return 0;
4372 }
4373 #endif
4374
4375 #ifdef DONTDEF
4376 /*VARARGS1*/
4377 panic(format,args)
4378 char *format;
4379 {
4380 fputs("Internal error:",stderr);
4381 _doprnt(format,&args,stderr);
4382 (void)putc('\n',stderr);
4383 as_where();
4384 abort();
4385 }
4386 #endif
4387
4388 /* We have no need to default values of symbols. */
4389
4390 /* ARGSUSED */
4391 symbolS *
4392 md_undefined_symbol (name)
4393 char *name;
4394 {
4395 return 0;
4396 }
4397
4398 /* Parse an operand that is machine-specific.
4399 We just return without modifying the expression if we have nothing
4400 to do. */
4401
4402 /* ARGSUSED */
4403 void
4404 md_operand (expressionP)
4405 expressionS *expressionP;
4406 {
4407 }
4408
4409 /* Round up a section size to the appropriate boundary. */
4410 long
4411 md_section_align (segment, size)
4412 segT segment;
4413 long size;
4414 {
4415 return size; /* Byte alignment is fine */
4416 }
4417
4418 /* Exactly what point is a PC-relative offset relative TO?
4419 On the 68k, they're relative to the address of the offset, plus
4420 its size. (??? Is this right? FIXME-SOON!) */
4421 long
4422 md_pcrel_from (fixP)
4423 fixS *fixP;
4424 {
4425 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
4426 }
4427
4428 #ifdef MRI
4429 void s_ds(size)
4430 {
4431 unsigned int fill = get_absolute_expression() * size;
4432 char *p = frag_var (rs_fill, fill, fill, (relax_substateT)0, (symbolS *)0,
4433 1, (char *)0);
4434 * p = 0;
4435 demand_empty_rest_of_line();
4436 }
4437
4438 void s_dc(size)
4439 {
4440
4441 cons(size);
4442
4443
4444 }
4445
4446 void s_dcb(size)
4447 {
4448 int repeat = get_absolute_expression();
4449 int fill;
4450
4451 if (*input_line_pointer == ',')
4452 {
4453 char *p;
4454 input_line_pointer++;
4455
4456 fill = get_absolute_expression();
4457 p = frag_var(rs_fill,
4458 size,
4459 size,
4460 (relax_substateT)0,
4461 (symbolS *)0,
4462 repeat,
4463 0);
4464 md_number_to_chars(p, fill, size);
4465 }
4466 demand_empty_rest_of_line();
4467
4468
4469 }
4470
4471 void s_chip()
4472 {
4473 unsigned int target = get_absolute_expression();
4474 #define MACHINE_MASK (m68000 | m68008 | m68010 | m68020 | m68040)
4475 switch (target)
4476 {
4477 case 68000:
4478 case 68008:
4479 current_architecture = (current_architecture & ~ MACHINE_MASK) | m68000;
4480 break;
4481 case 68010:
4482 current_architecture = (current_architecture & ~ MACHINE_MASK) | m68010;
4483 break;
4484 case 68020:
4485 current_architecture = (current_architecture & ~ MACHINE_MASK) | m68020;
4486 break;
4487 case 68030:
4488 current_architecture = (current_architecture & ~ MACHINE_MASK) | m68030;
4489 break;
4490 case 68040:
4491 current_architecture = (current_architecture & ~ MACHINE_MASK) | m68040;
4492 break;
4493 case 68881:
4494 current_architecture |= m68881;
4495 break;
4496 case 68882:
4497 current_architecture |= m68882;
4498 break;
4499 case 68851:
4500 current_architecture |= m68851;
4501 break;
4502
4503 default:
4504 as_bad("Unrecognised CHIP %d\n", target);
4505
4506 }
4507 demand_empty_rest_of_line();
4508 }
4509
4510 #endif
4511
4512 /*
4513 * Local Variables:
4514 * comment-column: 0
4515 * fill-column: 131
4516 * End:
4517 */
4518
4519 /* end of tc-m68kmote.c */
This page took 0.11818 seconds and 5 git commands to generate.