1 /* tc-m68kmote.c All the m68020 specific stuff in one convenient, huge,
2 slow to compile, easy to find file.
3 Copyright (C) 1987, 1991, 1992 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
28 /* note that this file includes real declarations and thus can only be included by one source file per executable. */
29 #include "opcode/m68k.h"
31 /* This variable contains the value to write out at the beginning of
32 the a.out file. The 2<<16 means that this is a 68020 file instead
33 of an old-style 68000 file */
35 long omagic
= 2<<16|OMAGIC
; /* Magic byte for header file */
40 /* This array holds the chars that always start a comment. If the
41 pre-processor is disabled, these aren't very useful */
42 const char comment_chars
[] = "|";
44 /* This array holds the chars that only start a comment at the beginning of
45 a line. If the line seems to have the form '# 123 filename'
46 .line and .file directives will appear in the pre-processed output */
47 /* Note that input_file.c hand checks for '#' at the beginning of the
48 first line of the input file. This is because the compiler outputs
49 #NO_APP at the beginning of its output. */
50 /* Also note that comments like this one will always work. */
52 const char line_comment_chars
[] = "*";
54 const char line_comment_chars
[] = "#";
59 /* Chars that can be used to separate mant from exp in floating point nums */
60 const char EXP_CHARS
[] = "eE";
62 /* Chars that mean this number is a floating point constant */
66 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
68 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
69 changed in read.c . Ideally it shouldn't have to know about it at all,
70 but nothing is ideal around here.
73 int md_reloc_size
= 8; /* Size of relocation record */
75 /* Its an arbitrary name: This means I don't approve of it */
76 /* See flames below */
77 static struct obstack robyn
;
79 #define TAB(x,y) (((x)<<2)+(y))
80 #define TABTYPE(xy) ((xy) >> 2)
93 /* Operands we can parse: (And associated modes)
99 reg: address or data register
100 areg: address register
101 apc: address register, PC, ZPC or empty string
102 num: 16 or 32 bit num
104 sz: w or l if omitted, l assumed
105 scale: 1 2 4 or 8 if omitted, 1 assumed
107 7.4 IMMED #num --> NUM
108 0.? DREG dreg --> dreg
109 1.? AREG areg --> areg
110 2.? AINDR areg@ --> *(areg)
111 3.? AINC areg@+ --> *(areg++)
112 4.? ADEC areg@- --> *(--areg)
113 5.? AOFF apc@(numw) --> *(apc+numw) -- empty string and ZPC not allowed here
114 6.? AINDX apc@(num,reg:sz:scale) --> *(apc+num+reg*scale)
115 6.? AINDX apc@(reg:sz:scale) --> same, with num=0
116 6.? APODX apc@(num)@(num2,reg:sz:scale) --> *(*(apc+num)+num2+reg*scale)
117 6.? APODX apc@(num)@(reg:sz:scale) --> same, with num2=0
118 6.? AMIND apc@(num)@(num2) --> *(*(apc+num)+num2) (previous mode without an index reg)
119 6.? APRDX apc@(num,reg:sz:scale)@(num2) --> *(*(apc+num+reg*scale)+num2)
120 6.? APRDX apc@(reg:sz:scale)@(num2) --> same, with num=0
121 7.0 ABSL num:sz --> *(num)
122 num --> *(num) (sz L assumed)
123 *** MSCR otherreg --> Magic
125 5.? AOFF apc@(num) --> *(apc+num) -- empty string and ZPC not allowed here still
126 ?.? DINDR dreg@ --> (dreg) -- cas2 only
136 a1@(5,d2:w:1) @(45,d6:l:4)
141 #name@(numw) -->turn into PC rel mode
142 apc@(num8,reg:sz:scale) --> *(apc+num8+reg*scale)
169 short e_siz
; /* 0== default 1==short/byte 2==word 3==long */
172 /* DATA and ADDR have to be contiguous, so that reg-DATA gives 0-7==data reg,
173 8-15==addr reg for operands that take both types */
176 DATA
= 1, /* 1- 8 == data registers 0-7 */
196 /* Note that COPNUM==processor #1 -- COPNUM+7==#8, which stores as 000 */
201 FPREG
, /* Eight FP registers */
210 COPNUM
= (FPREG
+8), /* Co-processor #1-#8 */
219 PC
, /* Program counter */
220 ZPC
, /* Hack for Program space, but 0 addressing */
222 CCR
, /* Condition code Reg */
224 /* These have to be in order for the movec instruction to work. */
225 USP
, /* User Stack Pointer */
226 ISP
, /* Interrupt stack pointer */
241 /* end of movec ordering constraints */
274 IC
, /* instruction cache token */
275 DC
, /* data cache token */
276 NC
, /* no cache token */
277 BC
, /* both caches token */
281 /* Internal form of an operand. */
283 char *error
; /* Couldn't parse it */
284 enum operand_type mode
; /* What mode this instruction is in. */
285 enum _register reg
; /* Base register */
286 struct m68k_exp
*con1
;
287 int ireg
; /* Index register */
288 int isiz
; /* 0==unspec 1==byte(?) 2==short 3==long */
289 int imul
; /* Multipy ireg by this (1,2,4,or 8) */
290 struct m68k_exp
*con2
;
293 /* internal form of a 68020 instruction */
296 char *args
; /* list of opcode info */
299 int numo
; /* Number of shorts in opcode */
302 struct m68k_op operands
[6];
304 int nexp
; /* number of exprs in use */
305 struct m68k_exp exprs
[4];
307 int nfrag
; /* Number of frags we have to produce */
309 int fragoff
; /* Where in the current opcode[] the frag ends */
315 int nrel
; /* Num of reloc strucs in use */
323 } reloc
[5]; /* Five is enough??? */
326 #define cpu_of_arch(x) ((x) & m68000up)
327 #define float_of_arch(x) ((x) & mfloat)
328 #define mmu_of_arch(x) ((x) & mmmu)
330 static struct m68k_it the_ins
; /* the instruction being assembled */
332 /* Macros for adding things to the m68k_it struct */
334 #define addword(w) the_ins.opcode[the_ins.numo++]=(w)
336 /* Like addword, but goes BEFORE general operands */
337 #define insop(w) {int z;\
338 for(z=the_ins.numo;z>opcode->m_codenum;--z)\
339 the_ins.opcode[z]=the_ins.opcode[z-1];\
340 for(z=0;z<the_ins.nrel;z++)\
341 the_ins.reloc[z].n+=2;\
342 the_ins.opcode[opcode->m_codenum]=w;\
347 #define add_exp(beg,end) (\
348 the_ins.exprs[the_ins.nexp].e_beg=beg,\
349 the_ins.exprs[the_ins.nexp].e_end=end,\
350 &the_ins.exprs[the_ins.nexp++]\
354 /* The numo+1 kludge is so we can hit the low order byte of the prev word. Blecch*/
355 #define add_fix(width,exp,pc_rel) {\
356 the_ins.reloc[the_ins.nrel].n= ((width)=='B') ? (the_ins.numo*2-1) : \
357 (((width)=='b') ? ((the_ins.numo-1)*2) : (the_ins.numo*2));\
358 the_ins.reloc[the_ins.nrel].add=adds((exp));\
359 the_ins.reloc[the_ins.nrel].sub=subs((exp));\
360 the_ins.reloc[the_ins.nrel].off=offs((exp));\
361 the_ins.reloc[the_ins.nrel].wid=width;\
362 the_ins.reloc[the_ins.nrel++].pcrel=pc_rel;\
365 #define add_frag(add,off,type) {\
366 the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;\
367 the_ins.fragb[the_ins.nfrag].fadd=add;\
368 the_ins.fragb[the_ins.nfrag].foff=off;\
369 the_ins.fragb[the_ins.nfrag++].fragty=type;\
372 #define isvar(exp) ((exp) && (adds(exp) || subs(exp)))
374 #define seg(exp) ((exp)->e_exp.X_seg)
375 #define adds(exp) ((exp)->e_exp.X_add_symbol)
376 #define subs(exp) ((exp)->e_exp.X_subtract_symbol)
377 #define offs(exp) ((exp)->e_exp.X_add_number)
382 unsigned long m_opcode
;
385 enum m68k_architecture m_arch
;
386 struct m68k_incant
*m_next
;
389 #define getone(x) ((((x)->m_opcode)>>16)&0xffff)
390 #define gettwo(x) (((x)->m_opcode)&0xffff)
395 static char *crack_operand(char *str
, struct m68k_op
*opP
);
396 static int get_num(struct m68k_exp
*exp
, int ok
);
397 static int get_regs(int i
, char *str
, struct m68k_op
*opP
);
398 static int reverse_16_bits(int in
);
399 static int reverse_8_bits(int in
);
400 static int try_index(char **s
, struct m68k_op
*opP
);
401 static void install_gen_operand(int mode
, int val
);
402 static void install_operand(int mode
, int val
);
403 static void s_bss(void);
404 static void s_data1(void);
405 static void s_data2(void);
406 static void s_even(void);
407 static void s_proc(void);
409 #else /* not __STDC__ */
411 static char *crack_operand();
412 static int get_num();
413 static int get_regs();
414 static int reverse_16_bits();
415 static int reverse_8_bits();
416 static int try_index();
417 static void install_gen_operand();
418 static void install_operand();
420 static void s_data1();
421 static void s_data2();
422 static void s_even();
423 static void s_proc();
425 #endif /* not __STDC__ */
427 static enum m68k_architecture current_architecture
= _m68k_undef
;
429 /* BCC68000 is for patching in an extra jmp instruction for long offsets
430 on the 68000. The 68000 doesn't support long branches with branchs */
432 /* This table desribes how you change sizes for the various types of variable
433 size expressions. This version only supports two kinds. */
435 /* Note that calls to frag_var need to specify the maximum expansion needed */
436 /* This is currently 10 bytes for DBCC */
439 How far Forward this mode will reach:
440 How far Backward this mode will reach:
441 How many bytes this mode will add to the size of the frag
442 Which mode to go to if the offset won't fit in this one
446 { 1, 1, 0, 0 }, /* First entries aren't used */
447 { 1, 1, 0, 0 }, /* For no good reason except */
448 { 1, 1, 0, 0 }, /* that the VAX doesn't either */
451 { (127), (-128), 0, TAB(BRANCH
,SHORT
)},
452 { (32767), (-32768), 2, TAB(BRANCH
,LONG
) },
456 { 1, 1, 0, 0 }, /* FBRANCH doesn't come BYTE */
457 { (32767), (-32768), 2, TAB(FBRANCH
,LONG
)},
461 { 1, 1, 0, 0 }, /* PCREL doesn't come BYTE */
462 { (32767), (-32768), 2, TAB(PCREL
,LONG
)},
466 { (127), (-128), 0, TAB(BCC68000
,SHORT
)},
467 { (32767), (-32768), 2, TAB(BCC68000
,LONG
) },
468 { 0, 0, 6, 0 }, /* jmp long space */
471 { 1, 1, 0, 0 }, /* DBCC doesn't come BYTE */
472 { (32767), (-32768), 2, TAB(DBCC
,LONG
) },
473 { 0, 0, 10, 0 }, /* bra/jmp long space */
476 { 1, 1, 0, 0 }, /* PCLEA doesn't come BYTE */
477 { 32767, -32768, 2, TAB(PCLEA
,LONG
) },
483 /* These are the machine dependent pseudo-ops. These are included so
484 the assembler can work on the output from the SUN C compiler, which
488 /* This table describes all the machine specific pseudo-ops the assembler
489 has to support. The fields are:
490 pseudo-op name without dot
491 function to call to execute this pseudo-op
492 Integer arg to pass to the function
499 void s_align_bytes();
504 const pseudo_typeS md_pseudo_table
[] = {
505 { "xdef", s_globl
, 0 },
506 { "sect", s_sect
, 0 },
508 { "dc.d", float_cons
, 'd' },
509 { "dc.s", float_cons
, 'f' },
513 { "comline", s_ds
, 1 },
521 { "dcb.b", s_dcb
, 1 },
522 { "dcb.w", s_dcb
, 2 },
523 { "dcb.l", s_dcb
, 4 },
524 { "xcom", s_comm
, 0 },
525 { "align", s_align_bytes
, 0 },
526 { "chip", s_chip
, 0 },
531 const pseudo_typeS md_pseudo_table
[] = {
532 { "data1", s_data1
, 0 },
533 { "data2", s_data2
, 0 },
535 { "even", s_even
, 0 },
536 { "skip", s_space
, 0 },
537 { "proc", s_proc
, 0 },
546 /* #define isbyte(x) ((x)>=-128 && (x)<=127) */
547 /* #define isword(x) ((x)>=-32768 && (x)<=32767) */
549 #define issbyte(x) ((x)>=-128 && (x)<=127)
550 #define isubyte(x) ((x)>=0 && (x)<=255)
551 #define issword(x) ((x)>=-32768 && (x)<=32767)
552 #define isuword(x) ((x)>=0 && (x)<=65535)
554 #define isbyte(x) ((x)>=-128 && (x)<=255)
555 #define isword(x) ((x)>=-32768 && (x)<=65535)
556 #define islong(x) (1)
558 extern char *input_line_pointer
;
565 /* JF these tables here are for speed at the expense of size */
566 /* You can replace them with the #if 0 versions if you really
567 need space and don't mind it running a bit slower */
569 static char mklower_table
[256];
570 #define mklower(c) (mklower_table[(unsigned char)(c)])
571 static char notend_table
[256];
572 static char alt_notend_table
[256];
573 #define notend(s) ( !(notend_table[(unsigned char)(*s)] || (*s==':' &&\
574 alt_notend_table[(unsigned char)(s[1])])))
577 #define mklower(c) (isupper(c) ? tolower(c) : c)
580 #define ISSPACE(x) ((x) == ' ' || (x) == '\t')
582 #define MULTIPLIER '*'
585 #define MULTIPLIER ':'
590 /* JF modified this to handle cases where the first part of a symbol name
591 looks like a register */
594 * m68k_reg_parse() := if it looks like a register, return it's token &
595 * advance the pointer.
598 enum _register
m68k_reg_parse(ccp
)
601 #ifndef MAX_REG_NAME_LEN
602 #define MAX_REG_NAME_LEN (6)
603 #endif /* MAX_REG_NAME_LEN */
604 register char c
[MAX_REG_NAME_LEN
];
609 c
[0] = mklower(ccp
[0][0]);
610 #ifdef REGISTER_PREFIX
611 if (c
[0] != REGISTER_PREFIX
) {
616 for (p
= c
, q
= ccp
[0]; p
< c
+ MAX_REG_NAME_LEN
; ++p
, ++q
)
629 if(c
[1]>='0' && c
[1]<='7') {
634 else if (c
[1] == 'c') {
644 if (c
[3] >= '0' && c
[3] <= '7') {
646 ret
= BAD
+ c
[3] - '0';
650 if (c
[3] >= '0' && c
[3] <= '7') {
652 ret
= BAC
+ c
[3] - '0';
655 } else if (c
[1] == 'c') {
663 if (c
[1] == 'a' && c
[2] == 'l') {
668 /* This supports both CCR and CC as the ccr reg. */
669 if(c
[1]=='c' && c
[2]=='r') {
672 } else if(c
[1]=='c') {
675 } else if(c
[1]=='a' && (c
[2]=='a' || c
[2]=='c') && c
[3]=='r') {
677 ret
= c
[2]=='a' ? CAAR
: CACR
;
680 else if (c
[1] == 'r' && c
[2] == 'p') {
687 if (c
[1] >= '0' && c
[1] <= '7') {
689 ret
= DATA
+ c
[1] - '0';
690 } else if (c
[1] == 'f' && c
[2] == 'c') {
693 } else if (c
[1] == 'c') {
696 } else if (c
[1] == 't' && c
[2] == 't') {
697 if ('0' <= c
[3] && c
[3] <= '1') {
699 ret
= DTT0
+ (c
[3] - '0');
703 else if (c
[1] == 'r' && c
[2] == 'p') {
711 if(c
[2]>='0' && c
[2]<='7') {
713 ret
= FPREG
+c
[2]-'0';
716 } else if(c
[2]=='i') {
719 } else if(c
[2]=='s') {
720 n
= (c
[3] == 'r' ? 4 : 3);
722 } else if(c
[2]=='c') {
723 n
= (c
[3] == 'r' ? 4 : 3);
725 } else if (!isalpha(c
[2]) && !isdigit(c
[2])) {
734 if (c
[1] == 's' && c
[2] == 'p') {
737 } else if (c
[1] == 'c') {
740 } else if (c
[1] == 't' && c
[2] == 't') {
741 if ('0' <= c
[3] && c
[3] <= '1') {
743 ret
= ITT0
+ (c
[3] - '0');
748 if (c
[1] == 's' && c
[2] == 'p') {
751 } else if (c
[1] == 'm' && c
[2] == 'u' && c
[3] == 's' && c
[4] == 'r') {
765 if(c
[2] == 's' && c
[3]=='r') {
776 else if (c
[1] == 's' && c
[2] == 'r') {
784 if (c
[1] == 'c' && c
[2] == 'c') {
797 } else if (c
[1] == 'p') {
800 } else if (c
[1] == 'f' && c
[2] == 'c') {
812 if (c
[1] == 's' && c
[2] == 'p') {
815 } else if (c
[1] == 'r' && c
[2] == 'p') {
822 if (c
[1] == 'a' && c
[2] == 'l') {
827 if(c
[1]=='b' && c
[2]=='r') {
833 if(c
[1]=='p' && c
[2]=='c') {
842 #ifdef REGISTER_PREFIX
845 if(isalnum(ccp
[0][n
]) || ccp
[0][n
]=='_')
854 #define SKIP_WHITE() { str++; if(ISSPACE(*str)) str++;}
859 /* Parse an operand from the text *str into the operand struct *opP. */
863 register struct m68k_op
*opP
;
869 /* Skip leading blank */
873 opP
->error
="Missing operand";
876 /* *strend = last character of string */
877 for(strend
=str
;*strend
;strend
++)
881 /* Logic of the parsing switch(*str):
885 REG AREG or DREG or MSCR 3 or 2 or 13
886 REG- or REG/ REGLST 14
891 (EXPR,REG,INDX) AINDX 8
894 EXP2(REG,INDX) AINDX 8
897 REG means truth(m68k_reg_parse(&str))
898 INDX means truth(try_index(&str,opP))
900 EXP2 means not REG and not '(' and not '-('
904 /* "#<expression>" Immediate mode */
906 opP
->con1
=add_exp(str
,strend
);
911 i
=m68k_reg_parse(&str
);
914 /* "Rn" Register Direct mode */
916 if(i
>=DATA
+0 && i
<=DATA
+7)
918 else if(i
>=ADDR
+0 && i
<=ADDR
+7)
924 else if(*str
=='/' || *str
=='-') {
925 /* "Rm-Rn/Ro-Rp" Register list for MOVEM instruction */
927 return get_regs(i
,str
,opP
);
930 opP
->error
="Junk after register name";
937 i
=m68k_reg_parse(&str
);
938 if((i
<ADDR
+0 || i
>ADDR
+7) && i
!=PC
&& i
!=ZPC
&& i
!=FAIL
939 && (*str
!= ')' || str
[1] != '\0' || i
<DATA
+0 || i
>DATA
+7)) {
940 /* Can't indirect off non address regs,
941 but (dx) is OK for cas2. */
942 opP
->error
="Invalid indirect register";
950 /* "(An)" Address Register Indirect mode
951 or "(Dn)" for cas2 instruction. */
952 if (i
< DATA
+ 0 || i
> DATA
+ 7)
960 /* "(An)+" Register Indirect w Postincrement */
965 opP
->error
="Junk after indirect";
970 i
=try_index(&str
,opP
);
971 if(i
==FAIL
) return FAIL
;
972 /* "(An,Rn)" Register Indirect with Index mode*/
977 opP
->error
="Bad indirect syntax";
982 /* "(EXPR,..." , a displacement */
986 if(stmp
=index(str
,',')) {
987 opP
->con1
=add_exp(str
,stmp
-1);
990 i
=m68k_reg_parse(&str
);
991 if((i
<ADDR
+0 || i
>ADDR
+7) && i
!=PC
&& i
!=ZPC
) {
992 /* Can't indirect off non address regs */
993 opP
->error
="Invalid indirect register";
999 /* "(d,An)" Register Indirect w Displacement */
1005 i
=try_index(&str
,opP
);
1006 if(i
==FAIL
) return FAIL
;
1007 /* "(d,An,Rn)" Register Indirect with Index */
1012 opP
->error
="Bad indirect syntax";
1017 opP
->error
="Invalid register";
1022 opP
->error
="Missing register for indirect";
1031 i
=m68k_reg_parse(&str
);
1032 if((i
<ADDR
+0 || i
>ADDR
+7) && i
!=PC
&& i
!=ZPC
&& i
!=FAIL
) {
1033 /* Can't indirect off non address regs */
1034 opP
->error
="Invalid indirect register";
1042 /* "-(An)" Register Indirect with Predecrement */
1046 opP
->error
="Junk after indirect";
1049 opP
->error
="Bad indirect syntax";
1052 opP
->error
="Invalid register";
1055 /* if '-' but not "-(', do nothing */
1058 /* whether *str=='-' or not */
1060 /* "EXP2" or "EXP2(REG..." */
1063 if(stmp
=index(str
,'(')) {
1064 opP
->con1
=add_exp(str
,stmp
-1);
1066 i
=m68k_reg_parse(&str
);
1067 if((i
<ADDR
+0 || i
>ADDR
+7) && i
!=PC
&& i
!=ZPC
) {
1068 /* Can't indirect off non address regs */
1069 opP
->error
="Invalid indirect register";
1075 /* "d(An)" Register Indirect w Displacement */
1081 i
=try_index(&str
,opP
);
1082 if(i
==FAIL
) return FAIL
;
1083 /* "d(An,Rn)" Register Indirect with Index */
1088 opP
->error
="Bad indirect syntax";
1093 opP
->error
="Invalid register";
1098 /* "EXP2" Absolute */
1100 if(strend
[-1]=='.') { /* mode ==foo.[wl] */
1111 opP
->error
="Size spec not .W or .L";
1119 opP
->con1
=add_exp(str
,strend
);
1124 /* end of m68k_ip_op () */
1127 * m68k_ip_op := '#' + <anything>
1128 * | <register> + range_sep + get_regs
1131 * range_sep := '/' | '-' ;
1133 * SKIP_WHITE := <empty> | ' ' ;
1140 register struct m68k_op
*opP
;
1144 char *parse_index();
1146 if (ISSPACE(*str
)) {
1148 } /* Find the beginning of the string */
1151 opP
->error
="Missing operand";
1155 for(strend
= str
; *strend
; strend
++) ;;
1161 opP
->con1
=add_exp(str
,strend
);
1164 } /* Guess what: A constant. Shar and enjoy */
1166 i
= m68k_reg_parse(&str
);
1168 /* is a register, is exactly a register, and is followed by '@' */
1170 if((i
==FAIL
|| *str
!='\0') && *str
!='@') {
1173 if(i
!=FAIL
&& (*str
=='/' || *str
=='-')) {
1175 return(get_regs(i
,str
,opP
));
1177 if ((stmp
=strchr(str
,'@')) != '\0') {
1178 opP
->con1
=add_exp(str
,stmp
-1);
1184 if ((current_architecture
& m68020up
) == 0) {
1186 } /* if target is not a '20 or better */
1189 if(*stmp
++!='(' || *strend
--!=')') {
1190 opP
->error
="Malformed operand";
1193 i
=try_index(&stmp
,opP
);
1194 opP
->con2
=add_exp(stmp
,strend
);
1202 } /* if there's an '@' */
1204 opP
->con1
= add_exp(str
,strend
);
1206 } /* not a register, not exactly a register, or no '@' */
1211 if(i
>=DATA
+0 && i
<=DATA
+7)
1213 else if(i
>=ADDR
+0 && i
<=ADDR
+7)
1220 /* Can't indirect off non address regs, but Dx@ is OK for cas2 */
1221 if((i
<ADDR
+0 || i
>ADDR
+7) && i
!=PC
&& i
!=ZPC
&& i
!=FAIL
1222 && (str
[1] != '\0' || i
<DATA
+0 || i
>DATA
+7)) {
1223 opP
->error
="Invalid indirect register";
1231 if (i
< DATA
+ 0 || i
> DATA
+ 7)
1246 opP
->error
="Junk after indirect";
1249 /* Some kind of indexing involved. Lets find out how bad it is */
1250 i
=try_index(&str
,opP
);
1251 /* Didn't start with an index reg, maybe its offset or offset,reg */
1259 opP
->error
="Missing )";
1261 case ',': i
=0; break;
1262 case '(': i
++; break;
1263 case ')': --i
; break;
1266 /* if(str[-3]==':') {
1283 opP->error="Specified size isn't :w or :l";
1286 opP->con1=add_exp(beg_str,str-4);
1287 opP->con1->e_siz=siz;
1289 opP
->con1
=add_exp(beg_str
,str
-2);
1290 /* Should be offset,reg */
1292 i
=try_index(&str
,opP
);
1294 opP
->error
="Malformed index reg";
1299 /* We've now got offset) offset,reg) or reg) */
1302 /* Th-the-thats all folks */
1303 if (opP
->reg
== FAIL
) opP
->mode
= AINDX
; /* Other form of indirect */
1304 else if(opP
->ireg
== FAIL
) opP
->mode
= AOFF
;
1305 else opP
->mode
= AINDX
;
1308 /* Next thing had better be another @ */
1309 if(*str
!='@' || str
[1]!='(') {
1310 opP
->error
= "junk after indirect";
1314 if ((current_architecture
& m68020up
) == 0) {
1316 } /* if target is not a '20 or better */
1320 if(opP
->ireg
!= FAIL
) {
1323 i
= try_index(&str
, opP
);
1325 opP
->error
= "Two index registers! not allowed!";
1329 i
= try_index(&str
, opP
);
1340 opP
->error
="Missing )";
1342 case ',': i
=0; break;
1343 case '(': i
++; break;
1344 case ')': --i
; break;
1348 opP
->con2
=add_exp(beg_str
,str
-2);
1350 if (str
[-1] == ',') {
1351 if (opP
->ireg
!= FAIL
) {
1352 opP
->error
= "Can't have two index regs";
1356 i
= try_index(&str
, opP
);
1359 opP
->error
= "malformed index reg";
1364 } else if (opP
->ireg
!= FAIL
) {
1374 opP
->error
="Junk after indirect";
1378 } /* m68k_ip_op() */
1382 * try_index := data_or_address_register + ')' + SKIP_W
1383 * | data_or_address_register + ':' + SKIP_W + size_spec + SKIP_W + multiplier + ')' + SKIP_W
1385 * multiplier := <empty>
1386 * | ':' + multiplier_number
1389 * multiplier_number := '1' | '2' | '4' | '8' ;
1391 * size_spec := 'l' | 'L' | 'w' | 'W' ;
1393 * SKIP_W := <empty> | ' ' ;
1397 static int try_index(s
,opP
)
1399 struct m68k_op
*opP
;
1403 #define SKIP_W() { ss++; if (ISSPACE(*ss)) ss++;}
1407 i
=m68k_reg_parse(&ss
);
1408 if(!(i
>=DATA
+0 && i
<=ADDR
+7)) { /* if i is not DATA or ADDR reg */
1423 opP
->error
="Missing : in index register";
1438 opP
->error
="Index register size spec not :w or :l";
1454 opP
->error
="index multiplier not 1, 2, 4 or 8";
1461 opP
->error
="Missing )";
1470 #ifdef TEST1 /* TEST1 tests m68k_ip_op(), which parses operands */
1474 struct m68k_op thark
;
1479 memset(&thark
, '\0', sizeof(thark
));
1480 if(!m68k_ip_op(buf
,&thark
)) printf("FAIL:");
1482 printf("op1 error %s in %s\n",thark
.error
,buf
);
1483 printf("mode %d, reg %d, ",thark
.mode
,thark
.reg
);
1485 printf("Constant: '%.*s',",1+thark
.e_const
-thark
.b_const
,thark
.b_const
);
1486 printf("ireg %d, isiz %d, imul %d ",thark
.ireg
,thark
.isiz
,thark
.imul
);
1488 printf("Iadd: '%.*s'",1+thark
.e_iadd
-thark
.b_iadd
,thark
.b_iadd
);
1497 static struct hash_control
* op_hash
= NULL
; /* handle of the OPCODE hash table
1498 NULL means any use before m68k_ip_begin()
1505 * This converts a string into a 68k instruction.
1506 * The string must be a bare single instruction in sun format
1507 * with RMS-style 68020 indirects
1510 * It provides some error messages: at most one fatal error message (which
1511 * stops the scan) and at most one warning message for each operand.
1512 * The 68k instruction is returned in exploded form, since we have no
1513 * knowledge of how you parse (or evaluate) your expressions.
1514 * We do however strip off and decode addressing modes and operation
1517 * This function's value is a string. If it is not "" then an internal
1518 * logic error was found: read this code to assign meaning to the string.
1519 * No argument string should generate such an error string:
1520 * it means a bug in our code, not in the user's text.
1522 * You MUST have called m68k_ip_begin() once and m86_ip_end() never before using
1526 /* JF this function no longer returns a useful value. Sorry */
1527 void m68k_ip (instring
)
1531 register struct m68k_op
*opP
;
1532 register struct m68k_incant
*opcode
, prev_opcode
;
1534 register int tmpreg
= 0,
1543 char *crack_operand();
1545 LITTLENUM_TYPE words
[6];
1546 LITTLENUM_TYPE
*wordp
;
1548 if (ISSPACE(*instring
))
1549 instring
++; /* skip leading whitespace */
1551 /* Scan up to end of operation-code, which MUST end in end-of-string
1552 or exactly 1 space. */
1553 for (p
= instring
; *p
!= '\0'; p
++)
1558 if (p
== instring
) {
1559 the_ins
.error
= "No operator";
1560 the_ins
.opcode
[0] = NULL
;
1561 /* the_ins.numo=1; */
1565 /* p now points to the end of the opcode name, probably whitespace.
1566 make sure the name is null terminated by clobbering the whitespace,
1567 look it up in the hash table, then fix it back. */
1571 /* Copy from input line to our private buffer, and drop any dots */
1574 char *dst
= our_copy
;
1575 char *src
= instring
;
1585 opcode
= (struct m68k_incant
*)hash_find (op_hash
, our_copy
);
1587 /* If no match, try again with a w suffix */
1592 opcode
= (struct m68k_incant
*)hash_find (op_hash
, our_copy
);
1600 opcode
= (struct m68k_incant
*)hash_find (op_hash
, instring
);
1604 if (opcode
== NULL
) {
1605 the_ins
.error
= "Unknown opcode";
1606 the_ins
.opcode
[0] = NULL
;
1607 /* the_ins.numo=1; */
1611 /* found a legitimate opcode, start matching operands */
1612 while (ISSPACE(*p
)) ++p
;
1614 for(opP
= &the_ins
.operands
[0]; *p
; opP
++) {
1616 p
= crack_operand(p
, opP
);
1619 the_ins
.error
=opP
->error
;
1624 opsfound
= opP
- &the_ins
.operands
[0];
1626 /* This ugly hack is to support the floating pt opcodes in their standard form */
1627 /* Essentially, we fake a first enty of type COP#1 */
1628 if (opcode
->m_operands
[0]=='I') {
1631 for(n
=opsfound
;n
>0;--n
)
1632 the_ins
.operands
[n
]=the_ins
.operands
[n
-1];
1634 /* memcpy((char *)(&the_ins.operands[1]), (char *)(&the_ins.operands[0]), opsfound*sizeof(the_ins.operands[0])); */
1635 memset((char *)(&the_ins
.operands
[0]), '\0', sizeof(the_ins
.operands
[0]));
1636 the_ins
.operands
[0].mode
=MSCR
;
1637 the_ins
.operands
[0].reg
=COPNUM
; /* COP #1 */
1641 /* We've got the operands. Find an opcode that'll accept them */
1642 for (losing
= 0; ; ) {
1643 /* if we didn't get the right number of ops,
1644 or we have no common model with this pattern
1645 then reject this pattern. */
1647 if (opsfound
!= opcode
->m_opnum
1648 || ((opcode
->m_arch
& current_architecture
) == 0)) {
1653 for (s
=opcode
->m_operands
, opP
= &the_ins
.operands
[0]; *s
&& !losing
; s
+= 2, opP
++) {
1654 /* Warning: this switch is huge! */
1655 /* I've tried to organize the cases into this order:
1656 non-alpha first, then alpha by letter. lower-case goes directly
1657 before uppercase counterpart. */
1658 /* Code with multiple case ...: gets sorted by the lowest case ...
1659 it belongs to. I hope this makes sense. */
1662 if (opP
->mode
== MSCR
|| opP
->mode
== IMMED
1663 || opP
->mode
== DREG
|| opP
->mode
== AREG
1664 || opP
->mode
== AINC
|| opP
->mode
== ADEC
1665 || opP
->mode
== REGLST
)
1670 if(opP
->mode
!=IMMED
)
1675 t
=get_num(opP
->con1
,80);
1676 if(s
[1]=='b' && !isbyte(t
))
1678 else if(s
[1]=='w' && !isword(t
))
1685 if(opP
->mode
!=IMMED
)
1690 if(opP
->mode
==MSCR
|| opP
->mode
==AREG
||
1691 opP
->mode
==IMMED
|| opP
->reg
==PC
|| opP
->reg
==ZPC
|| opP
->mode
==REGLST
)
1696 if(opP
->mode
==MSCR
|| opP
->reg
==PC
||
1697 opP
->reg
==ZPC
|| opP
->mode
==REGLST
)
1703 if(opP
->mode
==MSCR
|| opP
->mode
==DREG
||
1704 opP
->mode
==AREG
|| opP
->mode
==IMMED
|| opP
->reg
==PC
|| opP
->reg
==ZPC
||
1705 opP
->mode
==AINC
|| opP
->mode
==ADEC
|| opP
->mode
==REGLST
)
1710 if(opP
->mode
==MSCR
|| opP
->mode
==REGLST
)
1725 if(opP
->mode
==MSCR
|| opP
->mode
==AREG
||
1726 opP
->mode
==AINC
|| opP
->mode
==ADEC
|| opP
->mode
==IMMED
|| opP
->mode
==REGLST
)
1731 if(opP
->mode
==MSCR
|| opP
->mode
==AREG
|| opP
->mode
==REGLST
)
1736 if(opP
->mode
==MSCR
|| opP
->mode
==AREG
||
1737 opP
->mode
==AINC
|| opP
->mode
==ADEC
|| opP
->mode
==IMMED
|| opP
->reg
==PC
||
1738 opP
->reg
==ZPC
|| opP
->mode
==REGLST
)
1743 if(opP
->mode
==MSCR
|| opP
->mode
==AREG
||
1744 opP
->mode
==IMMED
|| opP
->mode
==REGLST
)
1748 case '~': /* For now! (JF FOO is this right?) */
1749 if(opP
->mode
==MSCR
|| opP
->mode
==DREG
||
1750 opP
->mode
==AREG
|| opP
->mode
==IMMED
|| opP
->reg
==PC
|| opP
->reg
==ZPC
|| opP
->mode
==REGLST
)
1759 if (opP
->mode
!= AINDR
) {
1761 } /* if not address register indirect */
1764 if(opP
->mode
!=ABSL
|| (flagseen
['S'] && instring
[0] == 'j'
1765 && instring
[1] == 'b'
1766 && instring
[2] == 's'
1767 && instring
[3] == 'r'))
1772 if(opP
->mode
!=MSCR
|| opP
->reg
!=CCR
)
1776 case 'd': /* FOO This mode is a KLUDGE!! */
1777 if(opP
->mode
!=AOFF
&& (opP
->mode
!=ABSL
||
1778 opP
->con1
->e_beg
[0]!='(' || opP
->con1
->e_end
[0]!=')'))
1788 if(opP
->mode
!=MSCR
|| opP
->reg
<(FPREG
+0) || opP
->reg
>(FPREG
+7))
1793 if(opP
->mode
!=MSCR
|| opP
->reg
<COPNUM
||
1799 if (opP
->mode
!= MSCR
1802 || cpu_of_arch(current_architecture
) < m68010
/* before 68010 had none */
1803 || (cpu_of_arch(current_architecture
) < m68020
1807 && opP
->reg
!= VBR
) /* 68010's had only these */
1808 || (cpu_of_arch(current_architecture
) < m68040
1816 && opP
->reg
!= ISP
) /* 680[23]0's have only these */
1817 || (cpu_of_arch(current_architecture
) == m68040
/* 68040 has all but this */
1818 && opP
->reg
== CAAR
)) {
1820 } /* doesn't cut it */
1824 if(opP
->mode
!=IMMED
)
1830 if(opP
->mode
==DREG
|| opP
->mode
==AREG
|| opP
->mode
==FPREG
) {
1835 opP
->reg
=1<<(opP
->reg
-DATA
);
1837 } else if(opP
->mode
!=REGLST
) {
1839 } else if(s
[1]=='8' && opP
->reg
&0x0FFffFF)
1841 else if(s
[1]=='3' && opP
->reg
&0x7000000)
1846 if(opP
->mode
!=IMMED
)
1851 t
=get_num(opP
->con1
,80);
1852 if(!issbyte(t
) || isvar(opP
->con1
))
1858 if(opP
->mode
!=DREG
&& opP
->mode
!=IMMED
)
1863 if(opP
->mode
!=IMMED
)
1868 t
=get_num(opP
->con1
,80);
1869 if(t
<1 || t
>8 || isvar(opP
->con1
))
1875 if(opP
->mode
!=DREG
&& opP
->mode
!=AREG
)
1880 if(opP
->mode
!=AINDR
&& opP
->mode
!=DINDR
)
1885 if(opP
->mode
!=MSCR
|| !(opP
->reg
==FPI
|| opP
->reg
==FPS
|| opP
->reg
==FPC
))
1890 if(opP
->mode
!=MSCR
|| opP
->reg
!=SR
)
1895 if(opP
->mode
!=MSCR
|| opP
->reg
!=USP
)
1899 /* JF these are out of order. We could put them
1900 in order if we were willing to put up with
1901 bunches of #ifdef m68851s in the code */
1903 /* Memory addressing mode used by pflushr */
1905 if(opP
->mode
==MSCR
|| opP
->mode
==DREG
||
1906 opP
->mode
==AREG
|| opP
->mode
==REGLST
)
1911 if (opP
->mode
!= MSCR
|| (opP
->reg
!= SFC
&& opP
->reg
!= DFC
))
1916 if (opP
->mode
!= MSCR
|| (opP
->reg
!= TC
&& opP
->reg
!= CAL
&&
1917 opP
->reg
!= VAL
&& opP
->reg
!= SCC
&& opP
->reg
!= AC
))
1922 if (opP
->reg
!= VAL
)
1927 if (opP
->mode
!= MSCR
|| (opP
->reg
!= DRP
&& opP
->reg
!= SRP
&&
1933 if (opP
->mode
!= MSCR
||
1934 (!(opP
->reg
>= BAD
&& opP
->reg
<= BAD
+7) &&
1935 !(opP
->reg
>= BAC
&& opP
->reg
<= BAC
+7)))
1940 if (opP
->reg
!= PSR
)
1945 if (opP
->reg
!= PCSR
)
1953 && opP
->reg
!= BC
) {
1955 } /* not a cache specifier. */
1959 if (opP
->mode
!= ABSL
) {
1961 } /* not absolute */
1965 as_fatal("Internal error: Operand mode %c unknown in line %s of file \"%s\"",
1966 *s
, __LINE__
, __FILE__
);
1967 } /* switch on type of operand */
1970 } /* for each operand */
1971 } /* if immediately wrong */
1978 if (!opcode
->m_next
)
1980 if ((opcode
->m_arch
& current_architecture
) == 0)
1982 the_ins
.error
= "Opcode not available on architecture specified";
1988 the_ins
.error
= "instruction/operands mismatch";
1992 } /* Fell off the end */
1993 opcode
= opcode
->m_next
;
1997 /* now assemble it */
1999 the_ins
.args
=opcode
->m_operands
;
2000 the_ins
.numargs
=opcode
->m_opnum
;
2001 the_ins
.numo
=opcode
->m_codenum
;
2002 the_ins
.opcode
[0]=getone(opcode
);
2003 the_ins
.opcode
[1]=gettwo(opcode
);
2005 for (s
= the_ins
.args
, opP
= &the_ins
.operands
[0]; *s
; s
+= 2, opP
++) {
2006 /* This switch is a doozy.
2007 Watch the first step; its a big one! */
2025 tmpreg
=0x3c; /* 7.4 */
2026 if (strchr("bwl",s
[1])) nextword
=get_num(opP
->con1
,80);
2027 else nextword
=nextword
=get_num(opP
->con1
,0);
2028 if(isvar(opP
->con1
))
2029 add_fix(s
[1],opP
->con1
,0);
2032 if(!isbyte(nextword
))
2033 opP
->error
="operand out of range";
2038 if(!isword(nextword
))
2039 opP
->error
="operand out of range";
2044 addword(nextword
>>16);
2066 as_fatal("Internal error: Can't decode %c%c in line %s of file \"%s\"",
2067 *s
, s
[1], __LINE__
, __FILE__
);
2072 /* We gotta put out some float */
2073 if(seg(opP
->con1
)!=SEG_BIG
) {
2074 int_to_gen(nextword
);
2075 gen_to_words(words
,baseo
,(long int)outro
);
2076 for(wordp
=words
;baseo
--;wordp
++)
2080 if(offs(opP
->con1
)>0) {
2081 as_warn("Bignum assumed to be binary bit-pattern");
2082 if(offs(opP
->con1
)>baseo
) {
2083 as_warn("Bignum too big for %c format; truncated",s
[1]);
2084 offs(opP
->con1
)=baseo
;
2086 baseo
-=offs(opP
->con1
);
2087 for(wordp
=generic_bignum
+offs(opP
->con1
)-1;offs(opP
->con1
)--;--wordp
)
2093 gen_to_words(words
,baseo
,(long)outro
);
2094 for (wordp
=words
;baseo
--;wordp
++)
2098 tmpreg
=opP
->reg
-DATA
; /* 0.dreg */
2101 tmpreg
=0x08+opP
->reg
-ADDR
; /* 1.areg */
2104 tmpreg
=0x10+opP
->reg
-ADDR
; /* 2.areg */
2107 tmpreg
=0x20+opP
->reg
-ADDR
; /* 4.areg */
2110 tmpreg
=0x18+opP
->reg
-ADDR
; /* 3.areg */
2114 nextword
=get_num(opP
->con1
,80);
2115 /* Force into index mode. Hope this works */
2117 /* We do the first bit for 32-bit displacements,
2118 and the second bit for 16 bit ones. It is
2119 possible that we should make the default be
2120 WORD instead of LONG, but I think that'd
2121 break GCC, so we put up with a little
2122 inefficiency for the sake of working output.
2125 if( !issword(nextword
)
2126 || ( isvar(opP
->con1
)
2127 && ( ( opP
->con1
->e_siz
==0
2128 && flagseen
['l']==0)
2129 || opP
->con1
->e_siz
==3))) {
2132 tmpreg
=0x3B; /* 7.3 */
2134 tmpreg
=0x30+opP
->reg
-ADDR
; /* 6.areg */
2135 if(isvar(opP
->con1
)) {
2137 add_frag(adds(opP
->con1
),
2139 TAB(PCLEA
,SZ_UNDEF
));
2143 add_fix('l',opP
->con1
,1);
2147 addword(nextword
>>16);
2150 tmpreg
=0x3A; /* 7.2 */
2152 tmpreg
=0x28+opP
->reg
-ADDR
; /* 5.areg */
2154 if(isvar(opP
->con1
)) {
2156 add_fix('w',opP
->con1
,1);
2158 add_fix('w',opP
->con1
,0);
2167 know(current_architecture
& m68020up
);
2168 /* intentional fall-through */
2171 baseo
=get_num(opP
->con1
,80);
2172 outro
=get_num(opP
->con2
,80);
2173 /* Figure out the 'addressing mode' */
2174 /* Also turn on the BASE_DISABLE bit, if needed */
2175 if(opP
->reg
==PC
|| opP
->reg
==ZPC
) {
2176 tmpreg
=0x3b; /* 7.3 */
2179 } else if(opP
->reg
==FAIL
) {
2181 tmpreg
=0x30; /* 6.garbage */
2182 } else tmpreg
=0x30+opP
->reg
-ADDR
; /* 6.areg */
2184 siz1
= (opP
->con1
) ? opP
->con1
->e_siz
: 0;
2185 siz2
= (opP
->con2
) ? opP
->con2
->e_siz
: 0;
2187 /* Index register stuff */
2188 if(opP
->ireg
>=DATA
+0 && opP
->ireg
<=ADDR
+7) {
2189 nextword
|=(opP
->ireg
-DATA
)<<12;
2191 if(opP
->isiz
==0 || opP
->isiz
==3)
2195 case 2: nextword
|=0x200; break;
2196 case 4: nextword
|=0x400; break;
2197 case 8: nextword
|=0x600; break;
2198 default: as_fatal("failed sanity check.");
2201 GET US OUT OF HERE! */
2203 /* Must be INDEX, with an index
2204 register. Address register
2205 cannot be ZERO-PC, and either
2206 :b was forced, or we know
2208 if( opP
->mode
==AINDX
2213 && !isvar(opP
->con1
)))) {
2214 nextword
+=baseo
&0xff;
2216 if(isvar(opP
->con1
))
2217 add_fix('B',opP
->con1
,0);
2221 nextword
|=0x40; /* No index reg */
2223 /* It aint simple */
2225 /* If the guy specified a width, we assume that
2226 it is wide enough. Maybe it isn't. If so, we lose
2230 if(isvar(opP
->con1
) || !issword(baseo
)) {
2241 as_warn("Byte dispacement won't work. Defaulting to :w");
2250 /* Figure out innner displacement stuff */
2251 if(opP
->mode
!=AINDX
) {
2254 if(isvar(opP
->con2
) || !issword(outro
)) {
2265 as_warn("Byte dispacement won't work. Defaulting to :w");
2273 if(opP
->mode
==APODX
) nextword
|=0x04;
2274 else if(opP
->mode
==AMIND
) nextword
|=0x40;
2278 if(isvar(opP
->con1
)) {
2279 if(opP
->reg
==PC
|| opP
->reg
==ZPC
) {
2280 add_fix(siz1
==3 ? 'l' : 'w',opP
->con1
,1);
2281 opP
->con1
->e_exp
.X_add_number
+=6;
2283 add_fix(siz1
==3 ? 'l' : 'w',opP
->con1
,0);
2290 if(isvar(opP
->con2
)) {
2291 if(opP
->reg
==PC
|| opP
->reg
==ZPC
) {
2292 add_fix(siz2
==3 ? 'l' : 'w',opP
->con2
,1);
2293 opP
->con1
->e_exp
.X_add_number
+=6;
2295 add_fix(siz2
==3 ? 'l' : 'w',opP
->con2
,0);
2305 nextword
=get_num(opP
->con1
,80);
2306 switch(opP
->con1
->e_siz
) {
2308 as_warn("Unknown size for absolute reference");
2310 if(!isvar(opP
->con1
) && issword(offs(opP
->con1
))) {
2311 tmpreg
=0x38; /* 7.0 */
2315 /* Don't generate pc relative code
2316 on 68010 and 68000 */
2319 && seg(opP
->con1
) == SEG_TEXT
2320 && now_seg
== SEG_TEXT
2321 && cpu_of_arch(current_architecture
) < m68020
2323 && !strchr("~%&$?", s
[0])) {
2324 tmpreg
=0x3A; /* 7.2 */
2325 add_frag(adds(opP
->con1
),
2327 TAB(PCREL
,SZ_UNDEF
));
2330 case 3: /* Fall through into long */
2331 if(isvar(opP
->con1
))
2332 add_fix('l',opP
->con1
,0);
2334 tmpreg
=0x39; /* 7.1 mode */
2335 addword(nextword
>>16);
2340 if(isvar(opP
->con1
))
2341 add_fix('w',opP
->con1
,0);
2343 tmpreg
=0x38; /* 7.0 mode */
2349 as_bad("invalid indirect register");
2353 as_bad("unknown/incorrect operand");
2356 install_gen_operand(s
[1],tmpreg
);
2361 switch(s
[1]) { /* JF: I hate floating point! */
2376 tmpreg
=get_num(opP
->con1
,tmpreg
);
2377 if(isvar(opP
->con1
))
2378 add_fix(s
[1],opP
->con1
,0);
2380 case 'b': /* Danger: These do no check for
2381 certain types of overflow.
2384 opP
->error
="out of range";
2386 if(isvar(opP
->con1
))
2387 the_ins
.reloc
[the_ins
.nrel
-1].n
=(opcode
->m_codenum
)*2;
2391 opP
->error
="out of range";
2393 if(isvar(opP
->con1
))
2394 the_ins
.reloc
[the_ins
.nrel
-1].n
=(opcode
->m_codenum
)*2;
2397 insop(tmpreg
); /* Because of the way insop works, we put these two out backwards */
2399 if(isvar(opP
->con1
))
2400 the_ins
.reloc
[the_ins
.nrel
-1].n
=(opcode
->m_codenum
)*2;
2406 install_operand(s
[1],tmpreg
);
2409 as_fatal("Internal error: Unknown mode #%c in line %s of file \"%s\"", s
[1], __LINE__
, __FILE__
);
2417 install_operand(s
[1],opP
->reg
-ADDR
);
2421 tmpreg
=get_num(opP
->con1
,80);
2424 /* Needs no offsetting */
2425 add_fix('B',opP
->con1
,1);
2428 /* Offset the displacement to be relative to byte disp location */
2429 opP
->con1
->e_exp
.X_add_number
+=2;
2430 add_fix('w',opP
->con1
,1);
2435 if (cpu_of_arch(current_architecture
) < m68020
) /* 68000 or 010 */
2436 as_warn("Can't use long branches on 68000/68010");
2437 the_ins
.opcode
[the_ins
.numo
-1]|=0xff;
2438 /* Offset the displacement to be relative to byte disp location */
2439 opP
->con1
->e_exp
.X_add_number
+=4;
2440 add_fix('l',opP
->con1
,1);
2445 if(subs(opP
->con1
)) /* We can't relax it */
2448 /* This could either be a symbol, or an
2449 absolute address. No matter, the
2450 frag hacking will finger it out.
2451 Not quite: it can't switch from
2452 BRANCH to BCC68000 for the case
2453 where opnd is absolute (it needs
2454 to use the 68000 hack since no
2455 conditional abs jumps). */
2456 if (((cpu_of_arch(current_architecture
) < m68020
) || (0==adds(opP
->con1
)))
2457 && (the_ins
.opcode
[0] >= 0x6200)
2458 && (the_ins
.opcode
[0] <= 0x6f00)) {
2459 add_frag(adds(opP
->con1
),offs(opP
->con1
),TAB(BCC68000
,SZ_UNDEF
));
2461 add_frag(adds(opP
->con1
),offs(opP
->con1
),TAB(BRANCH
,SZ_UNDEF
));
2465 if(isvar(opP
->con1
)) {
2466 /* check for DBcc instruction */
2467 if ((the_ins
.opcode
[0] & 0xf0f8) ==0x50c8) {
2468 /* size varies if patch */
2469 /* needed for long form */
2470 add_frag(adds(opP
->con1
),offs(opP
->con1
),TAB(DBCC
,SZ_UNDEF
));
2475 opP
->con1
->e_exp
.X_add_number
+=2;
2476 add_fix('w',opP
->con1
,1);
2480 case 'C': /* Fixed size LONG coproc branches */
2481 the_ins
.opcode
[the_ins
.numo
-1]|=0x40;
2482 /* Offset the displacement to be relative to byte disp location */
2483 /* Coproc branches don't have a byte disp option, but they are
2484 compatible with the ordinary branches, which do... */
2485 opP
->con1
->e_exp
.X_add_number
+=4;
2486 add_fix('l',opP
->con1
,1);
2490 case 'c': /* Var size Coprocesssor branches */
2491 if(subs(opP
->con1
)) {
2492 add_fix('l',opP
->con1
,1);
2493 add_frag((symbolS
*)0,(long)0,TAB(FBRANCH
,LONG
));
2494 } else if(adds(opP
->con1
)) {
2495 add_frag(adds(opP
->con1
),offs(opP
->con1
),TAB(FBRANCH
,SZ_UNDEF
));
2497 /* add_frag((symbolS *)0,offs(opP->con1),TAB(FBRANCH,SHORT)); */
2498 the_ins
.opcode
[the_ins
.numo
-1]|=0x40;
2499 add_fix('l',opP
->con1
,1);
2505 as_fatal("Internal error: operand type B%c unknown in line %s of file \"%s\"",
2506 s
[1], __LINE__
, __FILE__
);
2510 case 'C': /* Ignore it */
2513 case 'd': /* JF this is a kludge */
2514 if(opP
->mode
==AOFF
) {
2515 install_operand('s',opP
->reg
-ADDR
);
2519 tmpP
=opP
->con1
->e_end
-2;
2521 opP
->con1
->e_end
-=4; /* point to the , */
2522 baseo
=m68k_reg_parse(&tmpP
);
2523 if(baseo
<ADDR
+0 || baseo
>ADDR
+7) {
2524 as_bad("Unknown address reg, using A0");
2527 install_operand('s',baseo
);
2529 tmpreg
=get_num(opP
->con1
,80);
2530 if(!issword(tmpreg
)) {
2531 as_warn("Expression out of range, using 0");
2538 install_operand(s
[1],opP
->reg
-DATA
);
2542 install_operand(s
[1],opP
->reg
-FPREG
);
2546 tmpreg
=1+opP
->reg
-COPNUM
;
2549 install_operand(s
[1],tmpreg
);
2552 case 'J': /* JF foo */
2554 case SFC
: tmpreg
=0x000; break;
2555 case DFC
: tmpreg
=0x001; break;
2556 case CACR
: tmpreg
=0x002; break;
2557 case TC
: tmpreg
=0x003; break;
2558 case ITT0
: tmpreg
=0x004; break;
2559 case ITT1
: tmpreg
=0x005; break;
2560 case DTT0
: tmpreg
=0x006; break;
2561 case DTT1
: tmpreg
=0x007; break;
2563 case USP
: tmpreg
=0x800; break;
2564 case VBR
: tmpreg
=0x801; break;
2565 case CAAR
: tmpreg
=0x802; break;
2566 case MSP
: tmpreg
=0x803; break;
2567 case ISP
: tmpreg
=0x804; break;
2568 case MMUSR
: tmpreg
=0x805; break;
2569 case URP
: tmpreg
=0x806; break;
2570 case SRP
: tmpreg
=0x807; break;
2572 as_fatal("failed sanity check.");
2574 install_operand(s
[1],tmpreg
);
2578 tmpreg
=get_num(opP
->con1
,55);
2579 install_operand(s
[1],tmpreg
&0x7f);
2585 if(tmpreg
&0x7FF0000)
2586 as_bad("Floating point register in register list");
2587 insop(reverse_16_bits(tmpreg
));
2589 if(tmpreg
&0x700FFFF)
2590 as_bad("Wrong register in floating-point reglist");
2591 install_operand(s
[1],reverse_8_bits(tmpreg
>>16));
2598 if(tmpreg
&0x7FF0000)
2599 as_bad("Floating point register in register list");
2601 } else if(s
[1]=='8') {
2602 if(tmpreg
&0x0FFFFFF)
2603 as_bad("incorrect register in reglist");
2604 install_operand(s
[1],tmpreg
>>24);
2606 if(tmpreg
&0x700FFFF)
2607 as_bad("wrong register in floating-point reglist");
2609 install_operand(s
[1],tmpreg
>>16);
2614 install_operand(s
[1],get_num(opP
->con1
,60));
2618 tmpreg
= (opP
->mode
==DREG
)
2619 ? 0x20+opP
->reg
-DATA
2620 : (get_num(opP
->con1
,40)&0x1F);
2621 install_operand(s
[1],tmpreg
);
2625 tmpreg
=get_num(opP
->con1
,10);
2628 install_operand(s
[1],tmpreg
);
2633 /* This depends on the fact that ADDR registers are
2634 eight more than their corresponding DATA regs, so
2635 the result will have the ADDR_REG bit set */
2636 install_operand(s
[1],opP
->reg
-DATA
);
2640 if(opP
->reg
==FPI
) tmpreg
=0x1;
2641 else if(opP
->reg
==FPS
) tmpreg
=0x2;
2642 else if(opP
->reg
==FPC
) tmpreg
=0x4;
2643 else as_fatal("failed sanity check.");
2644 install_operand(s
[1],tmpreg
);
2647 case 'S': /* Ignore it */
2651 install_operand(s
[1],get_num(opP
->con1
,30));
2654 case 'U': /* Ignore it */
2659 case NC
: tmpreg
= 0; break;
2660 case DC
: tmpreg
= 1; break;
2661 case IC
: tmpreg
= 2; break;
2662 case BC
: tmpreg
= 3; break;
2664 as_fatal("failed sanity check");
2665 } /* switch on cache token */
2666 install_operand(s
[1], tmpreg
);
2669 /* JF: These are out of order, I fear. */
2679 as_fatal("failed sanity check.");
2681 install_operand(s
[1],tmpreg
);
2702 as_fatal("failed sanity check.");
2704 install_operand(s
[1],tmpreg
);
2708 if (opP
->reg
== VAL
)
2710 as_fatal("failed sanity check.");
2725 as_fatal("failed sanity check.");
2727 install_operand(s
[1],tmpreg
);
2732 case BAD
: case BAD
+1: case BAD
+2: case BAD
+3:
2733 case BAD
+4: case BAD
+5: case BAD
+6: case BAD
+7:
2734 tmpreg
= (4 << 10) | ((opP
->reg
- BAD
) << 2);
2737 case BAC
: case BAC
+1: case BAC
+2: case BAC
+3:
2738 case BAC
+4: case BAC
+5: case BAC
+6: case BAC
+7:
2739 tmpreg
= (5 << 10) | ((opP
->reg
- BAC
) << 2);
2743 as_fatal("failed sanity check.");
2745 install_operand(s
[1], tmpreg
);
2748 know(opP
->reg
== PSR
);
2751 know(opP
->reg
== PCSR
);
2755 tmpreg
=get_num(opP
->con1
,80);
2756 install_operand(s
[1], tmpreg
);
2759 as_fatal("Internal error: Operand type %c unknown in line %s of file \"%s\"", s
[0], __LINE__
, __FILE__
);
2762 /* By the time whe get here (FINALLY) the_ins contains the complete
2763 instruction, ready to be emitted. . . */
2767 * get_regs := '/' + ?
2768 * | '-' + <register>
2769 * | '-' + <register> + ?
2774 * The idea here must be to scan in a set of registers but I don't
2775 * understand it. Looks awfully sloppy to me but I don't have any doc on
2782 static int get_regs(i
,str
,opP
)
2784 struct m68k_op
*opP
;
2787 /* 26, 25, 24, 23-16, 15-8, 0-7 */
2788 /* Low order 24 bits encoded fpc,fps,fpi,fp7-fp0,a7-a0,d7-d0 */
2789 unsigned long cur_regs
= 0;
2793 #define ADD_REG(x) { if(x==FPI) cur_regs|=(1<<24);\
2794 else if(x==FPS) cur_regs|=(1<<25);\
2795 else if(x==FPC) cur_regs|=(1<<26);\
2796 else cur_regs|=(1<<(x-1)); }
2803 } else if(*str
=='-') {
2805 reg2
=m68k_reg_parse(&str
);
2806 if(reg2
<DATA
|| reg2
>=FPREG
+8 || reg1
==FPI
|| reg1
==FPS
|| reg1
==FPC
) {
2807 opP
->error
="unknown register in register list";
2816 } else if(*str
=='\0') {
2820 opP
->error
="unknow character in register list";
2823 /* DJA -- Bug Fix. Did't handle d1-d2/a1 until the following instruction was added */
2826 reg1
=m68k_reg_parse(&str
);
2827 if((reg1
<DATA
|| reg1
>=FPREG
+8) && !(reg1
==FPI
|| reg1
==FPS
|| reg1
==FPC
)) {
2828 opP
->error
="unknown register in register list";
2836 static int reverse_16_bits(in
)
2842 static int mask
[16] = {
2843 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
2844 0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000
2851 } /* reverse_16_bits() */
2853 static int reverse_8_bits(in
)
2859 static int mask
[8] = {
2860 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
2868 } /* reverse_8_bits() */
2870 static void install_operand(mode
,val
)
2876 the_ins
.opcode
[0]|=val
& 0xFF; /* JF FF is for M kludge */
2879 the_ins
.opcode
[0]|=val
<<9;
2882 the_ins
.opcode
[1]|=val
<<12;
2885 the_ins
.opcode
[1]|=val
<<6;
2888 the_ins
.opcode
[1]|=val
;
2891 the_ins
.opcode
[2]|=val
<<12;
2894 the_ins
.opcode
[2]|=val
<<6;
2897 /* DANGER! This is a hack to force cas2l and cas2w cmds
2898 to be three words long! */
2900 the_ins
.opcode
[2]|=val
;
2903 the_ins
.opcode
[1]|=val
<<7;
2906 the_ins
.opcode
[1]|=val
<<10;
2910 the_ins
.opcode
[1]|=val
<<5;
2915 the_ins
.opcode
[1]|=(val
<<10)|(val
<<7);
2918 the_ins
.opcode
[1]|=(val
<<12)|val
;
2921 the_ins
.opcode
[0]|=val
=0xff;
2924 the_ins
.opcode
[0]|=val
<<9;
2927 the_ins
.opcode
[1]|=val
;
2930 the_ins
.opcode
[1]|=val
;
2931 the_ins
.numo
++; /* What a hack */
2934 the_ins
.opcode
[1]|=val
<<4;
2941 the_ins
.opcode
[0] |= (val
<< 6);
2944 the_ins
.opcode
[1] = (val
>> 16);
2945 the_ins
.opcode
[2] = val
& 0xffff;
2949 as_fatal("failed sanity check.");
2951 } /* install_operand() */
2953 static void install_gen_operand(mode
,val
)
2959 the_ins
.opcode
[0]|=val
;
2962 /* This is a kludge!!! */
2963 the_ins
.opcode
[0]|=(val
&0x07)<<9|(val
&0x38)<<3;
2972 the_ins
.opcode
[0]|=val
;
2974 /* more stuff goes here */
2976 as_fatal("failed sanity check.");
2978 } /* install_gen_operand() */
2981 * verify that we have some number of paren pairs, do m68k_ip_op(), and
2982 * then deal with the bitfield hack.
2985 static char *crack_operand(str
,opP
)
2987 register struct m68k_op
*opP
;
2989 register int parens
;
2991 register char *beg_str
;
2997 for(parens
=0;*str
&& (parens
>0 || notend(str
));str
++) {
2998 if(*str
=='(') parens
++;
2999 else if(*str
==')') {
3000 if(!parens
) { /* ERROR */
3001 opP
->error
="Extra )";
3007 if(!*str
&& parens
) { /* ERROR */
3008 opP
->error
="Missing )";
3013 if(m68k_ip_op(beg_str
,opP
)==FAIL
) {
3020 c
= *++str
; /* JF bitfield hack */
3025 as_bad("Missing operand");
3030 /* See the comment up above where the #define notend(... is */
3035 if(*s
==',') return 0;
3036 if(*s
=='{' || *s
=='}')
3038 if(*s
!=':') return 1;
3039 /* This kludge here is for the division cmd, which is a kludge */
3040 if(index("aAdD#(",s
[1])) return 0;
3046 int done_pseudo(str
)
3049 extern struct hash_control
* po_hash
;
3056 is_end_of_line
[0] = 1;
3057 /* Skip over name of pseudo, change to lower case */
3058 while (isalpha(*ptr
) || *ptr
== '.')
3060 if (isupper(*ptr
)) {
3061 *ptr
= tolower(*ptr
);
3070 pop
= (pseudo_typeS
*)hash_find(po_hash
, str
);
3073 if (pop
!= (pseudo_typeS
*)NULL
)
3075 input_line_pointer
= null_ptr
+1;
3077 /* Now we point to first non-blank char after pseudo op */
3078 (*pop
->poc_handler
)(pop
->poc_val
);
3079 input_line_pointer
--;
3084 /* Just put back the char where the null was put and return as if nothing had happened */
3092 /* This is the guts of the machine-dependent assembler. STR points to a
3093 machine dependent instruction. This function is supposed to emit
3094 the frags/bytes it assembles to.
3105 int shorts_this_frag
;
3107 /* if (done_pseudo(str)) return ;*/
3111 if (current_architecture
== 0) {
3112 current_architecture
= (m68020
3120 } /* default current_architecture */
3122 memset((char *)(&the_ins
), '\0', sizeof(the_ins
)); /* JF for paranoia sake */
3127 for(n
=the_ins
.numargs
;n
;--n
)
3128 if(the_ins
.operands
[n
].error
) {
3129 er
=the_ins
.operands
[n
].error
;
3134 as_bad("\"%s\" -- Statement '%s' ignored",er
,str
);
3138 if(the_ins
.nfrag
==0) { /* No frag hacking involved; just put it out */
3139 toP
=frag_more(2*the_ins
.numo
);
3140 fromP
= &the_ins
.opcode
[0];
3141 for(m
=the_ins
.numo
;m
;--m
) {
3142 md_number_to_chars(toP
,(long)(*fromP
),2);
3146 /* put out symbol-dependent info */
3147 for(m
=0;m
<the_ins
.nrel
;m
++) {
3148 switch(the_ins
.reloc
[m
].wid
) {
3165 as_fatal("Don't know how to figure width of %c in md_assemble()",the_ins
.reloc
[m
].wid
);
3169 (toP
-frag_now
->fr_literal
)-the_ins
.numo
*2+the_ins
.reloc
[m
].n
,
3171 the_ins
.reloc
[m
].add
,
3172 the_ins
.reloc
[m
].sub
,
3173 the_ins
.reloc
[m
].off
,
3174 the_ins
.reloc
[m
].pcrel
,
3180 /* There's some frag hacking */
3181 for(n
=0,fromP
= &the_ins
.opcode
[0];n
<the_ins
.nfrag
;n
++) {
3184 if(n
==0) wid
=2*the_ins
.fragb
[n
].fragoff
;
3185 else wid
=2*(the_ins
.numo
-the_ins
.fragb
[n
-1].fragoff
);
3189 for(m
=wid
/2;m
;--m
) {
3190 md_number_to_chars(toP
,(long)(*fromP
),2);
3195 for(m
=0;m
<the_ins
.nrel
;m
++) {
3196 if((the_ins
.reloc
[m
].n
)>= 2*shorts_this_frag
/* 2*the_ins.fragb[n].fragoff */) {
3197 the_ins
.reloc
[m
].n
-= 2*shorts_this_frag
/* 2*the_ins.fragb[n].fragoff */;
3200 wid
=the_ins
.reloc
[m
].wid
;
3203 the_ins
.reloc
[m
].wid
=0;
3204 wid
= (wid
=='b') ? 1 : (wid
=='w') ? 2 : (wid
=='l') ? 4 : 4000;
3207 (toP
-frag_now
->fr_literal
)-the_ins
.numo
*2+the_ins
.reloc
[m
].n
,
3209 the_ins
.reloc
[m
].add
,
3210 the_ins
.reloc
[m
].sub
,
3211 the_ins
.reloc
[m
].off
,
3212 the_ins
.reloc
[m
].pcrel
,
3215 /* know(the_ins.fragb[n].fadd); */
3216 (void)frag_var(rs_machine_dependent
,10,0,(relax_substateT
)(the_ins
.fragb
[n
].fragty
),
3217 the_ins
.fragb
[n
].fadd
,the_ins
.fragb
[n
].foff
,to_beg_P
);
3219 n
=(the_ins
.numo
-the_ins
.fragb
[n
-1].fragoff
);
3222 toP
=frag_more(n
*sizeof(short));
3224 md_number_to_chars(toP
,(long)(*fromP
),2);
3230 for(m
=0;m
<the_ins
.nrel
;m
++) {
3233 wid
=the_ins
.reloc
[m
].wid
;
3236 the_ins
.reloc
[m
].wid
=0;
3237 wid
= (wid
=='b') ? 1 : (wid
=='w') ? 2 : (wid
=='l') ? 4 : 4000;
3240 (the_ins
.reloc
[m
].n
+ toP
-frag_now
->fr_literal
)- /* the_ins.numo */ shorts_this_frag
*2,
3242 the_ins
.reloc
[m
].add
,
3243 the_ins
.reloc
[m
].sub
,
3244 the_ins
.reloc
[m
].off
,
3245 the_ins
.reloc
[m
].pcrel
,
3250 /* This function is called once, at assembler startup time. This should
3251 set up all the tables, etc that the MD part of the assembler needs
3257 * md_begin -- set up hash tables with 68000 instructions.
3258 * similar to what the vax assembler does. ---phr
3260 /* RMS claims the thing to do is take the m68k-opcode.h table, and make
3261 a copy of it at runtime, adding in the information we want but isn't
3262 there. I think it'd be better to have an awk script hack the table
3263 at compile time. Or even just xstr the table and use it as-is. But
3264 my lord ghod hath spoken, so we do it this way. Excuse the ugly var
3267 register const struct m68k_opcode
*ins
;
3268 register struct m68k_incant
*hack
,
3270 register char *retval
= 0; /* empty string, or error msg text */
3271 register unsigned int i
;
3274 if ((op_hash
= hash_new()) == NULL
)
3275 as_fatal("Virtual memory exhausted");
3277 obstack_begin(&robyn
,4000);
3278 for (ins
= m68k_opcodes
; ins
< endop
; ins
++) {
3279 hack
=slak
=(struct m68k_incant
*)obstack_alloc(&robyn
,sizeof(struct m68k_incant
));
3281 /* we *could* ignore insns that don't match our
3282 arch here but just leaving them out of the
3284 slak
->m_operands
=ins
->args
;
3285 slak
->m_opnum
=strlen(slak
->m_operands
)/2;
3286 slak
->m_arch
= ins
->arch
;
3287 slak
->m_opcode
=ins
->opcode
;
3288 /* This is kludgey */
3289 slak
->m_codenum
=((ins
->match
)&0xffffL
) ? 2 : 1;
3290 if((ins
+1)!=endop
&& !strcmp(ins
->name
,(ins
+1)->name
)) {
3291 slak
->m_next
=(struct m68k_incant
*) obstack_alloc(&robyn
,sizeof(struct m68k_incant
));
3298 retval
= hash_insert (op_hash
, ins
->name
,(char *)hack
);
3299 /* Didn't his mommy tell him about null pointers? */
3300 if(retval
&& *retval
)
3301 as_fatal("Internal Error: Can't hash %s: %s",ins
->name
,retval
);
3304 for (i
= 0; i
< sizeof(mklower_table
) ; i
++)
3305 mklower_table
[i
] = (isupper(c
= (char) i
)) ? tolower(c
) : c
;
3307 for (i
= 0 ; i
< sizeof(notend_table
) ; i
++) {
3308 notend_table
[i
] = 0;
3309 alt_notend_table
[i
] = 0;
3311 notend_table
[','] = 1;
3312 notend_table
['{'] = 1;
3313 notend_table
['}'] = 1;
3314 alt_notend_table
['a'] = 1;
3315 alt_notend_table
['A'] = 1;
3316 alt_notend_table
['d'] = 1;
3317 alt_notend_table
['D'] = 1;
3318 alt_notend_table
['#'] = 1;
3319 alt_notend_table
['f'] = 1;
3320 alt_notend_table
['F'] = 1;
3321 alt_notend_table
['('] = 1;
3323 #ifdef REGISTER_PREFIX
3324 alt_notend_table
[REGISTER_PREFIX
] = 1;
3331 #define notend(s) ((*s == ',' || *s == '}' || *s == '{' \
3332 || (*s == ':' && strchr("aAdD#(", s[1]))) \
3336 /* This funciton is called once, before the assembler exits. It is
3337 supposed to do any final cleanup for this part of the assembler.
3344 /* Equal to MAX_PRECISION in atof-ieee.c */
3345 #define MAX_LITTLENUMS 6
3347 /* Turn a string in str into a floating point constant of type
3348 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
3349 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
3352 md_atof(type
,litP
,sizeP
)
3358 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
3359 LITTLENUM_TYPE
*wordP
;
3390 return "Bad call to MD_ATOF()";
3392 t
=atof_ieee(input_line_pointer
,type
,words
);
3394 input_line_pointer
=t
;
3396 *sizeP
=prec
* sizeof(LITTLENUM_TYPE
);
3397 for(wordP
=words
;prec
--;) {
3398 md_number_to_chars(litP
,(long)(*wordP
++),sizeof(LITTLENUM_TYPE
));
3399 litP
+=sizeof(LITTLENUM_TYPE
);
3401 return ""; /* Someone should teach Dean about null pointers */
3404 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
3405 for use in the a.out file, and stores them in the array pointed to by buf.
3406 This knows about the endian-ness of the target machine and does
3407 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
3408 2 (short) and 4 (long) Floating numbers are put out as a series of
3409 LITTLENUMS (shorts, here at least)
3412 md_number_to_chars(buf
,val
,n
)
3432 as_fatal("failed sanity check.");
3437 md_apply_fix(fixP
, val
)
3441 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3443 switch(fixP
->fx_size
) {
3458 BAD_CASE (fixP
->fx_size
);
3463 /* *fragP has been relaxed to its final size, and now needs to have
3464 the bytes inside it modified to conform to the new size There is UGLY
3468 md_convert_frag(headers
, fragP
)
3469 object_headers
*headers
;
3470 register fragS
*fragP
;
3475 /* Address in object code of the displacement. */
3476 register int object_address
= fragP
-> fr_fix
+ fragP
-> fr_address
;
3478 #ifdef IBM_COMPILER_SUX
3479 /* This is wrong but it convinces the native rs6000 compiler to
3480 generate the code we want. */
3481 register char *buffer_address
= fragP
-> fr_literal
;
3482 buffer_address
+= fragP
-> fr_fix
;
3483 #else /* IBM_COMPILER_SUX */
3484 /* Address in gas core of the place to store the displacement. */
3485 register char *buffer_address
= fragP
->fr_fix
+ fragP
->fr_literal
;
3486 #endif /* IBM_COMPILER_SUX */
3488 /* No longer true: know(fragP->fr_symbol); */
3490 /* The displacement of the address, from current location. */
3491 disp
= fragP
->fr_symbol
? S_GET_VALUE(fragP
->fr_symbol
) : 0;
3492 disp
= (disp
+ fragP
->fr_offset
) - object_address
;
3494 switch(fragP
->fr_subtype
) {
3495 case TAB(BCC68000
,BYTE
):
3496 case TAB(BRANCH
,BYTE
):
3497 know(issbyte(disp
));
3499 as_bad("short branch with zero offset: use :w");
3500 fragP
->fr_opcode
[1]=disp
;
3503 case TAB(DBCC
,SHORT
):
3504 know(issword(disp
));
3507 case TAB(BCC68000
,SHORT
):
3508 case TAB(BRANCH
,SHORT
):
3509 know(issword(disp
));
3510 fragP
->fr_opcode
[1]=0x00;
3513 case TAB(BRANCH
,LONG
):
3514 if (cpu_of_arch(current_architecture
) < m68020
) {
3515 if (fragP
->fr_opcode
[0]==0x61) {
3516 fragP
->fr_opcode
[0]= 0x4E;
3517 fragP
->fr_opcode
[1]= 0xB9; /* JBSR with ABSL LONG offset */
3518 subseg_change(SEG_TEXT
, 0);
3531 } else if (fragP
->fr_opcode
[0]==0x60) {
3532 fragP
->fr_opcode
[0]= 0x4E;
3533 fragP
->fr_opcode
[1]= 0xF9; /* JMP with ABSL LONG offset */
3534 subseg_change(SEG_TEXT
, 0);
3535 fix_new(fragP
, fragP
->fr_fix
, 4, fragP
->fr_symbol
, 0, fragP
->fr_offset
,0,
3540 as_bad("Long branch offset not supported.");
3543 fragP
->fr_opcode
[1]=0xff;
3547 case TAB(BCC68000
,LONG
):
3548 /* only Bcc 68000 instructions can come here */
3549 /* change bcc into b!cc/jmp absl long */
3550 fragP
->fr_opcode
[0] ^= 0x01; /* invert bcc */
3551 fragP
->fr_opcode
[1] = 0x6; /* branch offset = 6 */
3553 /* JF: these used to be fr_opcode[2,3], but they may be in a
3554 different frag, in which case refering to them is a no-no.
3555 Only fr_opcode[0,1] are guaranteed to work. */
3556 *buffer_address
++ = 0x4e; /* put in jmp long (0x4ef9) */
3557 *buffer_address
++ = 0xf9;
3558 fragP
->fr_fix
+= 2; /* account for jmp instruction */
3559 subseg_change(SEG_TEXT
,0);
3560 fix_new(fragP
, fragP
->fr_fix
, 4, fragP
->fr_symbol
, 0,
3566 case TAB(DBCC
,LONG
):
3567 /* only DBcc 68000 instructions can come here */
3568 /* change dbcc into dbcc/jmp absl long */
3569 /* JF: these used to be fr_opcode[2-7], but that's wrong */
3570 *buffer_address
++ = 0x00; /* branch offset = 4 */
3571 *buffer_address
++ = 0x04;
3572 *buffer_address
++ = 0x60; /* put in bra pc+6 */
3573 *buffer_address
++ = 0x06;
3574 *buffer_address
++ = 0x4e; /* put in jmp long (0x4ef9) */
3575 *buffer_address
++ = 0xf9;
3577 fragP
->fr_fix
+= 6; /* account for bra/jmp instructions */
3578 subseg_change(SEG_TEXT
,0);
3579 fix_new(fragP
, fragP
->fr_fix
, 4, fragP
->fr_symbol
, 0,
3585 case TAB(FBRANCH
,SHORT
):
3586 know((fragP
->fr_opcode
[1]&0x40)==0);
3589 case TAB(FBRANCH
,LONG
):
3590 fragP
->fr_opcode
[1]|=0x40; /* Turn on LONG bit */
3593 case TAB(PCREL
,SHORT
):
3596 case TAB(PCREL
,LONG
):
3597 /* The thing to do here is force it to ABSOLUTE LONG, since
3598 PCREL is really trying to shorten an ABSOLUTE address anyway */
3599 /* JF FOO This code has not been tested */
3600 subseg_change(SEG_TEXT
,0);
3601 fix_new(fragP
, fragP
->fr_fix
, 4, fragP
->fr_symbol
, 0, fragP
->fr_offset
, 0, NO_RELOC
);
3602 if((fragP
->fr_opcode
[1] & 0x3F) != 0x3A)
3603 as_bad("Internal error (long PC-relative operand) for insn 0x%04lx at 0x%lx",
3604 fragP
->fr_opcode
[0],fragP
->fr_address
);
3605 fragP
->fr_opcode
[1]&= ~0x3F;
3606 fragP
->fr_opcode
[1]|=0x39; /* Mode 7.1 */
3608 /* md_number_to_chars(buffer_address,
3609 (long)(fragP->fr_symbol->sy_value + fragP->fr_offset),
3613 case TAB(PCLEA
,SHORT
):
3614 subseg_change(SEG_TEXT
,0);
3615 fix_new(fragP
,(int)(fragP
->fr_fix
),2,fragP
->fr_symbol
,(symbolS
*)0,fragP
->fr_offset
,1,
3617 fragP
->fr_opcode
[1] &= ~0x3F;
3618 fragP
->fr_opcode
[1] |= 0x3A;
3621 case TAB(PCLEA
,LONG
):
3622 subseg_change(SEG_TEXT
,0);
3623 fix_new(fragP
,(int)(fragP
->fr_fix
)+2,4,fragP
->fr_symbol
,(symbolS
*)0,fragP
->fr_offset
+2,1,
3625 *buffer_address
++ = 0x01;
3626 *buffer_address
++ = 0x70;
3628 /* buffer_address+=2; */
3632 } /* switch on subtype */
3635 md_number_to_chars(buffer_address
, (long) disp
, (int) ext
);
3636 fragP
->fr_fix
+= ext
;
3637 /* H_SET_TEXT_SIZE(headers, H_GET_TEXT_SIZE(headers) + ext); */
3638 } /* if extending */
3641 } /* md_convert_frag() */
3643 /* Force truly undefined symbols to their maximum size, and generally set up
3644 the frag list to be relaxed
3646 int md_estimate_size_before_relax(fragP
, segment
)
3647 register fragS
*fragP
;
3651 register char *buffer_address
= fragP
->fr_fix
+ fragP
->fr_literal
;
3653 old_fix
= fragP
->fr_fix
;
3655 /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */
3656 switch(fragP
->fr_subtype
) {
3658 case TAB(BRANCH
,SZ_UNDEF
): {
3659 if((fragP
->fr_symbol
!= NULL
) /* Not absolute */
3660 && S_GET_SEGMENT(fragP
->fr_symbol
) == segment
) {
3661 fragP
->fr_subtype
=TAB(TABTYPE(fragP
->fr_subtype
),BYTE
);
3663 } else if((fragP
->fr_symbol
== 0) || (cpu_of_arch(current_architecture
) < m68020
)) {
3664 /* On 68000, or for absolute value, switch to abs long */
3665 /* FIXME, we should check abs val, pick short or long */
3666 if(fragP
->fr_opcode
[0]==0x61) {
3667 fragP
->fr_opcode
[0]= 0x4E;
3668 fragP
->fr_opcode
[1]= 0xB9; /* JBSR with ABSL LONG offset */
3669 subseg_change(SEG_TEXT
, 0);
3670 fix_new(fragP
, fragP
->fr_fix
, 4,
3671 fragP
->fr_symbol
, 0, fragP
->fr_offset
, 0, NO_RELOC
);
3674 } else if(fragP
->fr_opcode
[0]==0x60) {
3675 fragP
->fr_opcode
[0]= 0x4E;
3676 fragP
->fr_opcode
[1]= 0xF9; /* JMP with ABSL LONG offset */
3677 subseg_change(SEG_TEXT
, 0);
3678 fix_new(fragP
, fragP
->fr_fix
, 4,
3679 fragP
->fr_symbol
, 0, fragP
->fr_offset
, 0, NO_RELOC
);
3683 as_warn("Long branch offset to extern symbol not supported.");
3685 } else { /* Symbol is still undefined. Make it simple */
3686 fix_new(fragP
, (int)(fragP
->fr_fix
), 4, fragP
->fr_symbol
,
3687 (symbolS
*)0, fragP
->fr_offset
+4, 1, NO_RELOC
);
3689 fragP
->fr_opcode
[1]=0xff;
3695 } /* case TAB(BRANCH,SZ_UNDEF) */
3697 case TAB(FBRANCH
,SZ_UNDEF
): {
3698 if(S_GET_SEGMENT(fragP
->fr_symbol
) == segment
|| flagseen
['l']) {
3699 fragP
->fr_subtype
= TAB(FBRANCH
,SHORT
);
3702 fragP
->fr_subtype
= TAB(FBRANCH
,LONG
);
3706 } /* TAB(FBRANCH,SZ_UNDEF) */
3708 case TAB(PCREL
,SZ_UNDEF
): {
3709 if(S_GET_SEGMENT(fragP
->fr_symbol
) == segment
|| flagseen
['l']) {
3710 fragP
->fr_subtype
= TAB(PCREL
,SHORT
);
3713 fragP
->fr_subtype
= TAB(PCREL
,LONG
);
3717 } /* TAB(PCREL,SZ_UNDEF) */
3719 case TAB(BCC68000
,SZ_UNDEF
): {
3720 if((fragP
->fr_symbol
!= NULL
)
3721 && S_GET_SEGMENT(fragP
->fr_symbol
) == segment
) {
3722 fragP
->fr_subtype
=TAB(BCC68000
,BYTE
);
3725 /* only Bcc 68000 instructions can come here */
3726 /* change bcc into b!cc/jmp absl long */
3727 fragP
->fr_opcode
[0] ^= 0x01; /* invert bcc */
3729 fragP
->fr_opcode
[1] = 0x04; /* branch offset = 6 */
3730 /* JF: these were fr_opcode[2,3] */
3731 buffer_address
[0] = 0x4e; /* put in jmp long (0x4ef9) */
3732 buffer_address
[1] = 0xf8;
3733 fragP
->fr_fix
+= 2; /* account for jmp instruction */
3734 subseg_change(SEG_TEXT
,0);
3735 fix_new(fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
, 0,
3736 fragP
->fr_offset
, 0, NO_RELOC
);
3739 fragP
->fr_opcode
[1] = 0x06; /* branch offset = 6 */
3740 /* JF: these were fr_opcode[2,3] */
3741 buffer_address
[2] = 0x4e; /* put in jmp long (0x4ef9) */
3742 buffer_address
[3] = 0xf9;
3743 fragP
->fr_fix
+= 2; /* account for jmp instruction */
3744 subseg_change(SEG_TEXT
,0);
3745 fix_new(fragP
, fragP
->fr_fix
, 4, fragP
->fr_symbol
, 0,
3746 fragP
->fr_offset
, 0, NO_RELOC
);
3751 } /* case TAB(BCC68000,SZ_UNDEF) */
3753 case TAB(DBCC
,SZ_UNDEF
): {
3754 if (fragP
->fr_symbol
!= NULL
&& S_GET_SEGMENT(fragP
->fr_symbol
) == segment
) {
3755 fragP
->fr_subtype
=TAB(DBCC
,SHORT
);
3759 /* only DBcc 68000 instructions can come here */
3760 /* change dbcc into dbcc/jmp absl long */
3761 /* JF: these used to be fr_opcode[2-4], which is wrong. */
3762 buffer_address
[0] = 0x00; /* branch offset = 4 */
3763 buffer_address
[1] = 0x04;
3764 buffer_address
[2] = 0x60; /* put in bra pc + ... */
3767 /* JF: these were fr_opcode[5-7] */
3768 buffer_address
[3] = 0x04; /* plus 4 */
3769 buffer_address
[4] = 0x4e;/* Put in Jump Word */
3770 buffer_address
[5] = 0xf8;
3771 fragP
->fr_fix
+= 6; /* account for bra/jmp instruction */
3772 subseg_change(SEG_TEXT
,0);
3773 fix_new(fragP
, fragP
->fr_fix
, 2, fragP
->fr_symbol
, 0,
3774 fragP
->fr_offset
, 0, NO_RELOC
);
3777 /* JF: these were fr_opcode[5-7] */
3778 buffer_address
[3] = 0x06; /* Plus 6 */
3779 buffer_address
[4] = 0x4e; /* put in jmp long (0x4ef9) */
3780 buffer_address
[5] = 0xf9;
3781 fragP
->fr_fix
+= 6; /* account for bra/jmp instruction */
3782 subseg_change(SEG_TEXT
,0);
3783 fix_new(fragP
, fragP
->fr_fix
, 4, fragP
->fr_symbol
, 0,
3784 fragP
->fr_offset
, 0, NO_RELOC
);
3790 } /* case TAB(DBCC,SZ_UNDEF) */
3792 case TAB(PCLEA
,SZ_UNDEF
): {
3793 if ((S_GET_SEGMENT(fragP
->fr_symbol
))==segment
|| flagseen
['l']) {
3794 fragP
->fr_subtype
=TAB(PCLEA
,SHORT
);
3797 fragP
->fr_subtype
=TAB(PCLEA
,LONG
);
3801 } /* TAB(PCLEA,SZ_UNDEF) */
3806 } /* switch on subtype looking for SZ_UNDEF's. */
3808 /* now that SZ_UNDEF are taken care of, check others */
3809 switch(fragP
->fr_subtype
) {
3810 case TAB(BCC68000
,BYTE
):
3811 case TAB(BRANCH
,BYTE
):
3812 /* We can't do a short jump to the next instruction,
3813 so we force word mode. */
3814 if (fragP
->fr_symbol
&& S_GET_VALUE(fragP
->fr_symbol
)==0 &&
3815 fragP
->fr_symbol
->sy_frag
==fragP
->fr_next
) {
3816 fragP
->fr_subtype
=TAB(TABTYPE(fragP
->fr_subtype
),SHORT
);
3823 return fragP
->fr_var
+ fragP
->fr_fix
- old_fix
;
3826 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
3827 /* the bit-field entries in the relocation_info struct plays hell
3828 with the byte-order problems of cross-assembly. So as a hack,
3829 I added this mach. dependent ri twiddler. Ugly, but it gets
3831 /* on m68k: first 4 bytes are normal unsigned long, next three bytes
3832 are symbolnum, most sig. byte first. Last byte is broken up with
3833 bit 7 as pcrel, bits 6 & 5 as length, bit 4 as pcrel, and the lower
3834 nibble as nuthin. (on Sun 3 at least) */
3835 /* Translate the internal relocation information into target-specific
3839 md_ri_to_chars(the_bytes
, ri
)
3841 struct reloc_info_generic
*ri
;
3844 md_number_to_chars(the_bytes
, ri
->r_address
, 4);
3845 /* now the fun stuff */
3846 the_bytes
[4] = (ri
->r_symbolnum
>> 16) & 0x0ff;
3847 the_bytes
[5] = (ri
->r_symbolnum
>> 8) & 0x0ff;
3848 the_bytes
[6] = ri
->r_symbolnum
& 0x0ff;
3849 the_bytes
[7] = (((ri
->r_pcrel
<< 7) & 0x80) | ((ri
->r_length
<< 5) & 0x60) |
3850 ((ri
->r_extern
<< 4) & 0x10));
3852 #endif /* comment */
3854 void tc_aout_fix_to_chars(where
, fixP
, segment_address_in_file
)
3857 relax_addressT segment_address_in_file
;
3860 * In: length of relocation (or of address) in chars: 1, 2 or 4.
3861 * Out: GNU LD relocation length code: 0, 1, or 2.
3864 static unsigned char nbytes_r_length
[] = { 42, 0, 1, 42, 2 };
3870 md_number_to_chars(where
,
3871 fixP
->fx_frag
->fr_address
+ fixP
->fx_where
- segment_address_in_file
,
3874 /* now the fun stuff */
3875 if (S_GET_TYPE(fixP
->fx_addsy
) == N_UNDF
) {
3877 r_symbolnum
= fixP
->fx_addsy
->sy_number
;
3880 r_symbolnum
= S_GET_TYPE(fixP
->fx_addsy
);
3883 where
[4] = (r_symbolnum
>> 16) & 0x0ff;
3884 where
[5] = (r_symbolnum
>> 8) & 0x0ff;
3885 where
[6] = r_symbolnum
& 0x0ff;
3886 where
[7] = (((fixP
->fx_pcrel
<< 7) & 0x80) | ((nbytes_r_length
[fixP
->fx_size
] << 5) & 0x60) |
3887 ((r_extern
<< 4) & 0x10));
3890 } /* tc_aout_fix_to_chars() */
3892 #endif /* OBJ_AOUT or OBJ_BOUT */
3894 #ifndef WORKING_DOT_WORD
3895 const int md_short_jump_size
= 4;
3896 const int md_long_jump_size
= 6;
3899 md_create_short_jump(ptr
,from_addr
,to_addr
,frag
,to_symbol
)
3908 offset
= to_addr
- (from_addr
+2);
3910 md_number_to_chars(ptr
,(long)0x6000,2);
3911 md_number_to_chars(ptr
+2,(long)offset
,2);
3915 md_create_long_jump(ptr
,from_addr
,to_addr
,frag
,to_symbol
)
3924 if (cpu_of_arch(current_architecture
) < m68020
) {
3925 offset
=to_addr
-S_GET_VALUE(to_symbol
);
3926 md_number_to_chars(ptr
,(long)0x4EF9,2);
3927 md_number_to_chars(ptr
+2,(long)offset
,4);
3928 fix_new(frag
,(ptr
+2)-frag
->fr_literal
,4,to_symbol
,(symbolS
*)0,(long)0,0,
3931 offset
=to_addr
- (from_addr
+2);
3932 md_number_to_chars(ptr
,(long)0x60ff,2);
3933 md_number_to_chars(ptr
+2,(long)offset
,4);
3938 /* Different values of OK tell what its OK to return. Things that aren't OK are an error (what a shock, no?)
3941 10: Absolute 1:8 only
3942 20: Absolute 0:7 only
3943 30: absolute 0:15 only
3944 40: Absolute 0:31 only
3945 50: absolute 0:127 only
3946 55: absolute -64:63 only
3947 60: absolute -128:127 only
3948 70: absolute 0:4095 only
3953 static int get_num(exp
,ok
)
3954 struct m68k_exp
*exp
;
3962 if(*exp
->e_beg
=='0') {
3963 if(exp
->e_beg
[1]=='x')
3964 sscanf(exp
->e_beg
+2,"%x",&l
);
3966 sscanf(exp
->e_beg
+1,"%O",&l
);
3969 return atol(exp
->e_beg
);
3975 /* Can't do anything */
3978 if(!exp
->e_beg
|| !exp
->e_end
) {
3979 seg(exp
)=SEG_ABSOLUTE
;
3982 offs(exp
)= (ok
==10) ? 1 : 0;
3983 as_warn("Null expression defaults to %ld",offs(exp
));
3988 if(/* ok!=80 && */exp
->e_end
[-1]==SIZER
&& (exp
->e_end
-exp
->e_beg
)>=2) {
3989 switch(exp
->e_end
[0]) {
4005 as_bad("Unknown size for expression \"%c\"",exp
->e_end
[0]);
4009 c_save
=exp
->e_end
[1];
4011 save_in
=input_line_pointer
;
4012 input_line_pointer
=exp
->e_beg
;
4013 switch(expression(&(exp
->e_exp
))) {
4015 seg(exp
)=SEG_ABSOLUTE
;
4018 offs(exp
)= (ok
==10) ? 1 : 0;
4019 as_warn("Unknown expression: '%s' defaulting to %d",exp
->e_beg
,offs(exp
));
4023 /* Do the same thing the VAX asm does */
4024 seg(exp
)=SEG_ABSOLUTE
;
4029 as_warn("expression out of range: defaulting to 1");
4036 if(offs(exp
)<1 || offs(exp
)>8) {
4037 as_warn("expression out of range: defaulting to 1");
4042 if(offs(exp
)<0 || offs(exp
)>7)
4046 if(offs(exp
)<0 || offs(exp
)>15)
4050 if(offs(exp
)<0 || offs(exp
)>32)
4054 if(offs(exp
)<0 || offs(exp
)>127)
4058 if(offs(exp
)<-64 || offs(exp
)>63)
4062 if(offs(exp
)<-128 || offs(exp
)>127)
4066 if(offs(exp
)<0 || offs(exp
)>4095) {
4068 as_warn("expression out of range: defaulting to 0");
4080 case SEG_DIFFERENCE
:
4081 if(ok
>=10 && ok
<=70) {
4082 seg(exp
)=SEG_ABSOLUTE
;
4085 offs(exp
)= (ok
==10) ? 1 : 0;
4086 as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp
->e_beg
,offs(exp
));
4090 if(ok
==80 && offs(exp
)<0) { /* HACK! Turn it into a long */
4091 LITTLENUM_TYPE words
[6];
4093 gen_to_words(words
,2,8L);/* These numbers are magic! */
4094 seg(exp
)=SEG_ABSOLUTE
;
4097 offs(exp
)=words
[1]|(words
[0]<<16);
4099 seg(exp
)=SEG_ABSOLUTE
;
4102 offs(exp
)= (ok
==10) ? 1 : 0;
4103 as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp
->e_beg
,offs(exp
));
4107 as_fatal("failed sanity check.");
4109 if(input_line_pointer
!=exp
->e_end
+1)
4110 as_bad("Ignoring junk after expression");
4111 exp
->e_end
[1]=c_save
;
4112 input_line_pointer
=save_in
;
4114 switch(exp
->e_siz
) {
4116 if(!isbyte(offs(exp
)))
4117 as_warn("expression doesn't fit in BYTE");
4120 if(!isword(offs(exp
)))
4121 as_warn("expression doesn't fit in WORD");
4129 /* These are the back-ends for the various machine dependent pseudo-ops. */
4130 void demand_empty_rest_of_line(); /* Hate those extra verbose names */
4132 static void s_data1() {
4133 subseg_new(SEG_DATA
,1);
4134 demand_empty_rest_of_line();
4137 static void s_data2() {
4138 subseg_new(SEG_DATA
,2);
4139 demand_empty_rest_of_line();
4142 static void s_bss() {
4143 /* We don't support putting frags in the BSS segment, but we
4144 can put them into initialized data for now... */
4145 subseg_new(SEG_DATA
,255); /* FIXME-SOON */
4146 demand_empty_rest_of_line();
4149 static void s_even() {
4151 register long temp_fill
;
4153 temp
= 1; /* JF should be 2? */
4154 temp_fill
= get_absolute_expression ();
4155 if ( ! need_pass_2
) /* Never make frag if expect extra pass. */
4156 frag_align (temp
, (int)temp_fill
);
4157 demand_empty_rest_of_line();
4160 static void s_proc() {
4161 demand_empty_rest_of_line();
4164 /* s_space is defined in read.c .skip is simply an alias to it. */
4168 * Invocation line includes a switch not recognized by the base assembler.
4169 * See if it's a processor-specific option. These are:
4171 * -[A]m[c]68000, -[A]m[c]68008, -[A]m[c]68010, -[A]m[c]68020, -[A]m[c]68030, -[A]m[c]68040
4172 * -[A]m[c]68881, -[A]m[c]68882, -[A]m[c]68851
4173 * Select the architecture. Instructions or features not
4174 * supported by the selected architecture cause fatal
4175 * errors. More than one may be specified. The default is
4176 * -m68020 -m68851 -m68881. Note that -m68008 is a synonym
4177 * for -m68000, and -m68882 is a synonym for -m68881.
4179 * MAYBE_FLOAT_TOO is defined below so that specifying a processor type
4180 * (e.g. m68020) also requests that float instructions be included. This
4181 * is the default setup, mostly to avoid hassling users. A better
4182 * rearrangement of this structure would be to add an option to DENY
4183 * floating point opcodes, for people who want to really know there's none
4184 * of that funny floaty stuff going on. FIXME-later.
4186 #ifndef MAYBE_FLOAT_TOO
4187 #define MAYBE_FLOAT_TOO m68881
4190 int md_parse_option(argP
,cntP
,vecP
)
4196 case 'l': /* -l means keep external to 2 bit offset
4197 rather than 16 bit one */
4200 case 'S': /* -S means that jbsr's always turn into jsr's. */
4205 /* intentional fall-through */
4211 } /* allow an optional "c" */
4213 if (!strcmp(*argP
, "68000")
4214 || !strcmp(*argP
, "68008")) {
4215 current_architecture
|= m68000
;
4216 } else if (!strcmp(*argP
, "68010")) {
4218 omagic
= 1<<16|OMAGIC
;
4220 current_architecture
|= m68010
;
4222 } else if (!strcmp(*argP
, "68020")) {
4223 current_architecture
|= m68020
| MAYBE_FLOAT_TOO
;
4225 } else if (!strcmp(*argP
, "68030")) {
4226 current_architecture
|= m68030
| MAYBE_FLOAT_TOO
;
4228 } else if (!strcmp(*argP
, "68040")) {
4229 current_architecture
|= m68040
| MAYBE_FLOAT_TOO
;
4232 } else if (!strcmp(*argP
, "68881")) {
4233 current_architecture
|= m68881
;
4235 } else if (!strcmp(*argP
, "68882")) {
4236 current_architecture
|= m68882
;
4238 #endif /* NO_68881 */
4240 } else if (!strcmp(*argP
,"68851")) {
4241 current_architecture
|= m68851
;
4243 #endif /* NO_68851 */
4245 as_warn("Unknown architecture, \"%s\". option ignored", *argP
);
4246 } /* switch on architecture */
4248 while(**argP
) (*argP
)++;
4253 if (!strcmp(*argP
,"pic")) {
4255 break; /* -pic, Position Independent Code */
4269 /* TEST2: Test md_assemble() */
4270 /* Warning, this routine probably doesn't work anymore */
4274 struct m68k_it the_ins
;
4281 if(!gets(buf
) || !*buf
)
4283 if(buf
[0]=='|' || buf
[1]=='.')
4285 for(cp
=buf
;*cp
;cp
++)
4290 memset(&the_ins
, '\0', sizeof(the_ins
));
4291 m68k_ip(&the_ins
,buf
);
4293 printf("Error %s in %s\n",the_ins
.error
,buf
);
4295 printf("Opcode(%d.%s): ",the_ins
.numo
,the_ins
.args
);
4296 for(n
=0;n
<the_ins
.numo
;n
++)
4297 printf(" 0x%x",the_ins
.opcode
[n
]&0xffff);
4299 print_the_insn(&the_ins
.opcode
[0],stdout
);
4300 (void)putchar('\n');
4302 for(n
=0;n
<strlen(the_ins
.args
)/2;n
++) {
4303 if(the_ins
.operands
[n
].error
) {
4304 printf("op%d Error %s in %s\n",n
,the_ins
.operands
[n
].error
,buf
);
4307 printf("mode %d, reg %d, ",the_ins
.operands
[n
].mode
,the_ins
.operands
[n
].reg
);
4308 if(the_ins
.operands
[n
].b_const
)
4309 printf("Constant: '%.*s', ",1+the_ins
.operands
[n
].e_const
-the_ins
.operands
[n
].b_const
,the_ins
.operands
[n
].b_const
);
4310 printf("ireg %d, isiz %d, imul %d, ",the_ins
.operands
[n
].ireg
,the_ins
.operands
[n
].isiz
,the_ins
.operands
[n
].imul
);
4311 if(the_ins
.operands
[n
].b_iadd
)
4312 printf("Iadd: '%.*s',",1+the_ins
.operands
[n
].e_iadd
-the_ins
.operands
[n
].b_iadd
,the_ins
.operands
[n
].b_iadd
);
4313 (void)putchar('\n');
4323 while(ISSPACE(*str
))
4325 while(*str
&& !ISSPACE(*str
))
4327 if(str
[-1]==':' || str
[1]=='=')
4334 /* Possible states for relaxation:
4336 0 0 branch offset byte (bra, etc)
4340 1 0 indexed offsets byte a0@(32,d4:w:1) etc
4344 2 0 two-offset index word-word a0@(32,d4)@(45) etc
4363 extern fragS
*text_frag_root
;
4365 for(fragP
=text_frag_root
;fragP
;fragP
=fragP
->fr_next
) {
4366 printf("addr %lu next 0x%x fix %ld var %ld symbol 0x%x offset %ld\n",
4367 fragP
->fr_address
,fragP
->fr_next
,fragP
->fr_fix
,fragP
->fr_var
,fragP
->fr_symbol
,fragP
->fr_offset
);
4368 printf("opcode 0x%x type %d subtype %d\n\n",fragP
->fr_opcode
,fragP
->fr_type
,fragP
->fr_subtype
);
4380 fputs("Internal error:",stderr
);
4381 _doprnt(format
,&args
,stderr
);
4382 (void)putc('\n',stderr
);
4388 /* We have no need to default values of symbols. */
4392 md_undefined_symbol (name
)
4398 /* Parse an operand that is machine-specific.
4399 We just return without modifying the expression if we have nothing
4404 md_operand (expressionP
)
4405 expressionS
*expressionP
;
4409 /* Round up a section size to the appropriate boundary. */
4411 md_section_align (segment
, size
)
4415 return size
; /* Byte alignment is fine */
4418 /* Exactly what point is a PC-relative offset relative TO?
4419 On the 68k, they're relative to the address of the offset, plus
4420 its size. (??? Is this right? FIXME-SOON!) */
4422 md_pcrel_from (fixP
)
4425 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
4431 unsigned int fill
= get_absolute_expression() * size
;
4432 char *p
= frag_var (rs_fill
, fill
, fill
, (relax_substateT
)0, (symbolS
*)0,
4435 demand_empty_rest_of_line();
4448 int repeat
= get_absolute_expression();
4451 if (*input_line_pointer
== ',')
4454 input_line_pointer
++;
4456 fill
= get_absolute_expression();
4457 p
= frag_var(rs_fill
,
4464 md_number_to_chars(p
, fill
, size
);
4466 demand_empty_rest_of_line();
4473 unsigned int target
= get_absolute_expression();
4474 #define MACHINE_MASK (m68000 | m68008 | m68010 | m68020 | m68040)
4479 current_architecture
= (current_architecture
& ~ MACHINE_MASK
) | m68000
;
4482 current_architecture
= (current_architecture
& ~ MACHINE_MASK
) | m68010
;
4485 current_architecture
= (current_architecture
& ~ MACHINE_MASK
) | m68020
;
4488 current_architecture
= (current_architecture
& ~ MACHINE_MASK
) | m68030
;
4491 current_architecture
= (current_architecture
& ~ MACHINE_MASK
) | m68040
;
4494 current_architecture
|= m68881
;
4497 current_architecture
|= m68882
;
4500 current_architecture
|= m68851
;
4504 as_bad("Unrecognised CHIP %d\n", target
);
4507 demand_empty_rest_of_line();
4519 /* end of tc-m68kmote.c */