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