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